ocfs2: Add xattr bucket iteration for large numbers of EAs
Ocfs2 breaks up xattr index tree leaves into 4k regions, called buckets. Attributes are stored within a given bucket, depending on hash value. After a discussion with Mark, we decided that the per-bucket index (xe_entry[]) would only exist in the 1st block of a bucket. Likewise, name/value pairs will not straddle more than one block. This allows the majority of operations to work directly on the buffer heads in a leaf block. This patch adds code to iterate the buckets in an EA. A new abstration of ocfs2_xattr_bucket is added. It records the bhs in this bucket and ocfs2_xattr_header. This keeps the code neat, improving readibility. Signed-off-by: Tao Ma <tao.ma@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
这个提交包含在:
@@ -755,8 +755,13 @@ struct ocfs2_xattr_header {
|
||||
__le16 xh_count; /* contains the count of how
|
||||
many records are in the
|
||||
local xattr storage. */
|
||||
__le16 xh_reserved1;
|
||||
__le32 xh_reserved2;
|
||||
__le16 xh_free_start; /* current offset for storing
|
||||
xattr. */
|
||||
__le16 xh_name_value_len; /* total length of name/value
|
||||
length in this bucket. */
|
||||
__le16 xh_num_buckets; /* bucket nums in one extent
|
||||
record, only valid in the
|
||||
first bucket. */
|
||||
__le64 xh_csum;
|
||||
struct ocfs2_xattr_entry xh_entries[0]; /* xattr entry list. */
|
||||
};
|
||||
@@ -793,6 +798,10 @@ struct ocfs2_xattr_tree_root {
|
||||
#define OCFS2_XATTR_SIZE(size) (((size) + OCFS2_XATTR_ROUND) & \
|
||||
~(OCFS2_XATTR_ROUND))
|
||||
|
||||
#define OCFS2_XATTR_BUCKET_SIZE 4096
|
||||
#define OCFS2_XATTR_MAX_BLOCKS_PER_BUCKET (OCFS2_XATTR_BUCKET_SIZE \
|
||||
/ OCFS2_MIN_BLOCKSIZE)
|
||||
|
||||
/*
|
||||
* On disk structure for xattr block.
|
||||
*/
|
||||
@@ -963,6 +972,17 @@ static inline u64 ocfs2_backup_super_blkno(struct super_block *sb, int index)
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static inline u16 ocfs2_xattr_recs_per_xb(struct super_block *sb)
|
||||
{
|
||||
int size;
|
||||
|
||||
size = sb->s_blocksize -
|
||||
offsetof(struct ocfs2_xattr_block,
|
||||
xb_attrs.xb_root.xt_list.l_recs);
|
||||
|
||||
return size / sizeof(struct ocfs2_extent_rec);
|
||||
}
|
||||
#else
|
||||
static inline int ocfs2_fast_symlink_chars(int blocksize)
|
||||
{
|
||||
@@ -1046,6 +1066,17 @@ static inline uint64_t ocfs2_backup_super_blkno(int blocksize, int index)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ocfs2_xattr_recs_per_xb(int blocksize)
|
||||
{
|
||||
int size;
|
||||
|
||||
size = blocksize -
|
||||
offsetof(struct ocfs2_xattr_block,
|
||||
xb_attrs.xb_root.xt_list.l_recs);
|
||||
|
||||
return size / sizeof(struct ocfs2_extent_rec);
|
||||
}
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
|
||||
|
在新工单中引用
屏蔽一个用户