mirror of
https://github.com/torvalds/linux.git
synced 2024-11-21 19:41:42 +00:00
xfs: fix xfs_init_attr_trans not handling explicit operation codes
When we were converting the attr code to use an explicit operation code
instead of keying off of attr->value being null, we forgot to change the
code that initializes the transaction reservation. Split the function
into two helpers that handle the !remove and remove cases, then fix both
callsites to handle this correctly.
Fixes: c27411d4c6
("xfs: make attr removal an explicit operation")
Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Chandan Babu R <chandanbabu@kernel.org>
This commit is contained in:
parent
2b3f004d3d
commit
97835e6866
@ -329,26 +329,20 @@ xfs_attr_calc_size(
|
|||||||
return nblks;
|
return nblks;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize transaction reservation for attr operations */
|
/* Initialize transaction reservation for an xattr set/replace/upsert */
|
||||||
void
|
inline struct xfs_trans_res
|
||||||
xfs_init_attr_trans(
|
xfs_attr_set_resv(
|
||||||
struct xfs_da_args *args,
|
const struct xfs_da_args *args)
|
||||||
struct xfs_trans_res *tres,
|
|
||||||
unsigned int *total)
|
|
||||||
{
|
{
|
||||||
struct xfs_mount *mp = args->dp->i_mount;
|
struct xfs_mount *mp = args->dp->i_mount;
|
||||||
|
struct xfs_trans_res ret = {
|
||||||
|
.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
|
||||||
|
M_RES(mp)->tr_attrsetrt.tr_logres * args->total,
|
||||||
|
.tr_logcount = XFS_ATTRSET_LOG_COUNT,
|
||||||
|
.tr_logflags = XFS_TRANS_PERM_LOG_RES,
|
||||||
|
};
|
||||||
|
|
||||||
if (args->value) {
|
return ret;
|
||||||
tres->tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
|
|
||||||
M_RES(mp)->tr_attrsetrt.tr_logres *
|
|
||||||
args->total;
|
|
||||||
tres->tr_logcount = XFS_ATTRSET_LOG_COUNT;
|
|
||||||
tres->tr_logflags = XFS_TRANS_PERM_LOG_RES;
|
|
||||||
*total = args->total;
|
|
||||||
} else {
|
|
||||||
*tres = M_RES(mp)->tr_attrrm;
|
|
||||||
*total = XFS_ATTRRM_SPACE_RES(mp);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1006,7 +1000,7 @@ xfs_attr_set(
|
|||||||
struct xfs_trans_res tres;
|
struct xfs_trans_res tres;
|
||||||
int error, local;
|
int error, local;
|
||||||
int rmt_blks = 0;
|
int rmt_blks = 0;
|
||||||
unsigned int total;
|
unsigned int total = 0;
|
||||||
|
|
||||||
ASSERT(!args->trans);
|
ASSERT(!args->trans);
|
||||||
|
|
||||||
@ -1033,10 +1027,15 @@ xfs_attr_set(
|
|||||||
|
|
||||||
if (!local)
|
if (!local)
|
||||||
rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
|
rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
|
||||||
|
|
||||||
|
tres = xfs_attr_set_resv(args);
|
||||||
|
total = args->total;
|
||||||
break;
|
break;
|
||||||
case XFS_ATTRUPDATE_REMOVE:
|
case XFS_ATTRUPDATE_REMOVE:
|
||||||
XFS_STATS_INC(mp, xs_attr_remove);
|
XFS_STATS_INC(mp, xs_attr_remove);
|
||||||
rmt_blks = xfs_attr3_max_rmt_blocks(mp);
|
rmt_blks = xfs_attr3_max_rmt_blocks(mp);
|
||||||
|
tres = M_RES(mp)->tr_attrrm;
|
||||||
|
total = XFS_ATTRRM_SPACE_RES(mp);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1044,7 +1043,6 @@ xfs_attr_set(
|
|||||||
* Root fork attributes can use reserved data blocks for this
|
* Root fork attributes can use reserved data blocks for this
|
||||||
* operation if necessary
|
* operation if necessary
|
||||||
*/
|
*/
|
||||||
xfs_init_attr_trans(args, &tres, &total);
|
|
||||||
error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
|
error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
@ -565,8 +565,7 @@ bool xfs_attr_check_namespace(unsigned int attr_flags);
|
|||||||
bool xfs_attr_namecheck(unsigned int attr_flags, const void *name,
|
bool xfs_attr_namecheck(unsigned int attr_flags, const void *name,
|
||||||
size_t length);
|
size_t length);
|
||||||
int xfs_attr_calc_size(struct xfs_da_args *args, int *local);
|
int xfs_attr_calc_size(struct xfs_da_args *args, int *local);
|
||||||
void xfs_init_attr_trans(struct xfs_da_args *args, struct xfs_trans_res *tres,
|
struct xfs_trans_res xfs_attr_set_resv(const struct xfs_da_args *args);
|
||||||
unsigned int *total);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check to see if the attr should be upgraded from non-existent or shortform to
|
* Check to see if the attr should be upgraded from non-existent or shortform to
|
||||||
|
@ -746,7 +746,7 @@ xfs_attr_recover_work(
|
|||||||
struct xfs_attri_log_format *attrp;
|
struct xfs_attri_log_format *attrp;
|
||||||
struct xfs_attri_log_nameval *nv = attrip->attri_nameval;
|
struct xfs_attri_log_nameval *nv = attrip->attri_nameval;
|
||||||
int error;
|
int error;
|
||||||
int total;
|
unsigned int total = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* First check the validity of the attr described by the ATTRI. If any
|
* First check the validity of the attr described by the ATTRI. If any
|
||||||
@ -763,7 +763,20 @@ xfs_attr_recover_work(
|
|||||||
return PTR_ERR(attr);
|
return PTR_ERR(attr);
|
||||||
args = attr->xattri_da_args;
|
args = attr->xattri_da_args;
|
||||||
|
|
||||||
xfs_init_attr_trans(args, &resv, &total);
|
switch (xfs_attr_intent_op(attr)) {
|
||||||
|
case XFS_ATTRI_OP_FLAGS_PPTR_SET:
|
||||||
|
case XFS_ATTRI_OP_FLAGS_PPTR_REPLACE:
|
||||||
|
case XFS_ATTRI_OP_FLAGS_SET:
|
||||||
|
case XFS_ATTRI_OP_FLAGS_REPLACE:
|
||||||
|
resv = xfs_attr_set_resv(args);
|
||||||
|
total = args->total;
|
||||||
|
break;
|
||||||
|
case XFS_ATTRI_OP_FLAGS_PPTR_REMOVE:
|
||||||
|
case XFS_ATTRI_OP_FLAGS_REMOVE:
|
||||||
|
resv = M_RES(mp)->tr_attrrm;
|
||||||
|
total = XFS_ATTRRM_SPACE_RES(mp);
|
||||||
|
break;
|
||||||
|
}
|
||||||
resv = xlog_recover_resv(&resv);
|
resv = xlog_recover_resv(&resv);
|
||||||
error = xfs_trans_alloc(mp, &resv, total, 0, XFS_TRANS_RESERVE, &tp);
|
error = xfs_trans_alloc(mp, &resv, total, 0, XFS_TRANS_RESERVE, &tp);
|
||||||
if (error)
|
if (error)
|
||||||
|
Loading…
Reference in New Issue
Block a user