mirror of
https://github.com/torvalds/linux.git
synced 2024-11-27 06:31:52 +00:00
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:
parent
e3cc4554ce
commit
9df243a1a9
@ -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);
|
||||
}
|
||||
|
||||
/*========================================================================
|
||||
|
Loading…
Reference in New Issue
Block a user