]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: consolidate attribute value copying
authorDave Chinner <dchinner@redhat.com>
Fri, 13 Dec 2019 00:54:33 +0000 (19:54 -0500)
committerEric Sandeen <sandeen@redhat.com>
Fri, 13 Dec 2019 00:54:33 +0000 (19:54 -0500)
Source kernel commit: 9df243a1a9e607e7cf5d20ee46edd5ec84b7e400

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>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/xfs_attr_leaf.c

index ab6d053de74e7d32f90994945d879a4f29f8095a..0ed2478a31bc17cd8d11c8c1221c0cbf5d981820 100644 (file)
@@ -389,6 +389,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).
@@ -723,11 +761,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;
@@ -740,18 +779,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;
 }
@@ -2364,7 +2393,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);
@@ -2376,18 +2404,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);
@@ -2397,16 +2416,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);
 }
 
 /*========================================================================