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);
|
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).
|
* 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.
|
* exist or we can't retrieve the value.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xfs_attr_shortform_getvalue(xfs_da_args_t *args)
|
xfs_attr_shortform_getvalue(
|
||||||
|
struct xfs_da_args *args)
|
||||||
{
|
{
|
||||||
xfs_attr_shortform_t *sf;
|
struct xfs_attr_shortform *sf;
|
||||||
xfs_attr_sf_entry_t *sfe;
|
struct xfs_attr_sf_entry *sfe;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ASSERT(args->dp->i_afp->if_flags == XFS_IFINLINE);
|
ASSERT(args->dp->i_afp->if_flags == XFS_IFINLINE);
|
||||||
sf = (xfs_attr_shortform_t *)args->dp->i_afp->if_u1.if_data;
|
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;
|
continue;
|
||||||
if (!xfs_attr_namesp_match(args->flags, sfe->flags))
|
if (!xfs_attr_namesp_match(args->flags, sfe->flags))
|
||||||
continue;
|
continue;
|
||||||
if (args->flags & ATTR_KERNOVAL) {
|
return xfs_attr_copy_value(args, &sfe->nameval[args->namelen],
|
||||||
args->valuelen = sfe->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 -ENOATTR;
|
return -ENOATTR;
|
||||||
}
|
}
|
||||||
|
@ -2368,7 +2397,6 @@ xfs_attr3_leaf_getvalue(
|
||||||
struct xfs_attr_leaf_entry *entry;
|
struct xfs_attr_leaf_entry *entry;
|
||||||
struct xfs_attr_leaf_name_local *name_loc;
|
struct xfs_attr_leaf_name_local *name_loc;
|
||||||
struct xfs_attr_leaf_name_remote *name_rmt;
|
struct xfs_attr_leaf_name_remote *name_rmt;
|
||||||
int valuelen;
|
|
||||||
|
|
||||||
leaf = bp->b_addr;
|
leaf = bp->b_addr;
|
||||||
xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf);
|
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);
|
name_loc = xfs_attr3_leaf_name_local(leaf, args->index);
|
||||||
ASSERT(name_loc->namelen == args->namelen);
|
ASSERT(name_loc->namelen == args->namelen);
|
||||||
ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0);
|
ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0);
|
||||||
valuelen = be16_to_cpu(name_loc->valuelen);
|
return xfs_attr_copy_value(args,
|
||||||
if (args->flags & ATTR_KERNOVAL) {
|
&name_loc->nameval[args->namelen],
|
||||||
args->valuelen = valuelen;
|
be16_to_cpu(name_loc->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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index);
|
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->rmtblkno = be32_to_cpu(name_rmt->valueblk);
|
||||||
args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount,
|
args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount,
|
||||||
args->rmtvaluelen);
|
args->rmtvaluelen);
|
||||||
if (args->flags & ATTR_KERNOVAL) {
|
return xfs_attr_copy_value(args, NULL, args->rmtvaluelen);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*========================================================================
|
/*========================================================================
|
||||||
|
|
Loading…
Reference in New Issue