Skip to content

Commit

Permalink
ocfs2: reserve inline space for extended attribute
Browse files Browse the repository at this point in the history
Add the structures and helper functions we want for handling inline extended
attributes. We also update the inline-data handlers so that they properly
function in the event that we have both inline data and inline attributes
sharing an inode block.

Signed-off-by: Tiger Yang <tiger.yang@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
  • Loading branch information
Tiger Yang authored and Mark Fasheh committed Oct 13, 2008
1 parent f56654c commit fdd7770
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 9 deletions.
22 changes: 16 additions & 6 deletions fs/ocfs2/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -6577,20 +6577,29 @@ int ocfs2_zero_range_for_truncate(struct inode *inode, handle_t *handle,
return ret;
}

static void ocfs2_zero_dinode_id2(struct inode *inode, struct ocfs2_dinode *di)
static void ocfs2_zero_dinode_id2_with_xattr(struct inode *inode,
struct ocfs2_dinode *di)
{
unsigned int blocksize = 1 << inode->i_sb->s_blocksize_bits;
unsigned int xattrsize = le16_to_cpu(di->i_xattr_inline_size);

memset(&di->id2, 0, blocksize - offsetof(struct ocfs2_dinode, id2));
if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_XATTR_FL)
memset(&di->id2, 0, blocksize -
offsetof(struct ocfs2_dinode, id2) -
xattrsize);
else
memset(&di->id2, 0, blocksize -
offsetof(struct ocfs2_dinode, id2));
}

void ocfs2_dinode_new_extent_list(struct inode *inode,
struct ocfs2_dinode *di)
{
ocfs2_zero_dinode_id2(inode, di);
ocfs2_zero_dinode_id2_with_xattr(inode, di);
di->id2.i_list.l_tree_depth = 0;
di->id2.i_list.l_next_free_rec = 0;
di->id2.i_list.l_count = cpu_to_le16(ocfs2_extent_recs_per_inode(inode->i_sb));
di->id2.i_list.l_count = cpu_to_le16(
ocfs2_extent_recs_per_inode_with_xattr(inode->i_sb, di));
}

void ocfs2_set_inode_data_inline(struct inode *inode, struct ocfs2_dinode *di)
Expand All @@ -6607,9 +6616,10 @@ void ocfs2_set_inode_data_inline(struct inode *inode, struct ocfs2_dinode *di)
* We clear the entire i_data structure here so that all
* fields can be properly initialized.
*/
ocfs2_zero_dinode_id2(inode, di);
ocfs2_zero_dinode_id2_with_xattr(inode, di);

idata->id_count = cpu_to_le16(ocfs2_max_inline_data(inode->i_sb));
idata->id_count = cpu_to_le16(
ocfs2_max_inline_data_with_xattr(inode->i_sb, di));
}

int ocfs2_convert_inline_data_to_extents(struct inode *inode,
Expand Down
1 change: 1 addition & 0 deletions fs/ocfs2/ocfs2.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ struct ocfs2_super
int s_sectsize_bits;
int s_clustersize;
int s_clustersize_bits;
unsigned int s_xattr_inline_size;

atomic_t vol_state;
struct mutex recovery_lock;
Expand Down
46 changes: 43 additions & 3 deletions fs/ocfs2/ocfs2_fs.h
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,12 @@ struct ocfs2_new_group_input {
*/
#define OCFS2_DEFAULT_LOCAL_ALLOC_SIZE 8

/*
* Inline extended attribute size (in bytes)
* The value chosen should be aligned to 16 byte boundaries.
*/
#define OCFS2_MIN_XATTR_INLINE_SIZE 256

struct ocfs2_system_inode_info {
char *si_name;
int si_iflags;
Expand Down Expand Up @@ -622,7 +628,8 @@ struct ocfs2_dinode {
belongs to */
__le16 i_suballoc_bit; /* Bit offset in suballocator
block group */
/*10*/ __le32 i_reserved0;
/*10*/ __le16 i_reserved0;
__le16 i_xattr_inline_size;
__le32 i_clusters; /* Cluster count */
__le32 i_uid; /* Owner UID */
__le32 i_gid; /* Owning GID */
Expand All @@ -641,11 +648,12 @@ struct ocfs2_dinode {
__le32 i_atime_nsec;
__le32 i_ctime_nsec;
__le32 i_mtime_nsec;
__le32 i_attr;
/*70*/ __le32 i_attr;
__le16 i_orphaned_slot; /* Only valid when OCFS2_ORPHANED_FL
was set in i_flags */
__le16 i_dyn_features;
/*70*/ __le64 i_reserved2[8];
__le64 i_xattr_loc;
/*80*/ __le64 i_reserved2[7];
/*B8*/ union {
__le64 i_pad1; /* Generic way to refer to this
64bit union */
Expand Down Expand Up @@ -846,6 +854,20 @@ static inline int ocfs2_max_inline_data(struct super_block *sb)
offsetof(struct ocfs2_dinode, id2.i_data.id_data);
}

static inline int ocfs2_max_inline_data_with_xattr(struct super_block *sb,
struct ocfs2_dinode *di)
{
unsigned int xattrsize = le16_to_cpu(di->i_xattr_inline_size);

if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_XATTR_FL)
return sb->s_blocksize -
offsetof(struct ocfs2_dinode, id2.i_data.id_data) -
xattrsize;
else
return sb->s_blocksize -
offsetof(struct ocfs2_dinode, id2.i_data.id_data);
}

static inline int ocfs2_extent_recs_per_inode(struct super_block *sb)
{
int size;
Expand All @@ -856,6 +878,24 @@ static inline int ocfs2_extent_recs_per_inode(struct super_block *sb)
return size / sizeof(struct ocfs2_extent_rec);
}

static inline int ocfs2_extent_recs_per_inode_with_xattr(
struct super_block *sb,
struct ocfs2_dinode *di)
{
int size;
unsigned int xattrsize = le16_to_cpu(di->i_xattr_inline_size);

if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_XATTR_FL)
size = sb->s_blocksize -
offsetof(struct ocfs2_dinode, id2.i_list.l_recs) -
xattrsize;
else
size = sb->s_blocksize -
offsetof(struct ocfs2_dinode, id2.i_list.l_recs);

return size / sizeof(struct ocfs2_extent_rec);
}

static inline int ocfs2_chain_recs_per_inode(struct super_block *sb)
{
int size;
Expand Down
2 changes: 2 additions & 0 deletions fs/ocfs2/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -1424,6 +1424,8 @@ static int ocfs2_initialize_super(struct super_block *sb,

osb->slot_num = OCFS2_INVALID_SLOT;

osb->s_xattr_inline_size = OCFS2_MIN_XATTR_INLINE_SIZE;

osb->local_alloc_state = OCFS2_LA_UNUSED;
osb->local_alloc_bh = NULL;
INIT_DELAYED_WORK(&osb->la_enable_wq, ocfs2_la_enable_worker);
Expand Down

0 comments on commit fdd7770

Please sign in to comment.