aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/ocfs2_fs.h
diff options
context:
space:
mode:
authorMark Fasheh <mfasheh@suse.com>2008-11-12 19:27:44 -0500
committerMark Fasheh <mfasheh@suse.com>2009-04-03 14:39:15 -0400
commit9b7895efac906d66d19856194e1ba61f37e231a4 (patch)
tree1ee6d2630cf3617251638170dcaceef41ddda8ec /fs/ocfs2/ocfs2_fs.h
parent4a12ca3a00a244e1fd1e673d151ea38b71e11d55 (diff)
ocfs2: Add a name indexed b-tree to directory inodes
This patch makes use of Ocfs2's flexible btree code to add an additional tree to directory inodes. The new tree stores an array of small, fixed-length records in each leaf block. Each record stores a hash value, and pointer to a block in the traditional (unindexed) directory tree where a dirent with the given name hash resides. Lookup exclusively uses this tree to find dirents, thus providing us with constant time name lookups. Some of the hashing code was copied from ext3. Unfortunately, it has lots of unfixed checkpatch errors. I left that as-is so that tracking changes would be easier. Signed-off-by: Mark Fasheh <mfasheh@suse.com> Acked-by: Joel Becker <joel.becker@oracle.com>
Diffstat (limited to 'fs/ocfs2/ocfs2_fs.h')
-rw-r--r--fs/ocfs2/ocfs2_fs.h102
1 files changed, 99 insertions, 3 deletions
diff --git a/fs/ocfs2/ocfs2_fs.h b/fs/ocfs2/ocfs2_fs.h
index 2332ef740f4f..036eb03950a3 100644
--- a/fs/ocfs2/ocfs2_fs.h
+++ b/fs/ocfs2/ocfs2_fs.h
@@ -66,6 +66,8 @@
66#define OCFS2_GROUP_DESC_SIGNATURE "GROUP01" 66#define OCFS2_GROUP_DESC_SIGNATURE "GROUP01"
67#define OCFS2_XATTR_BLOCK_SIGNATURE "XATTR01" 67#define OCFS2_XATTR_BLOCK_SIGNATURE "XATTR01"
68#define OCFS2_DIR_TRAILER_SIGNATURE "DIRTRL1" 68#define OCFS2_DIR_TRAILER_SIGNATURE "DIRTRL1"
69#define OCFS2_DX_ROOT_SIGNATURE "DXDIR01"
70#define OCFS2_DX_LEAF_SIGNATURE "DXLEAF1"
69 71
70/* Compatibility flags */ 72/* Compatibility flags */
71#define OCFS2_HAS_COMPAT_FEATURE(sb,mask) \ 73#define OCFS2_HAS_COMPAT_FEATURE(sb,mask) \
@@ -151,6 +153,9 @@
151/* Support for extended attributes */ 153/* Support for extended attributes */
152#define OCFS2_FEATURE_INCOMPAT_XATTR 0x0200 154#define OCFS2_FEATURE_INCOMPAT_XATTR 0x0200
153 155
156/* Support for indexed directores */
157#define OCFS2_FEATURE_INCOMPAT_INDEXED_DIRS 0x0400
158
154/* Metadata checksum and error correction */ 159/* Metadata checksum and error correction */
155#define OCFS2_FEATURE_INCOMPAT_META_ECC 0x0800 160#define OCFS2_FEATURE_INCOMPAT_META_ECC 0x0800
156 161
@@ -628,8 +633,9 @@ struct ocfs2_super_block {
628/*B8*/ __le16 s_xattr_inline_size; /* extended attribute inline size 633/*B8*/ __le16 s_xattr_inline_size; /* extended attribute inline size
629 for this fs*/ 634 for this fs*/
630 __le16 s_reserved0; 635 __le16 s_reserved0;
631 __le32 s_reserved1; 636 __le32 s_dx_seed[3]; /* seed[0-2] for dx dir hash.
632/*C0*/ __le64 s_reserved2[16]; /* Fill out superblock */ 637 * s_uuid_hash serves as seed[3]. */
638/*C0*/ __le64 s_reserved2[15]; /* Fill out superblock */
633/*140*/ 639/*140*/
634 640
635 /* 641 /*
@@ -705,7 +711,8 @@ struct ocfs2_dinode {
705 __le16 i_dyn_features; 711 __le16 i_dyn_features;
706 __le64 i_xattr_loc; 712 __le64 i_xattr_loc;
707/*80*/ struct ocfs2_block_check i_check; /* Error checking */ 713/*80*/ struct ocfs2_block_check i_check; /* Error checking */
708/*88*/ __le64 i_reserved2[6]; 714/*88*/ __le64 i_dx_root; /* Pointer to dir index root block */
715 __le64 i_reserved2[5];
709/*B8*/ union { 716/*B8*/ union {
710 __le64 i_pad1; /* Generic way to refer to this 717 __le64 i_pad1; /* Generic way to refer to this
711 64bit union */ 718 64bit union */
@@ -781,6 +788,75 @@ struct ocfs2_dir_block_trailer {
781/*40*/ 788/*40*/
782}; 789};
783 790
791 /*
792 * A directory entry in the indexed tree. We don't store the full name here,
793 * but instead provide a pointer to the full dirent in the unindexed tree.
794 *
795 * We also store name_len here so as to reduce the number of leaf blocks we
796 * need to search in case of collisions.
797 */
798struct ocfs2_dx_entry {
799 __le32 dx_major_hash; /* Used to find logical
800 * cluster in index */
801 __le32 dx_minor_hash; /* Lower bits used to find
802 * block in cluster */
803 __le64 dx_dirent_blk; /* Physical block in unindexed
804 * tree holding this dirent. */
805};
806
807struct ocfs2_dx_entry_list {
808 __le32 de_reserved;
809 __le16 de_count; /* Maximum number of entries
810 * possible in de_entries */
811 __le16 de_num_used; /* Current number of
812 * de_entries entries */
813 struct ocfs2_dx_entry de_entries[0]; /* Indexed dir entries
814 * in a packed array of
815 * length de_num_used */
816};
817
818/*
819 * A directory indexing block. Each indexed directory has one of these,
820 * pointed to by ocfs2_dinode.
821 *
822 * This block stores an indexed btree root, and a set of free space
823 * start-of-list pointers.
824 */
825struct ocfs2_dx_root_block {
826 __u8 dr_signature[8]; /* Signature for verification */
827 struct ocfs2_block_check dr_check; /* Error checking */
828 __le16 dr_suballoc_slot; /* Slot suballocator this
829 * block belongs to. */
830 __le16 dr_suballoc_bit; /* Bit offset in suballocator
831 * block group */
832 __le32 dr_fs_generation; /* Must match super block */
833 __le64 dr_blkno; /* Offset on disk, in blocks */
834 __le64 dr_last_eb_blk; /* Pointer to last
835 * extent block */
836 __le32 dr_clusters; /* Clusters allocated
837 * to the indexed tree. */
838 __le32 dr_reserved1;
839 __le64 dr_dir_blkno; /* Pointer to parent inode */
840 __le64 dr_reserved2;
841 __le64 dr_reserved3[16];
842 struct ocfs2_extent_list dr_list; /* Keep this aligned to 128
843 * bits for maximum space
844 * efficiency. */
845};
846
847/*
848 * The header of a leaf block in the indexed tree.
849 */
850struct ocfs2_dx_leaf {
851 __u8 dl_signature[8];/* Signature for verification */
852 struct ocfs2_block_check dl_check; /* Error checking */
853 __le64 dl_blkno; /* Offset on disk, in blocks */
854 __le32 dl_fs_generation;/* Must match super block */
855 __le32 dl_reserved0;
856 __le64 dl_reserved1;
857 struct ocfs2_dx_entry_list dl_list;
858};
859
784/* 860/*
785 * On disk allocator group structure for OCFS2 861 * On disk allocator group structure for OCFS2
786 */ 862 */
@@ -1112,6 +1188,16 @@ static inline int ocfs2_extent_recs_per_inode_with_xattr(
1112 return size / sizeof(struct ocfs2_extent_rec); 1188 return size / sizeof(struct ocfs2_extent_rec);
1113} 1189}
1114 1190
1191static inline int ocfs2_extent_recs_per_dx_root(struct super_block *sb)
1192{
1193 int size;
1194
1195 size = sb->s_blocksize -
1196 offsetof(struct ocfs2_dx_root_block, dr_list.l_recs);
1197
1198 return size / sizeof(struct ocfs2_extent_rec);
1199}
1200
1115static inline int ocfs2_chain_recs_per_inode(struct super_block *sb) 1201static inline int ocfs2_chain_recs_per_inode(struct super_block *sb)
1116{ 1202{
1117 int size; 1203 int size;
@@ -1132,6 +1218,16 @@ static inline u16 ocfs2_extent_recs_per_eb(struct super_block *sb)
1132 return size / sizeof(struct ocfs2_extent_rec); 1218 return size / sizeof(struct ocfs2_extent_rec);
1133} 1219}
1134 1220
1221static inline int ocfs2_dx_entries_per_leaf(struct super_block *sb)
1222{
1223 int size;
1224
1225 size = sb->s_blocksize -
1226 offsetof(struct ocfs2_dx_leaf, dl_list.de_entries);
1227
1228 return size / sizeof(struct ocfs2_dx_entry);
1229}
1230
1135static inline u16 ocfs2_local_alloc_size(struct super_block *sb) 1231static inline u16 ocfs2_local_alloc_size(struct super_block *sb)
1136{ 1232{
1137 u16 size; 1233 u16 size;