Skip to content

Commit 97835e6

Browse files
Darrick J. WongChandan Babu R
authored andcommitted
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: c27411d ("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>
1 parent 2b3f004 commit 97835e6

File tree

3 files changed

+35
-25
lines changed

3 files changed

+35
-25
lines changed

fs/xfs/libxfs/xfs_attr.c

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -329,26 +329,20 @@ xfs_attr_calc_size(
329329
return nblks;
330330
}
331331

332-
/* Initialize transaction reservation for attr operations */
333-
void
334-
xfs_init_attr_trans(
335-
struct xfs_da_args *args,
336-
struct xfs_trans_res *tres,
337-
unsigned int *total)
332+
/* Initialize transaction reservation for an xattr set/replace/upsert */
333+
inline struct xfs_trans_res
334+
xfs_attr_set_resv(
335+
const struct xfs_da_args *args)
338336
{
339-
struct xfs_mount *mp = args->dp->i_mount;
340-
341-
if (args->value) {
342-
tres->tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
343-
M_RES(mp)->tr_attrsetrt.tr_logres *
344-
args->total;
345-
tres->tr_logcount = XFS_ATTRSET_LOG_COUNT;
346-
tres->tr_logflags = XFS_TRANS_PERM_LOG_RES;
347-
*total = args->total;
348-
} else {
349-
*tres = M_RES(mp)->tr_attrrm;
350-
*total = XFS_ATTRRM_SPACE_RES(mp);
351-
}
337+
struct xfs_mount *mp = args->dp->i_mount;
338+
struct xfs_trans_res ret = {
339+
.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
340+
M_RES(mp)->tr_attrsetrt.tr_logres * args->total,
341+
.tr_logcount = XFS_ATTRSET_LOG_COUNT,
342+
.tr_logflags = XFS_TRANS_PERM_LOG_RES,
343+
};
344+
345+
return ret;
352346
}
353347

354348
/*
@@ -1006,7 +1000,7 @@ xfs_attr_set(
10061000
struct xfs_trans_res tres;
10071001
int error, local;
10081002
int rmt_blks = 0;
1009-
unsigned int total;
1003+
unsigned int total = 0;
10101004

10111005
ASSERT(!args->trans);
10121006

@@ -1033,18 +1027,22 @@ xfs_attr_set(
10331027

10341028
if (!local)
10351029
rmt_blks = xfs_attr3_rmt_blocks(mp, args->valuelen);
1030+
1031+
tres = xfs_attr_set_resv(args);
1032+
total = args->total;
10361033
break;
10371034
case XFS_ATTRUPDATE_REMOVE:
10381035
XFS_STATS_INC(mp, xs_attr_remove);
10391036
rmt_blks = xfs_attr3_max_rmt_blocks(mp);
1037+
tres = M_RES(mp)->tr_attrrm;
1038+
total = XFS_ATTRRM_SPACE_RES(mp);
10401039
break;
10411040
}
10421041

10431042
/*
10441043
* Root fork attributes can use reserved data blocks for this
10451044
* operation if necessary
10461045
*/
1047-
xfs_init_attr_trans(args, &tres, &total);
10481046
error = xfs_trans_alloc_inode(dp, &tres, total, 0, rsvd, &args->trans);
10491047
if (error)
10501048
return error;

fs/xfs/libxfs/xfs_attr.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -565,8 +565,7 @@ bool xfs_attr_check_namespace(unsigned int attr_flags);
565565
bool xfs_attr_namecheck(unsigned int attr_flags, const void *name,
566566
size_t length);
567567
int xfs_attr_calc_size(struct xfs_da_args *args, int *local);
568-
void xfs_init_attr_trans(struct xfs_da_args *args, struct xfs_trans_res *tres,
569-
unsigned int *total);
568+
struct xfs_trans_res xfs_attr_set_resv(const struct xfs_da_args *args);
570569

571570
/*
572571
* Check to see if the attr should be upgraded from non-existent or shortform to

fs/xfs/xfs_attr_item.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,7 @@ xfs_attr_recover_work(
746746
struct xfs_attri_log_format *attrp;
747747
struct xfs_attri_log_nameval *nv = attrip->attri_nameval;
748748
int error;
749-
int total;
749+
unsigned int total = 0;
750750

751751
/*
752752
* First check the validity of the attr described by the ATTRI. If any
@@ -763,7 +763,20 @@ xfs_attr_recover_work(
763763
return PTR_ERR(attr);
764764
args = attr->xattri_da_args;
765765

766-
xfs_init_attr_trans(args, &resv, &total);
766+
switch (xfs_attr_intent_op(attr)) {
767+
case XFS_ATTRI_OP_FLAGS_PPTR_SET:
768+
case XFS_ATTRI_OP_FLAGS_PPTR_REPLACE:
769+
case XFS_ATTRI_OP_FLAGS_SET:
770+
case XFS_ATTRI_OP_FLAGS_REPLACE:
771+
resv = xfs_attr_set_resv(args);
772+
total = args->total;
773+
break;
774+
case XFS_ATTRI_OP_FLAGS_PPTR_REMOVE:
775+
case XFS_ATTRI_OP_FLAGS_REMOVE:
776+
resv = M_RES(mp)->tr_attrrm;
777+
total = XFS_ATTRRM_SPACE_RES(mp);
778+
break;
779+
}
767780
resv = xlog_recover_resv(&resv);
768781
error = xfs_trans_alloc(mp, &resv, total, 0, XFS_TRANS_RESERVE, &tp);
769782
if (error)

0 commit comments

Comments
 (0)