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:
OBS User autobuild 2010-11-20 11:35:17 +00:00 committed by Git OBS Bridge
parent 329320a471
commit ea8f27edae
36 changed files with 7 additions and 8004 deletions

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;
}

View File

@ -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();

View File

@ -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

View File

@ -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}

View File

@ -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