diff options
author | Dave Chinner <dchinner@redhat.com> | 2019-08-29 12:04:10 -0400 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2019-08-31 01:43:57 -0400 |
commit | 9df243a1a9e607e7cf5d20ee46edd5ec84b7e400 (patch) | |
tree | 7ba879e470dceb0957ee3b29412d3c2e6d416f7c | |
parent | e3cc4554ce1b2cc43262c93ebe6d8cde780d29ee (diff) |
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>
-rw-r--r-- | fs/xfs/libxfs/xfs_attr_leaf.c | 88 |
1 files changed, 49 insertions, 39 deletions
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 8085c4f0e5a0..f6a595e76343 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c | |||
@@ -393,6 +393,44 @@ xfs_attr_namesp_match(int arg_flags, int ondisk_flags) | |||
393 | return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags); | 393 | return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags); |
394 | } | 394 | } |
395 | 395 | ||
396 | static int | ||
397 | xfs_attr_copy_value( | ||
398 | struct xfs_da_args *args, | ||
399 | unsigned char *value, | ||
400 | int valuelen) | ||
401 | { | ||
402 | /* | ||
403 | * No copy if all we have to do is get the length | ||
404 | */ | ||
405 | if (args->flags & ATTR_KERNOVAL) { | ||
406 | args->valuelen = valuelen; | ||
407 | return 0; | ||
408 | } | ||
409 | |||
410 | /* | ||
411 | * No copy if the length of the existing buffer is too small | ||
412 | */ | ||
413 | if (args->valuelen < valuelen) { | ||
414 | args->valuelen = valuelen; | ||
415 | return -ERANGE; | ||
416 | } | ||
417 | args->valuelen = valuelen; | ||
418 | |||
419 | /* remote block xattr requires IO for copy-in */ | ||
420 | if (args->rmtblkno) | ||
421 | return xfs_attr_rmtval_get(args); | ||
422 | |||
423 | /* | ||
424 | * This is to prevent a GCC warning because the remote xattr case | ||
425 | * doesn't have a value to pass in. In that case, we never reach here, | ||
426 | * but GCC can't work that out and so throws a "passing NULL to | ||
427 | * memcpy" warning. | ||
428 | */ | ||
429 | if (!value) | ||
430 | return -EINVAL; | ||
431 | memcpy(args->value, value, valuelen); | ||
432 | return 0; | ||
433 | } | ||
396 | 434 | ||
397 | /*======================================================================== | 435 | /*======================================================================== |
398 | * External routines when attribute fork size < XFS_LITINO(mp). | 436 | * External routines when attribute fork size < XFS_LITINO(mp). |
@@ -727,11 +765,12 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args) | |||
727 | * exist or we can't retrieve the value. | 765 | * exist or we can't retrieve the value. |
728 | */ | 766 | */ |
729 | int | 767 | int |
730 | xfs_attr_shortform_getvalue(xfs_da_args_t *args) | 768 | xfs_attr_shortform_getvalue( |
769 | struct xfs_da_args *args) | ||
731 | { | 770 | { |
732 | xfs_attr_shortform_t *sf; | 771 | struct xfs_attr_shortform *sf; |
733 | xfs_attr_sf_entry_t *sfe; | 772 | struct xfs_attr_sf_entry *sfe; |
734 | int i; | 773 | int i; |
735 | 774 | ||
736 | ASSERT(args->dp->i_afp->if_flags == XFS_IFINLINE); | 775 | ASSERT(args->dp->i_afp->if_flags == XFS_IFINLINE); |
737 | sf = (xfs_attr_shortform_t *)args->dp->i_afp->if_u1.if_data; | 776 | 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) | |||
744 | continue; | 783 | continue; |
745 | if (!xfs_attr_namesp_match(args->flags, sfe->flags)) | 784 | if (!xfs_attr_namesp_match(args->flags, sfe->flags)) |
746 | continue; | 785 | continue; |
747 | if (args->flags & ATTR_KERNOVAL) { | 786 | return xfs_attr_copy_value(args, &sfe->nameval[args->namelen], |
748 | args->valuelen = sfe->valuelen; | 787 | sfe->valuelen); |
749 | return 0; | ||
750 | } | ||
751 | if (args->valuelen < sfe->valuelen) { | ||
752 | args->valuelen = sfe->valuelen; | ||
753 | return -ERANGE; | ||
754 | } | ||
755 | args->valuelen = sfe->valuelen; | ||
756 | memcpy(args->value, &sfe->nameval[args->namelen], | ||
757 | args->valuelen); | ||
758 | return 0; | ||
759 | } | 788 | } |
760 | return -ENOATTR; | 789 | return -ENOATTR; |
761 | } | 790 | } |
@@ -2368,7 +2397,6 @@ xfs_attr3_leaf_getvalue( | |||
2368 | struct xfs_attr_leaf_entry *entry; | 2397 | struct xfs_attr_leaf_entry *entry; |
2369 | struct xfs_attr_leaf_name_local *name_loc; | 2398 | struct xfs_attr_leaf_name_local *name_loc; |
2370 | struct xfs_attr_leaf_name_remote *name_rmt; | 2399 | struct xfs_attr_leaf_name_remote *name_rmt; |
2371 | int valuelen; | ||
2372 | 2400 | ||
2373 | leaf = bp->b_addr; | 2401 | leaf = bp->b_addr; |
2374 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); | 2402 | xfs_attr3_leaf_hdr_from_disk(args->geo, &ichdr, leaf); |
@@ -2380,18 +2408,9 @@ xfs_attr3_leaf_getvalue( | |||
2380 | name_loc = xfs_attr3_leaf_name_local(leaf, args->index); | 2408 | name_loc = xfs_attr3_leaf_name_local(leaf, args->index); |
2381 | ASSERT(name_loc->namelen == args->namelen); | 2409 | ASSERT(name_loc->namelen == args->namelen); |
2382 | ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0); | 2410 | ASSERT(memcmp(args->name, name_loc->nameval, args->namelen) == 0); |
2383 | valuelen = be16_to_cpu(name_loc->valuelen); | 2411 | return xfs_attr_copy_value(args, |
2384 | if (args->flags & ATTR_KERNOVAL) { | 2412 | &name_loc->nameval[args->namelen], |
2385 | args->valuelen = valuelen; | 2413 | be16_to_cpu(name_loc->valuelen)); |
2386 | return 0; | ||
2387 | } | ||
2388 | if (args->valuelen < valuelen) { | ||
2389 | args->valuelen = valuelen; | ||
2390 | return -ERANGE; | ||
2391 | } | ||
2392 | args->valuelen = valuelen; | ||
2393 | memcpy(args->value, &name_loc->nameval[args->namelen], valuelen); | ||
2394 | return 0; | ||
2395 | } | 2414 | } |
2396 | 2415 | ||
2397 | name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); | 2416 | name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); |
@@ -2401,16 +2420,7 @@ xfs_attr3_leaf_getvalue( | |||
2401 | args->rmtblkno = be32_to_cpu(name_rmt->valueblk); | 2420 | args->rmtblkno = be32_to_cpu(name_rmt->valueblk); |
2402 | args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount, | 2421 | args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount, |
2403 | args->rmtvaluelen); | 2422 | args->rmtvaluelen); |
2404 | if (args->flags & ATTR_KERNOVAL) { | 2423 | return xfs_attr_copy_value(args, NULL, args->rmtvaluelen); |
2405 | args->valuelen = args->rmtvaluelen; | ||
2406 | return 0; | ||
2407 | } | ||
2408 | if (args->valuelen < args->rmtvaluelen) { | ||
2409 | args->valuelen = args->rmtvaluelen; | ||
2410 | return -ERANGE; | ||
2411 | } | ||
2412 | args->valuelen = args->rmtvaluelen; | ||
2413 | return xfs_attr_rmtval_get(args); | ||
2414 | } | 2424 | } |
2415 | 2425 | ||
2416 | /*======================================================================== | 2426 | /*======================================================================== |