Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9df243a1 authored by Dave Chinner's avatar Dave Chinner Committed by Darrick J. Wong
Browse files

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: default avatarDave Chinner <dchinner@redhat.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent e3cc4554
Loading
Loading
Loading
Loading
+49 −39
Original line number Diff line number Diff line
@@ -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,10 +765,11 @@ 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;
	struct xfs_attr_shortform *sf;
	struct xfs_attr_sf_entry *sfe;
	int			i;

	ASSERT(args->dp->i_afp->if_flags == XFS_IFINLINE);
@@ -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);
}

/*========================================================================