ocfs2: Set xattr block entries with ocfs2_xa_set()
ocfs2_xattr_block_set() calls into ocfs2_xattr_set_entry() with just the HAS_XATTR flag. Most of the machinery of ocfs2_xattr_set_entry() is skipped. All that really happens other than the call to ocfs2_xa_set() is making sure the HAS_XATTR flag is set on the inode. But HAS_XATTR should be set when we also set di->i_xattr_loc. And that's done in ocfs2_create_xattr_block(). So let's move it there, and then ocfs2_xattr_block_set() can just call ocfs2_xa_set(). While we're there, ocfs2_create_xattr_block() can take the set_ctxt for a smaller argument list. It also learns to set HAS_XATTR_FL, because it knows for sure. ocfs2_create_empty_xatttr_block() in the reflink path fakes a set_ctxt to call ocfs2_create_xattr_block(). Signed-off-by: Joel Becker <joel.becker@oracle.com>
This commit is contained in:
parent
c5d95df5f7
commit
d3981544d7
1 changed files with 49 additions and 50 deletions
|
@ -2206,10 +2206,8 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
|
||||||
int ret;
|
int ret;
|
||||||
struct ocfs2_xa_loc loc;
|
struct ocfs2_xa_loc loc;
|
||||||
|
|
||||||
if (!(flag & OCFS2_INLINE_XATTR_FL))
|
BUG_ON(!(flag & OCFS2_INLINE_XATTR_FL));
|
||||||
BUG_ON(xs->xattr_bh == xs->inode_bh);
|
BUG_ON(xs->xattr_bh != xs->inode_bh);
|
||||||
else
|
|
||||||
BUG_ON(xs->xattr_bh != xs->inode_bh);
|
|
||||||
|
|
||||||
ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), xs->inode_bh,
|
ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), xs->inode_bh,
|
||||||
OCFS2_JOURNAL_ACCESS_WRITE);
|
OCFS2_JOURNAL_ACCESS_WRITE);
|
||||||
|
@ -2218,13 +2216,8 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xs->xattr_bh == xs->inode_bh)
|
ocfs2_init_dinode_xa_loc(&loc, inode, xs->inode_bh,
|
||||||
ocfs2_init_dinode_xa_loc(&loc, inode, xs->inode_bh,
|
xs->not_found ? NULL : xs->here);
|
||||||
xs->not_found ? NULL : xs->here);
|
|
||||||
else
|
|
||||||
ocfs2_init_xattr_block_xa_loc(&loc, inode, xs->xattr_bh,
|
|
||||||
xs->not_found ? NULL : xs->here);
|
|
||||||
|
|
||||||
ret = ocfs2_xa_set(&loc, xi, ctxt);
|
ret = ocfs2_xa_set(&loc, xi, ctxt);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
if (ret != -ENOSPC)
|
if (ret != -ENOSPC)
|
||||||
|
@ -2233,8 +2226,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
|
||||||
}
|
}
|
||||||
xs->here = loc.xl_entry;
|
xs->here = loc.xl_entry;
|
||||||
|
|
||||||
if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) &&
|
if (!(oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL)) {
|
||||||
(flag & OCFS2_INLINE_XATTR_FL)) {
|
|
||||||
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||||
unsigned int xattrsize = osb->s_xattr_inline_size;
|
unsigned int xattrsize = osb->s_xattr_inline_size;
|
||||||
|
|
||||||
|
@ -2254,7 +2246,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
|
||||||
}
|
}
|
||||||
/* Update xattr flag */
|
/* Update xattr flag */
|
||||||
spin_lock(&oi->ip_lock);
|
spin_lock(&oi->ip_lock);
|
||||||
oi->ip_dyn_features |= flag;
|
oi->ip_dyn_features |= OCFS2_INLINE_XATTR_FL;
|
||||||
di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features);
|
di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features);
|
||||||
spin_unlock(&oi->ip_lock);
|
spin_unlock(&oi->ip_lock);
|
||||||
|
|
||||||
|
@ -2748,12 +2740,11 @@ cleanup:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ocfs2_create_xattr_block(handle_t *handle,
|
static int ocfs2_create_xattr_block(struct inode *inode,
|
||||||
struct inode *inode,
|
|
||||||
struct buffer_head *inode_bh,
|
struct buffer_head *inode_bh,
|
||||||
struct ocfs2_alloc_context *meta_ac,
|
struct ocfs2_xattr_set_ctxt *ctxt,
|
||||||
struct buffer_head **ret_bh,
|
int indexed,
|
||||||
int indexed)
|
struct buffer_head **ret_bh)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
u16 suballoc_bit_start;
|
u16 suballoc_bit_start;
|
||||||
|
@ -2764,14 +2755,14 @@ static int ocfs2_create_xattr_block(handle_t *handle,
|
||||||
struct buffer_head *new_bh = NULL;
|
struct buffer_head *new_bh = NULL;
|
||||||
struct ocfs2_xattr_block *xblk;
|
struct ocfs2_xattr_block *xblk;
|
||||||
|
|
||||||
ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), inode_bh,
|
ret = ocfs2_journal_access_di(ctxt->handle, INODE_CACHE(inode),
|
||||||
OCFS2_JOURNAL_ACCESS_CREATE);
|
inode_bh, OCFS2_JOURNAL_ACCESS_CREATE);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
mlog_errno(ret);
|
mlog_errno(ret);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ocfs2_claim_metadata(osb, handle, meta_ac, 1,
|
ret = ocfs2_claim_metadata(osb, ctxt->handle, ctxt->meta_ac, 1,
|
||||||
&suballoc_bit_start, &num_got,
|
&suballoc_bit_start, &num_got,
|
||||||
&first_blkno);
|
&first_blkno);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -2782,7 +2773,7 @@ static int ocfs2_create_xattr_block(handle_t *handle,
|
||||||
new_bh = sb_getblk(inode->i_sb, first_blkno);
|
new_bh = sb_getblk(inode->i_sb, first_blkno);
|
||||||
ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode), new_bh);
|
ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode), new_bh);
|
||||||
|
|
||||||
ret = ocfs2_journal_access_xb(handle, INODE_CACHE(inode),
|
ret = ocfs2_journal_access_xb(ctxt->handle, INODE_CACHE(inode),
|
||||||
new_bh,
|
new_bh,
|
||||||
OCFS2_JOURNAL_ACCESS_CREATE);
|
OCFS2_JOURNAL_ACCESS_CREATE);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -2794,11 +2785,10 @@ static int ocfs2_create_xattr_block(handle_t *handle,
|
||||||
xblk = (struct ocfs2_xattr_block *)new_bh->b_data;
|
xblk = (struct ocfs2_xattr_block *)new_bh->b_data;
|
||||||
memset(xblk, 0, inode->i_sb->s_blocksize);
|
memset(xblk, 0, inode->i_sb->s_blocksize);
|
||||||
strcpy((void *)xblk, OCFS2_XATTR_BLOCK_SIGNATURE);
|
strcpy((void *)xblk, OCFS2_XATTR_BLOCK_SIGNATURE);
|
||||||
xblk->xb_suballoc_slot = cpu_to_le16(meta_ac->ac_alloc_slot);
|
xblk->xb_suballoc_slot = cpu_to_le16(ctxt->meta_ac->ac_alloc_slot);
|
||||||
xblk->xb_suballoc_bit = cpu_to_le16(suballoc_bit_start);
|
xblk->xb_suballoc_bit = cpu_to_le16(suballoc_bit_start);
|
||||||
xblk->xb_fs_generation = cpu_to_le32(osb->fs_generation);
|
xblk->xb_fs_generation = cpu_to_le32(osb->fs_generation);
|
||||||
xblk->xb_blkno = cpu_to_le64(first_blkno);
|
xblk->xb_blkno = cpu_to_le64(first_blkno);
|
||||||
|
|
||||||
if (indexed) {
|
if (indexed) {
|
||||||
struct ocfs2_xattr_tree_root *xr = &xblk->xb_attrs.xb_root;
|
struct ocfs2_xattr_tree_root *xr = &xblk->xb_attrs.xb_root;
|
||||||
xr->xt_clusters = cpu_to_le32(1);
|
xr->xt_clusters = cpu_to_le32(1);
|
||||||
|
@ -2809,14 +2799,17 @@ static int ocfs2_create_xattr_block(handle_t *handle,
|
||||||
xr->xt_list.l_next_free_rec = cpu_to_le16(1);
|
xr->xt_list.l_next_free_rec = cpu_to_le16(1);
|
||||||
xblk->xb_flags = cpu_to_le16(OCFS2_XATTR_INDEXED);
|
xblk->xb_flags = cpu_to_le16(OCFS2_XATTR_INDEXED);
|
||||||
}
|
}
|
||||||
|
ocfs2_journal_dirty(ctxt->handle, new_bh);
|
||||||
|
|
||||||
ret = ocfs2_journal_dirty(handle, new_bh);
|
/* Add it to the inode */
|
||||||
if (ret < 0) {
|
|
||||||
mlog_errno(ret);
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
di->i_xattr_loc = cpu_to_le64(first_blkno);
|
di->i_xattr_loc = cpu_to_le64(first_blkno);
|
||||||
ocfs2_journal_dirty(handle, inode_bh);
|
|
||||||
|
spin_lock(&OCFS2_I(inode)->ip_lock);
|
||||||
|
OCFS2_I(inode)->ip_dyn_features |= OCFS2_HAS_XATTR_FL;
|
||||||
|
di->i_dyn_features = cpu_to_le16(OCFS2_I(inode)->ip_dyn_features);
|
||||||
|
spin_unlock(&OCFS2_I(inode)->ip_lock);
|
||||||
|
|
||||||
|
ocfs2_journal_dirty(ctxt->handle, inode_bh);
|
||||||
|
|
||||||
*ret_bh = new_bh;
|
*ret_bh = new_bh;
|
||||||
new_bh = NULL;
|
new_bh = NULL;
|
||||||
|
@ -2838,13 +2831,13 @@ static int ocfs2_xattr_block_set(struct inode *inode,
|
||||||
struct ocfs2_xattr_set_ctxt *ctxt)
|
struct ocfs2_xattr_set_ctxt *ctxt)
|
||||||
{
|
{
|
||||||
struct buffer_head *new_bh = NULL;
|
struct buffer_head *new_bh = NULL;
|
||||||
handle_t *handle = ctxt->handle;
|
|
||||||
struct ocfs2_xattr_block *xblk = NULL;
|
struct ocfs2_xattr_block *xblk = NULL;
|
||||||
int ret;
|
int ret;
|
||||||
|
struct ocfs2_xa_loc loc;
|
||||||
|
|
||||||
if (!xs->xattr_bh) {
|
if (!xs->xattr_bh) {
|
||||||
ret = ocfs2_create_xattr_block(handle, inode, xs->inode_bh,
|
ret = ocfs2_create_xattr_block(inode, xs->inode_bh, ctxt,
|
||||||
ctxt->meta_ac, &new_bh, 0);
|
0, &new_bh);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
mlog_errno(ret);
|
mlog_errno(ret);
|
||||||
goto end;
|
goto end;
|
||||||
|
@ -2860,21 +2853,25 @@ static int ocfs2_xattr_block_set(struct inode *inode,
|
||||||
xblk = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data;
|
xblk = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data;
|
||||||
|
|
||||||
if (!(le16_to_cpu(xblk->xb_flags) & OCFS2_XATTR_INDEXED)) {
|
if (!(le16_to_cpu(xblk->xb_flags) & OCFS2_XATTR_INDEXED)) {
|
||||||
/* Set extended attribute into external block */
|
ocfs2_init_xattr_block_xa_loc(&loc, inode, xs->xattr_bh,
|
||||||
ret = ocfs2_xattr_set_entry(inode, xi, xs, ctxt,
|
xs->not_found ? NULL : xs->here);
|
||||||
OCFS2_HAS_XATTR_FL);
|
|
||||||
if (!ret || ret != -ENOSPC)
|
|
||||||
goto end;
|
|
||||||
|
|
||||||
ret = ocfs2_xattr_create_index_block(inode, xs, ctxt);
|
ret = ocfs2_xa_set(&loc, xi, ctxt);
|
||||||
if (ret)
|
if (!ret)
|
||||||
|
xs->here = loc.xl_entry;
|
||||||
|
else if (ret != -ENOSPC)
|
||||||
goto end;
|
goto end;
|
||||||
|
else {
|
||||||
|
ret = ocfs2_xattr_create_index_block(inode, xs, ctxt);
|
||||||
|
if (ret)
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ocfs2_xattr_set_entry_index_block(inode, xi, xs, ctxt);
|
if (le16_to_cpu(xblk->xb_flags) & OCFS2_XATTR_INDEXED)
|
||||||
|
ret = ocfs2_xattr_set_entry_index_block(inode, xi, xs, ctxt);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6434,9 +6431,11 @@ static int ocfs2_create_empty_xattr_block(struct inode *inode,
|
||||||
int indexed)
|
int indexed)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
handle_t *handle;
|
|
||||||
struct ocfs2_alloc_context *meta_ac;
|
struct ocfs2_alloc_context *meta_ac;
|
||||||
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
|
||||||
|
struct ocfs2_xattr_set_ctxt ctxt = {
|
||||||
|
.meta_ac = meta_ac,
|
||||||
|
};
|
||||||
|
|
||||||
ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac);
|
ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -6444,21 +6443,21 @@ static int ocfs2_create_empty_xattr_block(struct inode *inode,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
handle = ocfs2_start_trans(osb, OCFS2_XATTR_BLOCK_CREATE_CREDITS);
|
ctxt.handle = ocfs2_start_trans(osb, OCFS2_XATTR_BLOCK_CREATE_CREDITS);
|
||||||
if (IS_ERR(handle)) {
|
if (IS_ERR(ctxt.handle)) {
|
||||||
ret = PTR_ERR(handle);
|
ret = PTR_ERR(ctxt.handle);
|
||||||
mlog_errno(ret);
|
mlog_errno(ret);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
mlog(0, "create new xattr block for inode %llu, index = %d\n",
|
mlog(0, "create new xattr block for inode %llu, index = %d\n",
|
||||||
(unsigned long long)fe_bh->b_blocknr, indexed);
|
(unsigned long long)fe_bh->b_blocknr, indexed);
|
||||||
ret = ocfs2_create_xattr_block(handle, inode, fe_bh,
|
ret = ocfs2_create_xattr_block(inode, fe_bh, &ctxt, indexed,
|
||||||
meta_ac, ret_bh, indexed);
|
ret_bh);
|
||||||
if (ret)
|
if (ret)
|
||||||
mlog_errno(ret);
|
mlog_errno(ret);
|
||||||
|
|
||||||
ocfs2_commit_trans(osb, handle);
|
ocfs2_commit_trans(osb, ctxt.handle);
|
||||||
out:
|
out:
|
||||||
ocfs2_free_alloc_context(meta_ac);
|
ocfs2_free_alloc_context(meta_ac);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Reference in a new issue