Modify delayed operations to use the new xfs_attr_da* routines In this patch, xfs_trans_attr is modified to use the new xfs_attr_da_* scheme, and pass the -EAGAIN back to the calling function. The leaf_bp is also factored up to be released after the transactions are handled. xfs_attri_recover will need to handle the -EAGAIN by logging and committing the transaction before recalling xfs_trans_attr. xfs_attr_finish_item does not need to handle the -EAGAIN since it is handled by its calling function. But it does need to plumb in xfs_da_args from the log item since it cant keep args instantiated in its own function context. Signed-off-by: Allison Collins <allison.henderson@xxxxxxxxxx> --- libxfs/defer_item.c | 44 ++++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/libxfs/defer_item.c b/libxfs/defer_item.c index b3dacdc..7e842fc 100644 --- a/libxfs/defer_item.c +++ b/libxfs/defer_item.c @@ -124,6 +124,7 @@ int xfs_trans_attr( struct xfs_da_args *args, struct xfs_attrd_log_item *attrdp, + struct xfs_buf **leaf_bp, uint32_t op_flags) { int error; @@ -135,11 +136,11 @@ xfs_trans_attr( switch (op_flags) { case XFS_ATTR_OP_FLAGS_SET: args->op_flags |= XFS_DA_OP_ADDNAME; - error = xfs_attr_set_args(args); + error = xfs_attr_da_set_args(args, leaf_bp); break; case XFS_ATTR_OP_FLAGS_REMOVE: ASSERT(XFS_IFORK_Q((args->dp))); - error = xfs_attr_remove_args(args); + error = xfs_attr_da_remove_args(args); break; default: error = -EFSCORRUPTED; @@ -207,30 +208,40 @@ xfs_attr_finish_item( unsigned char *name_value; int error; int local; - struct xfs_da_args args; + struct xfs_da_args *args; struct xfs_name name; struct xfs_attrd_log_item *attrdp; struct xfs_attri_log_item *attrip; attr = container_of(item, struct xfs_attr_item, xattri_list); - name_value = ((unsigned char *)attr) + sizeof(struct xfs_attr_item); + args = &attr->xattri_args; + name_value = ((unsigned char *)attr) + sizeof(struct xfs_attr_item); name.name = name_value; name.len = attr->xattri_name_len; name.type = attr->xattri_flags; - error = xfs_attr_args_init(&args, attr->xattri_ip, &name); - if (error) - goto out; - args.hashval = xfs_da_hashname(args.name, args.namelen); - args.value = &name_value[attr->xattri_name_len]; - args.valuelen = attr->xattri_value_len; - args.op_flags = XFS_DA_OP_OKNOENT; - args.total = xfs_attr_calc_size(&args, &local); - args.trans = tp; + if (!(args->dc.flags & XFS_DC_INIT)) { + error = xfs_attr_args_init(args, attr->xattri_ip, &name); + if (error) + goto out; + + args->hashval = xfs_da_hashname(args->name, args->namelen); + args->value = &name_value[attr->xattri_name_len]; + args->valuelen = attr->xattri_value_len; + args->op_flags = XFS_DA_OP_OKNOENT; + args->total = xfs_attr_calc_size(args, &local); + args->dc.flags |= XFS_DC_INIT; + } + + /* + * Always reset trans after EAGAIN cycle + * since the transaction is new + */ + args->trans = tp; - error = xfs_trans_attr(&args, done_item, - attr->xattri_op_flags); + error = xfs_trans_attr(args, done_item, &args->dc.leaf_bp, + attr->xattri_op_flags); out: /* * We are about to free the xfs_attr_item, so we need to remove any @@ -243,7 +254,8 @@ out: attrip->attri_name_len = 0; attrip->attri_value_len = 0; - kmem_free(attr); + if (error != -EAGAIN) + kmem_free(attr); return error; } -- 2.7.4