Commit 4ed8a6bb authored by Mark Fasheh's avatar Mark Fasheh

ocfs2: Store dir index records inline

Allow us to store a small number of directory index records in the
ocfs2_dx_root_block. This saves us a disk read on small to medium sized
directories (less than about 250 entries). The inline root is automatically
turned into a root block with extents if the directory size increases beyond
it's capacity.
Signed-off-by: default avatarMark Fasheh <mfasheh@suse.com>
Acked-by: default avatarJoel Becker <joel.becker@oracle.com>
parent 9b7895ef
This diff is collapsed.
...@@ -37,6 +37,8 @@ struct ocfs2_dir_lookup_result { ...@@ -37,6 +37,8 @@ struct ocfs2_dir_lookup_result {
struct ocfs2_dir_entry *dl_entry; /* Target dirent in struct ocfs2_dir_entry *dl_entry; /* Target dirent in
* unindexed leaf */ * unindexed leaf */
struct buffer_head *dl_dx_root_bh; /* Root of indexed
* tree */
struct buffer_head *dl_dx_leaf_bh; /* Indexed leaf block */ struct buffer_head *dl_dx_leaf_bh; /* Indexed leaf block */
struct ocfs2_dx_entry *dl_dx_entry; /* Target dx_entry in struct ocfs2_dx_entry *dl_dx_entry; /* Target dx_entry in
* indexed leaf */ * indexed leaf */
......
...@@ -458,6 +458,16 @@ static inline int ocfs2_rename_credits(struct super_block *sb) ...@@ -458,6 +458,16 @@ static inline int ocfs2_rename_credits(struct super_block *sb)
#define OCFS2_DX_ROOT_REMOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + \ #define OCFS2_DX_ROOT_REMOVE_CREDITS (OCFS2_INODE_UPDATE_CREDITS + \
OCFS2_SUBALLOC_FREE) OCFS2_SUBALLOC_FREE)
static inline int ocfs2_calc_dxi_expand_credits(struct super_block *sb)
{
int credits = 1 + OCFS2_SUBALLOC_ALLOC;
credits += ocfs2_clusters_to_blocks(sb, 1);
credits += ocfs2_quota_trans_credits(sb);
return credits;
}
/* /*
* Please note that the caller must make sure that root_el is the root * Please note that the caller must make sure that root_el is the root
* of extent tree. So for an inode, it should be &fe->id2.i_list. Otherwise * of extent tree. So for an inode, it should be &fe->id2.i_list. Otherwise
......
...@@ -321,10 +321,8 @@ static int ocfs2_mknod(struct inode *dir, ...@@ -321,10 +321,8 @@ static int ocfs2_mknod(struct inode *dir,
want_clusters += 1; want_clusters += 1;
/* Dir indexing requires extra space as well */ /* Dir indexing requires extra space as well */
if (ocfs2_supports_indexed_dirs(osb)) { if (ocfs2_supports_indexed_dirs(osb))
want_clusters++;
want_meta++; want_meta++;
}
} }
status = ocfs2_reserve_new_metadata_blocks(osb, want_meta, &meta_ac); status = ocfs2_reserve_new_metadata_blocks(osb, want_meta, &meta_ac);
......
...@@ -815,6 +815,8 @@ struct ocfs2_dx_entry_list { ...@@ -815,6 +815,8 @@ struct ocfs2_dx_entry_list {
* length de_num_used */ * length de_num_used */
}; };
#define OCFS2_DX_FLAG_INLINE 0x01
/* /*
* A directory indexing block. Each indexed directory has one of these, * A directory indexing block. Each indexed directory has one of these,
* pointed to by ocfs2_dinode. * pointed to by ocfs2_dinode.
...@@ -835,13 +837,21 @@ struct ocfs2_dx_root_block { ...@@ -835,13 +837,21 @@ struct ocfs2_dx_root_block {
* extent block */ * extent block */
__le32 dr_clusters; /* Clusters allocated __le32 dr_clusters; /* Clusters allocated
* to the indexed tree. */ * to the indexed tree. */
__le32 dr_reserved1; __u8 dr_flags; /* OCFS2_DX_FLAG_* flags */
__u8 dr_reserved0;
__le16 dr_reserved1;
__le64 dr_dir_blkno; /* Pointer to parent inode */ __le64 dr_dir_blkno; /* Pointer to parent inode */
__le64 dr_reserved2; __le64 dr_reserved2;
__le64 dr_reserved3[16]; __le64 dr_reserved3[16];
struct ocfs2_extent_list dr_list; /* Keep this aligned to 128 union {
* bits for maximum space struct ocfs2_extent_list dr_list; /* Keep this aligned to 128
* efficiency. */ * 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. */
};
}; };
/* /*
...@@ -1228,6 +1238,16 @@ static inline int ocfs2_dx_entries_per_leaf(struct super_block *sb) ...@@ -1228,6 +1238,16 @@ static inline int ocfs2_dx_entries_per_leaf(struct super_block *sb)
return size / sizeof(struct ocfs2_dx_entry); 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) static inline u16 ocfs2_local_alloc_size(struct super_block *sb)
{ {
u16 size; u16 size;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment