xfs: consolidate attribute value copying

The same code is used to copy do the attribute copying in three
different places. Consolidate them into a single function in
preparation from on-demand buffer allocation.

Signed-off-by: Dave Chinner <dchinner@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
This commit is contained in:
Dave Chinner 2019-08-29 09:04:10 -07:00 committed by Darrick J. Wong
parent e3cc4554ce
commit 9df243a1a9
1 changed files with 49 additions and 39 deletions

View File

@ -393,6 +393,44 @@ xfs_attr_namesp_match(int arg_flags, int ondisk_flags)
return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags);
}
static int
xfs_attr_copy_value(
struct xfs_da_args *args,
unsigned char *value,
int valuelen)
{
/*
* No copy if all we have to do is get the length
*/
if (args->flags & ATTR_KERNOVAL) {
args->valuelen = valuelen;
return 0;
}
/*
* No copy if the length of the existing buffer is too small
*/
if (args->valuelen < valuelen) {
args->valuelen = valuelen;
return -ERANGE;
}
args->valuelen = valuelen;
/* remote block xattr requires IO for copy-in */
if (args->rmtblkno)
return xfs_attr_rmtval_get(args);
/*
* This is to prevent a GCC warning because the remote xattr case
* doesn't have a value to pass in. In that case, we never reach here,
* but GCC can't work that out and so throws a "passing NULL to
* memcpy" warning.
*/
if (!value)
return -EINVAL;
memcpy(args->value, value, valuelen);
return 0;
}
/*========================================================================
* External routines when attribute fork size < XFS_LITINO(mp).
@ -727,11 +765,12 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args)
* exist or we can't retrieve the value.
*/
int
xfs_attr_shortform_getvalue(xfs_da_args_t *args)
xfs_attr_shortform_getvalue(
struct xfs_da_args *args)
{
xfs_attr_shortform_t *sf;
xfs_attr_sf_entry_t *sfe;
int i;
struct xfs_attr_shortform *sf;
struct xfs_attr_sf_entry *sfe;
int i;
ASSERT(args->dp->i_afp->if_flags == XFS_IFINLINE);
sf = (xfs_attr_shortform_t *)args->dp->i_afp->if_u1.if_data;
@ -744,18 +783,8 @@ xfs_attr_shortform_getvalue(xfs_da_args_t *args)
continue;
if (!xfs_attr_namesp_match(args->flags, sfe->flags))
continue;
if (args->flags & ATTR_KERNOVAL) {
args->valuelen = sfe->valuelen;
return 0;
}
if (args->valuelen < sfe->valuelen) {
args->valuelen = sfe->valuelen;
return -ERANGE;
}
args->valuelen = sfe->valuelen;
memcpy(args->value, &sfe->nameval[args->namelen],
args->valuelen);
return 0;
return xfs_attr_copy_value(args, &sfe->nameval[args->namelen],
sfe->valuelen);
}
return -ENOATTR;
}
@ -2368,7 +2397,6 @@ xfs_attr3_leaf_getvalue(
struct xfs_attr_leaf_entry *entry;
struct xfs_attr_leaf_name_local *name_loc;
struct xfs_attr_leaf_name_remote *name_rmt;
int valuelen;
leaf = bp->b_addr;
xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
@ -2380,18 +2408,9 @@ xfs_attr3_leaf_getvalue(
name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
ASSERT(name_loc->namelen == args->namelen);
ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0);
valuelen = be16_to_cpu(name_loc->valuelen);
if (args->flags & ATTR_KERNOVAL) {
args->valuelen = valuelen;
return 0;
}
if (args->valuelen < valuelen) {
args->valuelen = valuelen;
return -ERANGE;
}
args->valuelen = valuelen;
memcpy(args->value, &name_loc->nameval[args->namelen], valuelen);
return 0;
return xfs_attr_copy_value(args,
&name_loc->nameval[args->namelen],
be16_to_cpu(name_loc->valuelen));
}
name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
@ -2401,16 +2420,7 @@ xfs_attr3_leaf_getvalue(
args->rmtblkno = be32_to_cpu(name_rmt->valueblk);
args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount,
args->rmtvaluelen);
if (args->flags & ATTR_KERNOVAL) {
args->valuelen = args->rmtvaluelen;
return 0;
}
if (args->valuelen < args->rmtvaluelen) {
args->valuelen = args->rmtvaluelen;
return -ERANGE;
}
args->valuelen = args->rmtvaluelen;
return xfs_attr_rmtval_get(args);
return xfs_attr_copy_value(args, NULL, args->rmtvaluelen);
}
/*========================================================================