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

Commit a7792aad authored by Dave Chinner's avatar Dave Chinner
Browse files

Merge branch 'xfs-4.7-cleanup-attr-listent' into for-next

parents 5b911354 3ab3ffca
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -112,8 +112,9 @@ typedef struct attrlist_cursor_kern {
 *========================================================================*/


/* Return 0 on success, or -errno; other state communicated via *context */
typedef int (*put_listent_func_t)(struct xfs_attr_list_context *, int,
			      unsigned char *, int, int, unsigned char *);
			      unsigned char *, int, int);

typedef struct xfs_attr_list_context {
	struct xfs_inode		*dp;		/* inode */
@@ -126,7 +127,6 @@ typedef struct xfs_attr_list_context {
	int				firstu;		/* first used byte in buffer */
	int				flags;		/* from VOP call */
	int				resynch;	/* T/F: resynch with cursor */
	int				put_value;	/* T/F: need value for listent */
	put_listent_func_t		put_listent;	/* list output fmt function */
	int				index;		/* index into output buffer */
} xfs_attr_list_context_t;
+26 −59
Original line number Diff line number Diff line
@@ -106,18 +106,15 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
					   sfe->flags,
					   sfe->nameval,
					   (int)sfe->namelen,
					   (int)sfe->valuelen,
					   &sfe->nameval[sfe->namelen]);

					   (int)sfe->valuelen);
			if (error)
				return error;
			/*
			 * Either search callback finished early or
			 * didn't fit it all in the buffer after all.
			 */
			if (context->seen_enough)
				break;

			if (error)
				return error;
			sfe = XFS_ATTR_SF_NEXTENTRY(sfe);
		}
		trace_xfs_attr_list_sf_all(context);
@@ -200,8 +197,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context)
					sbp->flags,
					sbp->name,
					sbp->namelen,
					sbp->valuelen,
					&sbp->name[sbp->namelen]);
					sbp->valuelen);
		if (error) {
			kmem_free(sbuf);
			return error;
@@ -416,6 +412,9 @@ xfs_attr3_leaf_list_int(
	 */
	retval = 0;
	for (; i < ichdr.count; entry++, i++) {
		char *name;
		int namelen, valuelen;

		if (be32_to_cpu(entry->hashval) != cursor->hashval) {
			cursor->hashval = be32_to_cpu(entry->hashval);
			cursor->offset = 0;
@@ -425,56 +424,25 @@ xfs_attr3_leaf_list_int(
			continue;		/* skip incomplete entries */

		if (entry->flags & XFS_ATTR_LOCAL) {
			xfs_attr_leaf_name_local_t *name_loc =
				xfs_attr3_leaf_name_local(leaf, i);

			retval = context->put_listent(context,
						entry->flags,
						name_loc->nameval,
						(int)name_loc->namelen,
						be16_to_cpu(name_loc->valuelen),
						&name_loc->nameval[name_loc->namelen]);
			if (retval)
				return retval;
		} else {
			xfs_attr_leaf_name_remote_t *name_rmt =
				xfs_attr3_leaf_name_remote(leaf, i);

			int valuelen = be32_to_cpu(name_rmt->valuelen);

			if (context->put_value) {
				xfs_da_args_t args;

				memset((char *)&args, 0, sizeof(args));
				args.geo = context->dp->i_mount->m_attr_geo;
				args.dp = context->dp;
				args.whichfork = XFS_ATTR_FORK;
				args.valuelen = valuelen;
				args.rmtvaluelen = valuelen;
				args.value = kmem_alloc(valuelen, KM_SLEEP | KM_NOFS);
				args.rmtblkno = be32_to_cpu(name_rmt->valueblk);
				args.rmtblkcnt = xfs_attr3_rmt_blocks(
							args.dp->i_mount, valuelen);
				retval = xfs_attr_rmtval_get(&args);
				if (!retval)
					retval = context->put_listent(context,
							entry->flags,
							name_rmt->name,
							(int)name_rmt->namelen,
							valuelen,
							args.value);
				kmem_free(args.value);
			xfs_attr_leaf_name_local_t *name_loc;

			name_loc = xfs_attr3_leaf_name_local(leaf, i);
			name = name_loc->nameval;
			namelen = name_loc->namelen;
			valuelen = be16_to_cpu(name_loc->valuelen);
		} else {
				retval = context->put_listent(context,
						entry->flags,
						name_rmt->name,
						(int)name_rmt->namelen,
						valuelen,
						NULL);
			xfs_attr_leaf_name_remote_t *name_rmt;

			name_rmt = xfs_attr3_leaf_name_remote(leaf, i);
			name = name_rmt->name;
			namelen = name_rmt->namelen;
			valuelen = be32_to_cpu(name_rmt->valuelen);
		}

		retval = context->put_listent(context, entry->flags,
					      name, namelen, valuelen);
		if (retval)
				return retval;
		}
			break;
		if (context->seen_enough)
			break;
		cursor->offset++;
@@ -551,8 +519,7 @@ xfs_attr_put_listent(
	int		flags,
	unsigned char	*name,
	int		namelen,
	int		valuelen,
	unsigned char	*value)
	int		valuelen)
{
	struct attrlist *alist = (struct attrlist *)context->alist;
	attrlist_ent_t *aep;
@@ -581,7 +548,7 @@ xfs_attr_put_listent(
		trace_xfs_attr_list_full(context);
		alist->al_more = 1;
		context->seen_enough = 1;
		return 1;
		return 0;
	}

	aep = (attrlist_ent_t *)&context->alist[context->firstu];
+11 −6
Original line number Diff line number Diff line
@@ -146,7 +146,7 @@ __xfs_xattr_put_listent(
	arraytop = context->count + prefix_len + namelen + 1;
	if (arraytop > context->firstu) {
		context->count = -1;	/* insufficient space */
		return 1;
		return 0;
	}
	offset = (char *)context->alist + context->count;
	strncpy(offset, prefix, prefix_len);
@@ -166,8 +166,7 @@ xfs_xattr_put_listent(
	int		flags,
	unsigned char	*name,
	int		namelen,
	int		valuelen,
	unsigned char	*value)
	int		valuelen)
{
	char *prefix;
	int prefix_len;
@@ -221,11 +220,15 @@ xfs_xattr_put_listent(
}

ssize_t
xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size)
xfs_vn_listxattr(
	struct dentry	*dentry,
	char		*data,
	size_t		size)
{
	struct xfs_attr_list_context context;
	struct attrlist_cursor_kern cursor = { 0 };
	struct inode	*inode = d_inode(dentry);
	int		error;

	/*
	 * First read the regular on-disk attributes.
@@ -239,7 +242,9 @@ xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size)
	context.firstu = context.bufsize;
	context.put_listent = xfs_xattr_put_listent;

	xfs_attr_list_int(&context);
	error = xfs_attr_list_int(&context);
	if (error)
		return error;
	if (context.count < 0)
		return -ERANGE;