forked from pool/ocfs2-tools
Autobuild autoformatter for 53417
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/ocfs2-tools?expand=0&rev=29
This commit is contained in:
parent
329320a471
commit
ea8f27edae
@ -1,843 +0,0 @@
|
||||
From 1f8bab1217e89bd3f2e0bbd9934dd07fc24dff5d Mon Sep 17 00:00:00 2001
|
||||
From: Mark Fasheh <mfasheh@suse.com>
|
||||
Date: Sun, 11 Apr 2010 16:09:58 +0800
|
||||
Subject: [PATCH 01/30] dx_dirs: Add library support for directory indexing
|
||||
|
||||
This patch updates ocs2_fs.h with the relevant directory indexing
|
||||
structures. Additionally, libocfs2/ is given swap
|
||||
functions for the new disk structures. The library also gets three new
|
||||
iteration functions:
|
||||
|
||||
ocfs2_dx_entries_iterate() - to iterate all index entries in an inline,
|
||||
or external index.
|
||||
|
||||
ocfs2_dx_frees_iterate() - an iterator for the dirblock free list.
|
||||
|
||||
ocfs2_extent_iterate_dx_root() - iterate the extent blocks of an index
|
||||
tree.
|
||||
|
||||
Caveats:
|
||||
|
||||
Right now, this is all read-only. A major 'TODO' item is adding the
|
||||
appropriate API's to enable creation, deletion and
|
||||
various manipulation of the dx tree, as well as individual items.
|
||||
|
||||
None of the other library code really knows about the directory index.
|
||||
This means that things like ocfs2_looup() is
|
||||
still using the old-style lookup via the unindexed dirent tree.
|
||||
|
||||
We need to add support for the newly increased links_count maximum. This
|
||||
should probably be a seperate patch though.
|
||||
|
||||
[modified the patch for code rebase and cleanup -- Coly Li]
|
||||
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
---
|
||||
include/ocfs2-kernel/ocfs2_fs.h | 129 +++++++++++++++++++++++++++++++-
|
||||
include/ocfs2/ocfs2.h | 46 ++++++++++++
|
||||
libocfs2/dir_iterate.c | 155 +++++++++++++++++++++++++++++++++++++++
|
||||
libocfs2/dirblock.c | 140 +++++++++++++++++++++++++++++++++++-
|
||||
libocfs2/extents.c | 89 ++++++++++++++++++++++
|
||||
libocfs2/feature_string.c | 12 +++-
|
||||
libocfs2/inode.c | 2 +
|
||||
sizetest/sizes.txt | 2 +-
|
||||
sizetest/sizetest.c | 3 +-
|
||||
9 files changed, 570 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/include/ocfs2-kernel/ocfs2_fs.h b/include/ocfs2-kernel/ocfs2_fs.h
|
||||
index 3fb0d6c..d4de181 100644
|
||||
--- a/include/ocfs2-kernel/ocfs2_fs.h
|
||||
+++ b/include/ocfs2-kernel/ocfs2_fs.h
|
||||
@@ -67,6 +67,8 @@
|
||||
#define OCFS2_XATTR_BLOCK_SIGNATURE "XATTR01"
|
||||
#define OCFS2_DIR_TRAILER_SIGNATURE "DIRTRL1"
|
||||
#define OCFS2_REFCOUNT_BLOCK_SIGNATURE "REFCNT1"
|
||||
+#define OCFS2_DX_ROOT_SIGNATURE "DXDIR01"
|
||||
+#define OCFS2_DX_LEAF_SIGNATURE "DXLEAF1"
|
||||
|
||||
/* Compatibility flags */
|
||||
#define OCFS2_HAS_COMPAT_FEATURE(sb,mask) \
|
||||
@@ -97,7 +99,8 @@
|
||||
| OCFS2_FEATURE_INCOMPAT_USERSPACE_STACK \
|
||||
| OCFS2_FEATURE_INCOMPAT_META_ECC \
|
||||
| OCFS2_FEATURE_INCOMPAT_XATTR \
|
||||
- | OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE)
|
||||
+ | OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE \
|
||||
+ | OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS)
|
||||
#define OCFS2_FEATURE_RO_COMPAT_SUPP (OCFS2_FEATURE_RO_COMPAT_UNWRITTEN \
|
||||
| OCFS2_FEATURE_RO_COMPAT_USRQUOTA \
|
||||
| OCFS2_FEATURE_RO_COMPAT_GRPQUOTA)
|
||||
@@ -153,6 +156,9 @@
|
||||
/* Support for extended attributes */
|
||||
#define OCFS2_FEATURE_INCOMPAT_XATTR 0x0200
|
||||
|
||||
+/* Support for indexed directores */
|
||||
+#define OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS 0x0400
|
||||
+
|
||||
/* Metadata checksum and error correction */
|
||||
#define OCFS2_FEATURE_INCOMPAT_META_ECC 0x0800
|
||||
|
||||
@@ -375,8 +381,11 @@ static struct ocfs2_system_inode_info ocfs2_system_inodes[NUM_SYSTEM_INODES] = {
|
||||
#define OCFS2_DIR_REC_LEN(name_len) (((name_len) + OCFS2_DIR_MEMBER_LEN + \
|
||||
OCFS2_DIR_ROUND) & \
|
||||
~OCFS2_DIR_ROUND)
|
||||
+#define OCFS2_DIR_MIN_REC_LEN OCFS2_DIR_REC_LEN(1)
|
||||
|
||||
#define OCFS2_LINK_MAX 32000
|
||||
+#define OCFS2_DX_LINK_MAX ((1U << 31) - 1U)
|
||||
+#define OCFS2_LINKS_HI_SHIFT 16
|
||||
|
||||
#define S_SHIFT 12
|
||||
static unsigned char ocfs2_type_by_mode[S_IFMT >> S_SHIFT] = {
|
||||
@@ -592,8 +601,9 @@ struct ocfs2_super_block {
|
||||
/*B8*/ __le16 s_xattr_inline_size; /* extended attribute inline size
|
||||
for this fs*/
|
||||
__le16 s_reserved0;
|
||||
- __le32 s_reserved1;
|
||||
-/*C0*/ __le64 s_reserved2[16]; /* Fill out superblock */
|
||||
+ __le32 s_dx_seed[3]; /* seed[0-2] for dx dir hash.
|
||||
+ * s_uuid_hash serves as seed[3]. */
|
||||
+/*C0*/ __le64 s_reserved2[15]; /* Fill out superblock */
|
||||
/*140*/
|
||||
|
||||
/*
|
||||
@@ -643,7 +653,7 @@ struct ocfs2_dinode {
|
||||
belongs to */
|
||||
__le16 i_suballoc_bit; /* Bit offset in suballocator
|
||||
block group */
|
||||
-/*10*/ __le16 i_reserved0;
|
||||
+/*10*/ __le16 i_links_count_hi; /* High 16 bits of links count */
|
||||
__le16 i_xattr_inline_size;
|
||||
__le32 i_clusters; /* Cluster count */
|
||||
__le32 i_uid; /* Owner UID */
|
||||
@@ -747,6 +757,87 @@ struct ocfs2_dir_block_trailer {
|
||||
/*40*/
|
||||
};
|
||||
|
||||
+ /*
|
||||
+ * A directory entry in the indexed tree. We don't store the full name here,
|
||||
+ * but instead provide a pointer to the full dirent in the unindexed tree.
|
||||
+ *
|
||||
+ * We also store name_len here so as to reduce the number of leaf blocks we
|
||||
+ * need to search in case of collisions.
|
||||
+ */
|
||||
+struct ocfs2_dx_entry {
|
||||
+ __le32 dx_major_hash; /* Used to find logical
|
||||
+ * cluster in index */
|
||||
+ __le32 dx_minor_hash; /* Lower bits used to find
|
||||
+ * block in cluster */
|
||||
+ __le64 dx_dirent_blk; /* Physical block in unindexed
|
||||
+ * tree holding this dirent. */
|
||||
+};
|
||||
+
|
||||
+struct ocfs2_dx_entry_list {
|
||||
+ __le32 de_reserved;
|
||||
+ __le16 de_count; /* Maximum number of entries
|
||||
+ * possible in de_entries */
|
||||
+ __le16 de_num_used; /* Current number of
|
||||
+ * de_entries entries */
|
||||
+ struct ocfs2_dx_entry de_entries[0]; /* Indexed dir entries
|
||||
+ * in a packed array of
|
||||
+ * length de_num_used */
|
||||
+};
|
||||
+
|
||||
+#define OCFS2_DX_FLAG_INLINE 0x01
|
||||
+
|
||||
+/*
|
||||
+ * A directory indexing block. Each indexed directory has one of these,
|
||||
+ * pointed to by ocfs2_dinode.
|
||||
+ *
|
||||
+ * This block stores an indexed btree root, and a set of free space
|
||||
+ * start-of-list pointers.
|
||||
+ */
|
||||
+struct ocfs2_dx_root_block {
|
||||
+ __u8 dr_signature[8]; /* Signature for verification */
|
||||
+ struct ocfs2_block_check dr_check; /* Error checking */
|
||||
+ __le16 dr_suballoc_slot; /* Slot suballocator this
|
||||
+ * block belongs to. */
|
||||
+ __le16 dr_suballoc_bit; /* Bit offset in suballocator
|
||||
+ * block group */
|
||||
+ __le32 dr_fs_generation; /* Must match super block */
|
||||
+ __le64 dr_blkno; /* Offset on disk, in blocks */
|
||||
+ __le64 dr_last_eb_blk; /* Pointer to last
|
||||
+ * extent block */
|
||||
+ __le32 dr_clusters; /* Clusters allocated
|
||||
+ * to the indexed tree. */
|
||||
+ __u8 dr_flags; /* OCFS2_DX_FLAG_* flags */
|
||||
+ __u8 dr_reserved0;
|
||||
+ __le16 dr_reserved1;
|
||||
+ __le64 dr_dir_blkno; /* Pointer to parent inode */
|
||||
+ __le64 dr_reserved2;
|
||||
+ __le64 dr_free_blk; /* Pointer to head of free
|
||||
+ * unindexed block list. */
|
||||
+ __le64 dr_reserved3[15];
|
||||
+ union {
|
||||
+ struct ocfs2_extent_list dr_list; /* Keep this aligned to 128
|
||||
+ * bits for maximum space
|
||||
+ * efficiency. */
|
||||
+ struct ocfs2_dx_entry_list dr_entries; /* In-root-block list of
|
||||
+ * entries. We grow out
|
||||
+ * to extents if this
|
||||
+ * gets too big. */
|
||||
+ };
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * The header of a leaf block in the indexed tree.
|
||||
+ */
|
||||
+struct ocfs2_dx_leaf {
|
||||
+ __u8 dl_signature[8];/* Signature for verification */
|
||||
+ struct ocfs2_block_check dl_check; /* Error checking */
|
||||
+ __le64 dl_blkno; /* Offset on disk, in blocks */
|
||||
+ __le32 dl_fs_generation;/* Must match super block */
|
||||
+ __le32 dl_reserved0;
|
||||
+ __le64 dl_reserved1;
|
||||
+ struct ocfs2_dx_entry_list dl_list;
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* On disk allocator group structure for OCFS2
|
||||
*/
|
||||
@@ -1133,6 +1224,16 @@ static inline int ocfs2_extent_recs_per_inode_with_xattr(
|
||||
return size / sizeof(struct ocfs2_extent_rec);
|
||||
}
|
||||
|
||||
+static inline int ocfs2_extent_recs_per_dx_root(struct super_block *sb)
|
||||
+{
|
||||
+ int size;
|
||||
+
|
||||
+ size = sb->s_blocksize -
|
||||
+ offsetof(struct ocfs2_dx_root_block, dr_list.l_recs);
|
||||
+
|
||||
+ return size / sizeof(struct ocfs2_extent_rec);
|
||||
+}
|
||||
+
|
||||
static inline int ocfs2_chain_recs_per_inode(struct super_block *sb)
|
||||
{
|
||||
int size;
|
||||
@@ -1153,6 +1254,26 @@ static inline u16 ocfs2_extent_recs_per_eb(struct super_block *sb)
|
||||
return size / sizeof(struct ocfs2_extent_rec);
|
||||
}
|
||||
|
||||
+static inline int ocfs2_dx_entries_per_leaf(struct super_block *sb)
|
||||
+{
|
||||
+ int size;
|
||||
+
|
||||
+ size = sb->s_blocksize -
|
||||
+ offsetof(struct ocfs2_dx_leaf, dl_list.de_entries);
|
||||
+
|
||||
+ return size / sizeof(struct ocfs2_dx_entry);
|
||||
+}
|
||||
+
|
||||
+static inline int ocfs2_dx_entries_per_root(struct super_block *sb)
|
||||
+{
|
||||
+ int size;
|
||||
+
|
||||
+ size = sb->s_blocksize -
|
||||
+ offsetof(struct ocfs2_dx_root_block, dr_entries.de_entries);
|
||||
+
|
||||
+ return size / sizeof(struct ocfs2_dx_entry);
|
||||
+}
|
||||
+
|
||||
static inline u16 ocfs2_local_alloc_size(struct super_block *sb)
|
||||
{
|
||||
u16 size;
|
||||
diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
|
||||
index d91f734..332d4bd 100644
|
||||
--- a/include/ocfs2/ocfs2.h
|
||||
+++ b/include/ocfs2/ocfs2.h
|
||||
@@ -473,6 +473,11 @@ int ocfs2_skip_dir_trailer(ocfs2_filesys *fs, struct ocfs2_dinode *di,
|
||||
struct ocfs2_dir_entry *de, unsigned long offset);
|
||||
void ocfs2_init_dir_trailer(ocfs2_filesys *fs, struct ocfs2_dinode *di,
|
||||
uint64_t blkno, void *buf);
|
||||
+errcode_t ocfs2_read_dx_root(ocfs2_filesys *fs, uint64_t block,
|
||||
+ void *buf);
|
||||
+errcode_t ocfs2_read_dx_leaf(ocfs2_filesys *fs, uint64_t block,
|
||||
+ void *buf);
|
||||
+int ocfs2_dir_indexed(struct ocfs2_dinode *di);
|
||||
|
||||
errcode_t ocfs2_dir_iterate2(ocfs2_filesys *fs,
|
||||
uint64_t dir,
|
||||
@@ -497,6 +502,27 @@ extern errcode_t ocfs2_dir_iterate(ocfs2_filesys *fs,
|
||||
void *priv_data),
|
||||
void *priv_data);
|
||||
|
||||
+extern errcode_t ocfs2_dx_entries_iterate(ocfs2_filesys *fs,
|
||||
+ struct ocfs2_dinode *dir,
|
||||
+ int flags,
|
||||
+ int (*func)(ocfs2_filesys *fs,
|
||||
+ struct ocfs2_dx_entry_list *entry_list,
|
||||
+ struct ocfs2_dx_root_block *dx_root,
|
||||
+ struct ocfs2_dx_leaf *dx_leaf,
|
||||
+ void *priv_data),
|
||||
+ void *priv_data);
|
||||
+
|
||||
+extern errcode_t ocfs2_dx_frees_iterate(ocfs2_filesys *fs,
|
||||
+ struct ocfs2_dinode *dir,
|
||||
+ struct ocfs2_dx_root_block *dx_root,
|
||||
+ int flags,
|
||||
+ int (*func)(ocfs2_filesys *fs,
|
||||
+ uint64_t blkno,
|
||||
+ struct ocfs2_dir_block_trailer *trailer,
|
||||
+ char *dirblock,
|
||||
+ void *priv_data),
|
||||
+ void *priv_data);
|
||||
+
|
||||
errcode_t ocfs2_lookup(ocfs2_filesys *fs, uint64_t dir,
|
||||
const char *name, int namelen, char *buf,
|
||||
uint64_t *inode);
|
||||
@@ -1224,6 +1250,13 @@ static inline int ocfs2_support_xattr(struct ocfs2_super_block *osb)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static inline int ocfs2_supports_indexed_dirs(struct ocfs2_super_block *osb)
|
||||
+{
|
||||
+ if (osb->s_feature_incompat & OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS)
|
||||
+ return 1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* When we're swapping some of our disk structures, a garbage count
|
||||
* can send us past the edge of a block buffer. This function guards
|
||||
@@ -1352,6 +1385,19 @@ errcode_t ocfs2_extent_iterate_inode(ocfs2_filesys *fs,
|
||||
int ref_recno,
|
||||
void *priv_data),
|
||||
void *priv_data);
|
||||
+errcode_t ocfs2_extent_iterate_dx_root(ocfs2_filesys *fs,
|
||||
+ struct ocfs2_dx_root_block *dx_root,
|
||||
+ int flags,
|
||||
+ char *block_buf,
|
||||
+ int (*func)(ocfs2_filesys *fs,
|
||||
+ struct ocfs2_extent_rec *rec,
|
||||
+ int tree_depth,
|
||||
+ uint32_t ccount,
|
||||
+ uint64_t ref_blkno,
|
||||
+ int ref_recno,
|
||||
+ void *priv_data),
|
||||
+ void *priv_data);
|
||||
+
|
||||
errcode_t ocfs2_block_iterate(ocfs2_filesys *fs,
|
||||
uint64_t blkno,
|
||||
int flags,
|
||||
diff --git a/libocfs2/dir_iterate.c b/libocfs2/dir_iterate.c
|
||||
index 00c8d16..1064d9f 100644
|
||||
--- a/libocfs2/dir_iterate.c
|
||||
+++ b/libocfs2/dir_iterate.c
|
||||
@@ -307,6 +307,161 @@ int ocfs2_process_dir_block(ocfs2_filesys *fs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+struct dx_iterator_data {
|
||||
+ int (*dx_func)(ocfs2_filesys *fs,
|
||||
+ struct ocfs2_dx_entry_list *entry_list,
|
||||
+ struct ocfs2_dx_root_block *dx_root,
|
||||
+ struct ocfs2_dx_leaf *dx_leaf,
|
||||
+ void *priv_data);
|
||||
+ void *dx_priv_data;
|
||||
+ char *leaf_buf;
|
||||
+ struct ocfs2_dx_root_block *dx_root;
|
||||
+};
|
||||
+
|
||||
+static int dx_iterator(ocfs2_filesys *fs,
|
||||
+ struct ocfs2_extent_rec *rec,
|
||||
+ int tree_depth,
|
||||
+ uint32_t ccount,
|
||||
+ uint64_t ref_blkno,
|
||||
+ int ref_recno,
|
||||
+ void *priv_data)
|
||||
+{
|
||||
+ int ret, i;
|
||||
+ struct ocfs2_dx_leaf *dx_leaf;
|
||||
+ struct dx_iterator_data *iter = priv_data;
|
||||
+ uint64_t blkno, count;
|
||||
+
|
||||
+ count = ocfs2_clusters_to_blocks(fs, rec->e_leaf_clusters);
|
||||
+
|
||||
+ blkno = rec->e_blkno;
|
||||
+ for (i = 0; i < count; i++) {
|
||||
+ ret = ocfs2_read_dx_leaf(fs, blkno, iter->leaf_buf);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ dx_leaf = (struct ocfs2_dx_leaf *)iter->leaf_buf;
|
||||
+ iter->dx_func(fs, &dx_leaf->dl_list, iter->dx_root, dx_leaf,
|
||||
+ iter->dx_priv_data);
|
||||
+
|
||||
+ blkno++;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+extern errcode_t ocfs2_dx_entries_iterate(ocfs2_filesys *fs,
|
||||
+ struct ocfs2_dinode *dir,
|
||||
+ int flags,
|
||||
+ int (*func)(ocfs2_filesys *fs,
|
||||
+ struct ocfs2_dx_entry_list *entry_list,
|
||||
+ struct ocfs2_dx_root_block *dx_root,
|
||||
+ struct ocfs2_dx_leaf *dx_leaf,
|
||||
+ void *priv_data),
|
||||
+ void *priv_data)
|
||||
+{
|
||||
+ errcode_t ret = 0;
|
||||
+ struct ocfs2_dx_root_block *dx_root;
|
||||
+ uint64_t dx_blkno;
|
||||
+ char *buf = NULL, *eb_buf = NULL, *leaf_buf = NULL;
|
||||
+ struct dx_iterator_data data;
|
||||
+
|
||||
+ if (!S_ISDIR(dir->i_mode) && !ocfs2_dir_indexed(dir)) {
|
||||
+ ret = 0;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ ret = ocfs2_malloc_block(fs->fs_io, &buf);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ dx_blkno = (uint64_t) dir->i_dx_root;
|
||||
+
|
||||
+ ret = ocfs2_read_dx_root(fs, dx_blkno, buf);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ dx_root = (struct ocfs2_dx_root_block *)buf;
|
||||
+
|
||||
+ if (dx_root->dr_flags & OCFS2_DX_FLAG_INLINE) {
|
||||
+ func(fs, &dx_root->dr_entries, dx_root, NULL, priv_data);
|
||||
+ ret = 0;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ ret = ocfs2_malloc_block(fs->fs_io, &eb_buf);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ ret = ocfs2_malloc_block(fs->fs_io, &leaf_buf);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ data.dx_func = func;
|
||||
+ data.dx_priv_data = priv_data;
|
||||
+ data.leaf_buf = leaf_buf;
|
||||
+ data.dx_root = dx_root;
|
||||
+ ret = ocfs2_extent_iterate_dx_root(fs, dx_root,
|
||||
+ OCFS2_EXTENT_FLAG_DATA_ONLY, eb_buf,
|
||||
+ dx_iterator, &data);
|
||||
+
|
||||
+out:
|
||||
+ if (buf)
|
||||
+ ocfs2_free(&buf);
|
||||
+ if (eb_buf)
|
||||
+ ocfs2_free(&eb_buf);
|
||||
+ if (leaf_buf)
|
||||
+ ocfs2_free(&leaf_buf);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+extern errcode_t ocfs2_dx_frees_iterate(ocfs2_filesys *fs,
|
||||
+ struct ocfs2_dinode *dir,
|
||||
+ struct ocfs2_dx_root_block *dx_root,
|
||||
+ int flags,
|
||||
+ int (*func)(ocfs2_filesys *fs,
|
||||
+ uint64_t blkno,
|
||||
+ struct ocfs2_dir_block_trailer *trailer,
|
||||
+ char *dirblock,
|
||||
+ void *priv_data),
|
||||
+ void *priv_data)
|
||||
+{
|
||||
+ errcode_t ret = 0;
|
||||
+ uint64_t blkno;
|
||||
+ char *buf = NULL;
|
||||
+ struct ocfs2_dir_block_trailer *trailer;
|
||||
+
|
||||
+ if (!S_ISDIR(dir->i_mode) || !(ocfs2_dir_indexed(dir))) {
|
||||
+ ret = 0;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (dx_root->dr_flags & OCFS2_DX_FLAG_INLINE) {
|
||||
+ ret = 0;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ ret = ocfs2_malloc_block(fs->fs_io, &buf);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ blkno = dx_root->dr_free_blk;
|
||||
+ while (blkno) {
|
||||
+ ret = ocfs2_read_dir_block(fs, dir, blkno, buf);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ trailer = ocfs2_dir_trailer_from_block(fs, buf);
|
||||
+
|
||||
+ func(fs, blkno, trailer, buf, priv_data);
|
||||
+
|
||||
+ blkno = trailer->db_free_next;
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ if (buf)
|
||||
+ ocfs2_free(&buf);
|
||||
+ return ret;
|
||||
+}
|
||||
|
||||
#ifdef DEBUG_EXE
|
||||
#include <stdlib.h>
|
||||
diff --git a/libocfs2/dirblock.c b/libocfs2/dirblock.c
|
||||
index fec8ffc..d68e5c0 100644
|
||||
--- a/libocfs2/dirblock.c
|
||||
+++ b/libocfs2/dirblock.c
|
||||
@@ -54,12 +54,17 @@ int ocfs2_dir_has_trailer(ocfs2_filesys *fs, struct ocfs2_dinode *di)
|
||||
(di->i_dyn_features & OCFS2_INLINE_DATA_FL))
|
||||
return 0;
|
||||
|
||||
+ if (ocfs2_supports_indexed_dirs(OCFS2_RAW_SB(fs->fs_super)) &&
|
||||
+ di->i_dyn_features & OCFS2_INDEXED_DIR_FL)
|
||||
+ return 1;
|
||||
+
|
||||
return ocfs2_meta_ecc(OCFS2_RAW_SB(fs->fs_super));
|
||||
}
|
||||
|
||||
int ocfs2_supports_dir_trailer(ocfs2_filesys *fs)
|
||||
{
|
||||
- return ocfs2_meta_ecc(OCFS2_RAW_SB(fs->fs_super));
|
||||
+ return ocfs2_meta_ecc(OCFS2_RAW_SB(fs->fs_super)) ||
|
||||
+ ocfs2_supports_indexed_dirs(OCFS2_RAW_SB(fs->fs_super));
|
||||
}
|
||||
|
||||
int ocfs2_skip_dir_trailer(ocfs2_filesys *fs, struct ocfs2_dinode *di,
|
||||
@@ -148,6 +153,8 @@ void ocfs2_swap_dir_trailer(struct ocfs2_dir_block_trailer *trailer)
|
||||
bswap_64(trailer->db_compat_rec_len);
|
||||
bswap_64(trailer->db_blkno);
|
||||
bswap_64(trailer->db_parent_dinode);
|
||||
+ bswap_16(trailer->db_free_rec_len);
|
||||
+ bswap_64(trailer->db_free_next);
|
||||
}
|
||||
|
||||
errcode_t ocfs2_read_dir_block(ocfs2_filesys *fs, struct ocfs2_dinode *di,
|
||||
@@ -222,3 +229,134 @@ out:
|
||||
ocfs2_free(&buf);
|
||||
return retval;
|
||||
}
|
||||
+
|
||||
+static void ocfs2_swap_dx_entry_to_cpu(struct ocfs2_dx_entry *dx_entry)
|
||||
+{
|
||||
+ if (cpu_is_little_endian)
|
||||
+ return;
|
||||
+
|
||||
+ dx_entry->dx_major_hash = bswap_32(dx_entry->dx_major_hash);
|
||||
+ dx_entry->dx_minor_hash = bswap_32(dx_entry->dx_minor_hash);
|
||||
+ dx_entry->dx_dirent_blk = bswap_64(dx_entry->dx_dirent_blk);
|
||||
+}
|
||||
+
|
||||
+static void ocfs2_swap_dx_entry_list_to_cpu(struct ocfs2_dx_entry_list *dl_list)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ if (cpu_is_little_endian)
|
||||
+ return;
|
||||
+
|
||||
+ dl_list->de_count = bswap_16(dl_list->de_count);
|
||||
+ dl_list->de_num_used = bswap_16(dl_list->de_num_used);
|
||||
+
|
||||
+ for (i = 0; i < dl_list->de_count; i++)
|
||||
+ ocfs2_swap_dx_entry_to_cpu(&dl_list->de_entries[i]);
|
||||
+}
|
||||
+
|
||||
+static void ocfs2_swap_dx_root_to_cpu(struct ocfs2_dx_root_block *dx_root)
|
||||
+{
|
||||
+ if (cpu_is_little_endian)
|
||||
+ return;
|
||||
+
|
||||
+ dx_root->dr_suballoc_slot = bswap_16(dx_root->dr_suballoc_slot);
|
||||
+ dx_root->dr_suballoc_bit = bswap_16(dx_root->dr_suballoc_bit);
|
||||
+ dx_root->dr_fs_generation = bswap_32(dx_root->dr_fs_generation);
|
||||
+ dx_root->dr_blkno = bswap_64(dx_root->dr_blkno);
|
||||
+ dx_root->dr_last_eb_blk = bswap_64(dx_root->dr_last_eb_blk);
|
||||
+ dx_root->dr_clusters = bswap_32(dx_root->dr_clusters);
|
||||
+ dx_root->dr_dir_blkno = bswap_64(dx_root->dr_dir_blkno);
|
||||
+ dx_root->dr_free_blk = bswap_64(dx_root->dr_free_blk);
|
||||
+
|
||||
+ if (dx_root->dr_flags & OCFS2_DX_FLAG_INLINE)
|
||||
+ ocfs2_swap_dx_entry_list_to_cpu(&dx_root->dr_entries);
|
||||
+ else
|
||||
+ ocfs2_swap_extent_list_to_cpu(&dx_root->dr_list);
|
||||
+}
|
||||
+
|
||||
+errcode_t ocfs2_read_dx_root(ocfs2_filesys *fs, uint64_t block,
|
||||
+ void *buf)
|
||||
+{
|
||||
+ errcode_t ret;
|
||||
+ struct ocfs2_dx_root_block *dx_root;
|
||||
+
|
||||
+ ret = ocfs2_read_blocks(fs, block, 1, buf);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ dx_root = (struct ocfs2_dx_root_block *)buf;
|
||||
+ ret = ocfs2_validate_meta_ecc(fs, buf, &dx_root->dr_check);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (memcmp(dx_root->dr_signature, OCFS2_DX_ROOT_SIGNATURE,
|
||||
+ strlen(OCFS2_DX_ROOT_SIGNATURE)))
|
||||
+ return OCFS2_ET_DIR_CORRUPTED;
|
||||
+
|
||||
+ ocfs2_swap_dx_root_to_cpu(dx_root);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void ocfs2_swap_dx_leaf_to_cpu(struct ocfs2_dx_leaf *dx_leaf)
|
||||
+{
|
||||
+ if (cpu_is_little_endian)
|
||||
+ return;
|
||||
+
|
||||
+ dx_leaf->dl_blkno = bswap_64(dx_leaf->dl_blkno);
|
||||
+ dx_leaf->dl_fs_generation = bswap_64(dx_leaf->dl_fs_generation);
|
||||
+
|
||||
+ ocfs2_swap_dx_entry_list_to_cpu(&dx_leaf->dl_list);
|
||||
+}
|
||||
+
|
||||
+errcode_t ocfs2_read_dx_leaf(ocfs2_filesys *fs, uint64_t block,
|
||||
+ void *buf)
|
||||
+{
|
||||
+ errcode_t ret;
|
||||
+ struct ocfs2_dx_leaf *dx_leaf;
|
||||
+
|
||||
+ ret = ocfs2_read_blocks(fs, block, 1, buf);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ dx_leaf = (struct ocfs2_dx_leaf *)buf;
|
||||
+ ret = ocfs2_validate_meta_ecc(fs, buf, &dx_leaf->dl_check);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (memcmp(dx_leaf->dl_signature, OCFS2_DX_LEAF_SIGNATURE,
|
||||
+ strlen(OCFS2_DX_LEAF_SIGNATURE)))
|
||||
+ return OCFS2_ET_DIR_CORRUPTED;
|
||||
+
|
||||
+ ocfs2_swap_dx_leaf_to_cpu(dx_leaf);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int ocfs2_dir_indexed(struct ocfs2_dinode *di)
|
||||
+{
|
||||
+ if (di->i_dyn_features & OCFS2_INDEXED_DIR_FL)
|
||||
+ return 1;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * Only use this when we already know the directory is indexed.
|
||||
+ */
|
||||
+int __ocfs2_is_dir_trailer(ocfs2_filesys *fs, unsigned long de_off)
|
||||
+{
|
||||
+ if (de_off == ocfs2_dir_trailer_blk_off(fs))
|
||||
+ return 1;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int ocfs2_is_dir_trailer(ocfs2_filesys *fs, struct ocfs2_dinode *di,
|
||||
+ unsigned long de_off)
|
||||
+{
|
||||
+ if (ocfs2_dir_has_trailer(fs, di)) {
|
||||
+ return __ocfs2_is_dir_trailer(fs, de_off);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/libocfs2/extents.c b/libocfs2/extents.c
|
||||
index ee7ef93..8c322b1 100644
|
||||
--- a/libocfs2/extents.c
|
||||
+++ b/libocfs2/extents.c
|
||||
@@ -550,6 +550,95 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+errcode_t ocfs2_extent_iterate_dx_root(ocfs2_filesys *fs,
|
||||
+ struct ocfs2_dx_root_block *dx_root,
|
||||
+ int flags,
|
||||
+ char *block_buf,
|
||||
+ int (*func)(ocfs2_filesys *fs,
|
||||
+ struct ocfs2_extent_rec *rec,
|
||||
+ int tree_depth,
|
||||
+ uint32_t ccount,
|
||||
+ uint64_t ref_blkno,
|
||||
+ int ref_recno,
|
||||
+ void *priv_data),
|
||||
+ void *priv_data)
|
||||
+{
|
||||
+ int i;
|
||||
+ int iret = 0;
|
||||
+ struct ocfs2_extent_list *el;
|
||||
+ errcode_t ret;
|
||||
+ struct extent_context ctxt;
|
||||
+
|
||||
+ if (dx_root->dr_flags & OCFS2_DX_FLAG_INLINE)
|
||||
+ return OCFS2_ET_INODE_CANNOT_BE_ITERATED;
|
||||
+
|
||||
+ el = &dx_root->dr_list;
|
||||
+ if (el->l_tree_depth) {
|
||||
+ ret = ocfs2_malloc0(sizeof(char *) * el->l_tree_depth,
|
||||
+ &ctxt.eb_bufs);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (block_buf) {
|
||||
+ ctxt.eb_bufs[0] = block_buf;
|
||||
+ } else {
|
||||
+ ret = ocfs2_malloc0(fs->fs_blocksize *
|
||||
+ el->l_tree_depth,
|
||||
+ &ctxt.eb_bufs[0]);
|
||||
+ if (ret)
|
||||
+ goto out_eb_bufs;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 1; i < el->l_tree_depth; i++) {
|
||||
+ ctxt.eb_bufs[i] = ctxt.eb_bufs[0] +
|
||||
+ i * fs->fs_blocksize;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ ctxt.eb_bufs = NULL;
|
||||
+
|
||||
+ ctxt.fs = fs;
|
||||
+ ctxt.func = func;
|
||||
+ ctxt.priv_data = priv_data;
|
||||
+ ctxt.flags = flags;
|
||||
+ ctxt.ccount = 0;
|
||||
+ ctxt.last_eb_blkno = 0;
|
||||
+ ctxt.last_eb_cpos = 0;
|
||||
+
|
||||
+ ret = 0;
|
||||
+ iret |= extent_iterate_el(el, 0, &ctxt);
|
||||
+ if (iret & OCFS2_EXTENT_ERROR)
|
||||
+ ret = ctxt.errcode;
|
||||
+
|
||||
+ if (iret & OCFS2_EXTENT_ABORT)
|
||||
+ goto out_abort;
|
||||
+
|
||||
+ /* we can only trust ctxt.last_eb_blkno if we walked the whole tree */
|
||||
+ if (dx_root->dr_last_eb_blk != ctxt.last_eb_blkno) {
|
||||
+ dx_root->dr_last_eb_blk = ctxt.last_eb_blkno;
|
||||
+ iret |= OCFS2_EXTENT_CHANGED;
|
||||
+ }
|
||||
+
|
||||
+out_abort:
|
||||
+#if 0
|
||||
+ /*
|
||||
+ * This block needs to be fixed up for write support.
|
||||
+ */
|
||||
+ if (!ret && (iret & OCFS2_EXTENT_CHANGED))
|
||||
+ ret = ocfs2_write_inode(fs, inode->i_blkno, (char *)inode);
|
||||
+#endif
|
||||
+
|
||||
+out_eb_bufs:
|
||||
+ if (ctxt.eb_bufs) {
|
||||
+ if (!block_buf && ctxt.eb_bufs[0])
|
||||
+ ocfs2_free(&ctxt.eb_bufs[0]);
|
||||
+ ocfs2_free(&ctxt.eb_bufs);
|
||||
+ }
|
||||
+
|
||||
+out:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
errcode_t ocfs2_extent_iterate(ocfs2_filesys *fs,
|
||||
uint64_t blkno,
|
||||
int flags,
|
||||
diff --git a/libocfs2/feature_string.c b/libocfs2/feature_string.c
|
||||
index 7021dba..9f395c6 100644
|
||||
--- a/libocfs2/feature_string.c
|
||||
+++ b/libocfs2/feature_string.c
|
||||
@@ -89,7 +89,8 @@ static ocfs2_fs_options feature_level_defaults[] = {
|
||||
OCFS2_FEATURE_INCOMPAT_INLINE_DATA |
|
||||
OCFS2_FEATURE_INCOMPAT_META_ECC |
|
||||
OCFS2_FEATURE_INCOMPAT_XATTR |
|
||||
- OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE,
|
||||
+ OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE |
|
||||
+ OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS,
|
||||
OCFS2_FEATURE_RO_COMPAT_UNWRITTEN |
|
||||
OCFS2_FEATURE_RO_COMPAT_USRQUOTA |
|
||||
OCFS2_FEATURE_RO_COMPAT_GRPQUOTA }, /* OCFS2_FEATURE_LEVEL_MAX_FEATURES */
|
||||
@@ -166,6 +167,11 @@ static struct fs_feature_flags ocfs2_supported_features[] = {
|
||||
{0, OCFS2_FEATURE_INCOMPAT_XATTR, 0},
|
||||
},
|
||||
{
|
||||
+ "indexed-dirs",
|
||||
+ {0, OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS, 0},
|
||||
+ {0, OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS, 0},
|
||||
+ },
|
||||
+ {
|
||||
"usrquota",
|
||||
{0, 0, OCFS2_FEATURE_RO_COMPAT_USRQUOTA},
|
||||
{0, 0, OCFS2_FEATURE_RO_COMPAT_USRQUOTA},
|
||||
@@ -248,6 +254,10 @@ static struct feature_name ocfs2_feature_names[] = {
|
||||
.fn_flag = {0, OCFS2_FEATURE_INCOMPAT_XATTR, 0},
|
||||
},
|
||||
{
|
||||
+ .fn_name = "IndexedDirs",
|
||||
+ .fn_flag = {0, OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS, 0},
|
||||
+ },
|
||||
+ {
|
||||
.fn_name = "usrquota",
|
||||
.fn_flag = {0, 0, OCFS2_FEATURE_RO_COMPAT_USRQUOTA},
|
||||
},
|
||||
diff --git a/libocfs2/inode.c b/libocfs2/inode.c
|
||||
index e9ce579..95419f4 100644
|
||||
--- a/libocfs2/inode.c
|
||||
+++ b/libocfs2/inode.c
|
||||
@@ -163,6 +163,8 @@ static void ocfs2_swap_inode_second(struct ocfs2_dinode *di)
|
||||
struct ocfs2_inline_data *id = &di->id2.i_data;
|
||||
|
||||
id->id_count = bswap_16(id->id_count);
|
||||
+ } else if (di->i_dyn_features & OCFS2_INDEXED_DIR_FL) {
|
||||
+ di->i_dx_root = bswap_64(di->i_dx_root);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/sizetest/sizes.txt b/sizetest/sizes.txt
|
||||
index d03b67c..1fb27a9 100644
|
||||
--- a/sizetest/sizes.txt
|
||||
+++ b/sizetest/sizes.txt
|
||||
@@ -110,7 +110,7 @@
|
||||
0x0C0 id2.i_chain +0x10
|
||||
0x0C0 id2.i_list +0x10
|
||||
0x0C0 id2.i_symlink +0x00
|
||||
- Total 0x200
|
||||
+ Total 0x208
|
||||
|
||||
[off] struct ocfs2_dir_entry [size]
|
||||
0x000 inode +0x08
|
||||
diff --git a/sizetest/sizetest.c b/sizetest/sizetest.c
|
||||
index bdb06a2..e01e800 100644
|
||||
--- a/sizetest/sizetest.c
|
||||
+++ b/sizetest/sizetest.c
|
||||
@@ -173,7 +173,7 @@ static void print_ocfs2_dinode(void)
|
||||
SHOW_OFFSET(struct ocfs2_dinode, i_generation);
|
||||
SHOW_OFFSET(struct ocfs2_dinode, i_suballoc_slot);
|
||||
SHOW_OFFSET(struct ocfs2_dinode, i_suballoc_bit);
|
||||
- SHOW_OFFSET(struct ocfs2_dinode, i_reserved0);
|
||||
+ SHOW_OFFSET(struct ocfs2_dinode, i_links_count_hi);
|
||||
SHOW_OFFSET(struct ocfs2_dinode, i_xattr_inline_size);
|
||||
SHOW_OFFSET(struct ocfs2_dinode, i_clusters);
|
||||
SHOW_OFFSET(struct ocfs2_dinode, i_uid);
|
||||
@@ -197,6 +197,7 @@ static void print_ocfs2_dinode(void)
|
||||
SHOW_OFFSET(struct ocfs2_dinode, i_dyn_features);
|
||||
SHOW_OFFSET(struct ocfs2_dinode, i_xattr_loc);
|
||||
SHOW_OFFSET(struct ocfs2_dinode, i_check);
|
||||
+ SHOW_OFFSET(struct ocfs2_dinode, i_dx_root);
|
||||
SHOW_OFFSET(struct ocfs2_dinode, i_reserved2);
|
||||
|
||||
SHOW_OFFSET(struct ocfs2_dinode, id1.i_pad1);
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,454 +0,0 @@
|
||||
From b891260ad1500f3f2c0562d4376307b18bc4a9f4 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Fasheh <mfasheh@suse.com>
|
||||
Date: Sun, 11 Apr 2010 16:09:59 +0800
|
||||
Subject: [PATCH 02/30] dx_dirs: debugfs.ocfs2 support
|
||||
|
||||
This adds a full set of functionality to debugfs.ocfs2 so that we can
|
||||
visualize and debug indexed directories. Aside
|
||||
from updates to other commands to dump newly added/used fields in old
|
||||
structures, we get the following debugfs.ocfs2 commands:
|
||||
|
||||
dx_space - Show all entries in the free list
|
||||
dx_dump - Show the directory index (including root block)
|
||||
dx_leaf - Show a single directory index leaf block
|
||||
dx_root - Show directory index root block, as well as any extent blocks
|
||||
for non-inline dx_roots.
|
||||
|
||||
[modified the patch for code rebase and cleanup -- Coly Li]
|
||||
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
---
|
||||
debugfs.ocfs2/commands.c | 173 ++++++++++++++++++++++++++++++++++++++++++
|
||||
debugfs.ocfs2/dump.c | 164 ++++++++++++++++++++++++++++++++++++++--
|
||||
debugfs.ocfs2/include/dump.h | 5 +
|
||||
3 files changed, 335 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/debugfs.ocfs2/commands.c b/debugfs.ocfs2/commands.c
|
||||
index 1c19ab4..04e56b4 100644
|
||||
--- a/debugfs.ocfs2/commands.c
|
||||
+++ b/debugfs.ocfs2/commands.c
|
||||
@@ -77,6 +77,10 @@ static void do_dirblocks(char **args);
|
||||
static void do_xattr(char **args);
|
||||
static void do_frag(char **args);
|
||||
static void do_refcount(char **args);
|
||||
+static void do_dx_root(char **args);
|
||||
+static void do_dx_leaf(char **args);
|
||||
+static void do_dx_dump(char **args);
|
||||
+static void do_dx_space(char **args);
|
||||
|
||||
dbgfs_gbls gbls;
|
||||
|
||||
@@ -116,6 +120,10 @@ static Command commands[] = {
|
||||
{ "dirblocks", do_dirblocks },
|
||||
{ "frag", do_frag },
|
||||
{ "refcount", do_refcount },
|
||||
+ { "dx_root", do_dx_root },
|
||||
+ { "dx_leaf", do_dx_leaf },
|
||||
+ { "dx_dump", do_dx_dump },
|
||||
+ { "dx_space", do_dx_space },
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -842,6 +850,10 @@ static void do_help (char **args)
|
||||
printf ("dlm_locks [-f <file>] [-l] lockname\t\t\tShow live dlm locking state\n");
|
||||
printf ("dump [-p] <filespec> <outfile>\t\tDumps file to outfile on a mounted fs\n");
|
||||
printf ("dirblocks <filespec>\t\t\tDump directory blocks\n");
|
||||
+ printf ("dx_space <filespec>\t\t\tDump directory free space list\n");
|
||||
+ printf ("dx_dump <blkno>\t\t\tShow directory index information\n");
|
||||
+ printf ("dx_leaf <blkno>\t\t\tShow directory index leaf block only\n");
|
||||
+ printf ("dx_root <blkno>\t\t\tShow directory index root block only\n");
|
||||
printf ("encode <filespec>\t\t\tShow lock name\n");
|
||||
printf ("extent <block#>\t\t\t\tShow extent block\n");
|
||||
printf ("findpath <block#>\t\t\tList one pathname of the inode/lockname\n");
|
||||
@@ -1316,6 +1328,167 @@ static void do_dirblocks (char **args)
|
||||
}
|
||||
|
||||
/*
|
||||
+ * do_dx_root()
|
||||
+ *
|
||||
+ */
|
||||
+static void do_dx_root (char **args)
|
||||
+{
|
||||
+ struct ocfs2_dx_root_block *dx_root;
|
||||
+ uint64_t blkno;
|
||||
+ char *buf = NULL;
|
||||
+ FILE *out;
|
||||
+ errcode_t ret = 0;
|
||||
+
|
||||
+ if (process_inodestr_args(args, 1, &blkno) != 1)
|
||||
+ return;
|
||||
+
|
||||
+ buf = gbls.blockbuf;
|
||||
+ out = open_pager(gbls.interactive);
|
||||
+
|
||||
+ ret = ocfs2_read_dx_root(gbls.fs, blkno, buf);
|
||||
+ if (ret) {
|
||||
+ com_err(args[0], ret, "while reading dx dir root "
|
||||
+ "block %"PRIu64"", blkno);
|
||||
+ close_pager (out);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ dx_root = (struct ocfs2_dx_root_block *)buf;
|
||||
+ dump_dx_root(out, dx_root);
|
||||
+ if (!(dx_root->dr_flags & OCFS2_DX_FLAG_INLINE))
|
||||
+ traverse_extents(gbls.fs, &dx_root->dr_list, out);
|
||||
+ close_pager(out);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * do_dx_leaf()
|
||||
+ *
|
||||
+ */
|
||||
+static void do_dx_leaf (char **args)
|
||||
+{
|
||||
+ struct ocfs2_dx_leaf *dx_leaf;
|
||||
+ uint64_t blkno;
|
||||
+ char *buf = NULL;
|
||||
+ FILE *out;
|
||||
+ errcode_t ret = 0;
|
||||
+
|
||||
+ if (process_inodestr_args(args, 1, &blkno) != 1)
|
||||
+ return;
|
||||
+
|
||||
+ buf = gbls.blockbuf;
|
||||
+ out = open_pager(gbls.interactive);
|
||||
+
|
||||
+ ret = ocfs2_read_dx_leaf(gbls.fs, blkno, buf);
|
||||
+ if (ret) {
|
||||
+ com_err(args[0], ret, "while reading dx dir leaf "
|
||||
+ "block %"PRIu64"", blkno);
|
||||
+ close_pager (out);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ dx_leaf = (struct ocfs2_dx_leaf *)buf;
|
||||
+ dump_dx_leaf(out, dx_leaf);
|
||||
+
|
||||
+ close_pager(out);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * do_dx_dump()
|
||||
+ *
|
||||
+ */
|
||||
+static void do_dx_dump (char **args)
|
||||
+{
|
||||
+ struct ocfs2_dinode *inode;
|
||||
+ uint64_t ino_blkno;
|
||||
+ char *buf = NULL;
|
||||
+ FILE *out;
|
||||
+ errcode_t ret = 0;
|
||||
+
|
||||
+ if (process_inode_args(args, &ino_blkno))
|
||||
+ return;
|
||||
+
|
||||
+ out = open_pager(gbls.interactive);
|
||||
+
|
||||
+ buf = gbls.blockbuf;
|
||||
+ ret = ocfs2_read_inode(gbls.fs, ino_blkno, buf);
|
||||
+ if (ret) {
|
||||
+ com_err(args[0], ret, "while reading inode %"PRIu64"",
|
||||
+ ino_blkno);
|
||||
+ close_pager (out);
|
||||
+ return ;
|
||||
+ }
|
||||
+
|
||||
+ inode = (struct ocfs2_dinode *)buf;
|
||||
+
|
||||
+ dump_dx_entries(out, inode);
|
||||
+
|
||||
+ close_pager(out);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * do_dx_space()
|
||||
+ *
|
||||
+ */
|
||||
+static void do_dx_space (char **args)
|
||||
+{
|
||||
+ struct ocfs2_dinode *inode;
|
||||
+ struct ocfs2_dx_root_block *dx_root;
|
||||
+ uint64_t ino_blkno, dx_blkno;
|
||||
+ char *buf = NULL, *dx_root_buf = NULL;
|
||||
+ FILE *out;
|
||||
+ errcode_t ret = 0;
|
||||
+
|
||||
+ if (process_inode_args(args, &ino_blkno))
|
||||
+ return;
|
||||
+
|
||||
+ out = open_pager(gbls.interactive);
|
||||
+
|
||||
+ buf = gbls.blockbuf;
|
||||
+ ret = ocfs2_read_inode(gbls.fs, ino_blkno, buf);
|
||||
+ if (ret) {
|
||||
+ com_err(args[0], ret, "while reading inode %"PRIu64"",
|
||||
+ ino_blkno);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ inode = (struct ocfs2_dinode *)buf;
|
||||
+ if (!(ocfs2_dir_indexed(inode))) {
|
||||
+ fprintf(out, "Inode %"PRIu64" is not indexed\n", ino_blkno);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ ret = ocfs2_malloc_block(gbls.fs->fs_io, &dx_root_buf);
|
||||
+ if (ret) {
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ dx_blkno = (uint64_t) inode->i_dx_root;
|
||||
+
|
||||
+ ret = ocfs2_read_dx_root(gbls.fs, dx_blkno, dx_root_buf);
|
||||
+ if (ret) {
|
||||
+ com_err(args[0], ret, "while reading dx dir root "
|
||||
+ "block %"PRIu64"", dx_blkno);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ dx_root = (struct ocfs2_dx_root_block *)dx_root_buf;
|
||||
+
|
||||
+ dump_dx_space(out, inode, dx_root);
|
||||
+out:
|
||||
+ close_pager(out);
|
||||
+ if (dx_root_buf)
|
||||
+ ocfs2_free(&dx_root_buf);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* do_extent()
|
||||
*
|
||||
*/
|
||||
diff --git a/debugfs.ocfs2/dump.c b/debugfs.ocfs2/dump.c
|
||||
index 7880991..2e887ce 100644
|
||||
--- a/debugfs.ocfs2/dump.c
|
||||
+++ b/debugfs.ocfs2/dump.c
|
||||
@@ -99,6 +99,9 @@ void dump_super_block(FILE *out, struct ocfs2_super_block *sb)
|
||||
fprintf(out, "%02X", sb->s_uuid[i]);
|
||||
fprintf(out, "\n");
|
||||
fprintf(out, "\tHash: %u (0x%x)\n", sb->s_uuid_hash, sb->s_uuid_hash);
|
||||
+ for (i = 0; i < 3; i++)
|
||||
+ fprintf(out, "\tDX Seed[%d]: 0x%08x\n", i, sb->s_dx_seed[i]);
|
||||
+
|
||||
if (ocfs2_userspace_stack(sb))
|
||||
fprintf(out,
|
||||
"\tCluster stack: %s\n"
|
||||
@@ -315,6 +318,9 @@ void dump_inode(FILE *out, struct ocfs2_dinode *in)
|
||||
if (in->i_dyn_features & OCFS2_INLINE_DATA_FL) {
|
||||
fprintf(out, "\tInline Data Max: %u\n",
|
||||
in->id2.i_data.id_count);
|
||||
+ } else if (in->i_dyn_features & OCFS2_INDEXED_DIR_FL) {
|
||||
+ fprintf(out, "\tIndexed Tree Root: %"PRIu64"\n",
|
||||
+ (uint64_t)in->i_dx_root);
|
||||
}
|
||||
|
||||
if (flags)
|
||||
@@ -490,6 +496,21 @@ int dump_dir_entry (struct ocfs2_dir_entry *rec, int offset, int blocksize,
|
||||
}
|
||||
|
||||
/*
|
||||
+ * dump_dir_trailer()
|
||||
+ */
|
||||
+static void dump_dir_trailer(FILE *out, struct ocfs2_dir_block_trailer *trailer)
|
||||
+{
|
||||
+ fprintf(out,
|
||||
+ "\tTrailer Block: %-15"PRIu64" Inode: %-15"PRIu64" rec_len: %-4u\n",
|
||||
+ trailer->db_blkno, trailer->db_parent_dinode,
|
||||
+ trailer->db_compat_rec_len);
|
||||
+ fprintf(out,
|
||||
+ "\tLargest hole: %u Next in list: %-15"PRIu64"\n",
|
||||
+ trailer->db_free_rec_len, trailer->db_free_next);
|
||||
+ dump_block_check(out, &trailer->db_check);
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
* dump_dir_block()
|
||||
*
|
||||
*/
|
||||
@@ -507,13 +528,9 @@ void dump_dir_block(FILE *out, char *buf)
|
||||
};
|
||||
|
||||
if (!strncmp((char *)trailer->db_signature, OCFS2_DIR_TRAILER_SIGNATURE,
|
||||
- sizeof(trailer->db_signature))) {
|
||||
- fprintf(out,
|
||||
- "\tTrailer Block: %-15"PRIu64" Inode: %-15"PRIu64" rec_len: %-4u\n",
|
||||
- trailer->db_blkno, trailer->db_parent_dinode,
|
||||
- trailer->db_compat_rec_len);
|
||||
- dump_block_check(out, &trailer->db_check);
|
||||
- } else
|
||||
+ sizeof(trailer->db_signature)))
|
||||
+ dump_dir_trailer(out, trailer);
|
||||
+ else
|
||||
end = gbls.fs->fs_blocksize;
|
||||
|
||||
fprintf(out, "\tEntries:\n");
|
||||
@@ -533,6 +550,139 @@ void dump_dir_block(FILE *out, char *buf)
|
||||
}
|
||||
}
|
||||
|
||||
+static void dump_dx_entry(FILE *out, int i, struct ocfs2_dx_entry *dx_entry)
|
||||
+{
|
||||
+ fprintf(out, "\t %-2d (0x%08x 0x%08x) %-13"PRIu64"\n",
|
||||
+ i, dx_entry->dx_major_hash, dx_entry->dx_minor_hash,
|
||||
+ (uint64_t)dx_entry->dx_dirent_blk);
|
||||
+}
|
||||
+
|
||||
+static void dump_dx_entry_list(FILE *out, struct ocfs2_dx_entry_list *dl_list,
|
||||
+ int traverse)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ fprintf(out, "\tCount: %u Num Used: %u\n",
|
||||
+ dl_list->de_count, dl_list->de_num_used);
|
||||
+
|
||||
+ if (traverse) {
|
||||
+ fprintf(out, "\t## %-11s %-13s\n", "Hash (Major Minor)",
|
||||
+ "Dir Block#");
|
||||
+
|
||||
+ for (i = 0; i < dl_list->de_num_used; i++)
|
||||
+ dump_dx_entry(out, i, &dl_list->de_entries[i]);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void dump_dx_root(FILE *out, struct ocfs2_dx_root_block *dr)
|
||||
+{
|
||||
+ char tmp_str[30];
|
||||
+ GString *flags = NULL;
|
||||
+
|
||||
+ flags = g_string_new(NULL);
|
||||
+ if (dr->dr_flags & OCFS2_DX_FLAG_INLINE)
|
||||
+ g_string_append(flags, "Inline ");
|
||||
+
|
||||
+ fprintf(out, "\tDir Index Root: %"PRIu64" FS Generation: %u (0x%x)\n",
|
||||
+ (uint64_t)dr->dr_blkno, dr->dr_fs_generation,
|
||||
+ dr->dr_fs_generation);
|
||||
+
|
||||
+ fprintf(out, "\tClusters: %u Last Extblk: %"PRIu64" "
|
||||
+ "Dir Inode: %"PRIu64"\n",
|
||||
+ dr->dr_clusters, (uint64_t)dr->dr_last_eb_blk,
|
||||
+ (uint64_t)dr->dr_dir_blkno);
|
||||
+
|
||||
+ if (dr->dr_suballoc_slot == (uint16_t)OCFS2_INVALID_SLOT)
|
||||
+ strcpy(tmp_str, "Global");
|
||||
+ else
|
||||
+ sprintf(tmp_str, "%d", dr->dr_suballoc_slot);
|
||||
+ fprintf(out, "\tSub Alloc Slot: %s Sub Alloc Bit: %u "
|
||||
+ "Flags: (0x%x) %s\n",
|
||||
+ tmp_str, dr->dr_suballoc_bit, dr->dr_flags, flags->str);
|
||||
+
|
||||
+ dump_block_check(out, &dr->dr_check);
|
||||
+
|
||||
+ if (dr->dr_flags & OCFS2_DX_FLAG_INLINE)
|
||||
+ dump_dx_entry_list(out, &dr->dr_entries, 0);
|
||||
+
|
||||
+ if (flags)
|
||||
+ g_string_free(flags, 1);
|
||||
+}
|
||||
+
|
||||
+void dump_dx_leaf (FILE *out, struct ocfs2_dx_leaf *dx_leaf)
|
||||
+{
|
||||
+ fprintf(out, "\tDir Index Leaf: %"PRIu64" FS Generation: %u (0x%x)\n",
|
||||
+ (uint64_t)dx_leaf->dl_blkno, dx_leaf->dl_fs_generation,
|
||||
+ dx_leaf->dl_fs_generation);
|
||||
+ dump_block_check(out, &dx_leaf->dl_check);
|
||||
+
|
||||
+ dump_dx_entry_list(out, &dx_leaf->dl_list, 1);
|
||||
+}
|
||||
+
|
||||
+static int entries_iter(ocfs2_filesys *fs,
|
||||
+ struct ocfs2_dx_entry_list *entry_list,
|
||||
+ struct ocfs2_dx_root_block *dx_root,
|
||||
+ struct ocfs2_dx_leaf *dx_leaf,
|
||||
+ void *priv_data)
|
||||
+{
|
||||
+ FILE *out = priv_data;
|
||||
+
|
||||
+ if (dx_leaf) {
|
||||
+ dump_dx_leaf(out, dx_leaf);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /* Inline entries. Dump the list directly. */
|
||||
+ dump_dx_entry_list(out, entry_list, 1);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void dump_dx_entries(FILE *out, struct ocfs2_dinode *inode)
|
||||
+{
|
||||
+ struct ocfs2_dx_root_block *dx_root;
|
||||
+ uint64_t dx_blkno;
|
||||
+ char *buf = NULL;
|
||||
+ errcode_t ret = 0;
|
||||
+
|
||||
+ if (ocfs2_malloc_block(gbls.fs->fs_io, &buf))
|
||||
+ return;
|
||||
+
|
||||
+ if (!(ocfs2_dir_indexed(inode)))
|
||||
+ return;
|
||||
+
|
||||
+ dx_blkno = (uint64_t) inode->i_dx_root;
|
||||
+
|
||||
+ ret = ocfs2_read_dx_root(gbls.fs, dx_blkno, buf);
|
||||
+ if (ret)
|
||||
+ return;
|
||||
+
|
||||
+ dx_root = (struct ocfs2_dx_root_block *)buf;
|
||||
+ dump_dx_root(out, dx_root);
|
||||
+
|
||||
+ ocfs2_dx_entries_iterate(gbls.fs, inode, 0, entries_iter, out);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static int dx_space_iter(ocfs2_filesys *fs,
|
||||
+ uint64_t blkno,
|
||||
+ struct ocfs2_dir_block_trailer *trailer,
|
||||
+ char *dirblock,
|
||||
+ void *priv_data)
|
||||
+{
|
||||
+ FILE *out = priv_data;
|
||||
+
|
||||
+ dump_dir_trailer(out, trailer);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+void dump_dx_space(FILE *out, struct ocfs2_dinode *inode,
|
||||
+ struct ocfs2_dx_root_block *dx_root)
|
||||
+{
|
||||
+ ocfs2_dx_frees_iterate(gbls.fs, inode, dx_root, 0, dx_space_iter, out);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* dump_jbd_header()
|
||||
*
|
||||
diff --git a/debugfs.ocfs2/include/dump.h b/debugfs.ocfs2/include/dump.h
|
||||
index cb677c9..79b10b3 100644
|
||||
--- a/debugfs.ocfs2/include/dump.h
|
||||
+++ b/debugfs.ocfs2/include/dump.h
|
||||
@@ -52,7 +52,12 @@ void dump_extent_block (FILE *out, struct ocfs2_extent_block *blk);
|
||||
void dump_group_descriptor (FILE *out, struct ocfs2_group_desc *grp, int index);
|
||||
int dump_dir_entry (struct ocfs2_dir_entry *rec, int offset, int blocksize,
|
||||
char *buf, void *priv_data);
|
||||
+void dump_dx_root (FILE *out, struct ocfs2_dx_root_block *dx_root);
|
||||
+void dump_dx_leaf (FILE *out, struct ocfs2_dx_leaf *dx_leaf);
|
||||
void dump_dir_block(FILE *out, char *buf);
|
||||
+void dump_dx_entries(FILE *out, struct ocfs2_dinode *inode);
|
||||
+void dump_dx_space(FILE *out, struct ocfs2_dinode *inode,
|
||||
+ struct ocfs2_dx_root_block *dx_root);
|
||||
void dump_jbd_header (FILE *out, journal_header_t *header);
|
||||
void dump_jbd_superblock (FILE *out, journal_superblock_t *jsb);
|
||||
void dump_jbd_block (FILE *out, journal_superblock_t *jsb,
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,73 +0,0 @@
|
||||
From 585f52a5dfd8cb4301d29804e7e05ddff1f3fca1 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Fasheh <mfasheh@suse.com>
|
||||
Date: Sun, 11 Apr 2010 16:10:00 +0800
|
||||
Subject: [PATCH 03/30] dx_dirs: mkfs.ocfs2 support
|
||||
|
||||
This adds only basic support to mkfs.ocfs2 to write the seed fields used
|
||||
in directory indexing. The feature string
|
||||
'indexed-dirs' is already there from a previous patch, so it is possible
|
||||
to create a new file system with the directory
|
||||
indexing feature turned on.
|
||||
|
||||
Future improvements that are needed:
|
||||
|
||||
- mkfs.ocfs2 should create the root directory and orphan dirs as
|
||||
indexed.
|
||||
- possibly also we want to do this for the system dir, but that might
|
||||
require some discussion.
|
||||
|
||||
[modified the patch for code rebase and cleanup -- Coly Li]
|
||||
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
---
|
||||
mkfs.ocfs2/mkfs.c | 17 ++++++++++++++---
|
||||
1 files changed, 14 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/mkfs.ocfs2/mkfs.c b/mkfs.ocfs2/mkfs.c
|
||||
index 5d01e3e..b43a9ba 100644
|
||||
--- a/mkfs.ocfs2/mkfs.c
|
||||
+++ b/mkfs.ocfs2/mkfs.c
|
||||
@@ -1004,6 +1004,8 @@ get_state(int argc, char **argv)
|
||||
if ((optind == argc) && !show_version)
|
||||
usage(progname);
|
||||
|
||||
+ srand48(time(NULL));
|
||||
+
|
||||
device_name = argv[optind];
|
||||
optind++;
|
||||
|
||||
@@ -2240,11 +2242,9 @@ format_superblock(State *s, SystemFileDiskRecord *rec,
|
||||
*/
|
||||
s->feature_flags.opt_compat &= ~OCFS2_FEATURE_COMPAT_BACKUP_SB;
|
||||
|
||||
- if (s->feature_flags.opt_incompat & OCFS2_FEATURE_INCOMPAT_XATTR) {
|
||||
+ if (s->feature_flags.opt_incompat & OCFS2_FEATURE_INCOMPAT_XATTR)
|
||||
di->id2.i_super.s_xattr_inline_size =
|
||||
OCFS2_MIN_XATTR_INLINE_SIZE;
|
||||
- di->id2.i_super.s_uuid_hash = ocfs2_xattr_uuid_hash(s->uuid);
|
||||
- }
|
||||
|
||||
di->id2.i_super.s_feature_incompat = s->feature_flags.opt_incompat;
|
||||
di->id2.i_super.s_feature_compat = s->feature_flags.opt_compat;
|
||||
@@ -2253,6 +2253,17 @@ format_superblock(State *s, SystemFileDiskRecord *rec,
|
||||
strcpy((char *)di->id2.i_super.s_label, s->vol_label);
|
||||
memcpy(di->id2.i_super.s_uuid, s->uuid, 16);
|
||||
|
||||
+ /* s_uuid_hash is also used by Indexed Dirs */
|
||||
+ if (s->feature_flags.opt_incompat & OCFS2_FEATURE_INCOMPAT_XATTR ||
|
||||
+ s->feature_flags.opt_incompat & OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS)
|
||||
+ di->id2.i_super.s_uuid_hash = ocfs2_xattr_uuid_hash(s->uuid);
|
||||
+
|
||||
+ if (s->feature_flags.opt_incompat & OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS) {
|
||||
+ di->id2.i_super.s_dx_seed[0] = mrand48();
|
||||
+ di->id2.i_super.s_dx_seed[1] = mrand48();
|
||||
+ di->id2.i_super.s_dx_seed[2] = mrand48();
|
||||
+ }
|
||||
+
|
||||
mkfs_swap_inode_from_cpu(s, di);
|
||||
mkfs_compute_meta_ecc(s, di, &di->i_check);
|
||||
do_pwrite(s, di, s->blocksize, super_off);
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,149 +0,0 @@
|
||||
From 0afd7bae3557bd443eac4e388c0c3cbf47690e5d Mon Sep 17 00:00:00 2001
|
||||
From: Mark Fasheh <mfasheh@suse.com>
|
||||
Date: Sun, 11 Apr 2010 16:10:01 +0800
|
||||
Subject: [PATCH 04/30] dx_dirs: Add tunefs.ocfs2 feature for indexed directories
|
||||
|
||||
This only enables them for now. Disabling is a bit more involved, and
|
||||
will come later.
|
||||
|
||||
[modified the patch for code rebase and cleanup -- Coly Li]
|
||||
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
---
|
||||
tunefs.ocfs2/Makefile | 1 +
|
||||
tunefs.ocfs2/feature_indexed_dirs.c | 89 +++++++++++++++++++++++++++++++++++
|
||||
tunefs.ocfs2/op_features.c | 2 +
|
||||
3 files changed, 92 insertions(+), 0 deletions(-)
|
||||
create mode 100644 tunefs.ocfs2/feature_indexed_dirs.c
|
||||
|
||||
diff --git a/tunefs.ocfs2/Makefile b/tunefs.ocfs2/Makefile
|
||||
index dad7034..6219af6 100644
|
||||
--- a/tunefs.ocfs2/Makefile
|
||||
+++ b/tunefs.ocfs2/Makefile
|
||||
@@ -26,6 +26,7 @@ OCFS2NE_FEATURES = \
|
||||
feature_sparse_files \
|
||||
feature_unwritten_extents \
|
||||
feature_xattr \
|
||||
+ feature_indexed_dirs \
|
||||
feature_quota
|
||||
|
||||
OCFS2NE_OPERATIONS = \
|
||||
diff --git a/tunefs.ocfs2/feature_indexed_dirs.c b/tunefs.ocfs2/feature_indexed_dirs.c
|
||||
new file mode 100644
|
||||
index 0000000..368eb87
|
||||
--- /dev/null
|
||||
+++ b/tunefs.ocfs2/feature_indexed_dirs.c
|
||||
@@ -0,0 +1,89 @@
|
||||
+/* -*- mode: c; c-basic-offset: 8; -*-
|
||||
+ * vim: noexpandtab sw=8 ts=8 sts=0:
|
||||
+ *
|
||||
+ * feature_indexed_dirs.c
|
||||
+ *
|
||||
+ * ocfs2 tune utility for enabling and disabling the directory indexing
|
||||
+ * feature.
|
||||
+ *
|
||||
+ * Copyright (C) 2009 Novell. All rights reserved.
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or
|
||||
+ * modify it under the terms of the GNU General Public
|
||||
+ * License version 2 as published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope that it will be useful,
|
||||
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
+ * General Public License for more details.
|
||||
+ */
|
||||
+
|
||||
+#include <stdio.h>
|
||||
+#include <stdlib.h>
|
||||
+#include <string.h>
|
||||
+#include <sys/stat.h>
|
||||
+#include <ctype.h>
|
||||
+#include <inttypes.h>
|
||||
+#include <assert.h>
|
||||
+
|
||||
+#include "ocfs2/ocfs2.h"
|
||||
+
|
||||
+#include "libocfs2ne.h"
|
||||
+
|
||||
+
|
||||
+static int enable_indexed_dirs(ocfs2_filesys *fs, int flags)
|
||||
+{
|
||||
+ errcode_t ret = 0;
|
||||
+ struct ocfs2_super_block *super = OCFS2_RAW_SB(fs->fs_super);
|
||||
+ struct tools_progress *prog;
|
||||
+
|
||||
+ if (ocfs2_supports_indexed_dirs(super)) {
|
||||
+ verbosef(VL_APP,
|
||||
+ "Directory indexing feature is already enabled; "
|
||||
+ "nothing to enable\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ if (!tools_interact("Enable the directory indexing feature on "
|
||||
+ "device \"%s\"? ",
|
||||
+ fs->fs_devname))
|
||||
+ goto out;
|
||||
+
|
||||
+ prog = tools_progress_start("Enable directory indexing", "dir idx", 1);
|
||||
+ if (!prog) {
|
||||
+ ret = TUNEFS_ET_NO_MEMORY;
|
||||
+ tcom_err(ret, "while initializing the progress display");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ OCFS2_SET_INCOMPAT_FEATURE(super,
|
||||
+ OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS);
|
||||
+ tunefs_block_signals();
|
||||
+ ret = ocfs2_write_super(fs);
|
||||
+ tunefs_unblock_signals();
|
||||
+ if (ret)
|
||||
+ tcom_err(ret, "while writing out the superblock");
|
||||
+
|
||||
+ tools_progress_step(prog, 1);
|
||||
+ tools_progress_stop(prog);
|
||||
+out:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * TUNEFS_FLAG_ALLOCATION because disabling will want to dealloc
|
||||
+ * blocks.
|
||||
+ */
|
||||
+DEFINE_TUNEFS_FEATURE_INCOMPAT(indexed_dirs,
|
||||
+ OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS,
|
||||
+ TUNEFS_FLAG_RW | TUNEFS_FLAG_ALLOCATION,
|
||||
+ enable_indexed_dirs,
|
||||
+ NULL);
|
||||
+
|
||||
+#ifdef DEBUG_EXE
|
||||
+int main(int argc, char *argv[])
|
||||
+{
|
||||
+ return tunefs_feature_main(argc, argv, &indexed_dirs_feature);
|
||||
+}
|
||||
+#endif
|
||||
diff --git a/tunefs.ocfs2/op_features.c b/tunefs.ocfs2/op_features.c
|
||||
index 91abca1..613ea7e 100644
|
||||
--- a/tunefs.ocfs2/op_features.c
|
||||
+++ b/tunefs.ocfs2/op_features.c
|
||||
@@ -44,6 +44,7 @@ extern struct tunefs_feature xattr_feature;
|
||||
extern struct tunefs_feature usrquota_feature;
|
||||
extern struct tunefs_feature grpquota_feature;
|
||||
extern struct tunefs_feature refcount_feature;
|
||||
+extern struct tunefs_feature indexed_dirs_feature;
|
||||
|
||||
/* List of features supported by ocfs2ne */
|
||||
static struct tunefs_feature *features[] = {
|
||||
@@ -58,6 +59,7 @@ static struct tunefs_feature *features[] = {
|
||||
&usrquota_feature,
|
||||
&grpquota_feature,
|
||||
&refcount_feature,
|
||||
+ &indexed_dirs_feature,
|
||||
NULL,
|
||||
};
|
||||
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,62 +0,0 @@
|
||||
From 56f5ac553c2686271b657ed8be4f8ca001aa7ed6 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Fasheh <mfasheh@suse.com>
|
||||
Date: Sun, 11 Apr 2010 16:10:02 +0800
|
||||
Subject: [PATCH 05/30] dx_dirs: Update for dr_num_entries
|
||||
|
||||
This just adds the new field, swaps it appropriately, and prints it in
|
||||
debuggs.
|
||||
|
||||
[Modified the patch for code rebase and cleanup -- Coly Li]
|
||||
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
---
|
||||
debugfs.ocfs2/dump.c | 2 ++
|
||||
include/ocfs2-kernel/ocfs2_fs.h | 5 ++++-
|
||||
libocfs2/dirblock.c | 1 +
|
||||
3 files changed, 7 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/debugfs.ocfs2/dump.c b/debugfs.ocfs2/dump.c
|
||||
index 2e887ce..88ec430 100644
|
||||
--- a/debugfs.ocfs2/dump.c
|
||||
+++ b/debugfs.ocfs2/dump.c
|
||||
@@ -600,6 +600,8 @@ void dump_dx_root(FILE *out, struct ocfs2_dx_root_block *dr)
|
||||
"Flags: (0x%x) %s\n",
|
||||
tmp_str, dr->dr_suballoc_bit, dr->dr_flags, flags->str);
|
||||
|
||||
+ fprintf(out, "\tTotal Entry Count: %d\n", dr->dr_num_entries);
|
||||
+
|
||||
dump_block_check(out, &dr->dr_check);
|
||||
|
||||
if (dr->dr_flags & OCFS2_DX_FLAG_INLINE)
|
||||
diff --git a/include/ocfs2-kernel/ocfs2_fs.h b/include/ocfs2-kernel/ocfs2_fs.h
|
||||
index d4de181..f3c2450 100644
|
||||
--- a/include/ocfs2-kernel/ocfs2_fs.h
|
||||
+++ b/include/ocfs2-kernel/ocfs2_fs.h
|
||||
@@ -810,7 +810,10 @@ struct ocfs2_dx_root_block {
|
||||
__u8 dr_reserved0;
|
||||
__le16 dr_reserved1;
|
||||
__le64 dr_dir_blkno; /* Pointer to parent inode */
|
||||
- __le64 dr_reserved2;
|
||||
+ __le32 dr_num_entries; /* Total number of
|
||||
+ * names stored in
|
||||
+ * this directory.*/
|
||||
+ __le32 dr_reserved2;
|
||||
__le64 dr_free_blk; /* Pointer to head of free
|
||||
* unindexed block list. */
|
||||
__le64 dr_reserved3[15];
|
||||
diff --git a/libocfs2/dirblock.c b/libocfs2/dirblock.c
|
||||
index d68e5c0..4bf48f3 100644
|
||||
--- a/libocfs2/dirblock.c
|
||||
+++ b/libocfs2/dirblock.c
|
||||
@@ -266,6 +266,7 @@ static void ocfs2_swap_dx_root_to_cpu(struct ocfs2_dx_root_block *dx_root)
|
||||
dx_root->dr_last_eb_blk = bswap_64(dx_root->dr_last_eb_blk);
|
||||
dx_root->dr_clusters = bswap_32(dx_root->dr_clusters);
|
||||
dx_root->dr_dir_blkno = bswap_64(dx_root->dr_dir_blkno);
|
||||
+ dx_root->dr_num_entries = bswap_32(dx_root->dr_num_entries);
|
||||
dx_root->dr_free_blk = bswap_64(dx_root->dr_free_blk);
|
||||
|
||||
if (dx_root->dr_flags & OCFS2_DX_FLAG_INLINE)
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,50 +0,0 @@
|
||||
From 5110de09d64c84037e7e2ecdf76ab2d0d0f77ff4 Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Sun, 11 Apr 2010 16:10:03 +0800
|
||||
Subject: [PATCH 06/30] dx_dirs: add missing 'ocfs2_filesys *fs' parameter
|
||||
|
||||
This patch add 'ocfs2_filesys *fs' parameter to
|
||||
ocfs2_swap_dx_root_to_cpu(), and fix the mismatched arguments when
|
||||
alling ocfs2_swap_extent_list_to_cpu().
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
---
|
||||
libocfs2/dirblock.c | 7 ++++---
|
||||
1 files changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libocfs2/dirblock.c b/libocfs2/dirblock.c
|
||||
index 4bf48f3..06a1b64 100644
|
||||
--- a/libocfs2/dirblock.c
|
||||
+++ b/libocfs2/dirblock.c
|
||||
@@ -254,7 +254,8 @@ static void ocfs2_swap_dx_entry_list_to_cpu(struct ocfs2_dx_entry_list *dl_list)
|
||||
ocfs2_swap_dx_entry_to_cpu(&dl_list->de_entries[i]);
|
||||
}
|
||||
|
||||
-static void ocfs2_swap_dx_root_to_cpu(struct ocfs2_dx_root_block *dx_root)
|
||||
+static void ocfs2_swap_dx_root_to_cpu(ocfs2_filesys *fs,
|
||||
+ struct ocfs2_dx_root_block *dx_root)
|
||||
{
|
||||
if (cpu_is_little_endian)
|
||||
return;
|
||||
@@ -272,7 +273,7 @@ static void ocfs2_swap_dx_root_to_cpu(struct ocfs2_dx_root_block *dx_root)
|
||||
if (dx_root->dr_flags & OCFS2_DX_FLAG_INLINE)
|
||||
ocfs2_swap_dx_entry_list_to_cpu(&dx_root->dr_entries);
|
||||
else
|
||||
- ocfs2_swap_extent_list_to_cpu(&dx_root->dr_list);
|
||||
+ ocfs2_swap_extent_list_to_cpu(fs, dx_root, &dx_root->dr_list);
|
||||
}
|
||||
|
||||
errcode_t ocfs2_read_dx_root(ocfs2_filesys *fs, uint64_t block,
|
||||
@@ -294,7 +295,7 @@ errcode_t ocfs2_read_dx_root(ocfs2_filesys *fs, uint64_t block,
|
||||
strlen(OCFS2_DX_ROOT_SIGNATURE)))
|
||||
return OCFS2_ET_DIR_CORRUPTED;
|
||||
|
||||
- ocfs2_swap_dx_root_to_cpu(dx_root);
|
||||
+ ocfs2_swap_dx_root_to_cpu(fs, dx_root);
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
1.7.0.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,415 +0,0 @@
|
||||
From 2bbbdef8534534b12cf3dd3ad9db6a1ebd74d0a3 Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Sun, 11 Apr 2010 16:10:05 +0800
|
||||
Subject: [PATCH 08/30] dx_dirs: fsck.ocfs2 support
|
||||
|
||||
This patch does a basic indexed dirs support in fsck.ocfs2.
|
||||
|
||||
During pass2, if a directory block is changed, and indexed dirs in
|
||||
enabled, the indexed tree of this directory will be
|
||||
truncate, then rebuild with the modified directory data. All the
|
||||
modified directories' inode numbers are recored in a
|
||||
rb-tree, when all directories get scanned, truncate and rebuild the
|
||||
directories whose inode recorded in the rb-tree.
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
---
|
||||
fsck.ocfs2/dirblocks.c | 125 ++++++++++++++++++++++++++++++++++++++-
|
||||
fsck.ocfs2/include/dirblocks.h | 4 +
|
||||
fsck.ocfs2/pass1.c | 54 +++++++++++++++++
|
||||
fsck.ocfs2/pass1b.c | 4 +-
|
||||
fsck.ocfs2/pass2.c | 48 +++++++++++++++-
|
||||
fsck.ocfs2/pass3.c | 1 +
|
||||
fsck.ocfs2/pass4.c | 1 +
|
||||
7 files changed, 229 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/fsck.ocfs2/dirblocks.c b/fsck.ocfs2/dirblocks.c
|
||||
index 1fd5560..085dd1f 100644
|
||||
--- a/fsck.ocfs2/dirblocks.c
|
||||
+++ b/fsck.ocfs2/dirblocks.c
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "fsck.h"
|
||||
#include "dirblocks.h"
|
||||
#include "util.h"
|
||||
+#include "extent.h"
|
||||
|
||||
errcode_t o2fsck_add_dir_block(o2fsck_dirblocks *db, uint64_t ino,
|
||||
uint64_t blkno, uint64_t blkcount)
|
||||
@@ -43,11 +44,9 @@ errcode_t o2fsck_add_dir_block(o2fsck_dirblocks *db, uint64_t ino,
|
||||
o2fsck_dirblock_entry *dbe, *tmp_dbe;
|
||||
errcode_t ret = 0;
|
||||
|
||||
- dbe = calloc(1, sizeof(*dbe));
|
||||
- if (dbe == NULL) {
|
||||
- ret = OCFS2_ET_NO_MEMORY;
|
||||
+ ret = ocfs2_malloc0(sizeof(o2fsck_dirblock_entry), &dbe);
|
||||
+ if (ret)
|
||||
goto out;
|
||||
- }
|
||||
|
||||
dbe->e_ino = ino;
|
||||
dbe->e_blkno = blkno;
|
||||
@@ -134,6 +133,73 @@ static int try_to_cache(ocfs2_filesys *fs, struct rb_node *node,
|
||||
return cached_blocks;
|
||||
}
|
||||
|
||||
+uint64_t o2fsck_search_reidx_dir(struct rb_root *root, uint64_t dino)
|
||||
+{
|
||||
+ struct rb_node *node = root->rb_node;
|
||||
+ o2fsck_dirblock_entry *dbe;
|
||||
+
|
||||
+ while (node) {
|
||||
+ dbe = rb_entry(node, o2fsck_dirblock_entry, e_node);
|
||||
+
|
||||
+ if (dino < dbe->e_ino)
|
||||
+ node = node->rb_left;
|
||||
+ else if (dino > dbe->e_ino)
|
||||
+ node = node->rb_right;
|
||||
+ else
|
||||
+ return dbe->e_ino;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static errcode_t o2fsck_add_reidx_dir_ino(struct rb_root *root, uint64_t dino)
|
||||
+{
|
||||
+ struct rb_node **p = &root->rb_node;
|
||||
+ struct rb_node *parent = NULL;
|
||||
+ o2fsck_dirblock_entry *dp, *tmp_dp;
|
||||
+ errcode_t ret = 0;
|
||||
+
|
||||
+ ret = ocfs2_malloc0(sizeof (o2fsck_dirblock_entry), &dp);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ dp->e_ino = dino;
|
||||
+
|
||||
+ while(*p)
|
||||
+ {
|
||||
+ parent = *p;
|
||||
+ tmp_dp = rb_entry(parent, o2fsck_dirblock_entry, e_node);
|
||||
+
|
||||
+ if (dp->e_ino < tmp_dp->e_ino)
|
||||
+ p = &(*p)->rb_left;
|
||||
+ else if (dp->e_ino > tmp_dp->e_ino)
|
||||
+ p = &(*p)->rb_right;
|
||||
+ else {
|
||||
+ ret = OCFS2_ET_INTERNAL_FAILURE;
|
||||
+ ocfs2_free(&dp);
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ rb_link_node(&dp->e_node, parent, p);
|
||||
+ rb_insert_color(&dp->e_node, root);
|
||||
+
|
||||
+out:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+errcode_t o2fsck_try_add_reidx_dir(struct rb_root *root, uint64_t dino)
|
||||
+{
|
||||
+ errcode_t ret = 0;
|
||||
+ uint64_t ino;
|
||||
+ ino = o2fsck_search_reidx_dir(root, dino);
|
||||
+ if (ino)
|
||||
+ goto out;
|
||||
+ ret = o2fsck_add_reidx_dir_ino(root, dino);
|
||||
+
|
||||
+out:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
void o2fsck_dir_block_iterate(o2fsck_state *ost, dirblock_iterator func,
|
||||
void *priv_data)
|
||||
{
|
||||
@@ -174,3 +240,54 @@ void o2fsck_dir_block_iterate(o2fsck_state *ost, dirblock_iterator func,
|
||||
if (pre_cache_buf)
|
||||
ocfs2_free(&pre_cache_buf);
|
||||
}
|
||||
+
|
||||
+static errcode_t ocfs2_rebuild_indexed_dir(ocfs2_filesys *fs, uint64_t ino)
|
||||
+{
|
||||
+ errcode_t ret = 0;
|
||||
+ char *di_buf = NULL;
|
||||
+ struct ocfs2_dinode *di;
|
||||
+
|
||||
+
|
||||
+ ret = ocfs2_malloc_block(fs->fs_io, &di_buf);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ ret = ocfs2_read_inode(fs, ino, di_buf);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+ di = (struct ocfs2_dinode *)di_buf;
|
||||
+
|
||||
+ /* do not rebuild indexed tree for inline directory */
|
||||
+ if (di->i_dyn_features & OCFS2_INLINE_DATA_FL)
|
||||
+ goto out;
|
||||
+
|
||||
+ ret = ocfs2_dx_dir_truncate(fs, ino);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ ret = ocfs2_dx_dir_build(fs, ino);
|
||||
+out:
|
||||
+ if (di_buf)
|
||||
+ ocfs2_free(&di_buf);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+errcode_t o2fsck_rebuild_indexed_dirs(ocfs2_filesys *fs, struct rb_root *root)
|
||||
+{
|
||||
+ struct rb_node *node;
|
||||
+ o2fsck_dirblock_entry *dbe;
|
||||
+ uint64_t ino;
|
||||
+ errcode_t ret = 0;
|
||||
+
|
||||
+ for (node = rb_first(root); node; node = rb_next(node)) {
|
||||
+ dbe = rb_entry(node, o2fsck_dirblock_entry, e_node);
|
||||
+ ino = dbe->e_ino;
|
||||
+ ret = ocfs2_rebuild_indexed_dir(fs, ino);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+ }
|
||||
+out:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
diff --git a/fsck.ocfs2/include/dirblocks.h b/fsck.ocfs2/include/dirblocks.h
|
||||
index 7b3a2e9..f85974f 100644
|
||||
--- a/fsck.ocfs2/include/dirblocks.h
|
||||
+++ b/fsck.ocfs2/include/dirblocks.h
|
||||
@@ -48,6 +48,10 @@ struct _o2fsck_state;
|
||||
void o2fsck_dir_block_iterate(struct _o2fsck_state *ost, dirblock_iterator func,
|
||||
void *priv_data);
|
||||
|
||||
+uint64_t o2fsck_search_reidx_dir(struct rb_root *root, uint64_t dino);
|
||||
+errcode_t o2fsck_try_add_reidx_dir(struct rb_root *root, uint64_t dino);
|
||||
+errcode_t o2fsck_rebuild_indexed_dirs(ocfs2_filesys *fs, struct rb_root *root);
|
||||
+errcode_t o2fsck_check_dir_index(struct _o2fsck_state *ost, struct ocfs2_dinode *di);
|
||||
|
||||
#endif /* __O2FSCK_DIRBLOCKS_H__ */
|
||||
|
||||
diff --git a/fsck.ocfs2/pass1.c b/fsck.ocfs2/pass1.c
|
||||
index 00f3d54..b53b908 100644
|
||||
--- a/fsck.ocfs2/pass1.c
|
||||
+++ b/fsck.ocfs2/pass1.c
|
||||
@@ -781,6 +781,53 @@ static int clear_block(ocfs2_filesys *fs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+
|
||||
+static errcode_t o2fsck_check_dx_dir(o2fsck_state *ost, struct ocfs2_dinode *di)
|
||||
+{
|
||||
+ errcode_t ret = 0;
|
||||
+ char *buf = NULL;
|
||||
+ struct ocfs2_dx_root_block *dx_root;
|
||||
+ ocfs2_filesys *fs = ost->ost_fs;
|
||||
+ struct extent_info ei = {0,};
|
||||
+ int changed = 0;
|
||||
+
|
||||
+ if (!ocfs2_supports_indexed_dirs(OCFS2_RAW_SB(fs->fs_super)))
|
||||
+ goto out;
|
||||
+
|
||||
+ if (!ocfs2_dir_indexed(di))
|
||||
+ goto out;
|
||||
+
|
||||
+ ret = ocfs2_malloc_block(fs->fs_io, &buf);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ ret = ocfs2_read_dx_root(fs, (uint64_t)di->i_dx_root, buf);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ dx_root = (struct ocfs2_dx_root_block *)buf;
|
||||
+ if (dx_root->dr_flags & OCFS2_DX_FLAG_INLINE)
|
||||
+ goto out;
|
||||
+
|
||||
+ ret = check_el(ost, &ei, di->i_blkno, &dx_root->dr_list,
|
||||
+ ocfs2_extent_recs_per_dx_root(fs->fs_blocksize),
|
||||
+ &changed);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (changed) {
|
||||
+ ret = ocfs2_write_dx_root(fs, (uint64_t)di->i_dx_root, (char *)dx_root);
|
||||
+ if (ret)
|
||||
+ com_err(whoami, ret, "while writing an updated "
|
||||
+ "dx_root block at %"PRIu64" for inode %"PRIu64,
|
||||
+ (uint64_t)di->i_dx_root, (uint64_t)di->i_blkno);
|
||||
+ }
|
||||
+out:
|
||||
+ if (buf)
|
||||
+ ocfs2_free(&buf);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* this verifies i_size and i_clusters for inodes that use i_list to
|
||||
* reference extents of data.
|
||||
@@ -836,6 +883,13 @@ static errcode_t o2fsck_check_blocks(ocfs2_filesys *fs, o2fsck_state *ost,
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ ret = o2fsck_check_dx_dir(ost, di);
|
||||
+ if (ret) {
|
||||
+ com_err(whoami, ret, "while iterating over the dir indexed "
|
||||
+ "tree for directory inode %"PRIu64, (uint64_t)di->i_blkno);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
if (S_ISLNK(di->i_mode))
|
||||
check_link_data(&vb);
|
||||
|
||||
diff --git a/fsck.ocfs2/pass1b.c b/fsck.ocfs2/pass1b.c
|
||||
index 0ea87b4..3ca1d7d 100644
|
||||
--- a/fsck.ocfs2/pass1b.c
|
||||
+++ b/fsck.ocfs2/pass1b.c
|
||||
@@ -902,8 +902,8 @@ static void name_inode(struct dir_scan_context *scan,
|
||||
pass1c_warn(OCFS2_ET_NO_MEMORY);
|
||||
}
|
||||
|
||||
-static int walk_iterate(struct ocfs2_dir_entry *de, int offset,
|
||||
- int blocksize, char *buf, void *priv_data)
|
||||
+static int walk_iterate(struct ocfs2_dir_entry *de, uint64_t blocknr,
|
||||
+ int offset, int blocksize, char *buf, void *priv_data)
|
||||
{
|
||||
struct dir_scan_context *scan = priv_data;
|
||||
|
||||
diff --git a/fsck.ocfs2/pass2.c b/fsck.ocfs2/pass2.c
|
||||
index d61c501..58efcd4 100644
|
||||
--- a/fsck.ocfs2/pass2.c
|
||||
+++ b/fsck.ocfs2/pass2.c
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <time.h>
|
||||
|
||||
#include "ocfs2/ocfs2.h"
|
||||
+#include "ocfs2/kernel-rbtree.h"
|
||||
|
||||
#include "dirparents.h"
|
||||
#include "icount.h"
|
||||
@@ -70,6 +71,7 @@ struct dirblock_data {
|
||||
errcode_t ret;
|
||||
o2fsck_strings strings;
|
||||
uint64_t last_ino;
|
||||
+ struct rb_root re_idx_dirs;
|
||||
};
|
||||
|
||||
static int dirent_has_dots(struct ocfs2_dir_entry *dirent, int num_dots)
|
||||
@@ -833,10 +835,11 @@ next:
|
||||
}
|
||||
|
||||
if (ocfs2_dir_has_trailer(dd->fs, di))
|
||||
- fix_dir_trailer(dd->ost, dbe,
|
||||
+ fix_dir_trailer(dd->ost,
|
||||
+ dbe,
|
||||
ocfs2_dir_trailer_from_block(dd->fs,
|
||||
dd->dirblock_buf),
|
||||
- &ret_flags);
|
||||
+ &ret_flags);
|
||||
|
||||
if (ret_flags & OCFS2_DIRENT_CHANGED) {
|
||||
if (di->i_dyn_features & OCFS2_INLINE_DATA_FL) {
|
||||
@@ -851,15 +854,47 @@ next:
|
||||
com_err(whoami, ret, "while writing dir block %"PRIu64,
|
||||
dbe->e_blkno);
|
||||
dd->ost->ost_write_error = 1;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (ocfs2_supports_indexed_dirs(OCFS2_RAW_SB(dd->fs->fs_super)) &&
|
||||
+ !(di->i_dyn_features & OCFS2_INLINE_DATA_FL) &&
|
||||
+ (di->i_dyn_features & OCFS2_INDEXED_DIR_FL)) {
|
||||
+ ret = o2fsck_try_add_reidx_dir(&dd->re_idx_dirs, dbe->e_ino);
|
||||
+ if (ret) {
|
||||
+ com_err(whoami, ret, "while adding block for "
|
||||
+ "directory inode %"PRIu64" to rebuild "
|
||||
+ "dir index", dbe->e_ino);
|
||||
+ goto out;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
+ /* truncate invalid indexed tree */
|
||||
+ if ((!ocfs2_supports_indexed_dirs(OCFS2_RAW_SB(dd->fs->fs_super)))&&
|
||||
+ di->i_dyn_features & OCFS2_INDEXED_DIR_FL ) {
|
||||
+ /* ignore the return value */
|
||||
+ ocfs2_dx_dir_truncate(dd->fs, dbe->e_ino);
|
||||
+ }
|
||||
+
|
||||
out:
|
||||
if (ret)
|
||||
dd->ret = ret;
|
||||
return ret_flags;
|
||||
}
|
||||
|
||||
+static void release_re_idx_dirs_rbtree(struct rb_root * root)
|
||||
+{
|
||||
+ struct rb_node *node;
|
||||
+ o2fsck_dirblock_entry *dp;
|
||||
+
|
||||
+ while ((node = rb_first(root)) != NULL) {
|
||||
+ dp = rb_entry(node, o2fsck_dirblock_entry, e_node);
|
||||
+ rb_erase(&dp->e_node, root);
|
||||
+ ocfs2_free(&dp);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
errcode_t o2fsck_pass2(o2fsck_state *ost)
|
||||
{
|
||||
o2fsck_dir_parent *dp;
|
||||
@@ -868,6 +903,7 @@ errcode_t o2fsck_pass2(o2fsck_state *ost)
|
||||
.ost = ost,
|
||||
.fs = ost->ost_fs,
|
||||
.last_ino = 0,
|
||||
+ .re_idx_dirs = RB_ROOT,
|
||||
};
|
||||
|
||||
printf("Pass 2: Checking directory entries.\n");
|
||||
@@ -905,6 +941,14 @@ errcode_t o2fsck_pass2(o2fsck_state *ost)
|
||||
dp->dp_dirent = ost->ost_fs->fs_sysdir_blkno;
|
||||
|
||||
o2fsck_dir_block_iterate(ost, pass2_dir_block_iterate, &dd);
|
||||
+
|
||||
+ if (dd.re_idx_dirs.rb_node) {
|
||||
+ ret = o2fsck_rebuild_indexed_dirs(ost->ost_fs, &dd.re_idx_dirs);
|
||||
+ if (ret)
|
||||
+ com_err(whoami, ret, "while rebuild indexed dirs.");
|
||||
+ }
|
||||
+ release_re_idx_dirs_rbtree(&dd.re_idx_dirs);
|
||||
+
|
||||
o2fsck_strings_free(&dd.strings);
|
||||
out:
|
||||
if (dd.dirblock_buf)
|
||||
diff --git a/fsck.ocfs2/pass3.c b/fsck.ocfs2/pass3.c
|
||||
index 457f312..94d9fbd 100644
|
||||
--- a/fsck.ocfs2/pass3.c
|
||||
+++ b/fsck.ocfs2/pass3.c
|
||||
@@ -193,6 +193,7 @@ struct fix_dot_dot_args {
|
||||
};
|
||||
|
||||
static int fix_dot_dot_dirent(struct ocfs2_dir_entry *dirent,
|
||||
+ uint64_t blocknr,
|
||||
int offset,
|
||||
int blocksize,
|
||||
char *buf,
|
||||
diff --git a/fsck.ocfs2/pass4.c b/fsck.ocfs2/pass4.c
|
||||
index d713d13..5ca4f17 100644
|
||||
--- a/fsck.ocfs2/pass4.c
|
||||
+++ b/fsck.ocfs2/pass4.c
|
||||
@@ -101,6 +101,7 @@ out:
|
||||
}
|
||||
|
||||
static int replay_orphan_iterate(struct ocfs2_dir_entry *dirent,
|
||||
+ uint64_t blocknr,
|
||||
int offset,
|
||||
int blocksize,
|
||||
char *buf,
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,217 +0,0 @@
|
||||
From c797d07a1021d5c3a5541236739dabb5dfd4c620 Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Sun, 11 Apr 2010 16:10:06 +0800
|
||||
Subject: [PATCH 09/30] dx_dirs: add 'blocknr' in callback of ocfs2_dir_iterate()
|
||||
|
||||
In order to make ocfs2_dx_dir_insert() easier to set the dir block
|
||||
number to a dx record, a new parameter 'uint64_t
|
||||
blocknr' is added into the call back function parameter of
|
||||
ocfs2_dir_iterate(). This patch includes (part of) the
|
||||
related changes which are not mentioned in previous patches.
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
---
|
||||
debugfs.ocfs2/dump.c | 6 +++---
|
||||
debugfs.ocfs2/find_inode_paths.c | 3 ++-
|
||||
debugfs.ocfs2/include/dump.h | 2 +-
|
||||
debugfs.ocfs2/utils.c | 4 ++--
|
||||
extras/find_hardlinks.c | 1 +
|
||||
extras/find_inode_paths.c | 1 +
|
||||
fswreck/dir.c | 3 +++
|
||||
ocfs2console/ocfs2interface/ocfs2module.c | 1 +
|
||||
tunefs.ocfs2/feature_quota.c | 3 ++-
|
||||
tunefs.ocfs2/op_list_sparse_files.c | 4 ++--
|
||||
tunefs.ocfs2/op_set_slot_count.c | 10 ++++++----
|
||||
11 files changed, 24 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/debugfs.ocfs2/dump.c b/debugfs.ocfs2/dump.c
|
||||
index 88ec430..d55fc0e 100644
|
||||
--- a/debugfs.ocfs2/dump.c
|
||||
+++ b/debugfs.ocfs2/dump.c
|
||||
@@ -461,8 +461,8 @@ void dump_group_descriptor (FILE *out, struct ocfs2_group_desc *grp,
|
||||
* dump_dir_entry()
|
||||
*
|
||||
*/
|
||||
-int dump_dir_entry (struct ocfs2_dir_entry *rec, int offset, int blocksize,
|
||||
- char *buf, void *priv_data)
|
||||
+int dump_dir_entry (struct ocfs2_dir_entry *rec, uint64_t blocknr, int offset,
|
||||
+ int blocksize, char *buf, void *priv_data)
|
||||
{
|
||||
list_dir_opts *ls = (list_dir_opts *)priv_data;
|
||||
char tmp = rec->name[rec->name_len];
|
||||
@@ -544,7 +544,7 @@ void dump_dir_block(FILE *out, char *buf)
|
||||
return;
|
||||
}
|
||||
|
||||
- dump_dir_entry(dirent, offset, gbls.fs->fs_blocksize, NULL,
|
||||
+ dump_dir_entry(dirent, 0, offset, gbls.fs->fs_blocksize, NULL,
|
||||
&ls_opts);
|
||||
offset += dirent->rec_len;
|
||||
}
|
||||
diff --git a/debugfs.ocfs2/find_inode_paths.c b/debugfs.ocfs2/find_inode_paths.c
|
||||
index e2d0e7d..cf9e88a 100644
|
||||
--- a/debugfs.ocfs2/find_inode_paths.c
|
||||
+++ b/debugfs.ocfs2/find_inode_paths.c
|
||||
@@ -38,7 +38,8 @@ struct walk_path {
|
||||
uint64_t *inode;
|
||||
};
|
||||
|
||||
-static int walk_tree_func(struct ocfs2_dir_entry *dentry, int offset,
|
||||
+static int walk_tree_func(struct ocfs2_dir_entry *dentry,
|
||||
+ uint64_t blocknr, int offset,
|
||||
int blocksize, char *buf, void *priv_data)
|
||||
{
|
||||
errcode_t ret;
|
||||
diff --git a/debugfs.ocfs2/include/dump.h b/debugfs.ocfs2/include/dump.h
|
||||
index 79b10b3..ae7b34a 100644
|
||||
--- a/debugfs.ocfs2/include/dump.h
|
||||
+++ b/debugfs.ocfs2/include/dump.h
|
||||
@@ -50,7 +50,7 @@ void dump_extent_list (FILE *out, struct ocfs2_extent_list *ext);
|
||||
void dump_chain_list (FILE *out, struct ocfs2_chain_list *cl);
|
||||
void dump_extent_block (FILE *out, struct ocfs2_extent_block *blk);
|
||||
void dump_group_descriptor (FILE *out, struct ocfs2_group_desc *grp, int index);
|
||||
-int dump_dir_entry (struct ocfs2_dir_entry *rec, int offset, int blocksize,
|
||||
+int dump_dir_entry (struct ocfs2_dir_entry *rec, uint64_t blocknr, int offset, int blocksize,
|
||||
char *buf, void *priv_data);
|
||||
void dump_dx_root (FILE *out, struct ocfs2_dx_root_block *dx_root);
|
||||
void dump_dx_leaf (FILE *out, struct ocfs2_dx_leaf *dx_leaf);
|
||||
diff --git a/debugfs.ocfs2/utils.c b/debugfs.ocfs2/utils.c
|
||||
index 6107d9e..2c5b588 100644
|
||||
--- a/debugfs.ocfs2/utils.c
|
||||
+++ b/debugfs.ocfs2/utils.c
|
||||
@@ -674,8 +674,8 @@ bail:
|
||||
* Copyright (C) 1994 Theodore Ts'o. This file may be redistributed
|
||||
* under the terms of the GNU Public License.
|
||||
*/
|
||||
-static int rdump_dirent(struct ocfs2_dir_entry *rec, int offset, int blocksize,
|
||||
- char *buf, void *priv_data)
|
||||
+static int rdump_dirent(struct ocfs2_dir_entry *rec, uint64_t blocknr,
|
||||
+ int offset, int blocksize, char *buf, void *priv_data)
|
||||
{
|
||||
rdump_opts *rd = (rdump_opts *)priv_data;
|
||||
char tmp = rec->name[rec->name_len];
|
||||
diff --git a/extras/find_hardlinks.c b/extras/find_hardlinks.c
|
||||
index b70f58b..2e1f697 100644
|
||||
--- a/extras/find_hardlinks.c
|
||||
+++ b/extras/find_hardlinks.c
|
||||
@@ -55,6 +55,7 @@ struct walk_path {
|
||||
};
|
||||
|
||||
static int walk_tree_func(struct ocfs2_dir_entry *dentry,
|
||||
+ uint64_t blocknr,
|
||||
int offset,
|
||||
int blocksize,
|
||||
char *buf,
|
||||
diff --git a/extras/find_inode_paths.c b/extras/find_inode_paths.c
|
||||
index 1725b40..b9ad920 100644
|
||||
--- a/extras/find_inode_paths.c
|
||||
+++ b/extras/find_inode_paths.c
|
||||
@@ -53,6 +53,7 @@ struct walk_path {
|
||||
};
|
||||
|
||||
static int walk_tree_func(struct ocfs2_dir_entry *dentry,
|
||||
+ uint64_t blocknr,
|
||||
int offset,
|
||||
int blocksize,
|
||||
char *buf,
|
||||
diff --git a/fswreck/dir.c b/fswreck/dir.c
|
||||
index 66309fd..eb8d0f2 100644
|
||||
--- a/fswreck/dir.c
|
||||
+++ b/fswreck/dir.c
|
||||
@@ -112,6 +112,7 @@ static int corrupt_match_dirent(struct dirent_corrupt_struct *dcs,
|
||||
}
|
||||
|
||||
static int rename_dirent_proc(struct ocfs2_dir_entry *dirent,
|
||||
+ uint64_t blocknr,
|
||||
int offset,
|
||||
int blocksize,
|
||||
char *buf,
|
||||
@@ -157,6 +158,7 @@ static int rename_dirent(ocfs2_filesys *fs, uint64_t dir,
|
||||
}
|
||||
|
||||
static int corrupt_dirent_ino_proc(struct ocfs2_dir_entry *dirent,
|
||||
+ uint64_t blocknr,
|
||||
int offset,
|
||||
int blocksize,
|
||||
char *buf,
|
||||
@@ -200,6 +202,7 @@ static int corrupt_dirent_ino(ocfs2_filesys *fs, uint64_t dir,
|
||||
}
|
||||
|
||||
static int corrupt_dirent_reclen_proc(struct ocfs2_dir_entry *dirent,
|
||||
+ uint64_t blocknr,
|
||||
int offset,
|
||||
int blocksize,
|
||||
char *buf,
|
||||
diff --git a/ocfs2console/ocfs2interface/ocfs2module.c b/ocfs2console/ocfs2interface/ocfs2module.c
|
||||
index bd3139d..18ad04c 100644
|
||||
--- a/ocfs2console/ocfs2interface/ocfs2module.c
|
||||
+++ b/ocfs2console/ocfs2interface/ocfs2module.c
|
||||
@@ -735,6 +735,7 @@ typedef struct
|
||||
|
||||
static int
|
||||
walk_dirs (struct ocfs2_dir_entry *dirent,
|
||||
+ uint64_t blocknr,
|
||||
int offset,
|
||||
int blocksize,
|
||||
char *buf,
|
||||
diff --git a/tunefs.ocfs2/feature_quota.c b/tunefs.ocfs2/feature_quota.c
|
||||
index 2da3cbe..08d7770 100644
|
||||
--- a/tunefs.ocfs2/feature_quota.c
|
||||
+++ b/tunefs.ocfs2/feature_quota.c
|
||||
@@ -165,7 +165,8 @@ struct remove_quota_files_ctxt {
|
||||
};
|
||||
|
||||
static int remove_quota_files_iterate(struct ocfs2_dir_entry *dirent,
|
||||
- int offset, int blocksize, char *buf,
|
||||
+ uint64_t blocknr, int offset,
|
||||
+ int blocksize, char *buf,
|
||||
void *priv_data)
|
||||
{
|
||||
struct remove_quota_files_ctxt *ctxt = priv_data;
|
||||
diff --git a/tunefs.ocfs2/op_list_sparse_files.c b/tunefs.ocfs2/op_list_sparse_files.c
|
||||
index 2f81d36..3127876 100644
|
||||
--- a/tunefs.ocfs2/op_list_sparse_files.c
|
||||
+++ b/tunefs.ocfs2/op_list_sparse_files.c
|
||||
@@ -290,8 +290,8 @@ bail:
|
||||
}
|
||||
|
||||
static int list_sparse_func(struct ocfs2_dir_entry *dirent,
|
||||
- int offset, int blocksize,
|
||||
- char *buf, void *priv_data)
|
||||
+ uint64_t blocknr, int offset,
|
||||
+ int blocksize, char *buf, void *priv_data)
|
||||
{
|
||||
errcode_t ret;
|
||||
char *di_buf = NULL;
|
||||
diff --git a/tunefs.ocfs2/op_set_slot_count.c b/tunefs.ocfs2/op_set_slot_count.c
|
||||
index 46ce2de..cdd4f1a 100644
|
||||
--- a/tunefs.ocfs2/op_set_slot_count.c
|
||||
+++ b/tunefs.ocfs2/op_set_slot_count.c
|
||||
@@ -699,8 +699,9 @@ static errcode_t truncate_orphan_dir(ocfs2_filesys *fs,
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int remove_slot_iterate(struct ocfs2_dir_entry *dirent, int offset,
|
||||
- int blocksize, char *buf, void *priv_data)
|
||||
+static int remove_slot_iterate(struct ocfs2_dir_entry *dirent,
|
||||
+ uint64_t blocknr, int offset, int blocksize,
|
||||
+ char *buf, void *priv_data)
|
||||
{
|
||||
struct remove_slot_ctxt *ctxt =
|
||||
(struct remove_slot_ctxt *)priv_data;
|
||||
@@ -783,8 +784,9 @@ bail:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int orphan_iterate(struct ocfs2_dir_entry *dirent, int offset,
|
||||
- int blocksize, char *buf, void *priv_data)
|
||||
+static int orphan_iterate(struct ocfs2_dir_entry *dirent,
|
||||
+ uint64_t blocknr, int offset, int blocksize,
|
||||
+ char *buf, void *priv_data)
|
||||
{
|
||||
int *has_orphan = (int *)priv_data;
|
||||
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,261 +0,0 @@
|
||||
From 88ed9a6f3d2bb06220c9188ad333b668b3936268 Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Sun, 11 Apr 2010 16:10:07 +0800
|
||||
Subject: [PATCH 10/30] dx_dirs: add disable indexed-dirs support in tunefs.ocfs2
|
||||
|
||||
This patch truncates all directories' indexed tree if '--fs-features
|
||||
noindexed-tree' option is given. The indexed dirs
|
||||
related flags on directory inodes and superblock are cleared too.
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
---
|
||||
tunefs.ocfs2/feature_indexed_dirs.c | 192 ++++++++++++++++++++++++++++++++++-
|
||||
tunefs.ocfs2/o2ne_err.et | 9 ++
|
||||
2 files changed, 199 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/tunefs.ocfs2/feature_indexed_dirs.c b/tunefs.ocfs2/feature_indexed_dirs.c
|
||||
index 368eb87..e9f87fb 100644
|
||||
--- a/tunefs.ocfs2/feature_indexed_dirs.c
|
||||
+++ b/tunefs.ocfs2/feature_indexed_dirs.c
|
||||
@@ -6,7 +6,7 @@
|
||||
* ocfs2 tune utility for enabling and disabling the directory indexing
|
||||
* feature.
|
||||
*
|
||||
- * Copyright (C) 2009 Novell. All rights reserved.
|
||||
+ * Copyright (C) 2009, 2010 Novell. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public
|
||||
@@ -30,6 +30,17 @@
|
||||
|
||||
#include "libocfs2ne.h"
|
||||
|
||||
+struct dx_dirs_inode {
|
||||
+ struct list_head list;
|
||||
+ uint64_t ino;
|
||||
+};
|
||||
+
|
||||
+struct dx_dirs_context {
|
||||
+ errcode_t ret;
|
||||
+ uint64_t dx_dirs_nr;
|
||||
+ struct list_head inodes;
|
||||
+ struct tools_progress *prog;
|
||||
+};
|
||||
|
||||
static int enable_indexed_dirs(ocfs2_filesys *fs, int flags)
|
||||
{
|
||||
@@ -71,6 +82,183 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static errcode_t dx_dir_iterate(ocfs2_filesys *fs, struct ocfs2_dinode *di,
|
||||
+ void *user_data)
|
||||
+{
|
||||
+ errcode_t ret = 0;
|
||||
+ struct dx_dirs_inode *dx_di = NULL;
|
||||
+ struct dx_dirs_context *ctxt= (struct dx_dirs_context *)user_data;
|
||||
+
|
||||
+ if (!S_ISDIR(di->i_mode))
|
||||
+ goto bail;
|
||||
+
|
||||
+ if (!(di->i_dyn_features & OCFS2_INDEXED_DIR_FL))
|
||||
+ goto bail;
|
||||
+
|
||||
+ ret = ocfs2_malloc0(sizeof(struct dx_dirs_inode), &dx_di);
|
||||
+ if (ret) {
|
||||
+ ret = TUNEFS_ET_NO_MEMORY;
|
||||
+ goto bail;
|
||||
+ }
|
||||
+
|
||||
+ dx_di->ino = di->i_blkno;
|
||||
+ ctxt->dx_dirs_nr ++;
|
||||
+ list_add_tail(&dx_di->list, &ctxt->inodes);
|
||||
+
|
||||
+ tools_progress_step(ctxt->prog, 1);
|
||||
+
|
||||
+bail:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static errcode_t find_indexed_dirs(ocfs2_filesys *fs,
|
||||
+ struct dx_dirs_context *ctxt)
|
||||
+{
|
||||
+ errcode_t ret;
|
||||
+
|
||||
+ ctxt->prog = tools_progress_start("Scanning filesystem", "scanning", 0);
|
||||
+ if (!ctxt->prog) {
|
||||
+ ret = TUNEFS_ET_NO_MEMORY;
|
||||
+ goto bail;
|
||||
+ }
|
||||
+
|
||||
+ ret = tunefs_foreach_inode(fs, dx_dir_iterate, ctxt);
|
||||
+ if (ret) {
|
||||
+ if (ret != TUNEFS_ET_NO_MEMORY)
|
||||
+ ret = TUNEFS_ET_DX_DIRS_SCAN_FAILED;
|
||||
+ goto bail;
|
||||
+ }
|
||||
+
|
||||
+ verbosef(VL_APP,
|
||||
+ "We have %lu indexed %s to truncate.\n",
|
||||
+ ctxt->dx_dirs_nr,
|
||||
+ (ctxt->dx_dirs_nr > 1)?"directories":"directory");
|
||||
+
|
||||
+bail:
|
||||
+ if (ctxt->prog)
|
||||
+ tools_progress_stop(ctxt->prog);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static errcode_t clean_indexed_dirs(ocfs2_filesys *fs,
|
||||
+ struct dx_dirs_context *ctxt)
|
||||
+{
|
||||
+ errcode_t ret = 0;
|
||||
+ struct list_head *pos;
|
||||
+ struct dx_dirs_inode *dx_di;
|
||||
+ struct tools_progress *prog;
|
||||
+ uint64_t dirs_truncated = 0;
|
||||
+
|
||||
+ prog = tools_progress_start("Truncating indexed dirs", "truncating",
|
||||
+ ctxt->dx_dirs_nr);
|
||||
+ if (!prog) {
|
||||
+ ret = TUNEFS_ET_NO_MEMORY;
|
||||
+ goto bail;
|
||||
+ }
|
||||
+
|
||||
+ list_for_each(pos, &ctxt->inodes) {
|
||||
+ dx_di = list_entry(pos, struct dx_dirs_inode, list);
|
||||
+
|
||||
+ ret = ocfs2_dx_dir_truncate(fs, dx_di->ino);
|
||||
+ if (ret) {
|
||||
+ verbosef(VL_APP,
|
||||
+ "Truncate directory (ino \"%lu\") failed.",
|
||||
+ dx_di->ino);
|
||||
+ ret = TUNEFS_ET_DX_DIRS_TRUNCATE_FAILED;
|
||||
+ goto bail;
|
||||
+ }
|
||||
+ dirs_truncated ++;
|
||||
+ tools_progress_step(prog, 1);
|
||||
+ }
|
||||
+
|
||||
+bail:
|
||||
+ tools_progress_stop(prog);
|
||||
+ verbosef(VL_APP,
|
||||
+ "\"%lu\" from \"%lu\" indexed %s truncated.",
|
||||
+ dirs_truncated, ctxt->dx_dirs_nr,
|
||||
+ (dirs_truncated <= 1) ? "directory is" : "directories are");
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static void release_dx_dirs_context(struct dx_dirs_context *ctxt)
|
||||
+{
|
||||
+ struct list_head *pos, *n;
|
||||
+ struct dx_dirs_inode *dx_di;
|
||||
+
|
||||
+ list_for_each_safe(pos, n, &ctxt->inodes) {
|
||||
+ dx_di = list_entry(pos, struct dx_dirs_inode, list);
|
||||
+ list_del(&dx_di->list);
|
||||
+ ocfs2_free(&dx_di);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static int disable_indexed_dirs(ocfs2_filesys *fs, int flags)
|
||||
+{
|
||||
+ errcode_t ret = 0;
|
||||
+ struct ocfs2_super_block *super = OCFS2_RAW_SB(fs->fs_super);
|
||||
+ struct dx_dirs_context ctxt;
|
||||
+ struct tools_progress *prog = NULL;
|
||||
+
|
||||
+ if (!ocfs2_supports_indexed_dirs(super)) {
|
||||
+ verbosef(VL_APP,
|
||||
+ "Directory indexing feature is not enabled; "
|
||||
+ "nothing to disable\n");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (!tools_interact("Disabling the directory indexing feature on "
|
||||
+ "device \"%s\"? ",
|
||||
+ fs->fs_devname))
|
||||
+ goto out;
|
||||
+
|
||||
+ prog = tools_progress_start("Disable directory indexing", "no dir idx", 2);
|
||||
+ if (!prog) {
|
||||
+ ret = TUNEFS_ET_NO_MEMORY;
|
||||
+ tcom_err(ret, "while initializing the progress display");
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ memset(&ctxt, 0, sizeof (struct dx_dirs_context));
|
||||
+ INIT_LIST_HEAD(&ctxt.inodes);
|
||||
+ ret = find_indexed_dirs(fs, &ctxt);
|
||||
+ if (ret) {
|
||||
+ tcom_err(ret, "while scanning indexed directories");
|
||||
+ goto out_cleanup;
|
||||
+ }
|
||||
+
|
||||
+ tools_progress_step(prog, 1);
|
||||
+
|
||||
+ tunefs_block_signals();
|
||||
+ ret = clean_indexed_dirs(fs, &ctxt);
|
||||
+ if (ret) {
|
||||
+ tcom_err(ret, "while truncate indexed directories");
|
||||
+ }
|
||||
+
|
||||
+ /* We already touched file system, must disable dx dirs flag here.
|
||||
+ * fsck.ocfs2 will handle the orphan indexed trees. */
|
||||
+ OCFS2_CLEAR_INCOMPAT_FEATURE(super,
|
||||
+ OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS);
|
||||
+ ret = ocfs2_write_super(fs);
|
||||
+ tunefs_unblock_signals();
|
||||
+
|
||||
+ if (ret) {
|
||||
+ ret = TUNEFS_ET_IO_WRITE_FAILED;
|
||||
+ tcom_err(ret, "while writing super block");
|
||||
+ }
|
||||
+
|
||||
+ tools_progress_step(prog, 1);
|
||||
+out_cleanup:
|
||||
+ release_dx_dirs_context(&ctxt);
|
||||
+out:
|
||||
+ if (prog)
|
||||
+ tools_progress_stop(prog);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* TUNEFS_FLAG_ALLOCATION because disabling will want to dealloc
|
||||
* blocks.
|
||||
@@ -79,7 +267,7 @@ DEFINE_TUNEFS_FEATURE_INCOMPAT(indexed_dirs,
|
||||
OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS,
|
||||
TUNEFS_FLAG_RW | TUNEFS_FLAG_ALLOCATION,
|
||||
enable_indexed_dirs,
|
||||
- NULL);
|
||||
+ disable_indexed_dirs);
|
||||
|
||||
#ifdef DEBUG_EXE
|
||||
int main(int argc, char *argv[])
|
||||
diff --git a/tunefs.ocfs2/o2ne_err.et b/tunefs.ocfs2/o2ne_err.et
|
||||
index 20031a5..c2f700b 100644
|
||||
--- a/tunefs.ocfs2/o2ne_err.et
|
||||
+++ b/tunefs.ocfs2/o2ne_err.et
|
||||
@@ -85,4 +85,13 @@ ec TUNEFS_ET_ONLINE_NOT_SUPPORTED,
|
||||
ec TUNEFS_ET_CLUSTER_SKIPPED,
|
||||
"Cluster stack initialization was skipped"
|
||||
|
||||
+ec TUNEFS_ET_DX_DIRS_SCAN_FAILED,
|
||||
+ "Scanning inodes for directory indexing failed"
|
||||
+
|
||||
+ec TUNEFS_ET_IO_WRITE_FAILED,
|
||||
+ "Write I/O failed"
|
||||
+
|
||||
+ec TUNEFS_ET_DX_DIRS_TRUNCATE_FAILED,
|
||||
+ "Truncate directory indexed tree failed"
|
||||
+
|
||||
end
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,139 +0,0 @@
|
||||
From 28f5939111c09de057750fb30ce40ade8bd2b8ef Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Sun, 11 Apr 2010 16:10:08 +0800
|
||||
Subject: [PATCH 11/30] dx_dirs: build indexed trees when enabling indexed-dirs
|
||||
|
||||
Previos enable indexed-dirs implementation only set superblock flag,
|
||||
does not build indexed trees for existed directories.
|
||||
Tis patch tries to build indexed trees for directories when enable
|
||||
indexed-dirs.
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
---
|
||||
tunefs.ocfs2/feature_indexed_dirs.c | 67 +++++++++++++++++++++++++++++++----
|
||||
tunefs.ocfs2/o2ne_err.et | 3 ++
|
||||
2 files changed, 63 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/tunefs.ocfs2/feature_indexed_dirs.c b/tunefs.ocfs2/feature_indexed_dirs.c
|
||||
index e9f87fb..cfa0dd0 100644
|
||||
--- a/tunefs.ocfs2/feature_indexed_dirs.c
|
||||
+++ b/tunefs.ocfs2/feature_indexed_dirs.c
|
||||
@@ -42,11 +42,46 @@ struct dx_dirs_context {
|
||||
struct tools_progress *prog;
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * If an indexed-dirs disabled directory has an indexed tree,
|
||||
+ * this tree is unreliable. it must be truncated and rebuilt.
|
||||
+ */
|
||||
+static errcode_t build_dx_dir(ocfs2_filesys *fs, struct ocfs2_dinode *di,
|
||||
+ void *user_data)
|
||||
+{
|
||||
+ errcode_t ret = 0;
|
||||
+ struct dx_dirs_context *ctxt = (struct dx_dirs_context *)user_data;
|
||||
+
|
||||
+ if (!S_ISDIR(di->i_mode))
|
||||
+ goto bail;
|
||||
+
|
||||
+ if (di->i_dyn_features & OCFS2_INDEXED_DIR_FL) {
|
||||
+ verbosef(VL_APP,
|
||||
+ "Directory inode %llu already has an indexed tree, "
|
||||
+ "rebuild the indexed tree.\n", di->i_blkno);
|
||||
+ ret = ocfs2_dx_dir_truncate(fs, di->i_blkno);
|
||||
+ if (ret) {
|
||||
+ ret = TUNEFS_ET_DX_DIRS_TRUNCATE_FAILED;
|
||||
+ tcom_err(ret, "while rebulid indexed tree");
|
||||
+ }
|
||||
+ }
|
||||
+ ret = ocfs2_dx_dir_build(fs, di->i_blkno);
|
||||
+ if (ret) {
|
||||
+ ret = TUNEFS_ET_DX_DIRS_BUILD_FAILED;
|
||||
+ tcom_err(ret, "while enable indexed-dirs");
|
||||
+ }
|
||||
+
|
||||
+bail:
|
||||
+ tools_progress_step(ctxt->prog, 1);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int enable_indexed_dirs(ocfs2_filesys *fs, int flags)
|
||||
{
|
||||
errcode_t ret = 0;
|
||||
struct ocfs2_super_block *super = OCFS2_RAW_SB(fs->fs_super);
|
||||
- struct tools_progress *prog;
|
||||
+ struct tools_progress *prog = NULL;
|
||||
+ struct dx_dirs_context ctxt;
|
||||
|
||||
if (ocfs2_supports_indexed_dirs(super)) {
|
||||
verbosef(VL_APP,
|
||||
@@ -55,30 +90,48 @@ static int enable_indexed_dirs(ocfs2_filesys *fs, int flags)
|
||||
goto out;
|
||||
}
|
||||
|
||||
-
|
||||
if (!tools_interact("Enable the directory indexing feature on "
|
||||
"device \"%s\"? ",
|
||||
fs->fs_devname))
|
||||
goto out;
|
||||
|
||||
- prog = tools_progress_start("Enable directory indexing", "dir idx", 1);
|
||||
+ prog = tools_progress_start("Enable directory indexing", "dir idx", 2);
|
||||
if (!prog) {
|
||||
ret = TUNEFS_ET_NO_MEMORY;
|
||||
tcom_err(ret, "while initializing the progress display");
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ memset(&ctxt, 0, sizeof(struct dx_dirs_context));
|
||||
+ ctxt.prog = tools_progress_start("Building indexed trees", "building", 0);
|
||||
+ if (!ctxt.prog) {
|
||||
+ ret = TUNEFS_ET_NO_MEMORY;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
OCFS2_SET_INCOMPAT_FEATURE(super,
|
||||
OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS);
|
||||
+
|
||||
tunefs_block_signals();
|
||||
ret = ocfs2_write_super(fs);
|
||||
- tunefs_unblock_signals();
|
||||
- if (ret)
|
||||
+ if (ret) {
|
||||
+ ret = TUNEFS_ET_IO_WRITE_FAILED;
|
||||
tcom_err(ret, "while writing out the superblock");
|
||||
-
|
||||
+ goto unblock_out;
|
||||
+ }
|
||||
tools_progress_step(prog, 1);
|
||||
- tools_progress_stop(prog);
|
||||
+ ret = tunefs_foreach_inode(fs, build_dx_dir, &ctxt);
|
||||
+ if (ret)
|
||||
+ tcom_err(ret, "while building indexed trees");
|
||||
+unblock_out:
|
||||
+ tunefs_unblock_signals();
|
||||
+ tools_progress_step(prog, 1);
|
||||
+ if (ctxt.prog)
|
||||
+ tools_progress_stop(ctxt.prog);
|
||||
out:
|
||||
+ if (prog)
|
||||
+ tools_progress_stop(prog);
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
diff --git a/tunefs.ocfs2/o2ne_err.et b/tunefs.ocfs2/o2ne_err.et
|
||||
index c2f700b..3561d8c 100644
|
||||
--- a/tunefs.ocfs2/o2ne_err.et
|
||||
+++ b/tunefs.ocfs2/o2ne_err.et
|
||||
@@ -94,4 +94,7 @@ ec TUNEFS_ET_IO_WRITE_FAILED,
|
||||
ec TUNEFS_ET_DX_DIRS_TRUNCATE_FAILED,
|
||||
"Truncate directory indexed tree failed"
|
||||
|
||||
+ec TUNEFS_ET_DX_DIRS_BUILD_FAILED,
|
||||
+ "Build directory indexed tree failed"
|
||||
+
|
||||
end
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,32 +0,0 @@
|
||||
From 183b0b3a12396e838dcb9c1e7dc0423eb3a4fbd5 Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Sun, 11 Apr 2010 16:10:09 +0800
|
||||
Subject: [PATCH 12/30] dx_dirs: fix return value of walk_dirblock() when enable metaecc
|
||||
|
||||
If there is no error, the return value 'ret' might be used with
|
||||
undefined initial value. This patch fixes the error by initiating
|
||||
it to 0.
|
||||
|
||||
Reported-by: Vit Pelcak <vpelcak@novell.com>
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
---
|
||||
tunefs.ocfs2/feature_metaecc.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/tunefs.ocfs2/feature_metaecc.c b/tunefs.ocfs2/feature_metaecc.c
|
||||
index c4de8be..799b404 100644
|
||||
--- a/tunefs.ocfs2/feature_metaecc.c
|
||||
+++ b/tunefs.ocfs2/feature_metaecc.c
|
||||
@@ -135,7 +135,7 @@ static errcode_t walk_dirblock(ocfs2_filesys *fs,
|
||||
struct tunefs_trailer_context *tc,
|
||||
struct tunefs_trailer_dirblock *db)
|
||||
{
|
||||
- errcode_t ret;
|
||||
+ errcode_t ret = 0;
|
||||
struct ocfs2_dir_entry *dirent, *prev = NULL;
|
||||
unsigned int real_rec_len;
|
||||
unsigned int offset = 0;
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,131 +0,0 @@
|
||||
From 947d4450eed4a18299d7b14b828a69533eb4a2ed Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Sun, 11 Apr 2010 16:10:10 +0800
|
||||
Subject: [PATCH 13/30] dx_dirs: try to install dir trailers when enable indexed-dirs
|
||||
|
||||
If metaecc feature is not enabled, previuos indexed-dirs patches in
|
||||
ocfs2-tools does not install dir trailers and move the dir entries which
|
||||
lie in the trailer area. This patch tries to install dir trailers when
|
||||
enable indexed-dirs feature.
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
---
|
||||
tunefs.ocfs2/feature_indexed_dirs.c | 8 ++++++++
|
||||
tunefs.ocfs2/feature_metaecc.c | 25 +++----------------------
|
||||
tunefs.ocfs2/libocfs2ne.h | 25 +++++++++++++++++++++++++
|
||||
tunefs.ocfs2/o2ne_err.et | 3 +++
|
||||
4 files changed, 39 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/tunefs.ocfs2/feature_indexed_dirs.c b/tunefs.ocfs2/feature_indexed_dirs.c
|
||||
index cfa0dd0..c26780e 100644
|
||||
--- a/tunefs.ocfs2/feature_indexed_dirs.c
|
||||
+++ b/tunefs.ocfs2/feature_indexed_dirs.c
|
||||
@@ -65,6 +65,14 @@ static errcode_t build_dx_dir(ocfs2_filesys *fs, struct ocfs2_dinode *di,
|
||||
tcom_err(ret, "while rebulid indexed tree");
|
||||
}
|
||||
}
|
||||
+
|
||||
+ ret = tunefs_install_dir_trailer(fs, di, NULL);
|
||||
+ if (ret) {
|
||||
+ ret = TUNEFS_ET_INSTALL_DIR_TRAILER_FAILED;
|
||||
+ tcom_err(ret, "while enable indexed-dirs");
|
||||
+ goto bail;
|
||||
+ }
|
||||
+
|
||||
ret = ocfs2_dx_dir_build(fs, di->i_blkno);
|
||||
if (ret) {
|
||||
ret = TUNEFS_ET_DX_DIRS_BUILD_FAILED;
|
||||
diff --git a/tunefs.ocfs2/feature_metaecc.c b/tunefs.ocfs2/feature_metaecc.c
|
||||
index 799b404..e6b48b5 100644
|
||||
--- a/tunefs.ocfs2/feature_metaecc.c
|
||||
+++ b/tunefs.ocfs2/feature_metaecc.c
|
||||
@@ -68,25 +68,6 @@ struct tunefs_trailer_dirblock {
|
||||
struct ocfs2_dir_entry *db_last;
|
||||
};
|
||||
|
||||
-/* A directory inode we're adding trailers to */
|
||||
-struct tunefs_trailer_context {
|
||||
- struct list_head d_list;
|
||||
- uint64_t d_blkno; /* block number of the dir */
|
||||
- struct ocfs2_dinode *d_di; /* The directory's inode */
|
||||
- struct list_head d_dirblocks; /* List of its dirblocks */
|
||||
- uint64_t d_bytes_needed; /* How many new bytes will
|
||||
- cover the dirents we are moving
|
||||
- to make way for trailers */
|
||||
- uint64_t d_blocks_needed; /* How many blocks covers
|
||||
- d_bytes_needed */
|
||||
- char *d_new_blocks; /* Buffer of new blocks to fill */
|
||||
- char *d_cur_block; /* Which block we're filling in
|
||||
- d_new_blocks */
|
||||
- struct ocfs2_dir_entry *d_next_dirent; /* Next dentry to use */
|
||||
- errcode_t d_err; /* Any processing error during
|
||||
- iteration of the directory */
|
||||
-};
|
||||
-
|
||||
static void tunefs_trailer_context_free(struct tunefs_trailer_context *tc)
|
||||
{
|
||||
struct tunefs_trailer_dirblock *db;
|
||||
@@ -529,9 +510,9 @@ out:
|
||||
}
|
||||
|
||||
|
||||
-static errcode_t tunefs_install_dir_trailer(ocfs2_filesys *fs,
|
||||
- struct ocfs2_dinode *di,
|
||||
- struct tunefs_trailer_context *tc)
|
||||
+errcode_t tunefs_install_dir_trailer(ocfs2_filesys *fs,
|
||||
+ struct ocfs2_dinode *di,
|
||||
+ struct tunefs_trailer_context *tc)
|
||||
{
|
||||
errcode_t ret = 0;
|
||||
struct tunefs_trailer_context *our_tc = NULL;
|
||||
diff --git a/tunefs.ocfs2/libocfs2ne.h b/tunefs.ocfs2/libocfs2ne.h
|
||||
index a8e1e5e..18380be 100644
|
||||
--- a/tunefs.ocfs2/libocfs2ne.h
|
||||
+++ b/tunefs.ocfs2/libocfs2ne.h
|
||||
@@ -281,5 +281,30 @@ errcode_t tunefs_feature_run(ocfs2_filesys *master_fs,
|
||||
int tunefs_feature_main(int argc, char *argv[], struct tunefs_feature *feat);
|
||||
int tunefs_op_main(int argc, char *argv[], struct tunefs_operation *op);
|
||||
|
||||
+/* A directory inode we're adding trailers to */
|
||||
+struct tunefs_trailer_context {
|
||||
+ struct list_head d_list;
|
||||
+ uint64_t d_blkno; /* block number of the dir */
|
||||
+ struct ocfs2_dinode *d_di; /* The directory's inode */
|
||||
+ struct list_head d_dirblocks; /* List of its dirblocks */
|
||||
+ uint64_t d_bytes_needed; /* How many new bytes will
|
||||
+ cover the dirents we are moving
|
||||
+ to make way for trailers */
|
||||
+ uint64_t d_blocks_needed; /* How many blocks covers
|
||||
+ d_bytes_needed */
|
||||
+ char *d_new_blocks; /* Buffer of new blocks to fill */
|
||||
+ char *d_cur_block; /* Which block we're filling in
|
||||
+ d_new_blocks */
|
||||
+ struct ocfs2_dir_entry *d_next_dirent; /* Next dentry to use */
|
||||
+ errcode_t d_err; /* Any processing error during
|
||||
+ iteration of the directory */
|
||||
+};
|
||||
+
|
||||
+/*
|
||||
+ * called from feature_metaecc.c and feature_indexed_dirs.c
|
||||
+ * to install dir trailers
|
||||
+ */
|
||||
+errcode_t tunefs_install_dir_trailer(ocfs2_filesys *fs, struct ocfs2_dinode *di,
|
||||
+ struct tunefs_trailer_context *tc);
|
||||
|
||||
#endif /* _LIBTUNEFS_H */
|
||||
diff --git a/tunefs.ocfs2/o2ne_err.et b/tunefs.ocfs2/o2ne_err.et
|
||||
index 3561d8c..955c338 100644
|
||||
--- a/tunefs.ocfs2/o2ne_err.et
|
||||
+++ b/tunefs.ocfs2/o2ne_err.et
|
||||
@@ -97,4 +97,7 @@ ec TUNEFS_ET_DX_DIRS_TRUNCATE_FAILED,
|
||||
ec TUNEFS_ET_DX_DIRS_BUILD_FAILED,
|
||||
"Build directory indexed tree failed"
|
||||
|
||||
+ec TUNEFS_ET_INSTALL_DIR_TRAILER_FAILED,
|
||||
+ "Install directory trailer failed"
|
||||
+
|
||||
end
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,32 +0,0 @@
|
||||
From 0fe34f26335f1d2f10550b2e12f65f6f24f39a6f Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Sun, 11 Apr 2010 16:10:11 +0800
|
||||
Subject: [PATCH 14/30] dx_dirs: add an initial man page entry for indexed-dirs
|
||||
|
||||
This patch add an initial man page entry for indexed-dirs feature
|
||||
string.
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
---
|
||||
mkfs.ocfs2/mkfs.ocfs2.8.in | 4 ++++
|
||||
1 files changed, 4 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/mkfs.ocfs2/mkfs.ocfs2.8.in b/mkfs.ocfs2/mkfs.ocfs2.8.in
|
||||
index c7a7888..a148133 100644
|
||||
--- a/mkfs.ocfs2/mkfs.ocfs2.8.in
|
||||
+++ b/mkfs.ocfs2/mkfs.ocfs2.8.in
|
||||
@@ -175,6 +175,10 @@ and number of inodes (files, directories, symbolic links) each group owns. It is
|
||||
to limit the maximum amount of space or inodes user can have. See a documentation of
|
||||
quota-tools package for more details.
|
||||
.RE
|
||||
+.TP
|
||||
+\fBindexed-dirs\fR
|
||||
+Enable directory indexing support. With this feature enabled, the file system creates indexed tree for non-inline directory entries. For large scale directories, directory entry lookup perfromance from the indexed tree is faster then from the legacy directory blocks.
|
||||
+.RE
|
||||
|
||||
.TP
|
||||
\fB\-\-fs\-feature\-level=\fR\fR\fIfeature\-level\fR
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,48 +0,0 @@
|
||||
From ed44744701bd4eeaf5ee0fcce9190cdf36b5b21c Mon Sep 17 00:00:00 2001
|
||||
From: Mark Fasheh <mfasheh@suse.com>
|
||||
Date: Mon, 19 Apr 2010 16:25:48 -0700
|
||||
Subject: [PATCH 15/30] fsck.ocfs2: prompt before truncating an invalid dir index
|
||||
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
---
|
||||
fsck.ocfs2/fsck.ocfs2.checks.8.in | 6 ++++++
|
||||
fsck.ocfs2/pass2.c | 6 +++++-
|
||||
2 files changed, 11 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/fsck.ocfs2/fsck.ocfs2.checks.8.in b/fsck.ocfs2/fsck.ocfs2.checks.8.in
|
||||
index 05561ae..5cda023 100644
|
||||
--- a/fsck.ocfs2/fsck.ocfs2.checks.8.in
|
||||
+++ b/fsck.ocfs2/fsck.ocfs2.checks.8.in
|
||||
@@ -1055,6 +1055,12 @@ but fsck has already found quota limits for this user / group.
|
||||
|
||||
Answering yes will use new values of limits for the user / group.
|
||||
|
||||
+.SS "IV_DX_TREE"
|
||||
+A directory index was found on an inode but that feature is not enabled on the
|
||||
+file system.
|
||||
+
|
||||
+Answering yes will truncate the invalid index.
|
||||
+
|
||||
.SH "SEE ALSO"
|
||||
.BR fsck.ocfs2(8)
|
||||
|
||||
diff --git a/fsck.ocfs2/pass2.c b/fsck.ocfs2/pass2.c
|
||||
index 58efcd4..b999761 100644
|
||||
--- a/fsck.ocfs2/pass2.c
|
||||
+++ b/fsck.ocfs2/pass2.c
|
||||
@@ -874,7 +874,11 @@ next:
|
||||
if ((!ocfs2_supports_indexed_dirs(OCFS2_RAW_SB(dd->fs->fs_super)))&&
|
||||
di->i_dyn_features & OCFS2_INDEXED_DIR_FL ) {
|
||||
/* ignore the return value */
|
||||
- ocfs2_dx_dir_truncate(dd->fs, dbe->e_ino);
|
||||
+ if (prompt(dd->ost, PY, PR_IV_DX_TREE, "A directory index was "
|
||||
+ "found on inode %"PRIu64" but the indexing feature "
|
||||
+ "is not set on the fs. Truncate the invalid index?",
|
||||
+ dbe->e_ino))
|
||||
+ ocfs2_dx_dir_truncate(dd->fs, dbe->e_ino);
|
||||
}
|
||||
|
||||
out:
|
||||
--
|
||||
1.7.0.2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,30 +0,0 @@
|
||||
From e618ad9a6cafae5351f87ae0601d3b16ec9af96a Mon Sep 17 00:00:00 2001
|
||||
From: Mark Fasheh <mfasheh@suse.com>
|
||||
Date: Mon, 19 Apr 2010 21:36:37 -0700
|
||||
Subject: [PATCH 17/30] dx_dirs: add check for invalid slot in ocfs2_new_dx_root()
|
||||
|
||||
This can happen in the case of a system inode, such as the root or orphan
|
||||
directories.
|
||||
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
---
|
||||
libocfs2/alloc.c | 3 +++
|
||||
1 files changed, 3 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/libocfs2/alloc.c b/libocfs2/alloc.c
|
||||
index 84f3b05..7f85a34 100644
|
||||
--- a/libocfs2/alloc.c
|
||||
+++ b/libocfs2/alloc.c
|
||||
@@ -658,6 +658,9 @@ errcode_t ocfs2_new_dx_root(ocfs2_filesys *fs,
|
||||
goto out;
|
||||
|
||||
slot = di->i_suballoc_slot;
|
||||
+ if (slot == (uint16_t)OCFS2_INVALID_SLOT)
|
||||
+ slot = 0;
|
||||
+
|
||||
ret = ocfs2_load_allocator(fs, EXTENT_ALLOC_SYSTEM_INODE,
|
||||
slot, &fs->fs_eb_allocs[slot]);
|
||||
if (ret)
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,137 +0,0 @@
|
||||
From 88d139c22a91b17ff451a50e37d002d8714748f3 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Fasheh <mfasheh@suse.com>
|
||||
Date: Mon, 19 Apr 2010 22:26:47 -0700
|
||||
Subject: [PATCH 18/30] mkfs.ocfs2: create root and orphan directories as indexed
|
||||
|
||||
If the indexed dirs feature is enabled but the inline directories feature is
|
||||
for some reason disabled, we'll create sub-optimal (non-indexed) root and
|
||||
orphan directories. It's easy however at the end of mkfs.ocfs2 to simply
|
||||
index these.
|
||||
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
---
|
||||
mkfs.ocfs2/mkfs.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++----
|
||||
mkfs.ocfs2/mkfs.h | 1 +
|
||||
2 files changed, 62 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/mkfs.ocfs2/mkfs.c b/mkfs.ocfs2/mkfs.c
|
||||
index b43a9ba..5507872 100644
|
||||
--- a/mkfs.ocfs2/mkfs.c
|
||||
+++ b/mkfs.ocfs2/mkfs.c
|
||||
@@ -82,6 +82,7 @@ static AllocGroup * initialize_alloc_group(State *s, const char *name,
|
||||
uint64_t blkno,
|
||||
uint16_t chain, uint16_t cpg,
|
||||
uint16_t bpc);
|
||||
+static void index_system_dirs(State *s, ocfs2_filesys *fs);
|
||||
static void create_lost_found_dir(State *s, ocfs2_filesys *fs);
|
||||
static void format_journals(State *s, ocfs2_filesys *fs);
|
||||
static void format_slotmap(State *s, ocfs2_filesys *fs);
|
||||
@@ -436,12 +437,6 @@ static void finish_normal_format(State *s)
|
||||
printf("done\n");
|
||||
|
||||
if (!s->quiet)
|
||||
- printf("Writing lost+found: ");
|
||||
- create_lost_found_dir(s, fs);
|
||||
- if (!s->quiet)
|
||||
- printf("done\n");
|
||||
-
|
||||
- if (!s->quiet)
|
||||
printf("Formatting quota files: ");
|
||||
|
||||
format_quota_files(s, fs);
|
||||
@@ -449,6 +444,24 @@ static void finish_normal_format(State *s)
|
||||
if (!s->quiet)
|
||||
printf("done\n");
|
||||
|
||||
+ if (s->dx_dirs && !s->inline_data) {
|
||||
+ /*
|
||||
+ * We want to do this after quota, but before adding
|
||||
+ * any new entries to directories.
|
||||
+ */
|
||||
+ if (!s->quiet)
|
||||
+ printf("Indexing system directories: ");
|
||||
+ index_system_dirs(s, fs);
|
||||
+ if (!s->quiet)
|
||||
+ printf("done\n");
|
||||
+ }
|
||||
+
|
||||
+ if (!s->quiet)
|
||||
+ printf("Writing lost+found: ");
|
||||
+ create_lost_found_dir(s, fs);
|
||||
+ if (!s->quiet)
|
||||
+ printf("done\n");
|
||||
+
|
||||
ocfs2_close(fs);
|
||||
}
|
||||
|
||||
@@ -1085,6 +1098,10 @@ get_state(int argc, char **argv)
|
||||
s->no_backup_super = 0;
|
||||
else
|
||||
s->no_backup_super = 1;
|
||||
+ if (s->feature_flags.opt_incompat & OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS)
|
||||
+ s->dx_dirs = 1;
|
||||
+ else
|
||||
+ s->dx_dirs = 0;
|
||||
|
||||
|
||||
/* Here if the user set these flags explicitly, we will use them and
|
||||
@@ -2751,6 +2768,44 @@ clear_both_ends(State *s)
|
||||
return ;
|
||||
}
|
||||
|
||||
+static void index_system_dirs(State *s, ocfs2_filesys *fs)
|
||||
+{
|
||||
+ errcode_t ret;
|
||||
+ int i, num_slots = OCFS2_RAW_SB(fs->fs_super)->s_max_slots;
|
||||
+ uint64_t orphan_dir_blkno;
|
||||
+
|
||||
+
|
||||
+ /* Start with the root directory */
|
||||
+ ret = ocfs2_dx_dir_build(fs, fs->fs_root_blkno);
|
||||
+ if (ret) {
|
||||
+ com_err(s->progname, ret, "while indexing root directory");
|
||||
+ goto bail;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < num_slots; i++) {
|
||||
+ ret = ocfs2_lookup_system_inode(fs, ORPHAN_DIR_SYSTEM_INODE,
|
||||
+ i, &orphan_dir_blkno);
|
||||
+ if (ret) {
|
||||
+ com_err(s->progname, ret,
|
||||
+ "while looking up orphan dir %d for indexing",
|
||||
+ i);
|
||||
+ goto bail;
|
||||
+ }
|
||||
+
|
||||
+ ret = ocfs2_dx_dir_build(fs, orphan_dir_blkno);
|
||||
+ if (ret) {
|
||||
+ com_err(s->progname, ret, "while indexing root directory");
|
||||
+ goto bail;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+
|
||||
+bail:
|
||||
+ clear_both_ends(s);
|
||||
+ exit(1);
|
||||
+}
|
||||
+
|
||||
static void create_lost_found_dir(State *s, ocfs2_filesys *fs)
|
||||
{
|
||||
errcode_t ret;
|
||||
diff --git a/mkfs.ocfs2/mkfs.h b/mkfs.ocfs2/mkfs.h
|
||||
index b702f00..c3aecd6 100644
|
||||
--- a/mkfs.ocfs2/mkfs.h
|
||||
+++ b/mkfs.ocfs2/mkfs.h
|
||||
@@ -188,6 +188,7 @@ struct _State {
|
||||
int mount;
|
||||
int no_backup_super;
|
||||
int inline_data;
|
||||
+ int dx_dirs;
|
||||
int dry_run;
|
||||
|
||||
uint32_t blocksize;
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,26 +0,0 @@
|
||||
From 912f3e698ed20eb14daad38ef79b106a30d39a02 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Fasheh <mfasheh@suse.com>
|
||||
Date: Tue, 20 Apr 2010 10:19:54 -0700
|
||||
Subject: [PATCH 19/30] libocfs2: fix flag check in ocfs2_init_dir()
|
||||
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
---
|
||||
libocfs2/expanddir.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/libocfs2/expanddir.c b/libocfs2/expanddir.c
|
||||
index ec05b74..eb18260 100644
|
||||
--- a/libocfs2/expanddir.c
|
||||
+++ b/libocfs2/expanddir.c
|
||||
@@ -238,7 +238,7 @@ errcode_t ocfs2_init_dir(ocfs2_filesys *fs,
|
||||
* directory to extent in ocfs2_expand_dir()
|
||||
*/
|
||||
if (ocfs2_supports_indexed_dirs(OCFS2_RAW_SB(fs->fs_super)) &&
|
||||
- (!cinode->ci_inode->i_dyn_features & OCFS2_INLINE_DATA_FL)) {
|
||||
+ !(cinode->ci_inode->i_dyn_features & OCFS2_INLINE_DATA_FL)) {
|
||||
ret = ocfs2_dx_dir_build(fs, dir);
|
||||
if (ret)
|
||||
goto bail;
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,40 +0,0 @@
|
||||
From 30a19b42c6da181fa3f96123041fb20e69d065d9 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Fasheh <mfasheh@suse.com>
|
||||
Date: Tue, 20 Apr 2010 10:20:24 -0700
|
||||
Subject: [PATCH 20/30] libocfs2: fix ocfs2_init_dir() to retain indexed flag
|
||||
|
||||
We were re-using the out of date 'cached inode' later in the function after
|
||||
ocfs2_dx_dir_build() (which updates and writes out the inode internally).
|
||||
|
||||
As a result, ocfs2_init_dir() was accidentally clearing
|
||||
OCFS2_INDEXED_DIR_FL. Fix this by refreshing the cache after the call to
|
||||
ocfs2_dx_dir_build().
|
||||
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
---
|
||||
libocfs2/expanddir.c | 9 +++++++++
|
||||
1 files changed, 9 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/libocfs2/expanddir.c b/libocfs2/expanddir.c
|
||||
index eb18260..a81cfbe 100644
|
||||
--- a/libocfs2/expanddir.c
|
||||
+++ b/libocfs2/expanddir.c
|
||||
@@ -242,6 +242,15 @@ errcode_t ocfs2_init_dir(ocfs2_filesys *fs,
|
||||
ret = ocfs2_dx_dir_build(fs, dir);
|
||||
if (ret)
|
||||
goto bail;
|
||||
+
|
||||
+ /*
|
||||
+ * Re-read the 'cached inode' as ocfs2_dx_dir_build()
|
||||
+ * may have written out changes which won't be
|
||||
+ * reflected in our copy.
|
||||
+ */
|
||||
+ ret = ocfs2_read_cached_inode(fs, dir, &cinode);
|
||||
+ if (ret)
|
||||
+ goto bail;
|
||||
}
|
||||
|
||||
/* set link count of the parent */
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,92 +0,0 @@
|
||||
From 4c1cf61779ee71c828134d956f5779e272a3195e Mon Sep 17 00:00:00 2001
|
||||
From: Mark Fasheh <mfasheh@suse.com>
|
||||
Date: Fri, 23 Apr 2010 23:09:05 -0700
|
||||
Subject: [PATCH 21/30] fsck.ocfs2: verify dirent -> dx entry linkages
|
||||
|
||||
During pass2 we can trivially do a lookup on dirents while walking the
|
||||
directory tree. This will help us make sure that an index entry exists for
|
||||
each dirent. If an entry is not found, the users is prompted and the parent
|
||||
directory will be marked for an index rebuild.
|
||||
|
||||
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
|
||||
---
|
||||
fsck.ocfs2/fsck.ocfs2.checks.8.in | 7 +++++++
|
||||
fsck.ocfs2/pass2.c | 37 +++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 44 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/fsck.ocfs2/fsck.ocfs2.checks.8.in b/fsck.ocfs2/fsck.ocfs2.checks.8.in
|
||||
index 5cda023..cfbb12e 100644
|
||||
--- a/fsck.ocfs2/fsck.ocfs2.checks.8.in
|
||||
+++ b/fsck.ocfs2/fsck.ocfs2.checks.8.in
|
||||
@@ -1061,6 +1061,13 @@ file system.
|
||||
|
||||
Answering yes will truncate the invalid index.
|
||||
|
||||
+.SS "DX_LOOKUP_FAILED"
|
||||
+A directory entry is missing an entry in the directory index. Not
|
||||
+found in directory index. The missing index entry will cause lookups
|
||||
+on this name to fail.
|
||||
+
|
||||
+Answering yes will rebuild the directory index, restoring the missing entry.
|
||||
+
|
||||
.SH "SEE ALSO"
|
||||
.BR fsck.ocfs2(8)
|
||||
|
||||
diff --git a/fsck.ocfs2/pass2.c b/fsck.ocfs2/pass2.c
|
||||
index b999761..e03bd4e 100644
|
||||
--- a/fsck.ocfs2/pass2.c
|
||||
+++ b/fsck.ocfs2/pass2.c
|
||||
@@ -648,6 +648,39 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static errcode_t fix_dirent_index(o2fsck_dirblock_entry *dbe,
|
||||
+ struct dirblock_data *dd,
|
||||
+ struct ocfs2_dir_entry *dirent,
|
||||
+ unsigned int *flags)
|
||||
+{
|
||||
+ errcode_t ret = 0;
|
||||
+ struct ocfs2_dinode *di = (struct ocfs2_dinode *)dd->inoblock_buf;
|
||||
+ uint64_t ino;
|
||||
+
|
||||
+ if (!ocfs2_supports_indexed_dirs(OCFS2_RAW_SB(dd->fs->fs_super)))
|
||||
+ goto out;
|
||||
+
|
||||
+ if (di->i_dyn_features & OCFS2_INDEXED_DIR_FL) {
|
||||
+ ret = ocfs2_lookup(dd->fs, dbe->e_ino, dirent->name,
|
||||
+ dirent->name_len, NULL, &ino);
|
||||
+ if (ret) {
|
||||
+ if (ret != OCFS2_ET_FILE_NOT_FOUND)
|
||||
+ goto out;
|
||||
+ ret = 0;
|
||||
+
|
||||
+ if (prompt(dd->ost, PY, PR_DX_LOOKUP_FAILED,
|
||||
+ "Directory inode %"PRIu64" is missing "
|
||||
+ "an index entry for child inode %"PRIu64
|
||||
+ "\n. Repair this by rebuilding the "
|
||||
+ "directory index?", dbe->e_ino, ino))
|
||||
+ *flags |= OCFS2_DIRENT_CHANGED;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ }
|
||||
+out:
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int corrupt_dirent_lengths(struct ocfs2_dir_entry *dirent, int left)
|
||||
{
|
||||
if ((dirent->rec_len >= OCFS2_DIR_REC_LEN(1)) &&
|
||||
@@ -805,6 +838,10 @@ static unsigned pass2_dir_block_iterate(o2fsck_dirblock_entry *dbe,
|
||||
if (dirent->inode == 0)
|
||||
goto next;
|
||||
|
||||
+ ret = fix_dirent_index(dbe, dd, dirent, &ret_flags);
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
+
|
||||
verbosef("dirent %.*s refs ino %"PRIu64"\n", dirent->name_len,
|
||||
dirent->name, (uint64_t)dirent->inode);
|
||||
o2fsck_icount_delta(dd->ost->ost_icount_refs, dirent->inode, 1);
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,106 +0,0 @@
|
||||
From 24b059e1e75a0ff5dabb8a6dfdc09e82d488c244 Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Mon, 26 Apr 2010 22:34:27 +0800
|
||||
Subject: [PATCH 22/30] dx_dirs: stop iterate dir entries for I/O error
|
||||
|
||||
Callback dx_iterator() may encounter an I/O error when calling
|
||||
ocfs2_read_dx_leaf(). The caller of dx_iterator is extent_iterate_el(),
|
||||
which does not accept error code other than OCFS2_EXTENT_ERROR and
|
||||
OCFS2_EXTENT_ABORT. The result is, dir entries iteration can not stop
|
||||
if there is an I/O error happens in dx_iterator().
|
||||
|
||||
This patch add 'errcode_t err' member to struct dx_iterator_data, if
|
||||
error returned from ocfs2_read_dx_leaf(), the error code will be
|
||||
stored here, then dx_iterator() returns OCFS2_EXTENT_ERROR to make
|
||||
extent_iterate_el() quit.
|
||||
|
||||
Thanks to Tao Ma for catching this error.
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Cc: Mark Fasheh <mfasheh@suse.com>
|
||||
Cc: Tao Ma <tao.ma@oracle.com>
|
||||
---
|
||||
libocfs2/dir_iterate.c | 22 +++++++++++++++-------
|
||||
libocfs2/extents.c | 2 +-
|
||||
2 files changed, 16 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/libocfs2/dir_iterate.c b/libocfs2/dir_iterate.c
|
||||
index 8a3f5a9..d044bb8 100644
|
||||
--- a/libocfs2/dir_iterate.c
|
||||
+++ b/libocfs2/dir_iterate.c
|
||||
@@ -320,6 +320,7 @@ struct dx_iterator_data {
|
||||
void *dx_priv_data;
|
||||
char *leaf_buf;
|
||||
struct ocfs2_dx_root_block *dx_root;
|
||||
+ errcode_t err;
|
||||
};
|
||||
|
||||
static int dx_iterator(ocfs2_filesys *fs,
|
||||
@@ -330,7 +331,7 @@ static int dx_iterator(ocfs2_filesys *fs,
|
||||
int ref_recno,
|
||||
void *priv_data)
|
||||
{
|
||||
- int ret, i;
|
||||
+ int err, i;
|
||||
struct ocfs2_dx_leaf *dx_leaf;
|
||||
struct dx_iterator_data *iter = priv_data;
|
||||
uint64_t blkno, count;
|
||||
@@ -339,9 +340,11 @@ static int dx_iterator(ocfs2_filesys *fs,
|
||||
|
||||
blkno = rec->e_blkno;
|
||||
for (i = 0; i < count; i++) {
|
||||
- ret = ocfs2_read_dx_leaf(fs, blkno, iter->leaf_buf);
|
||||
- if (ret)
|
||||
- return ret;
|
||||
+ err = ocfs2_read_dx_leaf(fs, blkno, iter->leaf_buf);
|
||||
+ if (err) {
|
||||
+ iter->err = err;
|
||||
+ return OCFS2_EXTENT_ERROR;
|
||||
+ }
|
||||
|
||||
dx_leaf = (struct ocfs2_dx_leaf *)iter->leaf_buf;
|
||||
iter->dx_func(fs, &dx_leaf->dl_list, iter->dx_root, dx_leaf,
|
||||
@@ -387,8 +390,7 @@ extern errcode_t ocfs2_dx_entries_iterate(ocfs2_filesys *fs,
|
||||
dx_root = (struct ocfs2_dx_root_block *)buf;
|
||||
|
||||
if (dx_root->dr_flags & OCFS2_DX_FLAG_INLINE) {
|
||||
- func(fs, &dx_root->dr_entries, dx_root, NULL, priv_data);
|
||||
- ret = 0;
|
||||
+ ret = func(fs, &dx_root->dr_entries, dx_root, NULL, priv_data);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -404,10 +406,16 @@ extern errcode_t ocfs2_dx_entries_iterate(ocfs2_filesys *fs,
|
||||
data.dx_priv_data = priv_data;
|
||||
data.leaf_buf = leaf_buf;
|
||||
data.dx_root = dx_root;
|
||||
+ data.err = 0;
|
||||
ret = ocfs2_extent_iterate_dx_root(fs, dx_root,
|
||||
OCFS2_EXTENT_FLAG_DATA_ONLY, eb_buf,
|
||||
dx_iterator, &data);
|
||||
-
|
||||
+ /* dx_iterator may set the error code for non-extents-related
|
||||
+ * errors. If the error code is set by dx_iterator, no matter
|
||||
+ * what ocfs2_extent_iterate_dx_root() returns, we should take
|
||||
+ * data.err as retured error code. */
|
||||
+ if (data.err)
|
||||
+ ret = data.err;
|
||||
out:
|
||||
if (buf)
|
||||
ocfs2_free(&buf);
|
||||
diff --git a/libocfs2/extents.c b/libocfs2/extents.c
|
||||
index 8c322b1..bb233f0 100644
|
||||
--- a/libocfs2/extents.c
|
||||
+++ b/libocfs2/extents.c
|
||||
@@ -470,7 +470,7 @@ errcode_t ocfs2_extent_iterate_inode(ocfs2_filesys *fs,
|
||||
uint64_t ref_blkno,
|
||||
int ref_recno,
|
||||
void *priv_data),
|
||||
- void *priv_data)
|
||||
+ void *priv_data)
|
||||
{
|
||||
int i;
|
||||
int iret = 0;
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,40 +0,0 @@
|
||||
From d4bbb81a8e6870155eb939a1f9d6def456fa3b91 Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Mon, 26 Apr 2010 22:35:02 +0800
|
||||
Subject: [PATCH 23/30] dx_dirs: check callback iter->dx_func() return value in dx_iterator()
|
||||
|
||||
This patch makes dx_iterator() check returned value of callback
|
||||
iter->dx_func(). If an error returned from the callback, dx_iterator()
|
||||
returns OCFS2_EXTENT_ERROR to stop the iteration.
|
||||
|
||||
Thanks to Tao Ma for catching the error.
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Cc: Mark Fasheh <mfasheh@suse.com>
|
||||
Cc: Tao Ma <tao.ma@oracle.com>
|
||||
---
|
||||
libocfs2/dir_iterate.c | 7 ++++++-
|
||||
1 files changed, 6 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/libocfs2/dir_iterate.c b/libocfs2/dir_iterate.c
|
||||
index d044bb8..9f2ff7e 100644
|
||||
--- a/libocfs2/dir_iterate.c
|
||||
+++ b/libocfs2/dir_iterate.c
|
||||
@@ -347,8 +347,13 @@ static int dx_iterator(ocfs2_filesys *fs,
|
||||
}
|
||||
|
||||
dx_leaf = (struct ocfs2_dx_leaf *)iter->leaf_buf;
|
||||
- iter->dx_func(fs, &dx_leaf->dl_list, iter->dx_root, dx_leaf,
|
||||
+ err = iter->dx_func(fs, &dx_leaf->dl_list, iter->dx_root, dx_leaf,
|
||||
iter->dx_priv_data);
|
||||
+ /* callback dx_func() is defined by users, the return value does not
|
||||
+ * follow libocfs2 error codes. Don't touch iter->err and just stop
|
||||
+ * the iteration here.*/
|
||||
+ if (err)
|
||||
+ return OCFS2_EXTENT_ERROR;
|
||||
|
||||
blkno++;
|
||||
}
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,45 +0,0 @@
|
||||
From c74da336c1e4eb2fac311c9e6ea8ef8fe9b0a6c1 Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Mon, 26 Apr 2010 22:35:27 +0800
|
||||
Subject: [PATCH 24/30] dx_dirs: remove unncessary return value assignment
|
||||
|
||||
This patch removes unnecessary return value assigned in
|
||||
ocfs2_dx_entries_iterate() and ocfs2_dx_frees_iterate().
|
||||
|
||||
Thanks for Tao Ma for catching this.
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Cc: Mark Fasheh <mfasheh@suse.com>
|
||||
Cc: Tao Ma <tao.ma@oracle.com>
|
||||
---
|
||||
libocfs2/dir_iterate.c | 3 ---
|
||||
1 files changed, 0 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/libocfs2/dir_iterate.c b/libocfs2/dir_iterate.c
|
||||
index 9f2ff7e..835305a 100644
|
||||
--- a/libocfs2/dir_iterate.c
|
||||
+++ b/libocfs2/dir_iterate.c
|
||||
@@ -378,7 +378,6 @@ extern errcode_t ocfs2_dx_entries_iterate(ocfs2_filesys *fs,
|
||||
struct dx_iterator_data data;
|
||||
|
||||
if (!S_ISDIR(dir->i_mode) && !ocfs2_dir_indexed(dir)) {
|
||||
- ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -448,12 +447,10 @@ extern errcode_t ocfs2_dx_frees_iterate(ocfs2_filesys *fs,
|
||||
struct ocfs2_dir_block_trailer *trailer;
|
||||
|
||||
if (!S_ISDIR(dir->i_mode) || !(ocfs2_dir_indexed(dir))) {
|
||||
- ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dx_root->dr_flags & OCFS2_DX_FLAG_INLINE) {
|
||||
- ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,33 +0,0 @@
|
||||
From 1e82ab1d1407d4578eda91214e843b5433a92d6f Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Mon, 26 Apr 2010 22:35:58 +0800
|
||||
Subject: [PATCH 25/30] dx_dirs: unifiy feature string of indexed-dirs
|
||||
|
||||
This patch changes the indexed-dirs fn_name of ocfs2_feature_name array
|
||||
from IndexedDirs to indexed-dirs. Which unitifies fn_name displayed in
|
||||
debugfs.ocfs2 to feature string 'indexed-dirs' used in mkfs.ocfs2 and
|
||||
tunefs.ocfs2.
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Cc: Mark Fasheh <mfasheh@suse.com>
|
||||
Cc: Tao Ma <tao.ma@oracle.com>
|
||||
---
|
||||
libocfs2/feature_string.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/libocfs2/feature_string.c b/libocfs2/feature_string.c
|
||||
index 9f395c6..83fec9a 100644
|
||||
--- a/libocfs2/feature_string.c
|
||||
+++ b/libocfs2/feature_string.c
|
||||
@@ -254,7 +254,7 @@ static struct feature_name ocfs2_feature_names[] = {
|
||||
.fn_flag = {0, OCFS2_FEATURE_INCOMPAT_XATTR, 0},
|
||||
},
|
||||
{
|
||||
- .fn_name = "IndexedDirs",
|
||||
+ .fn_name = "indexed-dirs",
|
||||
.fn_flag = {0, OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS, 0},
|
||||
},
|
||||
{
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,33 +0,0 @@
|
||||
From a3a8830774c41b90285d77ccc04a035c944080e9 Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Mon, 26 Apr 2010 22:36:38 +0800
|
||||
Subject: [PATCH 26/30] dx_dirs: Improve information displayed by dump_dx_root()
|
||||
|
||||
If dr->dr_suballoc_slot is OCFS2_INVALID_SLOT (which should not happen),
|
||||
should not display "Global", because there is not "Global" conception
|
||||
for dx root allocation slot. This patch fixes the display by
|
||||
"Invalid Slot".
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Cc: Mark Fasheh <mfasheh@suse.com>
|
||||
Cc: Tao Ma <tao.ma@oracle.com>
|
||||
---
|
||||
debugfs.ocfs2/dump.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/debugfs.ocfs2/dump.c b/debugfs.ocfs2/dump.c
|
||||
index d55fc0e..6ad202c 100644
|
||||
--- a/debugfs.ocfs2/dump.c
|
||||
+++ b/debugfs.ocfs2/dump.c
|
||||
@@ -593,7 +593,7 @@ void dump_dx_root(FILE *out, struct ocfs2_dx_root_block *dr)
|
||||
(uint64_t)dr->dr_dir_blkno);
|
||||
|
||||
if (dr->dr_suballoc_slot == (uint16_t)OCFS2_INVALID_SLOT)
|
||||
- strcpy(tmp_str, "Global");
|
||||
+ strcpy(tmp_str, "Invalid Slot");
|
||||
else
|
||||
sprintf(tmp_str, "%d", dr->dr_suballoc_slot);
|
||||
fprintf(out, "\tSub Alloc Slot: %s Sub Alloc Bit: %u "
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,103 +0,0 @@
|
||||
From cb9471a5f73c69858d9dd35ea90b86476e65e4ca Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Mon, 26 Apr 2010 22:37:05 +0800
|
||||
Subject: [PATCH 27/30] dx_dirs: stop iteration of dir trailer initialization for I/O error
|
||||
|
||||
Callback dir_trailer_func() may encounter malloc or I/O error, these
|
||||
errors can not return to its caller directly. This patch add a member
|
||||
'errcode_t err' to struct trailer_ctxt, which can catch the error. By
|
||||
this fix, dir_trailer_func() can return OCFS2_EXTENT_ERROR to stop dir
|
||||
iteration immediately and can return the REAL error as well.
|
||||
|
||||
Thanks to Tao Ma catches this error.
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Cc: Mark Fasheh <mfasheh@suse.com>
|
||||
Cc: Tao Ma <tao.ma@oracle.com>
|
||||
---
|
||||
libocfs2/dir_indexed.c | 37 +++++++++++++++++++++++++++++--------
|
||||
1 files changed, 29 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/libocfs2/dir_indexed.c b/libocfs2/dir_indexed.c
|
||||
index 9cae3d0..5f3db95 100644
|
||||
--- a/libocfs2/dir_indexed.c
|
||||
+++ b/libocfs2/dir_indexed.c
|
||||
@@ -121,6 +121,7 @@ int ocfs2_find_max_rec_len(ocfs2_filesys *fs, char *buf)
|
||||
struct trailer_ctxt {
|
||||
struct ocfs2_dx_root_block *dx_root;
|
||||
struct ocfs2_dinode *di;
|
||||
+ errcode_t err;
|
||||
};
|
||||
|
||||
/* make sure the space for trailer is reserved */
|
||||
@@ -170,8 +171,8 @@ static int dir_trailer_func(ocfs2_filesys *fs,
|
||||
struct ocfs2_dinode *di = ctxt->di;
|
||||
struct ocfs2_dx_root_block *dx_root = ctxt->dx_root;
|
||||
struct ocfs2_dir_block_trailer *trailer;
|
||||
- int max_rec_len = 0;
|
||||
- errcode_t ret = 0;
|
||||
+ int max_rec_len = 0, ret = 0;
|
||||
+ errcode_t err;
|
||||
char *blk = NULL;
|
||||
|
||||
ret = ocfs2_malloc_block(fs->fs_io, &blk);
|
||||
@@ -180,12 +181,20 @@ static int dir_trailer_func(ocfs2_filesys *fs,
|
||||
|
||||
/* here we don't trust trailer, cannot use
|
||||
* ocfs2_read_dir_block() */
|
||||
- ret = ocfs2_read_blocks(fs, blkno, 1, blk);
|
||||
- if (ret)
|
||||
+ err = ocfs2_read_blocks(fs, blkno, 1, blk);
|
||||
+ if (err) {
|
||||
+ ctxt->err = err;
|
||||
+ ret = OCFS2_EXTENT_ERROR;
|
||||
goto out;
|
||||
- ret = ocfs2_check_dir_trailer_space(fs, di, blkno, blk);
|
||||
- if (ret)
|
||||
+ }
|
||||
+
|
||||
+ err = ocfs2_check_dir_trailer_space(fs, di, blkno, blk);
|
||||
+ if (err) {
|
||||
+ ctxt->err = err;
|
||||
+ ret = OCFS2_EXTENT_ERROR;
|
||||
goto out;
|
||||
+ }
|
||||
+
|
||||
ocfs2_init_dir_trailer(fs, di, blkno, blk);
|
||||
max_rec_len = ocfs2_find_max_rec_len(fs, blk);
|
||||
trailer = ocfs2_dir_trailer_from_block(fs, blk);
|
||||
@@ -198,7 +207,12 @@ static int dir_trailer_func(ocfs2_filesys *fs,
|
||||
|
||||
/* comput trailer->db_check here, after writes out,
|
||||
* trailer is trustable */
|
||||
- ret = ocfs2_write_dir_block(fs, di, blkno, blk);
|
||||
+ err = ocfs2_write_dir_block(fs, di, blkno, blk);
|
||||
+ if (err) {
|
||||
+ ctxt->err = err;
|
||||
+ ret = OCFS2_EXTENT_ERROR;
|
||||
+ }
|
||||
+
|
||||
out:
|
||||
if (blk)
|
||||
ocfs2_free(&blk);
|
||||
@@ -219,9 +233,16 @@ static errcode_t ocfs2_init_dir_trailers(ocfs2_filesys *fs,
|
||||
|
||||
ctxt.di = di;
|
||||
ctxt.dx_root = dx_root;
|
||||
-
|
||||
+ ctxt.err = 0;
|
||||
ret = ocfs2_block_iterate_inode(fs, di,
|
||||
0, dir_trailer_func, &ctxt);
|
||||
+
|
||||
+ /* callback dir_trailer_func() may have error which can not
|
||||
+ * return to its caller directly. If dir_trailer_func() sets
|
||||
+ * error in ctxt.err, we should take this REAL error other
|
||||
+ * than the value returned by ocfs2_block_iterate_inode(). */
|
||||
+ if (ctxt.err)
|
||||
+ ret = ctxt.err;
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,141 +0,0 @@
|
||||
From 1f49857cc5fa914ac0d3577f841b398421ca01a0 Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Mon, 26 Apr 2010 22:37:32 +0800
|
||||
Subject: [PATCH 28/30] dx_dirs: stop dx insert iteration for callback error
|
||||
|
||||
Callback ocfs2_dx_dir_insert() may encounter memory alloc or I/O error.
|
||||
These kind of errors can not return to caller of the callback directly,
|
||||
so the dir block iteration for dx insert can not stop immediately when
|
||||
such errors occure.
|
||||
|
||||
This patch adds a member 'errcode_t err' to struct dx_insert_ctxt, which
|
||||
can catch the error and permit ocfs2_dx_dir_insert() returns
|
||||
OCFS2_EXTENT_ERROR to it's caller to stop the iteration immediately.
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Cc: Mark Fasheh <mfasheh@suse.com>
|
||||
Cc: Tao Ma <tao.ma@oracle.com>
|
||||
---
|
||||
libocfs2/dir_indexed.c | 61 +++++++++++++++++++++++++++++------------------
|
||||
1 files changed, 38 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/libocfs2/dir_indexed.c b/libocfs2/dir_indexed.c
|
||||
index 5f3db95..08c43b7 100644
|
||||
--- a/libocfs2/dir_indexed.c
|
||||
+++ b/libocfs2/dir_indexed.c
|
||||
@@ -269,6 +269,7 @@ struct dx_insert_ctxt {
|
||||
uint64_t dir_blkno;
|
||||
uint64_t dx_root_blkno;
|
||||
ocfs2_filesys *fs;
|
||||
+ errcode_t err;
|
||||
};
|
||||
|
||||
|
||||
@@ -1069,7 +1070,8 @@ static int ocfs2_dx_dir_insert(struct ocfs2_dir_entry *dentry,
|
||||
char *buf,
|
||||
void *priv_data)
|
||||
{
|
||||
- errcode_t ret = 0;
|
||||
+ int ret = 0;
|
||||
+ errcode_t err;
|
||||
char *dx_buf = NULL;
|
||||
char *dx_leaf_buf = NULL;
|
||||
struct ocfs2_dx_root_block *dx_root = NULL;
|
||||
@@ -1081,17 +1083,17 @@ static int ocfs2_dx_dir_insert(struct ocfs2_dir_entry *dentry,
|
||||
uint64_t dx_root_blkno = ctxt->dx_root_blkno;
|
||||
int write_dx_leaf = 0;
|
||||
|
||||
- ret = ocfs2_malloc_block(fs->fs_io, &dx_buf);
|
||||
- if (ret)
|
||||
- goto out;
|
||||
+ err = ocfs2_malloc_block(fs->fs_io, &dx_buf);
|
||||
+ if (err)
|
||||
+ goto set_err;
|
||||
|
||||
- ret = ocfs2_malloc_block(fs->fs_io, &dx_leaf_buf);
|
||||
- if (ret)
|
||||
- goto out;
|
||||
+ err = ocfs2_malloc_block(fs->fs_io, &dx_leaf_buf);
|
||||
+ if (err)
|
||||
+ goto set_err;
|
||||
|
||||
- ret = ocfs2_read_dx_root(fs, dx_root_blkno, dx_buf);
|
||||
- if (ret)
|
||||
- goto out;
|
||||
+ err = ocfs2_read_dx_root(fs, dx_root_blkno, dx_buf);
|
||||
+ if (err)
|
||||
+ goto set_err;
|
||||
|
||||
dx_root = (struct ocfs2_dx_root_block *)dx_buf;
|
||||
memset(&lookup, 0, sizeof(struct ocfs2_dir_lookup_result));
|
||||
@@ -1104,19 +1106,21 @@ static int ocfs2_dx_dir_insert(struct ocfs2_dir_entry *dentry,
|
||||
goto insert_into_entries;
|
||||
} else {
|
||||
/* root block is full, expand it to an extent */
|
||||
- ret = ocfs2_expand_inline_dx_root(fs, dx_root);
|
||||
- if (ret)
|
||||
- goto out;
|
||||
+ err = ocfs2_expand_inline_dx_root(fs, dx_root);
|
||||
+ if (err)
|
||||
+ goto set_err;
|
||||
}
|
||||
}
|
||||
|
||||
- ret = ocfs2_find_dir_space_dx(fs, dx_root,
|
||||
+ err = ocfs2_find_dir_space_dx(fs, dx_root,
|
||||
dentry->name, dentry->name_len, &lookup);
|
||||
- if (ret)
|
||||
- goto out;
|
||||
- ret = ocfs2_read_dx_leaf(fs, lookup.dl_dx_leaf_blkno, dx_leaf_buf);
|
||||
- if (ret)
|
||||
- goto out;
|
||||
+ if (err)
|
||||
+ goto set_err;
|
||||
+
|
||||
+ err = ocfs2_read_dx_leaf(fs, lookup.dl_dx_leaf_blkno, dx_leaf_buf);
|
||||
+ if (err)
|
||||
+ goto set_err;
|
||||
+
|
||||
dx_leaf = (struct ocfs2_dx_leaf *)dx_leaf_buf;
|
||||
entry_list = &dx_leaf->dl_list;
|
||||
write_dx_leaf = 1;
|
||||
@@ -1124,12 +1128,18 @@ static int ocfs2_dx_dir_insert(struct ocfs2_dir_entry *dentry,
|
||||
insert_into_entries:
|
||||
ocfs2_dx_entry_list_insert(entry_list, &lookup.dl_hinfo, blocknr);
|
||||
if (write_dx_leaf) {
|
||||
- ret = ocfs2_write_dx_leaf(fs, dx_leaf->dl_blkno, dx_leaf);
|
||||
- if (ret)
|
||||
- goto out;
|
||||
+ err = ocfs2_write_dx_leaf(fs, dx_leaf->dl_blkno, dx_leaf);
|
||||
+ if (err)
|
||||
+ goto set_err;
|
||||
}
|
||||
dx_root->dr_num_entries += 1;
|
||||
- ret = ocfs2_write_dx_root(fs, dx_root_blkno, dx_buf);
|
||||
+ err = ocfs2_write_dx_root(fs, dx_root_blkno, dx_buf);
|
||||
+ if (!err)
|
||||
+ goto out;
|
||||
+
|
||||
+set_err:
|
||||
+ ctxt->err = err;
|
||||
+ ret = OCFS2_EXTENT_ERROR;
|
||||
out:
|
||||
if (dx_leaf_buf)
|
||||
ocfs2_free(&dx_leaf_buf);
|
||||
@@ -1256,8 +1266,13 @@ errcode_t ocfs2_dx_dir_build(ocfs2_filesys *fs,
|
||||
ctxt.dir_blkno = dir;
|
||||
ctxt.dx_root_blkno = dr_blkno;
|
||||
ctxt.fs = fs;
|
||||
+ ctxt.err = 0;
|
||||
ret = ocfs2_dir_iterate(fs, dir, 0, NULL,
|
||||
ocfs2_dx_dir_insert, &ctxt);
|
||||
+ if (ctxt.err)
|
||||
+ ret = ctxt.err;
|
||||
+ if (ret)
|
||||
+ goto out;
|
||||
|
||||
/* check quota for dx_leaf */
|
||||
ret = ocfs2_read_dx_root(fs, dr_blkno, dx_buf);
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,63 +0,0 @@
|
||||
From 2dff67994c3d6015b2b989d79a00c2cd10669ed0 Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Mon, 26 Apr 2010 22:37:59 +0800
|
||||
Subject: [PATCH 29/30] dx_dirs: set OCFS2_INDEXED_DIR_FL after indexed tree gets built
|
||||
|
||||
In ocfs2_dx_dir_build(), current code set OCFS2_INDEXED_DIR_FL to
|
||||
di->i_dyn_features before inserting dir entries into the indexed tree.
|
||||
If there is any error during the insertion, the corresponded dirent will
|
||||
be lost from the indexed tree. Though this error can be checked and
|
||||
fixed in fsck.ocfs2, it should be fixed.
|
||||
|
||||
This patch modifies to set OCFS2_INDEXED_DIR_FL after
|
||||
ocfs2_dir_iterate() returns successfully. If ocfs2_dir_iterate() returns
|
||||
with error, ocfs2_dx_dir_build() will return error and stop to build the
|
||||
indexed tree for a specific directory. In this case, no dirent will be
|
||||
losted.
|
||||
|
||||
Thanks to Tao Ma to catch this.
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Cc: Mark Fasheh <mfasheh@suse.com>
|
||||
Cc: Tao Ma <tao.ma@oracle.com>
|
||||
---
|
||||
libocfs2/dir_indexed.c | 9 +++++++--
|
||||
1 files changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libocfs2/dir_indexed.c b/libocfs2/dir_indexed.c
|
||||
index 08c43b7..eb872fd 100644
|
||||
--- a/libocfs2/dir_indexed.c
|
||||
+++ b/libocfs2/dir_indexed.c
|
||||
@@ -1254,7 +1254,6 @@ errcode_t ocfs2_dx_dir_build(ocfs2_filesys *fs,
|
||||
dx_root->dr_entries.de_count = ocfs2_dx_entries_per_root(fs->fs_blocksize);
|
||||
|
||||
di->i_dx_root = dr_blkno;
|
||||
- di->i_dyn_features |= OCFS2_INDEXED_DIR_FL;
|
||||
|
||||
ret = ocfs2_write_dx_root(fs, dr_blkno, dx_buf);
|
||||
if (ret)
|
||||
@@ -1274,14 +1273,20 @@ errcode_t ocfs2_dx_dir_build(ocfs2_filesys *fs,
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
- /* check quota for dx_leaf */
|
||||
ret = ocfs2_read_dx_root(fs, dr_blkno, dx_buf);
|
||||
if (ret)
|
||||
goto out;
|
||||
ret = ocfs2_read_inode(fs, dir, di_buf);
|
||||
if (ret)
|
||||
goto out;
|
||||
+ /* set inode to use indexed-dirs */
|
||||
+ di->i_dyn_features |= OCFS2_INDEXED_DIR_FL;
|
||||
|
||||
+ ret = ocfs2_write_inode(fs, dir, di_buf);
|
||||
+ if(ret)
|
||||
+ goto out;
|
||||
+
|
||||
+ /* check quota for dx_leaf */
|
||||
change = ocfs2_clusters_to_bytes(fs,
|
||||
dx_root->dr_clusters);
|
||||
uid = di->i_uid;
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,97 +0,0 @@
|
||||
From 8cf3a61039b0bda46d8824e50c3989eae83b9a1a Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Mon, 26 Apr 2010 22:38:31 +0800
|
||||
Subject: [PATCH 30/30] dx_dirs: fix ocfs2_swap_dx_entry_list() for big endian
|
||||
|
||||
As Tao Ma suggested, current ocfs2_swap_dx_entry_list() is
|
||||
buggy for big endian hardware, because after dl_list->de_count
|
||||
swapped, it is referenced in the following loop.
|
||||
|
||||
This patch fixes this bug with adding an 'int to_cpu' argument, also
|
||||
modifies other routines who call ocfs2_swap_dx_entry_list().
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Cc: Mark Fasheh <mfasheh@suse.com>
|
||||
Cc: Tao Ma <tao.ma@oracle.com>
|
||||
---
|
||||
libocfs2/dirblock.c | 23 ++++++++++++++---------
|
||||
1 files changed, 14 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/libocfs2/dirblock.c b/libocfs2/dirblock.c
|
||||
index c22d843..e128d73 100644
|
||||
--- a/libocfs2/dirblock.c
|
||||
+++ b/libocfs2/dirblock.c
|
||||
@@ -245,29 +245,34 @@ static void ocfs2_swap_dx_entry(struct ocfs2_dx_entry *dx_entry)
|
||||
dx_entry->dx_dirent_blk = bswap_64(dx_entry->dx_dirent_blk);
|
||||
}
|
||||
|
||||
-static void ocfs2_swap_dx_entry_list(struct ocfs2_dx_entry_list *dl_list)
|
||||
+/* called for big endian */
|
||||
+static void ocfs2_swap_dx_entry_list(struct ocfs2_dx_entry_list *dl_list, int to_cpu)
|
||||
{
|
||||
int i;
|
||||
|
||||
- dl_list->de_count = bswap_16(dl_list->de_count);
|
||||
- dl_list->de_num_used = bswap_16(dl_list->de_num_used);
|
||||
+ if (to_cpu)
|
||||
+ dl_list->de_count = bswap_16(dl_list->de_count);
|
||||
|
||||
for (i = 0; i < dl_list->de_count; i++)
|
||||
ocfs2_swap_dx_entry(&dl_list->de_entries[i]);
|
||||
+ dl_list->de_num_used = bswap_16(dl_list->de_num_used);
|
||||
+
|
||||
+ if (!to_cpu)
|
||||
+ dl_list->de_count = bswap_16(dl_list->de_count);
|
||||
}
|
||||
|
||||
static void ocfs2_swap_dx_entry_list_to_cpu(struct ocfs2_dx_entry_list *dl_list)
|
||||
{
|
||||
if (cpu_is_little_endian)
|
||||
return;
|
||||
- ocfs2_swap_dx_entry_list(dl_list);
|
||||
+ ocfs2_swap_dx_entry_list(dl_list, 1);
|
||||
}
|
||||
|
||||
static void ocfs2_swap_dx_entry_list_from_cpu(struct ocfs2_dx_entry_list *dl_list)
|
||||
{
|
||||
if (cpu_is_little_endian)
|
||||
return;
|
||||
- ocfs2_swap_dx_entry_list(dl_list);
|
||||
+ ocfs2_swap_dx_entry_list(dl_list, 0);
|
||||
}
|
||||
|
||||
static void ocfs2_swap_dx_root_to_cpu(ocfs2_filesys *fs,
|
||||
@@ -384,26 +389,26 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static void ocfs2_swap_dx_leaf(struct ocfs2_dx_leaf *dx_leaf)
|
||||
+static void ocfs2_swap_dx_leaf(struct ocfs2_dx_leaf *dx_leaf, int to_cpu)
|
||||
{
|
||||
dx_leaf->dl_blkno = bswap_64(dx_leaf->dl_blkno);
|
||||
dx_leaf->dl_fs_generation = bswap_64(dx_leaf->dl_fs_generation);
|
||||
|
||||
- ocfs2_swap_dx_entry_list(&dx_leaf->dl_list);
|
||||
+ ocfs2_swap_dx_entry_list(&dx_leaf->dl_list, to_cpu);
|
||||
}
|
||||
|
||||
static void ocfs2_swap_dx_leaf_to_cpu(struct ocfs2_dx_leaf *dx_leaf)
|
||||
{
|
||||
if (cpu_is_little_endian)
|
||||
return;
|
||||
- ocfs2_swap_dx_leaf(dx_leaf);
|
||||
+ ocfs2_swap_dx_leaf(dx_leaf, 1);
|
||||
}
|
||||
|
||||
static void ocfs2_swap_dx_leaf_from_cpu(struct ocfs2_dx_leaf *dx_leaf)
|
||||
{
|
||||
if (cpu_is_little_endian)
|
||||
return;
|
||||
- ocfs2_swap_dx_leaf(dx_leaf);
|
||||
+ ocfs2_swap_dx_leaf(dx_leaf, 0);
|
||||
}
|
||||
|
||||
errcode_t ocfs2_read_dx_leaf(ocfs2_filesys *fs, uint64_t block,
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,87 +0,0 @@
|
||||
From 76e095ae3d132828bbb70bad68c428101d3652a9 Mon Sep 17 00:00:00 2001
|
||||
From: Coly Li <coly.li@suse.de>
|
||||
Date: Sun, 11 Apr 2010 00:03:33 +0800
|
||||
Subject: [PATCH 15/15] dx_dirs v11: enable metaecc and indexed-dirs support as default features
|
||||
|
||||
metaecc feature enables ECC checking for meta data, which helps the file
|
||||
system consistency. indexed-dirs feature enables indexed tree for
|
||||
directories, which improves lookup performance for large scale
|
||||
directories.
|
||||
|
||||
This patch enables metaecc and indexed-dirs support as default features.
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
Cc: Mark Fasheh <mfasheh@suse.com>
|
||||
---
|
||||
libocfs2/feature_string.c | 18 ++++++++++++++----
|
||||
mkfs.ocfs2/mkfs.ocfs2.8.in | 2 +-
|
||||
2 files changed, 15 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/libocfs2/feature_string.c b/libocfs2/feature_string.c
|
||||
index 0974fb6..b2413bf 100644
|
||||
--- a/libocfs2/feature_string.c
|
||||
+++ b/libocfs2/feature_string.c
|
||||
@@ -76,7 +76,9 @@ static ocfs2_fs_options feature_level_defaults[] = {
|
||||
{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
|
||||
OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC |
|
||||
OCFS2_FEATURE_INCOMPAT_INLINE_DATA |
|
||||
- OCFS2_FEATURE_INCOMPAT_XATTR,
|
||||
+ OCFS2_FEATURE_INCOMPAT_XATTR |
|
||||
+ OCFS2_FEATURE_INCOMPAT_META_ECC |
|
||||
+ OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS,
|
||||
OCFS2_FEATURE_RO_COMPAT_UNWRITTEN}, /* OCFS2_FEATURE_LEVEL_DEFAULT */
|
||||
|
||||
{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
|
||||
@@ -100,25 +102,33 @@ static ocfs2_fs_options mkfstypes_features_defaults[] = {
|
||||
{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
|
||||
OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC |
|
||||
OCFS2_FEATURE_INCOMPAT_INLINE_DATA |
|
||||
- OCFS2_FEATURE_INCOMPAT_XATTR,
|
||||
+ OCFS2_FEATURE_INCOMPAT_XATTR |
|
||||
+ OCFS2_FEATURE_INCOMPAT_META_ECC |
|
||||
+ OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS,
|
||||
OCFS2_FEATURE_RO_COMPAT_UNWRITTEN}, /* OCFS2_MKFSTYPE_DEFAULT */
|
||||
|
||||
{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
|
||||
OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC |
|
||||
OCFS2_FEATURE_INCOMPAT_INLINE_DATA |
|
||||
- OCFS2_FEATURE_INCOMPAT_XATTR,
|
||||
+ OCFS2_FEATURE_INCOMPAT_XATTR |
|
||||
+ OCFS2_FEATURE_INCOMPAT_META_ECC |
|
||||
+ OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS,
|
||||
OCFS2_FEATURE_RO_COMPAT_UNWRITTEN}, /* OCFS2_MKFSTYPE_DATAFILES */
|
||||
|
||||
{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
|
||||
OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC |
|
||||
OCFS2_FEATURE_INCOMPAT_INLINE_DATA |
|
||||
- OCFS2_FEATURE_INCOMPAT_XATTR,
|
||||
+ OCFS2_FEATURE_INCOMPAT_XATTR |
|
||||
+ OCFS2_FEATURE_INCOMPAT_META_ECC |
|
||||
+ OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS,
|
||||
OCFS2_FEATURE_RO_COMPAT_UNWRITTEN}, /* OCFS2_MKFSTYPE_MAIL */
|
||||
|
||||
{OCFS2_FEATURE_COMPAT_BACKUP_SB | OCFS2_FEATURE_COMPAT_JBD2_SB,
|
||||
OCFS2_FEATURE_INCOMPAT_SPARSE_ALLOC |
|
||||
OCFS2_FEATURE_INCOMPAT_INLINE_DATA |
|
||||
OCFS2_FEATURE_INCOMPAT_XATTR |
|
||||
+ OCFS2_FEATURE_INCOMPAT_META_ECC |
|
||||
+ OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS |
|
||||
OCFS2_FEATURE_INCOMPAT_REFCOUNT_TREE,
|
||||
OCFS2_FEATURE_RO_COMPAT_UNWRITTEN}, /* OCFS2_MKFSTYPE_VMSTORE */
|
||||
};
|
||||
diff --git a/mkfs.ocfs2/mkfs.ocfs2.8.in b/mkfs.ocfs2/mkfs.ocfs2.8.in
|
||||
index a148133..2fd7a70 100644
|
||||
--- a/mkfs.ocfs2/mkfs.ocfs2.8.in
|
||||
+++ b/mkfs.ocfs2/mkfs.ocfs2.8.in
|
||||
@@ -191,7 +191,7 @@ Chooses fewer features but ensures that the file system can be mounted from olde
|
||||
.RS 1.2i
|
||||
.TP
|
||||
\fBdefault\fR
|
||||
-The default feature set tries to strike a balance between providing new features and maintaining compatibility with relatively recent versions of \fIOCFS2\fR. It currently enables \fBsparse\fR, \fBunwritten\fR \fBinline-data\fR and \fBxattr\fR. It also enables \fBrefcount\fR for the \fIvmstore\fR volumes.
|
||||
+The default feature set tries to strike a balance between providing new features and maintaining compatibility with relatively recent versions of \fIOCFS2\fR. It currently enables \fBsparse\fR, \fBunwritten\fR, \fBinline-data\fR, \fRxattr\fR, \fRmetaecc\fR, and \fRindexed-dirs\fR. It also enables \fBrefcount\fR for the \fIvmstore\fR volumes.
|
||||
.RE
|
||||
.RS 1.2i
|
||||
.TP
|
||||
--
|
||||
1.7.0.2
|
||||
|
@ -1,47 +0,0 @@
|
||||
This is a simple patch which fix the issue that tunefs.ocfs2 online
|
||||
resize can't handle symbolic link of a device file. For example, in
|
||||
the LVM using scenario, '/dev/vg1/lv1' and '/dev/mapper/vg1-lv1' are
|
||||
the same device, '/dev/vg1/lv1' is just a symbolic link to
|
||||
'/dev/mapper/vg1-lv1'. But if we try to do online resize like
|
||||
'tunefs.ocfs2 -S /dev/vg1/lv1', it fails.
|
||||
|
||||
Signed-off-by: Jiaju Zhang <jjzhang@suse.de>
|
||||
---
|
||||
ocfs2_controld/mount.c | 20 +++++++++++++++++---
|
||||
1 files changed, 17 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/ocfs2_controld/mount.c b/ocfs2_controld/mount.c
|
||||
--- a/ocfs2_controld/mount.c
|
||||
+++ b/ocfs2_controld/mount.c
|
||||
@@ -260,13 +260,27 @@ static void add_service(struct mountgroup *mg, const char *device,
|
||||
const char *service, int ci, int fd)
|
||||
{
|
||||
struct service *ms;
|
||||
+ struct stat st1, st2;
|
||||
|
||||
- log_debug("Adding service %s to device %s uuid %s",
|
||||
+ log_debug("Adding service \"%s\" to device \"%s\" uuid \"%s\"",
|
||||
service, device, mg->mg_uuid);
|
||||
|
||||
- if (strcmp(mg->mg_device, device)) {
|
||||
+ if (stat(mg->mg_device, &st1)) {
|
||||
+ fill_error(mg, errno, "Failed to stat device \"%s\": %s",
|
||||
+ mg->mg_device, strerror(errno));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (stat(device, &st2)) {
|
||||
+ fill_error(mg, errno, "Failed to stat device \"%s\": %s",
|
||||
+ device, strerror(errno));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (st1.st_rdev != st2.st_rdev) {
|
||||
fill_error(mg, EINVAL,
|
||||
- "Trying to mount fs %s on device %s, but it is already mounted from device %s",
|
||||
+ "Trying to mount fs \"%s\" on device \"%s\", "
|
||||
+ "but it is already mounted from device \"%s\"",
|
||||
mg->mg_uuid, device, mg->mg_device);
|
||||
return;
|
||||
}
|
||||
|
@ -1,22 +0,0 @@
|
||||
Index: ocfs2-tools/mount.ocfs2/mount.ocfs2.c
|
||||
===================================================================
|
||||
--- ocfs2-tools.orig/mount.ocfs2/mount.ocfs2.c
|
||||
+++ ocfs2-tools/mount.ocfs2/mount.ocfs2.c
|
||||
@@ -261,7 +261,7 @@ int main(int argc, char **argv)
|
||||
char *extra = NULL;
|
||||
int dev_ro = 0;
|
||||
char *hbstr = NULL;
|
||||
- char stackstr[strlen(OCFS2_CLUSTER_STACK_ARG) + OCFS2_STACK_LABEL_LEN + 1] = "";
|
||||
+ char stackstr[strlen(OCFS2_CLUSTER_STACK_ARG) + OCFS2_STACK_LABEL_LEN + 1];
|
||||
ocfs2_filesys *fs = NULL;
|
||||
struct o2cb_cluster_desc cluster;
|
||||
struct o2cb_region_desc desc;
|
||||
@@ -269,6 +269,8 @@ int main(int argc, char **argv)
|
||||
int hb_started = 0;
|
||||
struct stat statbuf;
|
||||
|
||||
+ stackstr[0] = '\0';
|
||||
+
|
||||
initialize_ocfs_error_table();
|
||||
initialize_o2dl_error_table();
|
||||
initialize_o2cb_error_table();
|
@ -1,12 +0,0 @@
|
||||
Index: ocfs2-tools/o2cb_ctl/Makefile
|
||||
===================================================================
|
||||
--- ocfs2-tools.orig/o2cb_ctl/Makefile
|
||||
+++ ocfs2-tools/o2cb_ctl/Makefile
|
||||
@@ -40,6 +40,6 @@ o2cb_config_CPPFLAGS = $(GLIB_CFLAGS) -D
|
||||
o2cb_ctl_CPPFLAGS = $(GLIB_CFLAGS) -DG_DISABLE_DEPRECATED
|
||||
|
||||
o2cb_ctl: $(O2CB_CTL_OBJS) $(LIBOCFS2_DEPS) $(LIBO2CB_DEPS)
|
||||
- $(LINK) $(LIBO2CB_LIBS) $(GLIB_LIBS) $(LIBOCFS2_LIBS) $(COM_ERR_LIBS)
|
||||
+ $(LINK) $(LIBO2CB_LIBS) -Wl,-Bstatic $(GLIB_LIBS) -Wl,-Bdynamic $(LIBOCFS2_LIBS) $(COM_ERR_LIBS)
|
||||
|
||||
include $(TOPDIR)/Postamble.make
|
@ -22,8 +22,8 @@ Name: ocfs2-tools
|
||||
BuildRequires: e2fsprogs-devel glib2-devel libcorosync-devel libdlm-devel libopenais-devel libpacemaker-devel libxml2-devel libxslt-devel python-devel python-gtk-devel readline-devel update-desktop-files
|
||||
Summary: Oracle Cluster File System 2 Core Tools
|
||||
Version: 1.6.3
|
||||
Release: 0.<RELEASE1>
|
||||
License: GPL v2 or later
|
||||
Release: 1
|
||||
License: GPLv2+
|
||||
Group: System/Filesystems
|
||||
Source: ocfs2-tools.tar.bz2
|
||||
Source1: o2cb.ocf
|
||||
@ -34,9 +34,9 @@ Patch103: debug-ocfs2_hb_ctl.patch
|
||||
Patch104: ocfs2_controld-pacemaker.diff
|
||||
Patch105: bug-470741-debug_start_failures.patch
|
||||
Patch106: ocfs2-devel.diff
|
||||
Patch107: reflink-no-syscall.patch
|
||||
Patch107: reflink-no-syscall.patch
|
||||
Patch201: bug-543119-o2dlm.patch
|
||||
Patch202: fix-configure-check-libs.patch
|
||||
Patch202: fix-configure-check-libs.patch
|
||||
Url: http://oss.oracle.com/projects/ocfs2-tools/
|
||||
Requires: net-tools, modutils, e2fsprogs, /sbin/chkconfig, glib2 >= 2.2.3
|
||||
PreReq: %insserv_prereq %fillup_prereq
|
||||
@ -57,7 +57,7 @@ Authors:
|
||||
Oracle Corporation
|
||||
|
||||
%package -n ocfs2console
|
||||
License: GPL v2 or later
|
||||
License: GPLv2+
|
||||
Summary: Oracle Cluster Filesystem 2 GUI tools
|
||||
Group: System/Filesystems
|
||||
Obsoletes: ocfs2-support
|
||||
@ -77,7 +77,7 @@ Authors:
|
||||
Oracle Corporation
|
||||
|
||||
%package devel
|
||||
License: GPL v2 or later
|
||||
License: GPLv2+
|
||||
Summary: Oracle Cluster File System 2 Development files
|
||||
Group: System/Filesystems
|
||||
Requires: ocfs2-tools = %{version}, libcom_err, libcom_err-devel
|
||||
@ -95,7 +95,7 @@ Authors:
|
||||
Oracle Corporation
|
||||
|
||||
%package o2cb
|
||||
License: GPL v2 or later
|
||||
License: GPLv2+
|
||||
Summary: Oracle Cluster File System 2 Core Tools
|
||||
Group: System/Filesystems
|
||||
Requires: ocfs2-tools = %{version}
|
||||
|
@ -1,18 +0,0 @@
|
||||
This patch keeps ocfs2-tools version as 1.4.3, until we decide to update the package version.
|
||||
|
||||
Signed-off-by: Coly Li <coly.li@suse.de>
|
||||
---
|
||||
diff -ur ocfs2-tools/configure.in ocfs2-tools-new//configure.in
|
||||
--- ocfs2-tools/configure.in 2010-02-20 01:21:46.000000000 +0800
|
||||
+++ ocfs2-tools-new//configure.in 2010-03-11 09:38:01.000000000 +0800
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
# Adjust these for the software version.
|
||||
MAJOR_VERSION=1
|
||||
-MINOR_VERSION=6
|
||||
-MICRO_VERSION=0
|
||||
+MINOR_VERSION=4
|
||||
+MICRO_VERSION=3
|
||||
EXTRA_VERSION=
|
||||
|
||||
DIST_VERSION=$MAJOR_VERSION.$MINOR_VERSION.$MICRO_VERSION
|
Loading…
Reference in New Issue
Block a user