Linux-XFS Archive on lore.kernel.org
 help / color / Atom feed
* clean up the attr interface v3
@ 2020-01-29 17:02 Christoph Hellwig
  2020-01-29 17:02 ` [PATCH 01/30] xfs: reject invalid flags combinations in XFS_IOC_ATTRLIST_BY_HANDLE Christoph Hellwig
                   ` (29 more replies)
  0 siblings, 30 replies; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins

xfsprogs patches porting over the libxfs changes are available here:

    http://git.infradead.org/users/hch/xfsprogs.git/shortlog/refs/heads/attr-cleanup

Changes since v2:
 - add more comments
 - fix up an error handling corner case in __xfs_set_acl
 - add more cowbell^H^H^H^H^H^H^Hbool
 - add a new patch to reject invalid namespaces flags in
   XFS_IOC_ATTRLIST_BY_HANDLE
 - remove ATTR_ENTSIZE entirely

Changes since v1:
 - rebased to for-next, which includes the fixes from the first
   version

^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 01/30] xfs: reject invalid flags combinations in XFS_IOC_ATTRLIST_BY_HANDLE
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-02-05 13:46   ` Chandan Rajendra
  2020-01-29 17:02 ` [PATCH 02/30] xfs: remove the ATTR_INCOMPLETE flag Christoph Hellwig
                   ` (28 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins

While the flags field in the ABI and the on-disk format allows for
multiple namespace flags, that is a logically invalid combination and
listing multiple namespace flags will return no results as no attr
can have both set.  Reject this case early with -EINVAL.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_ioctl.c   | 2 ++
 fs/xfs/xfs_ioctl32.c | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index d42de92cb283..d974bf099d45 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -317,6 +317,8 @@ xfs_attrlist_by_handle(
 	 */
 	if (al_hreq.flags & ~(ATTR_ROOT | ATTR_SECURE))
 		return -EINVAL;
+	if (al_hreq.flags == (ATTR_ROOT | ATTR_SECURE))
+		return -EINVAL;
 
 	dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
 	if (IS_ERR(dentry))
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index 769581a79c58..9705172e5410 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -375,6 +375,8 @@ xfs_compat_attrlist_by_handle(
 	 */
 	if (al_hreq.flags & ~(ATTR_ROOT | ATTR_SECURE))
 		return -EINVAL;
+	if (al_hreq.flags == (ATTR_ROOT | ATTR_SECURE))
+		return -EINVAL;
 
 	dentry = xfs_compat_handlereq_to_dentry(parfilp, &al_hreq.hreq);
 	if (IS_ERR(dentry))
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 02/30] xfs: remove the ATTR_INCOMPLETE flag
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
  2020-01-29 17:02 ` [PATCH 01/30] xfs: reject invalid flags combinations in XFS_IOC_ATTRLIST_BY_HANDLE Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-01-29 17:02 ` [PATCH 03/30] xfs: merge xfs_attr_remove into xfs_attr_set Christoph Hellwig
                   ` (27 subsequent siblings)
  29 siblings, 0 replies; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

Replace the ATTR_INCOMPLETE flag with a new boolean field in struct
xfs_attr_list_context.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_attr.h | 5 ++---
 fs/xfs/scrub/attr.c      | 2 +-
 fs/xfs/xfs_attr_list.c   | 6 +-----
 3 files changed, 4 insertions(+), 9 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index 4243b2272642..71bcf1298e4c 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -36,11 +36,10 @@ struct xfs_attr_list_context;
 #define ATTR_KERNOTIME	0x1000	/* [kernel] don't update inode timestamps */
 #define ATTR_KERNOVAL	0x2000	/* [kernel] get attr size only, not value */
 
-#define ATTR_INCOMPLETE	0x4000	/* [kernel] return INCOMPLETE attr keys */
 #define ATTR_ALLOC	0x8000	/* [kernel] allocate xattr buffer on demand */
 
 #define ATTR_KERNEL_FLAGS \
-	(ATTR_KERNOTIME | ATTR_KERNOVAL | ATTR_INCOMPLETE | ATTR_ALLOC)
+	(ATTR_KERNOTIME | ATTR_KERNOVAL | ATTR_ALLOC)
 
 #define XFS_ATTR_FLAGS \
 	{ ATTR_DONTFOLLOW, 	"DONTFOLLOW" }, \
@@ -51,7 +50,6 @@ struct xfs_attr_list_context;
 	{ ATTR_REPLACE,		"REPLACE" }, \
 	{ ATTR_KERNOTIME,	"KERNOTIME" }, \
 	{ ATTR_KERNOVAL,	"KERNOVAL" }, \
-	{ ATTR_INCOMPLETE,	"INCOMPLETE" }, \
 	{ ATTR_ALLOC,		"ALLOC" }
 
 /*
@@ -123,6 +121,7 @@ typedef struct xfs_attr_list_context {
 	 * error values to the xfs_attr_list caller.
 	 */
 	int				seen_enough;
+	bool				allow_incomplete;
 
 	ssize_t				count;		/* num used entries */
 	int				dupcnt;		/* count dup hashvals seen */
diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
index d9f0dd444b80..d804558cdbca 100644
--- a/fs/xfs/scrub/attr.c
+++ b/fs/xfs/scrub/attr.c
@@ -497,7 +497,7 @@ xchk_xattr(
 	sx.context.resynch = 1;
 	sx.context.put_listent = xchk_xattr_listent;
 	sx.context.tp = sc->tp;
-	sx.context.flags = ATTR_INCOMPLETE;
+	sx.context.allow_incomplete = true;
 	sx.sc = sc;
 
 	/*
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index d37743bdf274..5139ef983cd6 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -452,7 +452,7 @@ xfs_attr3_leaf_list_int(
 		}
 
 		if ((entry->flags & XFS_ATTR_INCOMPLETE) &&
-		    !(context->flags & ATTR_INCOMPLETE))
+		    !context->allow_incomplete)
 			continue;		/* skip incomplete entries */
 
 		if (entry->flags & XFS_ATTR_LOCAL) {
@@ -632,10 +632,6 @@ xfs_attr_list(
 	    (cursor->hashval || cursor->blkno || cursor->offset))
 		return -EINVAL;
 
-	/* Only internal consumers can retrieve incomplete attrs. */
-	if (flags & ATTR_INCOMPLETE)
-		return -EINVAL;
-
 	/*
 	 * Check for a properly aligned buffer.
 	 */
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 03/30] xfs: merge xfs_attr_remove into xfs_attr_set
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
  2020-01-29 17:02 ` [PATCH 01/30] xfs: reject invalid flags combinations in XFS_IOC_ATTRLIST_BY_HANDLE Christoph Hellwig
  2020-01-29 17:02 ` [PATCH 02/30] xfs: remove the ATTR_INCOMPLETE flag Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-02-06  8:00   ` Chandan Rajendra
  2020-01-29 17:02 ` [PATCH 04/30] xfs: merge xfs_attrmulti_attr_remove into xfs_attrmulti_attr_set Christoph Hellwig
                   ` (26 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins

The Linux xattr and acl APIs use a single call for set an remove.  Modify
the high-level XFS API to match that and let xfs_attr_set handle removing
attributes as well.  With a little bit of reordering this removes a lot
of code.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_attr.c | 178 ++++++++++++++-------------------------
 fs/xfs/libxfs/xfs_attr.h |   2 -
 fs/xfs/xfs_acl.c         |  33 +++-----
 fs/xfs/xfs_ioctl.c       |   4 +-
 fs/xfs/xfs_xattr.c       |   9 +-
 5 files changed, 77 insertions(+), 149 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index e6149720ce02..bb391b96cd78 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -336,6 +336,10 @@ xfs_attr_remove_args(
 	return error;
 }
 
+/*
+ * Note: If value is NULL the attribute will be removed, just like the
+ * Linux ->setattr API.
+ */
 int
 xfs_attr_set(
 	struct xfs_inode	*dp,
@@ -350,149 +354,92 @@ xfs_attr_set(
 	struct xfs_trans_res	tres;
 	int			rsvd = (flags & ATTR_ROOT) != 0;
 	int			error, local;
-
-	XFS_STATS_INC(mp, xs_attr_set);
+	unsigned int		total;
 
 	if (XFS_FORCED_SHUTDOWN(dp->i_mount))
 		return -EIO;
 
-	error = xfs_attr_args_init(&args, dp, name, namelen, flags);
-	if (error)
-		return error;
-
-	args.value = value;
-	args.valuelen = valuelen;
-	args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT;
-	args.total = xfs_attr_calc_size(&args, &local);
-
 	error = xfs_qm_dqattach(dp);
 	if (error)
 		return error;
 
-	/*
-	 * If the inode doesn't have an attribute fork, add one.
-	 * (inode must not be locked when we call this routine)
-	 */
-	if (XFS_IFORK_Q(dp) == 0) {
-		int sf_size = sizeof(xfs_attr_sf_hdr_t) +
-			XFS_ATTR_SF_ENTSIZE_BYNAME(args.namelen, valuelen);
-
-		error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
-		if (error)
-			return error;
-	}
-
-	tres.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
-			 M_RES(mp)->tr_attrsetrt.tr_logres * args.total;
-	tres.tr_logcount = XFS_ATTRSET_LOG_COUNT;
-	tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
-
-	/*
-	 * Root fork attributes can use reserved data blocks for this
-	 * operation if necessary
-	 */
-	error = xfs_trans_alloc(mp, &tres, args.total, 0,
-			rsvd ? XFS_TRANS_RESERVE : 0, &args.trans);
+	error = xfs_attr_args_init(&args, dp, name, namelen, flags);
 	if (error)
 		return error;
 
-	xfs_ilock(dp, XFS_ILOCK_EXCL);
-	error = xfs_trans_reserve_quota_nblks(args.trans, dp, args.total, 0,
-				rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
-				       XFS_QMOPT_RES_REGBLKS);
-	if (error)
-		goto out_trans_cancel;
-
-	xfs_trans_ijoin(args.trans, dp, 0);
-	error = xfs_attr_set_args(&args);
-	if (error)
-		goto out_trans_cancel;
-	if (!args.trans) {
-		/* shortform attribute has already been committed */
-		goto out_unlock;
-	}
-
-	/*
-	 * If this is a synchronous mount, make sure that the
-	 * transaction goes to disk before returning to the user.
-	 */
-	if (mp->m_flags & XFS_MOUNT_WSYNC)
-		xfs_trans_set_sync(args.trans);
-
-	if ((flags & ATTR_KERNOTIME) == 0)
-		xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG);
+	args.value = value;
+	args.valuelen = valuelen;
 
 	/*
-	 * Commit the last in the sequence of transactions.
+	 * We have no control over the attribute names that userspace passes us
+	 * to remove, so we have to allow the name lookup prior to attribute
+	 * removal to fail as well.
 	 */
-	xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
-	error = xfs_trans_commit(args.trans);
-out_unlock:
-	xfs_iunlock(dp, XFS_ILOCK_EXCL);
-	return error;
-
-out_trans_cancel:
-	if (args.trans)
-		xfs_trans_cancel(args.trans);
-	goto out_unlock;
-}
+	args.op_flags = XFS_DA_OP_OKNOENT;
 
-/*
- * Generic handler routine to remove a name from an attribute list.
- * Transitions attribute list from Btree to shortform as necessary.
- */
-int
-xfs_attr_remove(
-	struct xfs_inode	*dp,
-	const unsigned char	*name,
-	size_t			namelen,
-	int			flags)
-{
-	struct xfs_mount	*mp = dp->i_mount;
-	struct xfs_da_args	args;
-	int			error;
+	if (value) {
+		XFS_STATS_INC(mp, xs_attr_set);
 
-	XFS_STATS_INC(mp, xs_attr_remove);
+		args.op_flags |= XFS_DA_OP_ADDNAME;
+		args.total = xfs_attr_calc_size(&args, &local);
 
-	if (XFS_FORCED_SHUTDOWN(dp->i_mount))
-		return -EIO;
+		/*
+		 * If the inode doesn't have an attribute fork, add one.
+		 * (inode must not be locked when we call this routine)
+		 */
+		if (XFS_IFORK_Q(dp) == 0) {
+			int sf_size = sizeof(struct xfs_attr_sf_hdr) +
+				XFS_ATTR_SF_ENTSIZE_BYNAME(args.namelen,
+						valuelen);
 
-	error = xfs_attr_args_init(&args, dp, name, namelen, flags);
-	if (error)
-		return error;
+			error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
+			if (error)
+				return error;
+		}
 
-	/*
-	 * we have no control over the attribute names that userspace passes us
-	 * to remove, so we have to allow the name lookup prior to attribute
-	 * removal to fail.
-	 */
-	args.op_flags = XFS_DA_OP_OKNOENT;
+		tres.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
+				 M_RES(mp)->tr_attrsetrt.tr_logres * args.total;
+		tres.tr_logcount = XFS_ATTRSET_LOG_COUNT;
+		tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
+		total = args.total;
+	} else {
+		XFS_STATS_INC(mp, xs_attr_remove);
 
-	error = xfs_qm_dqattach(dp);
-	if (error)
-		return error;
+		tres = M_RES(mp)->tr_attrrm;
+		total = XFS_ATTRRM_SPACE_RES(mp);
+	}
 
 	/*
 	 * Root fork attributes can use reserved data blocks for this
 	 * operation if necessary
 	 */
-	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_attrrm,
-			XFS_ATTRRM_SPACE_RES(mp), 0,
-			(flags & ATTR_ROOT) ? XFS_TRANS_RESERVE : 0,
-			&args.trans);
+	error = xfs_trans_alloc(mp, &tres, total, 0,
+			rsvd ? XFS_TRANS_RESERVE : 0, &args.trans);
 	if (error)
 		return error;
 
 	xfs_ilock(dp, XFS_ILOCK_EXCL);
-	/*
-	 * No need to make quota reservations here. We expect to release some
-	 * blocks not allocate in the common case.
-	 */
 	xfs_trans_ijoin(args.trans, dp, 0);
+	if (value) {
+		unsigned int	quota_flags = XFS_QMOPT_RES_REGBLKS;
 
-	error = xfs_attr_remove_args(&args);
-	if (error)
-		goto out;
+		if (rsvd)
+			quota_flags |= XFS_QMOPT_FORCE_RES;
+		error = xfs_trans_reserve_quota_nblks(args.trans, dp,
+				args.total, 0, quota_flags);
+		if (error)
+			goto out_trans_cancel;
+		error = xfs_attr_set_args(&args);
+		if (error)
+			goto out_trans_cancel;
+		/* shortform attribute has already been committed */
+		if (!args.trans)
+			goto out_unlock;
+	} else {
+		error = xfs_attr_remove_args(&args);
+		if (error)
+			goto out_trans_cancel;
+	}
 
 	/*
 	 * If this is a synchronous mount, make sure that the
@@ -509,15 +456,14 @@ xfs_attr_remove(
 	 */
 	xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
 	error = xfs_trans_commit(args.trans);
+out_unlock:
 	xfs_iunlock(dp, XFS_ILOCK_EXCL);
-
 	return error;
 
-out:
+out_trans_cancel:
 	if (args.trans)
 		xfs_trans_cancel(args.trans);
-	xfs_iunlock(dp, XFS_ILOCK_EXCL);
-	return error;
+	goto out_unlock;
 }
 
 /*========================================================================
diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index 71bcf1298e4c..db58a6c7dea5 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -152,8 +152,6 @@ int xfs_attr_get(struct xfs_inode *ip, const unsigned char *name,
 int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name,
 		 size_t namelen, unsigned char *value, int valuelen, int flags);
 int xfs_attr_set_args(struct xfs_da_args *args);
-int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name,
-		    size_t namelen, int flags);
 int xfs_attr_remove_args(struct xfs_da_args *args);
 int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
 		  int flags, struct attrlist_cursor_kern *cursor);
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index cd743fad8478..4e76063ff956 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -168,6 +168,8 @@ __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 {
 	struct xfs_inode *ip = XFS_I(inode);
 	unsigned char *ea_name;
+	struct xfs_acl *xfs_acl = NULL;
+	int len = 0;
 	int error;
 
 	switch (type) {
@@ -184,9 +186,7 @@ __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 	}
 
 	if (acl) {
-		struct xfs_acl *xfs_acl;
-		int len = XFS_ACL_MAX_SIZE(ip->i_mount);
-
+		len = XFS_ACL_MAX_SIZE(ip->i_mount);
 		xfs_acl = kmem_zalloc_large(len, 0);
 		if (!xfs_acl)
 			return -ENOMEM;
@@ -196,26 +196,17 @@ __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 		/* subtract away the unused acl entries */
 		len -= sizeof(struct xfs_acl_entry) *
 			 (XFS_ACL_MAX_ENTRIES(ip->i_mount) - acl->a_count);
-
-		error = xfs_attr_set(ip, ea_name, strlen(ea_name),
-				     (unsigned char *)xfs_acl, len, ATTR_ROOT);
-
-		kmem_free(xfs_acl);
-	} else {
-		/*
-		 * A NULL ACL argument means we want to remove the ACL.
-		 */
-		error = xfs_attr_remove(ip, ea_name,
-					strlen(ea_name),
-					ATTR_ROOT);
-
-		/*
-		 * If the attribute didn't exist to start with that's fine.
-		 */
-		if (error == -ENOATTR)
-			error = 0;
 	}
 
+	error = xfs_attr_set(ip, ea_name, strlen(ea_name),
+			(unsigned char *)xfs_acl, len, ATTR_ROOT);
+	kmem_free(xfs_acl);
+
+	/*
+	 * If the attribute didn't exist to start with that's fine.
+	 */
+	if (!acl && error == -ENOATTR)
+		error = 0;
 	if (!error)
 		set_cached_acl(inode, type, acl);
 	return error;
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index d974bf099d45..79c418888e9a 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -417,12 +417,10 @@ xfs_attrmulti_attr_remove(
 	uint32_t		flags)
 {
 	int			error;
-	size_t			namelen;
 
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 		return -EPERM;
-	namelen = strlen(name);
-	error = xfs_attr_remove(XFS_I(inode), name, namelen, flags);
+	error = xfs_attr_set(XFS_I(inode), name, strlen(name), NULL, 0, flags);
 	if (!error)
 		xfs_forget_acl(inode, name, flags);
 	return error;
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
index b0fedb543f97..1670bfbc9ad2 100644
--- a/fs/xfs/xfs_xattr.c
+++ b/fs/xfs/xfs_xattr.c
@@ -69,7 +69,6 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
 	int			xflags = handler->flags;
 	struct xfs_inode	*ip = XFS_I(inode);
 	int			error;
-	size_t			namelen = strlen(name);
 
 	/* Convert Linux syscall to XFS internal ATTR flags */
 	if (flags & XATTR_CREATE)
@@ -77,14 +76,10 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
 	if (flags & XATTR_REPLACE)
 		xflags |= ATTR_REPLACE;
 
-	if (value)
-		error = xfs_attr_set(ip, name, namelen, (void *)value, size,
-				xflags);
-	else
-		error = xfs_attr_remove(ip, name, namelen, xflags);
+	error = xfs_attr_set(ip, (unsigned char *)name, strlen(name),
+				(void *)value, size, xflags);
 	if (!error)
 		xfs_forget_acl(inode, name, xflags);
-
 	return error;
 }
 
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 04/30] xfs: merge xfs_attrmulti_attr_remove into xfs_attrmulti_attr_set
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (2 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 03/30] xfs: merge xfs_attr_remove into xfs_attr_set Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-02-06  9:21   ` Chandan Rajendra
  2020-01-29 17:02 ` [PATCH 05/30] xfs: use strndup_user in XFS_IOC_ATTRMULTI_BY_HANDLE Christoph Hellwig
                   ` (25 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

Merge the ioctl handlers just like the low-level xfs_attr_set function.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_ioctl.c   | 34 ++++++++++------------------------
 fs/xfs/xfs_ioctl.h   |  6 ------
 fs/xfs/xfs_ioctl32.c |  4 ++--
 3 files changed, 12 insertions(+), 32 deletions(-)

diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 79c418888e9a..b806003caacd 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -389,18 +389,20 @@ xfs_attrmulti_attr_set(
 	uint32_t		len,
 	uint32_t		flags)
 {
-	unsigned char		*kbuf;
+	unsigned char		*kbuf = NULL;
 	int			error;
 	size_t			namelen;
 
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 		return -EPERM;
-	if (len > XFS_XATTR_SIZE_MAX)
-		return -EINVAL;
 
-	kbuf = memdup_user(ubuf, len);
-	if (IS_ERR(kbuf))
-		return PTR_ERR(kbuf);
+	if (ubuf) {
+		if (len > XFS_XATTR_SIZE_MAX)
+			return -EINVAL;
+		kbuf = memdup_user(ubuf, len);
+		if (IS_ERR(kbuf))
+			return PTR_ERR(kbuf);
+	}
 
 	namelen = strlen(name);
 	error = xfs_attr_set(XFS_I(inode), name, namelen, kbuf, len, flags);
@@ -410,22 +412,6 @@ xfs_attrmulti_attr_set(
 	return error;
 }
 
-int
-xfs_attrmulti_attr_remove(
-	struct inode		*inode,
-	unsigned char		*name,
-	uint32_t		flags)
-{
-	int			error;
-
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-		return -EPERM;
-	error = xfs_attr_set(XFS_I(inode), name, strlen(name), NULL, 0, flags);
-	if (!error)
-		xfs_forget_acl(inode, name, flags);
-	return error;
-}
-
 STATIC int
 xfs_attrmulti_by_handle(
 	struct file		*parfilp,
@@ -504,8 +490,8 @@ xfs_attrmulti_by_handle(
 			ops[i].am_error = mnt_want_write_file(parfilp);
 			if (ops[i].am_error)
 				break;
-			ops[i].am_error = xfs_attrmulti_attr_remove(
-					d_inode(dentry), attr_name,
+			ops[i].am_error = xfs_attrmulti_attr_set(
+					d_inode(dentry), attr_name, NULL, 0,
 					ops[i].am_flags);
 			mnt_drop_write_file(parfilp);
 			break;
diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
index 420bd95dc326..819504df00ae 100644
--- a/fs/xfs/xfs_ioctl.h
+++ b/fs/xfs/xfs_ioctl.h
@@ -46,12 +46,6 @@ xfs_attrmulti_attr_set(
 	uint32_t		len,
 	uint32_t		flags);
 
-extern int
-xfs_attrmulti_attr_remove(
-	struct inode		*inode,
-	unsigned char		*name,
-	uint32_t		flags);
-
 extern struct dentry *
 xfs_handle_to_dentry(
 	struct file		*parfilp,
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index 9705172e5410..e085f304e539 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -488,8 +488,8 @@ xfs_compat_attrmulti_by_handle(
 			ops[i].am_error = mnt_want_write_file(parfilp);
 			if (ops[i].am_error)
 				break;
-			ops[i].am_error = xfs_attrmulti_attr_remove(
-					d_inode(dentry), attr_name,
+			ops[i].am_error = xfs_attrmulti_attr_set(
+					d_inode(dentry), attr_name, NULL, 0,
 					ops[i].am_flags);
 			mnt_drop_write_file(parfilp);
 			break;
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 05/30] xfs: use strndup_user in XFS_IOC_ATTRMULTI_BY_HANDLE
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (3 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 04/30] xfs: merge xfs_attrmulti_attr_remove into xfs_attrmulti_attr_set Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-02-06 10:33   ` Chandan Rajendra
  2020-01-29 17:02 ` [PATCH 06/30] xfs: factor out a helper for a single XFS_IOC_ATTRMULTI_BY_HANDLE op Christoph Hellwig
                   ` (24 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

Simplify the user copy code by using strndup_user.  This means that we
now do one memory allocation per operation instead of one per ioctl,
but memory allocations are cheap compared to the actual file system
operations.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_ioctl.c   | 17 +++++------------
 fs/xfs/xfs_ioctl32.c | 17 +++++------------
 2 files changed, 10 insertions(+), 24 deletions(-)

diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index b806003caacd..bb490a954c0b 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -448,11 +448,6 @@ xfs_attrmulti_by_handle(
 		goto out_dput;
 	}
 
-	error = -ENOMEM;
-	attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL);
-	if (!attr_name)
-		goto out_kfree_ops;
-
 	error = 0;
 	for (i = 0; i < am_hreq.opcount; i++) {
 		if ((ops[i].am_flags & ATTR_ROOT) &&
@@ -462,12 +457,11 @@ xfs_attrmulti_by_handle(
 		}
 		ops[i].am_flags &= ~ATTR_KERNEL_FLAGS;
 
-		ops[i].am_error = strncpy_from_user((char *)attr_name,
-				ops[i].am_attrname, MAXNAMELEN);
-		if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN)
-			error = -ERANGE;
-		if (ops[i].am_error < 0)
+		attr_name = strndup_user(ops[i].am_attrname, MAXNAMELEN);
+		if (IS_ERR(attr_name)) {
+			ops[i].am_error = PTR_ERR(attr_name);
 			break;
+		}
 
 		switch (ops[i].am_opcode) {
 		case ATTR_OP_GET:
@@ -498,13 +492,12 @@ xfs_attrmulti_by_handle(
 		default:
 			ops[i].am_error = -EINVAL;
 		}
+		kfree(attr_name);
 	}
 
 	if (copy_to_user(am_hreq.ops, ops, size))
 		error = -EFAULT;
 
-	kfree(attr_name);
- out_kfree_ops:
 	kfree(ops);
  out_dput:
 	dput(dentry);
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index e085f304e539..936c2f62fb6c 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -445,11 +445,6 @@ xfs_compat_attrmulti_by_handle(
 		goto out_dput;
 	}
 
-	error = -ENOMEM;
-	attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL);
-	if (!attr_name)
-		goto out_kfree_ops;
-
 	error = 0;
 	for (i = 0; i < am_hreq.opcount; i++) {
 		if ((ops[i].am_flags & ATTR_ROOT) &&
@@ -459,13 +454,12 @@ xfs_compat_attrmulti_by_handle(
 		}
 		ops[i].am_flags &= ~ATTR_KERNEL_FLAGS;
 
-		ops[i].am_error = strncpy_from_user((char *)attr_name,
-				compat_ptr(ops[i].am_attrname),
+		attr_name = strndup_user(compat_ptr(ops[i].am_attrname),
 				MAXNAMELEN);
-		if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN)
-			error = -ERANGE;
-		if (ops[i].am_error < 0)
+		if (IS_ERR(attr_name)) {
+			ops[i].am_error = PTR_ERR(attr_name);
 			break;
+		}
 
 		switch (ops[i].am_opcode) {
 		case ATTR_OP_GET:
@@ -496,13 +490,12 @@ xfs_compat_attrmulti_by_handle(
 		default:
 			ops[i].am_error = -EINVAL;
 		}
+		kfree(attr_name);
 	}
 
 	if (copy_to_user(compat_ptr(am_hreq.ops), ops, size))
 		error = -EFAULT;
 
-	kfree(attr_name);
- out_kfree_ops:
 	kfree(ops);
  out_dput:
 	dput(dentry);
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 06/30] xfs: factor out a helper for a single XFS_IOC_ATTRMULTI_BY_HANDLE op
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (4 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 05/30] xfs: use strndup_user in XFS_IOC_ATTRMULTI_BY_HANDLE Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-02-07  5:20   ` Chandan Rajendra
  2020-01-29 17:02 ` [PATCH 07/30] xfs: remove the name == NULL check from xfs_attr_args_init Christoph Hellwig
                   ` (23 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins

Add a new helper to handle a single attr multi ioctl operation that
can be shared between the native and compat ioctl implementation.

There is a slight change in heavior in that we don't break out of the
loop when copying in the attribute name fails.  The previous behavior
was rather inconsistent here as it continued for any other kind of
error.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_ioctl.c   | 97 +++++++++++++++++++++++---------------------
 fs/xfs/xfs_ioctl.h   | 18 ++------
 fs/xfs/xfs_ioctl32.c | 50 +++--------------------
 3 files changed, 59 insertions(+), 106 deletions(-)

diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index bb490a954c0b..cfdd80b4ea2d 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -349,7 +349,7 @@ xfs_attrlist_by_handle(
 	return error;
 }
 
-int
+static int
 xfs_attrmulti_attr_get(
 	struct inode		*inode,
 	unsigned char		*name,
@@ -381,7 +381,7 @@ xfs_attrmulti_attr_get(
 	return error;
 }
 
-int
+static int
 xfs_attrmulti_attr_set(
 	struct inode		*inode,
 	unsigned char		*name,
@@ -412,6 +412,51 @@ xfs_attrmulti_attr_set(
 	return error;
 }
 
+int
+xfs_ioc_attrmulti_one(
+	struct file		*parfilp,
+	struct inode		*inode,
+	uint32_t		opcode,
+	void __user		*uname,
+	void __user		*value,
+	uint32_t		*len,
+	uint32_t		flags)
+{
+	unsigned char		*name;
+	int			error;
+
+	if ((flags & ATTR_ROOT) && (flags & ATTR_SECURE))
+		return -EINVAL;
+	flags &= ~ATTR_KERNEL_FLAGS;
+
+	name = strndup_user(uname, MAXNAMELEN);
+	if (IS_ERR(name))
+		return PTR_ERR(name);
+
+	switch (opcode) {
+	case ATTR_OP_GET:
+		error = xfs_attrmulti_attr_get(inode, name, value, len, flags);
+		break;
+	case ATTR_OP_REMOVE:
+		value = NULL;
+		*len = 0;
+		/*FALLTHRU*/
+	case ATTR_OP_SET:
+		error = mnt_want_write_file(parfilp);
+		if (error)
+			break;
+		error = xfs_attrmulti_attr_set(inode, name, value, *len, flags);
+		mnt_drop_write_file(parfilp);
+		break;
+	default:
+		error = -EINVAL;
+		break;
+	}
+
+	kfree(name);
+	return error;
+}
+
 STATIC int
 xfs_attrmulti_by_handle(
 	struct file		*parfilp,
@@ -422,7 +467,6 @@ xfs_attrmulti_by_handle(
 	xfs_fsop_attrmulti_handlereq_t am_hreq;
 	struct dentry		*dentry;
 	unsigned int		i, size;
-	unsigned char		*attr_name;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
@@ -450,49 +494,10 @@ xfs_attrmulti_by_handle(
 
 	error = 0;
 	for (i = 0; i < am_hreq.opcount; i++) {
-		if ((ops[i].am_flags & ATTR_ROOT) &&
-		    (ops[i].am_flags & ATTR_SECURE)) {
-			ops[i].am_error = -EINVAL;
-			continue;
-		}
-		ops[i].am_flags &= ~ATTR_KERNEL_FLAGS;
-
-		attr_name = strndup_user(ops[i].am_attrname, MAXNAMELEN);
-		if (IS_ERR(attr_name)) {
-			ops[i].am_error = PTR_ERR(attr_name);
-			break;
-		}
-
-		switch (ops[i].am_opcode) {
-		case ATTR_OP_GET:
-			ops[i].am_error = xfs_attrmulti_attr_get(
-					d_inode(dentry), attr_name,
-					ops[i].am_attrvalue, &ops[i].am_length,
-					ops[i].am_flags);
-			break;
-		case ATTR_OP_SET:
-			ops[i].am_error = mnt_want_write_file(parfilp);
-			if (ops[i].am_error)
-				break;
-			ops[i].am_error = xfs_attrmulti_attr_set(
-					d_inode(dentry), attr_name,
-					ops[i].am_attrvalue, ops[i].am_length,
-					ops[i].am_flags);
-			mnt_drop_write_file(parfilp);
-			break;
-		case ATTR_OP_REMOVE:
-			ops[i].am_error = mnt_want_write_file(parfilp);
-			if (ops[i].am_error)
-				break;
-			ops[i].am_error = xfs_attrmulti_attr_set(
-					d_inode(dentry), attr_name, NULL, 0,
-					ops[i].am_flags);
-			mnt_drop_write_file(parfilp);
-			break;
-		default:
-			ops[i].am_error = -EINVAL;
-		}
-		kfree(attr_name);
+		ops[i].am_error = xfs_ioc_attrmulti_one(parfilp,
+				d_inode(dentry), ops[i].am_opcode,
+				ops[i].am_attrname, ops[i].am_attrvalue,
+				&ops[i].am_length, ops[i].am_flags);
 	}
 
 	if (copy_to_user(am_hreq.ops, ops, size))
diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
index 819504df00ae..bb50cb3dc61f 100644
--- a/fs/xfs/xfs_ioctl.h
+++ b/fs/xfs/xfs_ioctl.h
@@ -30,21 +30,9 @@ xfs_readlink_by_handle(
 	struct file		*parfilp,
 	xfs_fsop_handlereq_t	*hreq);
 
-extern int
-xfs_attrmulti_attr_get(
-	struct inode		*inode,
-	unsigned char		*name,
-	unsigned char		__user *ubuf,
-	uint32_t		*len,
-	uint32_t		flags);
-
-extern int
-xfs_attrmulti_attr_set(
-	struct inode		*inode,
-	unsigned char		*name,
-	const unsigned char	__user *ubuf,
-	uint32_t		len,
-	uint32_t		flags);
+int xfs_ioc_attrmulti_one(struct file *parfilp, struct inode *inode,
+		uint32_t opcode, void __user *uname, void __user *value,
+		uint32_t *len, uint32_t flags);
 
 extern struct dentry *
 xfs_handle_to_dentry(
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index 936c2f62fb6c..e1daf095c585 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -418,7 +418,6 @@ xfs_compat_attrmulti_by_handle(
 	compat_xfs_fsop_attrmulti_handlereq_t	am_hreq;
 	struct dentry				*dentry;
 	unsigned int				i, size;
-	unsigned char				*attr_name;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
@@ -447,50 +446,11 @@ xfs_compat_attrmulti_by_handle(
 
 	error = 0;
 	for (i = 0; i < am_hreq.opcount; i++) {
-		if ((ops[i].am_flags & ATTR_ROOT) &&
-		    (ops[i].am_flags & ATTR_SECURE)) {
-			ops[i].am_error = -EINVAL;
-			continue;
-		}
-		ops[i].am_flags &= ~ATTR_KERNEL_FLAGS;
-
-		attr_name = strndup_user(compat_ptr(ops[i].am_attrname),
-				MAXNAMELEN);
-		if (IS_ERR(attr_name)) {
-			ops[i].am_error = PTR_ERR(attr_name);
-			break;
-		}
-
-		switch (ops[i].am_opcode) {
-		case ATTR_OP_GET:
-			ops[i].am_error = xfs_attrmulti_attr_get(
-					d_inode(dentry), attr_name,
-					compat_ptr(ops[i].am_attrvalue),
-					&ops[i].am_length, ops[i].am_flags);
-			break;
-		case ATTR_OP_SET:
-			ops[i].am_error = mnt_want_write_file(parfilp);
-			if (ops[i].am_error)
-				break;
-			ops[i].am_error = xfs_attrmulti_attr_set(
-					d_inode(dentry), attr_name,
-					compat_ptr(ops[i].am_attrvalue),
-					ops[i].am_length, ops[i].am_flags);
-			mnt_drop_write_file(parfilp);
-			break;
-		case ATTR_OP_REMOVE:
-			ops[i].am_error = mnt_want_write_file(parfilp);
-			if (ops[i].am_error)
-				break;
-			ops[i].am_error = xfs_attrmulti_attr_set(
-					d_inode(dentry), attr_name, NULL, 0,
-					ops[i].am_flags);
-			mnt_drop_write_file(parfilp);
-			break;
-		default:
-			ops[i].am_error = -EINVAL;
-		}
-		kfree(attr_name);
+		ops[i].am_error = xfs_ioc_attrmulti_one(parfilp,
+				d_inode(dentry), ops[i].am_opcode,
+				compat_ptr(ops[i].am_attrname),
+				compat_ptr(ops[i].am_attrvalue),
+				&ops[i].am_length, ops[i].am_flags);
 	}
 
 	if (copy_to_user(compat_ptr(am_hreq.ops), ops, size))
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 07/30] xfs: remove the name == NULL check from xfs_attr_args_init
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (5 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 06/30] xfs: factor out a helper for a single XFS_IOC_ATTRMULTI_BY_HANDLE op Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-02-07  6:15   ` Chandan Rajendra
  2020-01-29 17:02 ` [PATCH 08/30] xfs: remove the MAXNAMELEN " Christoph Hellwig
                   ` (22 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

All callers provide a valid name pointer, remove the redundant check.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_attr.c | 4 ----
 1 file changed, 4 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index bb391b96cd78..a968158b9bb1 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -65,10 +65,6 @@ xfs_attr_args_init(
 	size_t			namelen,
 	int			flags)
 {
-
-	if (!name)
-		return -EINVAL;
-
 	memset(args, 0, sizeof(*args));
 	args->geo = dp->i_mount->m_attr_geo;
 	args->whichfork = XFS_ATTR_FORK;
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 08/30] xfs: remove the MAXNAMELEN check from xfs_attr_args_init
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (6 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 07/30] xfs: remove the name == NULL check from xfs_attr_args_init Christoph Hellwig
@ 2020-01-29 17:02 ` " Christoph Hellwig
  2020-02-07  6:56   ` Chandan Rajendra
  2020-01-29 17:02 ` [PATCH 09/30] xfs: move struct xfs_da_args to xfs_types.h Christoph Hellwig
                   ` (21 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

All the callers already check the length when allocating the
in-kernel xattrs buffers.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_attr.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index a968158b9bb1..f887d62e0956 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -72,9 +72,6 @@ xfs_attr_args_init(
 	args->flags = flags;
 	args->name = name;
 	args->namelen = namelen;
-	if (args->namelen >= MAXNAMELEN)
-		return -EFAULT;		/* match IRIX behaviour */
-
 	args->hashval = xfs_da_hashname(args->name, args->namelen);
 	return 0;
 }
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 09/30] xfs: move struct xfs_da_args to xfs_types.h
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (7 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 08/30] xfs: remove the MAXNAMELEN " Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-01-29 17:02 ` [PATCH 10/30] xfs: turn xfs_da_args.value into a void pointer Christoph Hellwig
                   ` (20 subsequent siblings)
  29 siblings, 0 replies; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

To allow passing a struct xfs_da_args to the high-level attr helpers
it needs to be easily includable by files like xfs_xattr.c.  Move the
struct definition to xfs_types.h to allow for that.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_da_btree.h | 64 ------------------------------------
 fs/xfs/libxfs/xfs_types.h    | 60 +++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 64 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_da_btree.h b/fs/xfs/libxfs/xfs_da_btree.h
index 0f4fbb0889ff..dd2f48b8ee07 100644
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -36,70 +36,6 @@ struct xfs_da_geometry {
 	size_t		data_entry_offset;
 };
 
-/*========================================================================
- * Btree searching and modification structure definitions.
- *========================================================================*/
-
-/*
- * Search comparison results
- */
-enum xfs_dacmp {
-	XFS_CMP_DIFFERENT,	/* names are completely different */
-	XFS_CMP_EXACT,		/* names are exactly the same */
-	XFS_CMP_CASE		/* names are same but differ in case */
-};
-
-/*
- * Structure to ease passing around component names.
- */
-typedef struct xfs_da_args {
-	struct xfs_da_geometry *geo;	/* da block geometry */
-	const uint8_t		*name;		/* string (maybe not NULL terminated) */
-	int		namelen;	/* length of string (maybe no NULL) */
-	uint8_t		filetype;	/* filetype of inode for directories */
-	uint8_t		*value;		/* set of bytes (maybe contain NULLs) */
-	int		valuelen;	/* length of value */
-	int		flags;		/* argument flags (eg: ATTR_NOCREATE) */
-	xfs_dahash_t	hashval;	/* hash value of name */
-	xfs_ino_t	inumber;	/* input/output inode number */
-	struct xfs_inode *dp;		/* directory inode to manipulate */
-	struct xfs_trans *trans;	/* current trans (changes over time) */
-	xfs_extlen_t	total;		/* total blocks needed, for 1st bmap */
-	int		whichfork;	/* data or attribute fork */
-	xfs_dablk_t	blkno;		/* blkno of attr leaf of interest */
-	int		index;		/* index of attr of interest in blk */
-	xfs_dablk_t	rmtblkno;	/* remote attr value starting blkno */
-	int		rmtblkcnt;	/* remote attr value block count */
-	int		rmtvaluelen;	/* remote attr value length in bytes */
-	xfs_dablk_t	blkno2;		/* blkno of 2nd attr leaf of interest */
-	int		index2;		/* index of 2nd attr in blk */
-	xfs_dablk_t	rmtblkno2;	/* remote attr value starting blkno */
-	int		rmtblkcnt2;	/* remote attr value block count */
-	int		rmtvaluelen2;	/* remote attr value length in bytes */
-	int		op_flags;	/* operation flags */
-	enum xfs_dacmp	cmpresult;	/* name compare result for lookups */
-} xfs_da_args_t;
-
-/*
- * Operation flags:
- */
-#define XFS_DA_OP_JUSTCHECK	0x0001	/* check for ok with no space */
-#define XFS_DA_OP_RENAME	0x0002	/* this is an atomic rename op */
-#define XFS_DA_OP_ADDNAME	0x0004	/* this is an add operation */
-#define XFS_DA_OP_OKNOENT	0x0008	/* lookup/add op, ENOENT ok, else die */
-#define XFS_DA_OP_CILOOKUP	0x0010	/* lookup to return CI name if found */
-#define XFS_DA_OP_ALLOCVAL	0x0020	/* lookup to alloc buffer if found  */
-#define XFS_DA_OP_INCOMPLETE	0x0040	/* lookup INCOMPLETE attr keys */
-
-#define XFS_DA_OP_FLAGS \
-	{ XFS_DA_OP_JUSTCHECK,	"JUSTCHECK" }, \
-	{ XFS_DA_OP_RENAME,	"RENAME" }, \
-	{ XFS_DA_OP_ADDNAME,	"ADDNAME" }, \
-	{ XFS_DA_OP_OKNOENT,	"OKNOENT" }, \
-	{ XFS_DA_OP_CILOOKUP,	"CILOOKUP" }, \
-	{ XFS_DA_OP_ALLOCVAL,	"ALLOCVAL" }, \
-	{ XFS_DA_OP_INCOMPLETE,	"INCOMPLETE" }
-
 /*
  * Storage for holding state during Btree searches and split/join ops.
  *
diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
index 397d94775440..e2711d119665 100644
--- a/fs/xfs/libxfs/xfs_types.h
+++ b/fs/xfs/libxfs/xfs_types.h
@@ -175,6 +175,66 @@ enum xfs_ag_resv_type {
 	XFS_AG_RESV_RMAPBT,
 };
 
+/*
+ * Dir/attr btree search comparison results.
+ */
+enum xfs_dacmp {
+	XFS_CMP_DIFFERENT,	/* names are completely different */
+	XFS_CMP_EXACT,		/* names are exactly the same */
+	XFS_CMP_CASE		/* names are same but differ in case */
+};
+
+/*
+ * Structure to ease passing around dir/attr component names.
+ */
+typedef struct xfs_da_args {
+	struct xfs_da_geometry *geo;	/* da block geometry */
+	const uint8_t	*name;		/* string (maybe not NULL terminated) */
+	int		namelen;	/* length of string (maybe no NULL) */
+	uint8_t		filetype;	/* filetype of inode for directories */
+	uint8_t		*value;		/* set of bytes (maybe contain NULLs) */
+	int		valuelen;	/* length of value */
+	int		flags;		/* argument flags (eg: ATTR_NOCREATE) */
+	xfs_dahash_t	hashval;	/* hash value of name */
+	xfs_ino_t	inumber;	/* input/output inode number */
+	struct xfs_inode *dp;		/* directory inode to manipulate */
+	struct xfs_trans *trans;	/* current trans (changes over time) */
+	xfs_extlen_t	total;		/* total blocks needed, for 1st bmap */
+	int		whichfork;	/* data or attribute fork */
+	xfs_dablk_t	blkno;		/* blkno of attr leaf of interest */
+	int		index;		/* index of attr of interest in blk */
+	xfs_dablk_t	rmtblkno;	/* remote attr value starting blkno */
+	int		rmtblkcnt;	/* remote attr value block count */
+	int		rmtvaluelen;	/* remote attr value length in bytes */
+	xfs_dablk_t	blkno2;		/* blkno of 2nd attr leaf of interest */
+	int		index2;		/* index of 2nd attr in blk */
+	xfs_dablk_t	rmtblkno2;	/* remote attr value starting blkno */
+	int		rmtblkcnt2;	/* remote attr value block count */
+	int		rmtvaluelen2;	/* remote attr value length in bytes */
+	int		op_flags;	/* operation flags */
+	enum xfs_dacmp	cmpresult;	/* name compare result for lookups */
+} xfs_da_args_t;
+
+/*
+ * Operation flags:
+ */
+#define XFS_DA_OP_JUSTCHECK	0x0001	/* check for ok with no space */
+#define XFS_DA_OP_RENAME	0x0002	/* this is an atomic rename op */
+#define XFS_DA_OP_ADDNAME	0x0004	/* this is an add operation */
+#define XFS_DA_OP_OKNOENT	0x0008	/* lookup/add op, ENOENT ok, else die */
+#define XFS_DA_OP_CILOOKUP	0x0010	/* lookup to return CI name if found */
+#define XFS_DA_OP_ALLOCVAL	0x0020	/* lookup to alloc buffer if found  */
+#define XFS_DA_OP_INCOMPLETE	0x0040	/* lookup INCOMPLETE attr keys */
+
+#define XFS_DA_OP_FLAGS \
+	{ XFS_DA_OP_JUSTCHECK,	"JUSTCHECK" }, \
+	{ XFS_DA_OP_RENAME,	"RENAME" }, \
+	{ XFS_DA_OP_ADDNAME,	"ADDNAME" }, \
+	{ XFS_DA_OP_OKNOENT,	"OKNOENT" }, \
+	{ XFS_DA_OP_CILOOKUP,	"CILOOKUP" }, \
+	{ XFS_DA_OP_ALLOCVAL,	"ALLOCVAL" }, \
+	{ XFS_DA_OP_INCOMPLETE,	"INCOMPLETE" }
+
 /*
  * Type verifier functions
  */
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 10/30] xfs: turn xfs_da_args.value into a void pointer
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (8 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 09/30] xfs: move struct xfs_da_args to xfs_types.h Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-01-29 17:02 ` [PATCH 11/30] xfs: pass an initialized xfs_da_args structure to xfs_attr_set Christoph Hellwig
                   ` (19 subsequent siblings)
  29 siblings, 0 replies; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

The xattr values are blobs and should not be typed.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_types.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
index e2711d119665..634814dd1d10 100644
--- a/fs/xfs/libxfs/xfs_types.h
+++ b/fs/xfs/libxfs/xfs_types.h
@@ -192,7 +192,7 @@ typedef struct xfs_da_args {
 	const uint8_t	*name;		/* string (maybe not NULL terminated) */
 	int		namelen;	/* length of string (maybe no NULL) */
 	uint8_t		filetype;	/* filetype of inode for directories */
-	uint8_t		*value;		/* set of bytes (maybe contain NULLs) */
+	void		*value;		/* set of bytes (maybe contain NULLs) */
 	int		valuelen;	/* length of value */
 	int		flags;		/* argument flags (eg: ATTR_NOCREATE) */
 	xfs_dahash_t	hashval;	/* hash value of name */
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 11/30] xfs: pass an initialized xfs_da_args structure to xfs_attr_set
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (9 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 10/30] xfs: turn xfs_da_args.value into a void pointer Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-02-07  9:42   ` Chandan Rajendra
  2020-01-29 17:02 ` [PATCH 12/30] xfs: pass an initialized xfs_da_args to xfs_attr_get Christoph Hellwig
                   ` (18 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

Instead of converting from one style of arguments to another in
xfs_attr_set, pass the structure from higher up in the call chain.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_attr.c | 69 ++++++++++++++++++----------------------
 fs/xfs/libxfs/xfs_attr.h |  3 +-
 fs/xfs/xfs_acl.c         | 31 +++++++++---------
 fs/xfs/xfs_ioctl.c       | 20 +++++++-----
 fs/xfs/xfs_iops.c        | 13 +++++---
 fs/xfs/xfs_xattr.c       | 19 +++++++----
 6 files changed, 81 insertions(+), 74 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index f887d62e0956..eea6d90af276 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -330,22 +330,17 @@ xfs_attr_remove_args(
 }
 
 /*
- * Note: If value is NULL the attribute will be removed, just like the
+ * Note: If args->value is NULL the attribute will be removed, just like the
  * Linux ->setattr API.
  */
 int
 xfs_attr_set(
-	struct xfs_inode	*dp,
-	const unsigned char	*name,
-	size_t			namelen,
-	unsigned char		*value,
-	int			valuelen,
-	int			flags)
+	struct xfs_da_args	*args)
 {
+	struct xfs_inode	*dp = args->dp;
 	struct xfs_mount	*mp = dp->i_mount;
-	struct xfs_da_args	args;
 	struct xfs_trans_res	tres;
-	int			rsvd = (flags & ATTR_ROOT) != 0;
+	int			rsvd = (args->flags & ATTR_ROOT) != 0;
 	int			error, local;
 	unsigned int		total;
 
@@ -356,25 +351,22 @@ xfs_attr_set(
 	if (error)
 		return error;
 
-	error = xfs_attr_args_init(&args, dp, name, namelen, flags);
-	if (error)
-		return error;
-
-	args.value = value;
-	args.valuelen = valuelen;
+	args->geo = mp->m_attr_geo;
+	args->whichfork = XFS_ATTR_FORK;
+	args->hashval = xfs_da_hashname(args->name, args->namelen);
 
 	/*
 	 * We have no control over the attribute names that userspace passes us
 	 * to remove, so we have to allow the name lookup prior to attribute
 	 * removal to fail as well.
 	 */
-	args.op_flags = XFS_DA_OP_OKNOENT;
+	args->op_flags = XFS_DA_OP_OKNOENT;
 
-	if (value) {
+	if (args->value) {
 		XFS_STATS_INC(mp, xs_attr_set);
 
-		args.op_flags |= XFS_DA_OP_ADDNAME;
-		args.total = xfs_attr_calc_size(&args, &local);
+		args->op_flags |= XFS_DA_OP_ADDNAME;
+		args->total = xfs_attr_calc_size(args, &local);
 
 		/*
 		 * If the inode doesn't have an attribute fork, add one.
@@ -382,8 +374,8 @@ xfs_attr_set(
 		 */
 		if (XFS_IFORK_Q(dp) == 0) {
 			int sf_size = sizeof(struct xfs_attr_sf_hdr) +
-				XFS_ATTR_SF_ENTSIZE_BYNAME(args.namelen,
-						valuelen);
+				XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen,
+						args->valuelen);
 
 			error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
 			if (error)
@@ -391,10 +383,11 @@ xfs_attr_set(
 		}
 
 		tres.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
-				 M_RES(mp)->tr_attrsetrt.tr_logres * args.total;
+				 M_RES(mp)->tr_attrsetrt.tr_logres *
+					args->total;
 		tres.tr_logcount = XFS_ATTRSET_LOG_COUNT;
 		tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
-		total = args.total;
+		total = args->total;
 	} else {
 		XFS_STATS_INC(mp, xs_attr_remove);
 
@@ -407,29 +400,29 @@ xfs_attr_set(
 	 * operation if necessary
 	 */
 	error = xfs_trans_alloc(mp, &tres, total, 0,
-			rsvd ? XFS_TRANS_RESERVE : 0, &args.trans);
+			rsvd ? XFS_TRANS_RESERVE : 0, &args->trans);
 	if (error)
 		return error;
 
 	xfs_ilock(dp, XFS_ILOCK_EXCL);
-	xfs_trans_ijoin(args.trans, dp, 0);
-	if (value) {
+	xfs_trans_ijoin(args->trans, dp, 0);
+	if (args->value) {
 		unsigned int	quota_flags = XFS_QMOPT_RES_REGBLKS;
 
 		if (rsvd)
 			quota_flags |= XFS_QMOPT_FORCE_RES;
-		error = xfs_trans_reserve_quota_nblks(args.trans, dp,
-				args.total, 0, quota_flags);
+		error = xfs_trans_reserve_quota_nblks(args->trans, dp,
+				args->total, 0, quota_flags);
 		if (error)
 			goto out_trans_cancel;
-		error = xfs_attr_set_args(&args);
+		error = xfs_attr_set_args(args);
 		if (error)
 			goto out_trans_cancel;
 		/* shortform attribute has already been committed */
-		if (!args.trans)
+		if (!args->trans)
 			goto out_unlock;
 	} else {
-		error = xfs_attr_remove_args(&args);
+		error = xfs_attr_remove_args(args);
 		if (error)
 			goto out_trans_cancel;
 	}
@@ -439,23 +432,23 @@ xfs_attr_set(
 	 * transaction goes to disk before returning to the user.
 	 */
 	if (mp->m_flags & XFS_MOUNT_WSYNC)
-		xfs_trans_set_sync(args.trans);
+		xfs_trans_set_sync(args->trans);
 
-	if ((flags & ATTR_KERNOTIME) == 0)
-		xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG);
+	if ((args->flags & ATTR_KERNOTIME) == 0)
+		xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
 
 	/*
 	 * Commit the last in the sequence of transactions.
 	 */
-	xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
-	error = xfs_trans_commit(args.trans);
+	xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
+	error = xfs_trans_commit(args->trans);
 out_unlock:
 	xfs_iunlock(dp, XFS_ILOCK_EXCL);
 	return error;
 
 out_trans_cancel:
-	if (args.trans)
-		xfs_trans_cancel(args.trans);
+	if (args->trans)
+		xfs_trans_cancel(args->trans);
 	goto out_unlock;
 }
 
diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index db58a6c7dea5..07ca543db831 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -149,8 +149,7 @@ int xfs_attr_get_ilocked(struct xfs_inode *ip, struct xfs_da_args *args);
 int xfs_attr_get(struct xfs_inode *ip, const unsigned char *name,
 		 size_t namelen, unsigned char **value, int *valuelenp,
 		 int flags);
-int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name,
-		 size_t namelen, unsigned char *value, int valuelen, int flags);
+int xfs_attr_set(struct xfs_da_args *args);
 int xfs_attr_set_args(struct xfs_da_args *args);
 int xfs_attr_remove_args(struct xfs_da_args *args);
 int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index 4e76063ff956..e9ae7cbe1973 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -166,41 +166,42 @@ xfs_get_acl(struct inode *inode, int type)
 int
 __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 {
-	struct xfs_inode *ip = XFS_I(inode);
-	unsigned char *ea_name;
-	struct xfs_acl *xfs_acl = NULL;
-	int len = 0;
-	int error;
+	struct xfs_inode	*ip = XFS_I(inode);
+	struct xfs_da_args	args = {
+		.dp		= ip,
+		.flags		= ATTR_ROOT,
+	};
+	int			error;
 
 	switch (type) {
 	case ACL_TYPE_ACCESS:
-		ea_name = SGI_ACL_FILE;
+		args.name = SGI_ACL_FILE;
 		break;
 	case ACL_TYPE_DEFAULT:
 		if (!S_ISDIR(inode->i_mode))
 			return acl ? -EACCES : 0;
-		ea_name = SGI_ACL_DEFAULT;
+		args.name = SGI_ACL_DEFAULT;
 		break;
 	default:
 		return -EINVAL;
 	}
+	args.namelen = strlen(args.name);
 
 	if (acl) {
-		len = XFS_ACL_MAX_SIZE(ip->i_mount);
-		xfs_acl = kmem_zalloc_large(len, 0);
-		if (!xfs_acl)
+		args.valuelen = XFS_ACL_MAX_SIZE(ip->i_mount);
+		args.value = kmem_zalloc_large(args.valuelen, 0);
+		if (!args.value)
 			return -ENOMEM;
 
-		xfs_acl_to_disk(xfs_acl, acl);
+		xfs_acl_to_disk(args.value, acl);
 
 		/* subtract away the unused acl entries */
-		len -= sizeof(struct xfs_acl_entry) *
+		args.valuelen -= sizeof(struct xfs_acl_entry) *
 			 (XFS_ACL_MAX_ENTRIES(ip->i_mount) - acl->a_count);
 	}
 
-	error = xfs_attr_set(ip, ea_name, strlen(ea_name),
-			(unsigned char *)xfs_acl, len, ATTR_ROOT);
-	kmem_free(xfs_acl);
+	error = xfs_attr_set(&args);
+	kmem_free(args.value);
 
 	/*
 	 * If the attribute didn't exist to start with that's fine.
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index cfdd80b4ea2d..47a88b5cfa63 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -389,9 +389,13 @@ xfs_attrmulti_attr_set(
 	uint32_t		len,
 	uint32_t		flags)
 {
-	unsigned char		*kbuf = NULL;
+	struct xfs_da_args	args = {
+		.dp		= XFS_I(inode),
+		.flags		= flags,
+		.name		= name,
+		.namelen	= strlen(name),
+	};
 	int			error;
-	size_t			namelen;
 
 	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
 		return -EPERM;
@@ -399,16 +403,16 @@ xfs_attrmulti_attr_set(
 	if (ubuf) {
 		if (len > XFS_XATTR_SIZE_MAX)
 			return -EINVAL;
-		kbuf = memdup_user(ubuf, len);
-		if (IS_ERR(kbuf))
-			return PTR_ERR(kbuf);
+		args.value = memdup_user(ubuf, len);
+		if (IS_ERR(args.value))
+			return PTR_ERR(args.value);
+		args.valuelen = len;
 	}
 
-	namelen = strlen(name);
-	error = xfs_attr_set(XFS_I(inode), name, namelen, kbuf, len, flags);
+	error = xfs_attr_set(&args);
 	if (!error)
 		xfs_forget_acl(inode, name, flags);
-	kfree(kbuf);
+	kfree(args.value);
 	return error;
 }
 
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 81f2f93caec0..94cd4254656c 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -50,10 +50,15 @@ xfs_initxattrs(
 	int			error = 0;
 
 	for (xattr = xattr_array; xattr->name != NULL; xattr++) {
-		error = xfs_attr_set(ip, xattr->name,
-				     strlen(xattr->name),
-				     xattr->value, xattr->value_len,
-				     ATTR_SECURE);
+		struct xfs_da_args	args = {
+			.dp		= ip,
+			.flags		= ATTR_SECURE,
+			.name		= xattr->name,
+			.namelen	= strlen(xattr->name),
+			.value		= xattr->value,
+			.valuelen	= xattr->value_len,
+		};
+		error = xfs_attr_set(&args);
 		if (error < 0)
 			break;
 	}
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
index 1670bfbc9ad2..09f967f97699 100644
--- a/fs/xfs/xfs_xattr.c
+++ b/fs/xfs/xfs_xattr.c
@@ -66,20 +66,25 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
 		struct inode *inode, const char *name, const void *value,
 		size_t size, int flags)
 {
-	int			xflags = handler->flags;
-	struct xfs_inode	*ip = XFS_I(inode);
+	struct xfs_da_args	args = {
+		.dp		= XFS_I(inode),
+		.flags		= handler->flags,
+		.name		= name,
+		.namelen	= strlen(name),
+		.value		= (unsigned char *)value,
+		.valuelen	= size,
+	};
 	int			error;
 
 	/* Convert Linux syscall to XFS internal ATTR flags */
 	if (flags & XATTR_CREATE)
-		xflags |= ATTR_CREATE;
+		args.flags |= ATTR_CREATE;
 	if (flags & XATTR_REPLACE)
-		xflags |= ATTR_REPLACE;
+		args.flags |= ATTR_REPLACE;
 
-	error = xfs_attr_set(ip, (unsigned char *)name, strlen(name),
-				(void *)value, size, xflags);
+	error = xfs_attr_set(&args);
 	if (!error)
-		xfs_forget_acl(inode, name, xflags);
+		xfs_forget_acl(inode, name, args.flags);
 	return error;
 }
 
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 12/30] xfs: pass an initialized xfs_da_args to xfs_attr_get
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (10 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 11/30] xfs: pass an initialized xfs_da_args structure to xfs_attr_set Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-02-07 13:13   ` Chandan Rajendra
  2020-01-29 17:02 ` [PATCH 13/30] xfs: remove the xfs_inode argument to xfs_attr_get_ilocked Christoph Hellwig
                   ` (17 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

Instead of converting from one style of arguments to another in
xfs_attr_set, pass the structure from higher up in the call chain.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_attr.c | 80 ++++++++++++----------------------------
 fs/xfs/libxfs/xfs_attr.h |  4 +-
 fs/xfs/xfs_acl.c         | 35 ++++++++----------
 fs/xfs/xfs_ioctl.c       | 25 ++++++++-----
 fs/xfs/xfs_xattr.c       | 24 ++++++------
 5 files changed, 68 insertions(+), 100 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index eea6d90af276..288b39e81efd 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -56,26 +56,6 @@ STATIC int xfs_attr_node_removename(xfs_da_args_t *args);
 STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
 STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
 
-
-STATIC int
-xfs_attr_args_init(
-	struct xfs_da_args	*args,
-	struct xfs_inode	*dp,
-	const unsigned char	*name,
-	size_t			namelen,
-	int			flags)
-{
-	memset(args, 0, sizeof(*args));
-	args->geo = dp->i_mount->m_attr_geo;
-	args->whichfork = XFS_ATTR_FORK;
-	args->dp = dp;
-	args->flags = flags;
-	args->name = name;
-	args->namelen = namelen;
-	args->hashval = xfs_da_hashname(args->name, args->namelen);
-	return 0;
-}
-
 int
 xfs_inode_hasattr(
 	struct xfs_inode	*ip)
@@ -115,15 +95,15 @@ xfs_attr_get_ilocked(
 /*
  * Retrieve an extended attribute by name, and its value if requested.
  *
- * If ATTR_KERNOVAL is set in @flags, then the caller does not want the value,
- * just an indication whether the attribute exists and the size of the value if
- * it exists. The size is returned in @valuelenp,
+ * If ATTR_KERNOVAL is set in args->flags, then the caller does not want the
+ * value, just an indication whether the attribute exists and the size of the
+ * value if it exists. The size is returned in args.valuelen.
  *
  * If the attribute is found, but exceeds the size limit set by the caller in
- * @valuelenp, return -ERANGE with the size of the attribute that was found in
- * @valuelenp.
+ * args->valuelen, return -ERANGE with the size of the attribute that was found
+ * in args->valuelen.
  *
- * If ATTR_ALLOC is set in @flags, allocate the buffer for the value after
+ * If ATTR_ALLOC is set in args->flags, allocate the buffer for the value after
  * existence of the attribute has been determined. On success, return that
  * buffer to the caller and leave them to free it. On failure, free any
  * allocated buffer and ensure the buffer pointer returned to the caller is
@@ -131,51 +111,37 @@ xfs_attr_get_ilocked(
  */
 int
 xfs_attr_get(
-	struct xfs_inode	*ip,
-	const unsigned char	*name,
-	size_t			namelen,
-	unsigned char		**value,
-	int			*valuelenp,
-	int			flags)
+	struct xfs_da_args	*args)
 {
-	struct xfs_da_args	args;
 	uint			lock_mode;
 	int			error;
 
-	ASSERT((flags & (ATTR_ALLOC | ATTR_KERNOVAL)) || *value);
+	ASSERT((args->flags & (ATTR_ALLOC | ATTR_KERNOVAL)) || args->value);
 
-	XFS_STATS_INC(ip->i_mount, xs_attr_get);
+	XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
 
-	if (XFS_FORCED_SHUTDOWN(ip->i_mount))
+	if (XFS_FORCED_SHUTDOWN(args->dp->i_mount))
 		return -EIO;
 
-	error = xfs_attr_args_init(&args, ip, name, namelen, flags);
-	if (error)
-		return error;
+	args->geo = args->dp->i_mount->m_attr_geo;
+	args->whichfork = XFS_ATTR_FORK;
+	args->hashval = xfs_da_hashname(args->name, args->namelen);
 
 	/* Entirely possible to look up a name which doesn't exist */
-	args.op_flags = XFS_DA_OP_OKNOENT;
-	if (flags & ATTR_ALLOC)
-		args.op_flags |= XFS_DA_OP_ALLOCVAL;
-	else
-		args.value = *value;
-	args.valuelen = *valuelenp;
+	args->op_flags = XFS_DA_OP_OKNOENT;
+	if (args->flags & ATTR_ALLOC)
+		args->op_flags |= XFS_DA_OP_ALLOCVAL;
 
-	lock_mode = xfs_ilock_attr_map_shared(ip);
-	error = xfs_attr_get_ilocked(ip, &args);
-	xfs_iunlock(ip, lock_mode);
-	*valuelenp = args.valuelen;
+	lock_mode = xfs_ilock_attr_map_shared(args->dp);
+	error = xfs_attr_get_ilocked(args->dp, args);
+	xfs_iunlock(args->dp, lock_mode);
 
 	/* on error, we have to clean up allocated value buffers */
-	if (error) {
-		if (flags & ATTR_ALLOC) {
-			kmem_free(args.value);
-			*value = NULL;
-		}
-		return error;
+	if (error && (args->flags & ATTR_ALLOC)) {
+		kmem_free(args->value);
+		args->value = NULL;
 	}
-	*value = args.value;
-	return 0;
+	return error;
 }
 
 /*
diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index 07ca543db831..be77d13a2902 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -146,9 +146,7 @@ int xfs_attr_list_int_ilocked(struct xfs_attr_list_context *);
 int xfs_attr_list_int(struct xfs_attr_list_context *);
 int xfs_inode_hasattr(struct xfs_inode *ip);
 int xfs_attr_get_ilocked(struct xfs_inode *ip, struct xfs_da_args *args);
-int xfs_attr_get(struct xfs_inode *ip, const unsigned char *name,
-		 size_t namelen, unsigned char **value, int *valuelenp,
-		 int flags);
+int xfs_attr_get(struct xfs_da_args *args);
 int xfs_attr_set(struct xfs_da_args *args);
 int xfs_attr_set_args(struct xfs_da_args *args);
 int xfs_attr_remove_args(struct xfs_da_args *args);
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index e9ae7cbe1973..780924984492 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -120,34 +120,31 @@ xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl)
 struct posix_acl *
 xfs_get_acl(struct inode *inode, int type)
 {
-	struct xfs_inode *ip = XFS_I(inode);
-	struct posix_acl *acl = NULL;
-	struct xfs_acl *xfs_acl = NULL;
-	unsigned char *ea_name;
-	int error;
-	int len;
+	struct xfs_inode	*ip = XFS_I(inode);
+	struct xfs_mount	*mp = ip->i_mount;
+	struct posix_acl	*acl = NULL;
+	struct xfs_da_args	args = {
+		.dp		= ip,
+		.flags		= ATTR_ALLOC | ATTR_ROOT,
+		.valuelen	= XFS_ACL_MAX_SIZE(mp),
+	};
+	int			error;
 
 	trace_xfs_get_acl(ip);
 
 	switch (type) {
 	case ACL_TYPE_ACCESS:
-		ea_name = SGI_ACL_FILE;
+		args.name = SGI_ACL_FILE;
 		break;
 	case ACL_TYPE_DEFAULT:
-		ea_name = SGI_ACL_DEFAULT;
+		args.name = SGI_ACL_DEFAULT;
 		break;
 	default:
 		BUG();
 	}
+	args.namelen = strlen(args.name);
 
-	/*
-	 * If we have a cached ACLs value just return it, not need to
-	 * go out to the disk.
-	 */
-	len = XFS_ACL_MAX_SIZE(ip->i_mount);
-	error = xfs_attr_get(ip, ea_name, strlen(ea_name),
-				(unsigned char **)&xfs_acl, &len,
-				ATTR_ALLOC | ATTR_ROOT);
+	error = xfs_attr_get(&args);
 	if (error) {
 		/*
 		 * If the attribute doesn't exist make sure we have a negative
@@ -156,9 +153,9 @@ xfs_get_acl(struct inode *inode, int type)
 		if (error != -ENOATTR)
 			acl = ERR_PTR(error);
 	} else  {
-		acl = xfs_acl_from_disk(ip->i_mount, xfs_acl, len,
-					XFS_ACL_MAX_ENTRIES(ip->i_mount));
-		kmem_free(xfs_acl);
+		acl = xfs_acl_from_disk(mp, args.value, args.valuelen,
+					XFS_ACL_MAX_ENTRIES(mp));
+		kmem_free(args.value);
 	}
 	return acl;
 }
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 47a88b5cfa63..2da22595f828 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -357,27 +357,32 @@ xfs_attrmulti_attr_get(
 	uint32_t		*len,
 	uint32_t		flags)
 {
-	unsigned char		*kbuf;
-	int			error = -EFAULT;
-	size_t			namelen;
+	struct xfs_da_args	args = {
+		.dp		= XFS_I(inode),
+		.flags		= flags,
+		.name		= name,
+		.namelen	= strlen(name),
+		.valuelen	= *len,
+	};
+	int			error;
 
 	if (*len > XFS_XATTR_SIZE_MAX)
 		return -EINVAL;
-	kbuf = kmem_zalloc_large(*len, 0);
-	if (!kbuf)
+
+	args.value = kmem_zalloc_large(*len, 0);
+	if (!args.value)
 		return -ENOMEM;
 
-	namelen = strlen(name);
-	error = xfs_attr_get(XFS_I(inode), name, namelen, &kbuf, (int *)len,
-			     flags);
+	error = xfs_attr_get(&args);
 	if (error)
 		goto out_kfree;
 
-	if (copy_to_user(ubuf, kbuf, *len))
+	*len = args.valuelen;
+	if (copy_to_user(ubuf, args.value, args.valuelen))
 		error = -EFAULT;
 
 out_kfree:
-	kmem_free(kbuf);
+	kmem_free(args.value);
 	return error;
 }
 
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
index 09f967f97699..b3ce5e8777f9 100644
--- a/fs/xfs/xfs_xattr.c
+++ b/fs/xfs/xfs_xattr.c
@@ -21,22 +21,24 @@ static int
 xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
 		struct inode *inode, const char *name, void *value, size_t size)
 {
-	int xflags = handler->flags;
-	struct xfs_inode *ip = XFS_I(inode);
-	int error, asize = size;
-	size_t namelen = strlen(name);
+	struct xfs_da_args	args = {
+		.dp		= XFS_I(inode),
+		.flags		= handler->flags,
+		.name		= name,
+		.namelen	= strlen(name),
+		.value		= value,
+		.valuelen	= size,
+	};
+	int			error;
 
 	/* Convert Linux syscall to XFS internal ATTR flags */
-	if (!size) {
-		xflags |= ATTR_KERNOVAL;
-		value = NULL;
-	}
+	if (!size)
+		args.flags |= ATTR_KERNOVAL;
 
-	error = xfs_attr_get(ip, name, namelen, (unsigned char **)&value,
-			     &asize, xflags);
+	error = xfs_attr_get(&args);
 	if (error)
 		return error;
-	return asize;
+	return args.valuelen;
 }
 
 void
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 13/30] xfs: remove the xfs_inode argument to xfs_attr_get_ilocked
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (11 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 12/30] xfs: pass an initialized xfs_da_args to xfs_attr_get Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-02-07 13:19   ` Chandan Rajendra
  2020-01-29 17:02 ` [PATCH 14/30] xfs: remove ATTR_KERNOVAL Christoph Hellwig
                   ` (16 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

The inode can easily be derived from the args structure.  Also
don't bother with else statements after early returns.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_attr.c | 15 +++++++--------
 fs/xfs/libxfs/xfs_attr.h |  2 +-
 fs/xfs/scrub/attr.c      |  2 +-
 3 files changed, 9 insertions(+), 10 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 288b39e81efd..fd095e3d4a9a 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -77,19 +77,18 @@ xfs_inode_hasattr(
  */
 int
 xfs_attr_get_ilocked(
-	struct xfs_inode	*ip,
 	struct xfs_da_args	*args)
 {
-	ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
+	ASSERT(xfs_isilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
 
-	if (!xfs_inode_hasattr(ip))
+	if (!xfs_inode_hasattr(args->dp))
 		return -ENOATTR;
-	else if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL)
+
+	if (args->dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL)
 		return xfs_attr_shortform_getvalue(args);
-	else if (xfs_bmap_one_block(ip, XFS_ATTR_FORK))
+	if (xfs_bmap_one_block(args->dp, XFS_ATTR_FORK))
 		return xfs_attr_leaf_get(args);
-	else
-		return xfs_attr_node_get(args);
+	return xfs_attr_node_get(args);
 }
 
 /*
@@ -133,7 +132,7 @@ xfs_attr_get(
 		args->op_flags |= XFS_DA_OP_ALLOCVAL;
 
 	lock_mode = xfs_ilock_attr_map_shared(args->dp);
-	error = xfs_attr_get_ilocked(args->dp, args);
+	error = xfs_attr_get_ilocked(args);
 	xfs_iunlock(args->dp, lock_mode);
 
 	/* on error, we have to clean up allocated value buffers */
diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index be77d13a2902..b8c4ed27f626 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -145,7 +145,7 @@ int xfs_attr_inactive(struct xfs_inode *dp);
 int xfs_attr_list_int_ilocked(struct xfs_attr_list_context *);
 int xfs_attr_list_int(struct xfs_attr_list_context *);
 int xfs_inode_hasattr(struct xfs_inode *ip);
-int xfs_attr_get_ilocked(struct xfs_inode *ip, struct xfs_da_args *args);
+int xfs_attr_get_ilocked(struct xfs_da_args *args);
 int xfs_attr_get(struct xfs_da_args *args);
 int xfs_attr_set(struct xfs_da_args *args);
 int xfs_attr_set_args(struct xfs_da_args *args);
diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
index d804558cdbca..f983c2b969e0 100644
--- a/fs/xfs/scrub/attr.c
+++ b/fs/xfs/scrub/attr.c
@@ -162,7 +162,7 @@ xchk_xattr_listent(
 	args.value = xchk_xattr_valuebuf(sx->sc);
 	args.valuelen = valuelen;
 
-	error = xfs_attr_get_ilocked(context->dp, &args);
+	error = xfs_attr_get_ilocked(&args);
 	if (!xchk_fblock_process_error(sx->sc, XFS_ATTR_FORK, args.blkno,
 			&error))
 		goto fail_xref;
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 14/30] xfs: remove ATTR_KERNOVAL
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (12 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 13/30] xfs: remove the xfs_inode argument to xfs_attr_get_ilocked Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-02-08  4:36   ` Chandan Rajendra
  2020-01-29 17:02 ` [PATCH 15/30] xfs: remove ATTR_ALLOC and XFS_DA_OP_ALLOCVAL Christoph Hellwig
                   ` (15 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

We can just pass down the Linux convention of a zero valuelen to just
query for the existance of an attribute to the low-level code instead.
The use in the legacy xfs_attr_list code only used by the ioctl
interface was already dead code, as the callers check that the flag
is not present.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_attr.c        |  8 ++++----
 fs/xfs/libxfs/xfs_attr.h        |  4 +---
 fs/xfs/libxfs/xfs_attr_leaf.c   | 14 +++++++-------
 fs/xfs/libxfs/xfs_attr_remote.c |  2 +-
 fs/xfs/xfs_attr_list.c          |  3 ---
 fs/xfs/xfs_xattr.c              |  4 ----
 6 files changed, 13 insertions(+), 22 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index fd095e3d4a9a..469417786bfc 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -94,9 +94,9 @@ xfs_attr_get_ilocked(
 /*
  * Retrieve an extended attribute by name, and its value if requested.
  *
- * If ATTR_KERNOVAL is set in args->flags, then the caller does not want the
- * value, just an indication whether the attribute exists and the size of the
- * value if it exists. The size is returned in args.valuelen.
+ * If args->valuelen is zero, then the caller does not want the value, just an
+ * indication whether the attribute exists and the size of the value if it
+ * exists. The size is returned in args.valuelen.
  *
  * If the attribute is found, but exceeds the size limit set by the caller in
  * args->valuelen, return -ERANGE with the size of the attribute that was found
@@ -115,7 +115,7 @@ xfs_attr_get(
 	uint			lock_mode;
 	int			error;
 
-	ASSERT((args->flags & (ATTR_ALLOC | ATTR_KERNOVAL)) || args->value);
+	ASSERT((args->flags & ATTR_ALLOC) || !args->valuelen || args->value);
 
 	XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
 
diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index b8c4ed27f626..fe064cd81747 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -34,12 +34,11 @@ struct xfs_attr_list_context;
 #define ATTR_REPLACE	0x0020	/* pure set: fail if attr does not exist */
 
 #define ATTR_KERNOTIME	0x1000	/* [kernel] don't update inode timestamps */
-#define ATTR_KERNOVAL	0x2000	/* [kernel] get attr size only, not value */
 
 #define ATTR_ALLOC	0x8000	/* [kernel] allocate xattr buffer on demand */
 
 #define ATTR_KERNEL_FLAGS \
-	(ATTR_KERNOTIME | ATTR_KERNOVAL | ATTR_ALLOC)
+	(ATTR_KERNOTIME | ATTR_ALLOC)
 
 #define XFS_ATTR_FLAGS \
 	{ ATTR_DONTFOLLOW, 	"DONTFOLLOW" }, \
@@ -49,7 +48,6 @@ struct xfs_attr_list_context;
 	{ ATTR_CREATE,		"CREATE" }, \
 	{ ATTR_REPLACE,		"REPLACE" }, \
 	{ ATTR_KERNOTIME,	"KERNOTIME" }, \
-	{ ATTR_KERNOVAL,	"KERNOVAL" }, \
 	{ ATTR_ALLOC,		"ALLOC" }
 
 /*
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index fed537a4353d..5e700dfc48a9 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -464,7 +464,7 @@ xfs_attr_copy_value(
 	/*
 	 * No copy if all we have to do is get the length
 	 */
-	if (args->flags & ATTR_KERNOVAL) {
+	if (!args->valuelen) {
 		args->valuelen = valuelen;
 		return 0;
 	}
@@ -830,9 +830,9 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args)
 /*
  * Retrieve the attribute value and length.
  *
- * If ATTR_KERNOVAL is specified, only the length needs to be returned.
- * Unlike a lookup, we only return an error if the attribute does not
- * exist or we can't retrieve the value.
+ * If args->valuelen is zero, only the length needs to be returned.  Unlike a
+ * lookup, we only return an error if the attribute does not exist or we can't
+ * retrieve the value.
  */
 int
 xfs_attr_shortform_getvalue(
@@ -2444,9 +2444,9 @@ xfs_attr3_leaf_lookup_int(
  * Get the value associated with an attribute name from a leaf attribute
  * list structure.
  *
- * If ATTR_KERNOVAL is specified, only the length needs to be returned.
- * Unlike a lookup, we only return an error if the attribute does not
- * exist or we can't retrieve the value.
+ * If args->valuelen is zero, only the length needs to be returned.  Unlike a
+ * lookup, we only return an error if the attribute does not exist or we can't
+ * retrieve the value.
  */
 int
 xfs_attr3_leaf_getvalue(
diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c
index a266d05df146..023ac8b85b4a 100644
--- a/fs/xfs/libxfs/xfs_attr_remote.c
+++ b/fs/xfs/libxfs/xfs_attr_remote.c
@@ -397,7 +397,7 @@ xfs_attr_rmtval_get(
 
 	trace_xfs_attr_rmtval_get(args);
 
-	ASSERT(!(args->flags & ATTR_KERNOVAL));
+	ASSERT(args->valuelen != 0);
 	ASSERT(args->rmtvaluelen == args->valuelen);
 
 	valuelen = args->rmtvaluelen;
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index 5139ef983cd6..ac8dc64447d6 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -568,7 +568,6 @@ xfs_attr_put_listent(
 	int arraytop;
 
 	ASSERT(!context->seen_enough);
-	ASSERT(!(context->flags & ATTR_KERNOVAL));
 	ASSERT(context->count >= 0);
 	ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
 	ASSERT(context->firstu >= sizeof(*alist));
@@ -637,8 +636,6 @@ xfs_attr_list(
 	 */
 	if (((long)buffer) & (sizeof(int)-1))
 		return -EFAULT;
-	if (flags & ATTR_KERNOVAL)
-		bufsize = 0;
 
 	/*
 	 * Initialize the output buffer.
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
index b3ce5e8777f9..c9c44f8aebed 100644
--- a/fs/xfs/xfs_xattr.c
+++ b/fs/xfs/xfs_xattr.c
@@ -31,10 +31,6 @@ xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
 	};
 	int			error;
 
-	/* Convert Linux syscall to XFS internal ATTR flags */
-	if (!size)
-		args.flags |= ATTR_KERNOVAL;
-
 	error = xfs_attr_get(&args);
 	if (error)
 		return error;
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 15/30] xfs: remove ATTR_ALLOC and XFS_DA_OP_ALLOCVAL
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (13 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 14/30] xfs: remove ATTR_KERNOVAL Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-02-08  5:13   ` Chandan Rajendra
  2020-01-29 17:02 ` [PATCH 16/30] xfs: replace ATTR_KERNOTIME with XFS_DA_OP_NOTIME Christoph Hellwig
                   ` (14 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins

Use a NULL args->value as the indicator to lazily allocate a buffer
instead, and let the caller always free args->value instead of
duplicating the cleanup.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_attr.c      | 20 +++++---------------
 fs/xfs/libxfs/xfs_attr.h      |  7 ++-----
 fs/xfs/libxfs/xfs_attr_leaf.c |  2 +-
 fs/xfs/libxfs/xfs_types.h     |  2 --
 fs/xfs/xfs_acl.c              | 20 ++++++++++----------
 5 files changed, 18 insertions(+), 33 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 469417786bfc..1382e51ef85e 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -98,15 +98,14 @@ xfs_attr_get_ilocked(
  * indication whether the attribute exists and the size of the value if it
  * exists. The size is returned in args.valuelen.
  *
+ * If args->value is NULL but args->valuelen is non-zero, allocate the buffer
+ * for the value after existence of the attribute has been determined. The
+ * caller always has to free args->value if it is set, no matter if this
+ * function was successful or not.
+ *
  * If the attribute is found, but exceeds the size limit set by the caller in
  * args->valuelen, return -ERANGE with the size of the attribute that was found
  * in args->valuelen.
- *
- * If ATTR_ALLOC is set in args->flags, allocate the buffer for the value after
- * existence of the attribute has been determined. On success, return that
- * buffer to the caller and leave them to free it. On failure, free any
- * allocated buffer and ensure the buffer pointer returned to the caller is
- * null.
  */
 int
 xfs_attr_get(
@@ -115,8 +114,6 @@ xfs_attr_get(
 	uint			lock_mode;
 	int			error;
 
-	ASSERT((args->flags & ATTR_ALLOC) || !args->valuelen || args->value);
-
 	XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
 
 	if (XFS_FORCED_SHUTDOWN(args->dp->i_mount))
@@ -128,18 +125,11 @@ xfs_attr_get(
 
 	/* Entirely possible to look up a name which doesn't exist */
 	args->op_flags = XFS_DA_OP_OKNOENT;
-	if (args->flags & ATTR_ALLOC)
-		args->op_flags |= XFS_DA_OP_ALLOCVAL;
 
 	lock_mode = xfs_ilock_attr_map_shared(args->dp);
 	error = xfs_attr_get_ilocked(args);
 	xfs_iunlock(args->dp, lock_mode);
 
-	/* on error, we have to clean up allocated value buffers */
-	if (error && (args->flags & ATTR_ALLOC)) {
-		kmem_free(args->value);
-		args->value = NULL;
-	}
 	return error;
 }
 
diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index fe064cd81747..a6de050675c9 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -35,10 +35,8 @@ struct xfs_attr_list_context;
 
 #define ATTR_KERNOTIME	0x1000	/* [kernel] don't update inode timestamps */
 
-#define ATTR_ALLOC	0x8000	/* [kernel] allocate xattr buffer on demand */
-
 #define ATTR_KERNEL_FLAGS \
-	(ATTR_KERNOTIME | ATTR_ALLOC)
+	(ATTR_KERNOTIME)
 
 #define XFS_ATTR_FLAGS \
 	{ ATTR_DONTFOLLOW, 	"DONTFOLLOW" }, \
@@ -47,8 +45,7 @@ struct xfs_attr_list_context;
 	{ ATTR_SECURE,		"SECURE" }, \
 	{ ATTR_CREATE,		"CREATE" }, \
 	{ ATTR_REPLACE,		"REPLACE" }, \
-	{ ATTR_KERNOTIME,	"KERNOTIME" }, \
-	{ ATTR_ALLOC,		"ALLOC" }
+	{ ATTR_KERNOTIME,	"KERNOTIME" }
 
 /*
  * The maximum size (into the kernel or returned from the kernel) of an
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index 5e700dfc48a9..b0658eb8fbcc 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -477,7 +477,7 @@ xfs_attr_copy_value(
 		return -ERANGE;
 	}
 
-	if (args->op_flags & XFS_DA_OP_ALLOCVAL) {
+	if (!args->value) {
 		args->value = kmem_alloc_large(valuelen, 0);
 		if (!args->value)
 			return -ENOMEM;
diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
index 634814dd1d10..3379ebc0c7c5 100644
--- a/fs/xfs/libxfs/xfs_types.h
+++ b/fs/xfs/libxfs/xfs_types.h
@@ -223,7 +223,6 @@ typedef struct xfs_da_args {
 #define XFS_DA_OP_ADDNAME	0x0004	/* this is an add operation */
 #define XFS_DA_OP_OKNOENT	0x0008	/* lookup/add op, ENOENT ok, else die */
 #define XFS_DA_OP_CILOOKUP	0x0010	/* lookup to return CI name if found */
-#define XFS_DA_OP_ALLOCVAL	0x0020	/* lookup to alloc buffer if found  */
 #define XFS_DA_OP_INCOMPLETE	0x0040	/* lookup INCOMPLETE attr keys */
 
 #define XFS_DA_OP_FLAGS \
@@ -232,7 +231,6 @@ typedef struct xfs_da_args {
 	{ XFS_DA_OP_ADDNAME,	"ADDNAME" }, \
 	{ XFS_DA_OP_OKNOENT,	"OKNOENT" }, \
 	{ XFS_DA_OP_CILOOKUP,	"CILOOKUP" }, \
-	{ XFS_DA_OP_ALLOCVAL,	"ALLOCVAL" }, \
 	{ XFS_DA_OP_INCOMPLETE,	"INCOMPLETE" }
 
 /*
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index 780924984492..bc78b7c33401 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -125,7 +125,7 @@ xfs_get_acl(struct inode *inode, int type)
 	struct posix_acl	*acl = NULL;
 	struct xfs_da_args	args = {
 		.dp		= ip,
-		.flags		= ATTR_ALLOC | ATTR_ROOT,
+		.flags		= ATTR_ROOT,
 		.valuelen	= XFS_ACL_MAX_SIZE(mp),
 	};
 	int			error;
@@ -144,19 +144,19 @@ xfs_get_acl(struct inode *inode, int type)
 	}
 	args.namelen = strlen(args.name);
 
+	/*
+	 * If the attribute doesn't exist make sure we have a negative cache
+	 * entry, for any other error assume it is transient.
+	 */
 	error = xfs_attr_get(&args);
-	if (error) {
-		/*
-		 * If the attribute doesn't exist make sure we have a negative
-		 * cache entry, for any other error assume it is transient.
-		 */
-		if (error != -ENOATTR)
-			acl = ERR_PTR(error);
-	} else  {
+	if (!error) {
 		acl = xfs_acl_from_disk(mp, args.value, args.valuelen,
 					XFS_ACL_MAX_ENTRIES(mp));
-		kmem_free(args.value);
+	} else if (error != -ENOATTR) {
+		acl = ERR_PTR(error);
 	}
+
+	kmem_free(args.value);
 	return acl;
 }
 
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 16/30] xfs: replace ATTR_KERNOTIME with XFS_DA_OP_NOTIME
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (14 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 15/30] xfs: remove ATTR_ALLOC and XFS_DA_OP_ALLOCVAL Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-02-08 11:35   ` Chandan Rajendra
  2020-01-29 17:02 ` [PATCH 17/30] xfs: factor out a xfs_attr_match helper Christoph Hellwig
                   ` (13 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

op_flags with the XFS_DA_OP_* flags is the usual place for in-kernel
only flags, so move the notime flag there.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_attr.c  | 4 ++--
 fs/xfs/libxfs/xfs_attr.h  | 8 +-------
 fs/xfs/libxfs/xfs_types.h | 2 ++
 fs/xfs/scrub/attr.c       | 2 +-
 fs/xfs/xfs_ioctl.c        | 1 -
 5 files changed, 6 insertions(+), 11 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 1382e51ef85e..3b1db2afb104 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -186,7 +186,7 @@ xfs_attr_try_sf_addname(
 	 * Commit the shortform mods, and we're done.
 	 * NOTE: this is also the error path (EEXIST, etc).
 	 */
-	if (!error && (args->flags & ATTR_KERNOTIME) == 0)
+	if (!error && !(args->op_flags & XFS_DA_OP_NOTIME))
 		xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
 
 	if (mp->m_flags & XFS_MOUNT_WSYNC)
@@ -389,7 +389,7 @@ xfs_attr_set(
 	if (mp->m_flags & XFS_MOUNT_WSYNC)
 		xfs_trans_set_sync(args->trans);
 
-	if ((args->flags & ATTR_KERNOTIME) == 0)
+	if (!(args->op_flags & XFS_DA_OP_NOTIME))
 		xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
 
 	/*
diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index a6de050675c9..0f369399effd 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -33,19 +33,13 @@ struct xfs_attr_list_context;
 #define ATTR_CREATE	0x0010	/* pure create: fail if attr already exists */
 #define ATTR_REPLACE	0x0020	/* pure set: fail if attr does not exist */
 
-#define ATTR_KERNOTIME	0x1000	/* [kernel] don't update inode timestamps */
-
-#define ATTR_KERNEL_FLAGS \
-	(ATTR_KERNOTIME)
-
 #define XFS_ATTR_FLAGS \
 	{ ATTR_DONTFOLLOW, 	"DONTFOLLOW" }, \
 	{ ATTR_ROOT,		"ROOT" }, \
 	{ ATTR_TRUST,		"TRUST" }, \
 	{ ATTR_SECURE,		"SECURE" }, \
 	{ ATTR_CREATE,		"CREATE" }, \
-	{ ATTR_REPLACE,		"REPLACE" }, \
-	{ ATTR_KERNOTIME,	"KERNOTIME" }
+	{ ATTR_REPLACE,		"REPLACE" }
 
 /*
  * The maximum size (into the kernel or returned from the kernel) of an
diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
index 3379ebc0c7c5..1594325d7742 100644
--- a/fs/xfs/libxfs/xfs_types.h
+++ b/fs/xfs/libxfs/xfs_types.h
@@ -223,6 +223,7 @@ typedef struct xfs_da_args {
 #define XFS_DA_OP_ADDNAME	0x0004	/* this is an add operation */
 #define XFS_DA_OP_OKNOENT	0x0008	/* lookup/add op, ENOENT ok, else die */
 #define XFS_DA_OP_CILOOKUP	0x0010	/* lookup to return CI name if found */
+#define XFS_DA_OP_NOTIME	0x0020	/* don't update inode timestamps */
 #define XFS_DA_OP_INCOMPLETE	0x0040	/* lookup INCOMPLETE attr keys */
 
 #define XFS_DA_OP_FLAGS \
@@ -231,6 +232,7 @@ typedef struct xfs_da_args {
 	{ XFS_DA_OP_ADDNAME,	"ADDNAME" }, \
 	{ XFS_DA_OP_OKNOENT,	"OKNOENT" }, \
 	{ XFS_DA_OP_CILOOKUP,	"CILOOKUP" }, \
+	{ XFS_DA_OP_NOTIME,	"NOTIME" }, \
 	{ XFS_DA_OP_INCOMPLETE,	"INCOMPLETE" }
 
 /*
diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
index f983c2b969e0..05537627211d 100644
--- a/fs/xfs/scrub/attr.c
+++ b/fs/xfs/scrub/attr.c
@@ -147,7 +147,7 @@ xchk_xattr_listent(
 		return;
 	}
 
-	args.flags = ATTR_KERNOTIME;
+	args.op_flags = XFS_DA_OP_NOTIME;
 	if (flags & XFS_ATTR_ROOT)
 		args.flags |= ATTR_ROOT;
 	else if (flags & XFS_ATTR_SECURE)
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 2da22595f828..dd1cb8c50518 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -436,7 +436,6 @@ xfs_ioc_attrmulti_one(
 
 	if ((flags & ATTR_ROOT) && (flags & ATTR_SECURE))
 		return -EINVAL;
-	flags &= ~ATTR_KERNEL_FLAGS;
 
 	name = strndup_user(uname, MAXNAMELEN);
 	if (IS_ERR(name))
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 17/30] xfs: factor out a xfs_attr_match helper
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (15 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 16/30] xfs: replace ATTR_KERNOTIME with XFS_DA_OP_NOTIME Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-02-08 12:48   ` Chandan Rajendra
  2020-01-29 17:02 ` [PATCH 18/30] xfs: cleanup struct xfs_attr_list_context Christoph Hellwig
                   ` (12 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

Factor out a helper that compares an on-disk attr vs the name, length and
flags specified in struct xfs_da_args.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_attr_leaf.c | 80 +++++++++++++----------------------
 1 file changed, 30 insertions(+), 50 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index b0658eb8fbcc..8852754153ba 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -445,14 +445,21 @@ xfs_attr3_leaf_read(
  * Namespace helper routines
  *========================================================================*/
 
-/*
- * If namespace bits don't match return 0.
- * If all match then return 1.
- */
-STATIC int
-xfs_attr_namesp_match(int arg_flags, int ondisk_flags)
+static bool
+xfs_attr_match(
+	struct xfs_da_args	*args,
+	uint8_t			namelen,
+	unsigned char		*name,
+	int			flags)
 {
-	return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags);
+	if (args->namelen != namelen)
+		return false;
+	if (memcmp(args->name, name, namelen) != 0)
+		return false;
+	if (XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags) !=
+	    XFS_ATTR_NSP_ONDISK(flags))
+		return false;
+	return true;
 }
 
 static int
@@ -678,15 +685,8 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
 	sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data;
 	sfe = &sf->list[0];
 	for (i = 0; i < sf->hdr.count; sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
-#ifdef DEBUG
-		if (sfe->namelen != args->namelen)
-			continue;
-		if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
-			continue;
-		if (!xfs_attr_namesp_match(args->flags, sfe->flags))
-			continue;
-		ASSERT(0);
-#endif
+		ASSERT(!xfs_attr_match(args, sfe->namelen, sfe->nameval,
+			sfe->flags));
 	}
 
 	offset = (char *)sfe - (char *)sf;
@@ -749,13 +749,9 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
 	for (i = 0; i < end; sfe = XFS_ATTR_SF_NEXTENTRY(sfe),
 					base += size, i++) {
 		size = XFS_ATTR_SF_ENTSIZE(sfe);
-		if (sfe->namelen != args->namelen)
-			continue;
-		if (memcmp(sfe->nameval, args->name, args->namelen) != 0)
-			continue;
-		if (!xfs_attr_namesp_match(args->flags, sfe->flags))
-			continue;
-		break;
+		if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
+				sfe->flags))
+			break;
 	}
 	if (i == end)
 		return -ENOATTR;
@@ -816,13 +812,9 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args)
 	sfe = &sf->list[0];
 	for (i = 0; i < sf->hdr.count;
 				sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
-		if (sfe->namelen != args->namelen)
-			continue;
-		if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
-			continue;
-		if (!xfs_attr_namesp_match(args->flags, sfe->flags))
-			continue;
-		return -EEXIST;
+		if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
+				sfe->flags))
+			return -EEXIST;
 	}
 	return -ENOATTR;
 }
@@ -847,14 +839,10 @@ xfs_attr_shortform_getvalue(
 	sfe = &sf->list[0];
 	for (i = 0; i < sf->hdr.count;
 				sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
-		if (sfe->namelen != args->namelen)
-			continue;
-		if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
-			continue;
-		if (!xfs_attr_namesp_match(args->flags, sfe->flags))
-			continue;
-		return xfs_attr_copy_value(args, &sfe->nameval[args->namelen],
-						sfe->valuelen);
+		if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
+				sfe->flags))
+			return xfs_attr_copy_value(args,
+				&sfe->nameval[args->namelen], sfe->valuelen);
 	}
 	return -ENOATTR;
 }
@@ -2409,23 +2397,15 @@ xfs_attr3_leaf_lookup_int(
 		}
 		if (entry->flags & XFS_ATTR_LOCAL) {
 			name_loc = xfs_attr3_leaf_name_local(leaf, probe);
-			if (name_loc->namelen != args->namelen)
-				continue;
-			if (memcmp(args->name, name_loc->nameval,
-							args->namelen) != 0)
-				continue;
-			if (!xfs_attr_namesp_match(args->flags, entry->flags))
+			if (!xfs_attr_match(args, name_loc->namelen,
+					name_loc->nameval, entry->flags))
 				continue;
 			args->index = probe;
 			return -EEXIST;
 		} else {
 			name_rmt = xfs_attr3_leaf_name_remote(leaf, probe);
-			if (name_rmt->namelen != args->namelen)
-				continue;
-			if (memcmp(args->name, name_rmt->name,
-							args->namelen) != 0)
-				continue;
-			if (!xfs_attr_namesp_match(args->flags, entry->flags))
+			if (!xfs_attr_match(args, name_rmt->namelen,
+					name_rmt->name, entry->flags))
 				continue;
 			args->index = probe;
 			args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 18/30] xfs: cleanup struct xfs_attr_list_context
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (16 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 17/30] xfs: factor out a xfs_attr_match helper Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-02-08 15:53   ` Chandan Rajendra
  2020-01-29 17:02 ` [PATCH 19/30] xfs: remove the unused ATTR_ENTRY macro Christoph Hellwig
                   ` (11 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

Replace the alist char pointer with a void buffer given that different
callers use it in different ways.  Use the chance to remove the typedef
and reduce the indentation of the struct definition so that it doesn't
overflow 80 char lines all over.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_attr.h | 34 +++++++++++++-------------
 fs/xfs/xfs_attr_list.c   | 53 ++++++++++++++++++++--------------------
 fs/xfs/xfs_trace.h       | 16 ++++++------
 fs/xfs/xfs_xattr.c       |  6 ++---
 4 files changed, 55 insertions(+), 54 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index 0f369399effd..0c8f7c7a6b65 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -99,28 +99,28 @@ typedef struct attrlist_cursor_kern {
 typedef void (*put_listent_func_t)(struct xfs_attr_list_context *, int,
 			      unsigned char *, int, int);
 
-typedef struct xfs_attr_list_context {
-	struct xfs_trans		*tp;
-	struct xfs_inode		*dp;		/* inode */
-	struct attrlist_cursor_kern	*cursor;	/* position in list */
-	char				*alist;		/* output buffer */
+struct xfs_attr_list_context {
+	struct xfs_trans	*tp;
+	struct xfs_inode	*dp;		/* inode */
+	struct attrlist_cursor_kern *cursor;	/* position in list */
+	void			*buffer;	/* output buffer */
 
 	/*
 	 * Abort attribute list iteration if non-zero.  Can be used to pass
 	 * error values to the xfs_attr_list caller.
 	 */
-	int				seen_enough;
-	bool				allow_incomplete;
-
-	ssize_t				count;		/* num used entries */
-	int				dupcnt;		/* count dup hashvals seen */
-	int				bufsize;	/* total buffer size */
-	int				firstu;		/* first used byte in buffer */
-	int				flags;		/* from VOP call */
-	int				resynch;	/* T/F: resynch with cursor */
-	put_listent_func_t		put_listent;	/* list output fmt function */
-	int				index;		/* index into output buffer */
-} xfs_attr_list_context_t;
+	int			seen_enough;
+	bool			allow_incomplete;
+
+	ssize_t			count;		/* num used entries */
+	int			dupcnt;		/* count dup hashvals seen */
+	int			bufsize;	/* total buffer size */
+	int			firstu;		/* first used byte in buffer */
+	int			flags;		/* from VOP call */
+	int			resynch;	/* T/F: resynch with cursor */
+	put_listent_func_t	put_listent;	/* list output fmt function */
+	int			index;		/* index into output buffer */
+};
 
 
 /*========================================================================
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index ac8dc64447d6..9c4acb6dc856 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -488,10 +488,11 @@ xfs_attr3_leaf_list_int(
  * Copy out attribute entries for attr_list(), for leaf attribute lists.
  */
 STATIC int
-xfs_attr_leaf_list(xfs_attr_list_context_t *context)
+xfs_attr_leaf_list(
+	struct xfs_attr_list_context	*context)
 {
-	int error;
-	struct xfs_buf *bp;
+	struct xfs_buf			*bp;
+	int				error;
 
 	trace_xfs_attr_leaf_list(context);
 
@@ -527,11 +528,11 @@ xfs_attr_list_int_ilocked(
 
 int
 xfs_attr_list_int(
-	xfs_attr_list_context_t *context)
+	struct xfs_attr_list_context	*context)
 {
-	int error;
-	xfs_inode_t *dp = context->dp;
-	uint		lock_mode;
+	struct xfs_inode		*dp = context->dp;
+	uint				lock_mode;
+	int				error;
 
 	XFS_STATS_INC(dp->i_mount, xs_attr_list);
 
@@ -557,15 +558,15 @@ xfs_attr_list_int(
  */
 STATIC void
 xfs_attr_put_listent(
-	xfs_attr_list_context_t *context,
-	int		flags,
-	unsigned char	*name,
-	int		namelen,
-	int		valuelen)
+	struct xfs_attr_list_context	*context,
+	int			flags,
+	unsigned char		*name,
+	int			namelen,
+	int			valuelen)
 {
-	struct attrlist *alist = (struct attrlist *)context->alist;
-	attrlist_ent_t *aep;
-	int arraytop;
+	struct attrlist		*alist = context->buffer;
+	struct attrlist_ent	*aep;
+	int			arraytop;
 
 	ASSERT(!context->seen_enough);
 	ASSERT(context->count >= 0);
@@ -593,7 +594,7 @@ xfs_attr_put_listent(
 		return;
 	}
 
-	aep = (attrlist_ent_t *)&context->alist[context->firstu];
+	aep = context->buffer + context->firstu;
 	aep->a_valuelen = valuelen;
 	memcpy(aep->a_name, name, namelen);
 	aep->a_name[namelen] = 0;
@@ -612,15 +613,15 @@ xfs_attr_put_listent(
  */
 int
 xfs_attr_list(
-	xfs_inode_t	*dp,
-	char		*buffer,
-	int		bufsize,
-	int		flags,
-	attrlist_cursor_kern_t *cursor)
+	struct xfs_inode		*dp,
+	char				*buffer,
+	int				bufsize,
+	int				flags,
+	struct attrlist_cursor_kern	*cursor)
 {
-	xfs_attr_list_context_t context;
-	struct attrlist *alist;
-	int error;
+	struct xfs_attr_list_context	context;
+	struct attrlist			*alist;
+	int				error;
 
 	/*
 	 * Validate the cursor.
@@ -645,12 +646,12 @@ xfs_attr_list(
 	context.cursor = cursor;
 	context.resynch = 1;
 	context.flags = flags;
-	context.alist = buffer;
+	context.buffer = buffer;
 	context.bufsize = (bufsize & ~(sizeof(int)-1));  /* align */
 	context.firstu = context.bufsize;
 	context.put_listent = xfs_attr_put_listent;
 
-	alist = (struct attrlist *)context.alist;
+	alist = context.buffer;
 	alist->al_count = 0;
 	alist->al_more = 0;
 	alist->al_offset[0] = context.bufsize;
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index a86be7f807ee..8358a92987f9 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -45,7 +45,7 @@ DECLARE_EVENT_CLASS(xfs_attr_list_class,
 		__field(u32, hashval)
 		__field(u32, blkno)
 		__field(u32, offset)
-		__field(void *, alist)
+		__field(void *, buffer)
 		__field(int, bufsize)
 		__field(int, count)
 		__field(int, firstu)
@@ -58,21 +58,21 @@ DECLARE_EVENT_CLASS(xfs_attr_list_class,
 		__entry->hashval = ctx->cursor->hashval;
 		__entry->blkno = ctx->cursor->blkno;
 		__entry->offset = ctx->cursor->offset;
-		__entry->alist = ctx->alist;
+		__entry->buffer = ctx->buffer;
 		__entry->bufsize = ctx->bufsize;
 		__entry->count = ctx->count;
 		__entry->firstu = ctx->firstu;
 		__entry->flags = ctx->flags;
 	),
 	TP_printk("dev %d:%d ino 0x%llx cursor h/b/o 0x%x/0x%x/%u dupcnt %u "
-		  "alist %p size %u count %u firstu %u flags %d %s",
+		  "buffer %p size %u count %u firstu %u flags %d %s",
 		  MAJOR(__entry->dev), MINOR(__entry->dev),
 		   __entry->ino,
 		   __entry->hashval,
 		   __entry->blkno,
 		   __entry->offset,
 		   __entry->dupcnt,
-		   __entry->alist,
+		   __entry->buffer,
 		   __entry->bufsize,
 		   __entry->count,
 		   __entry->firstu,
@@ -169,7 +169,7 @@ TRACE_EVENT(xfs_attr_list_node_descend,
 		__field(u32, hashval)
 		__field(u32, blkno)
 		__field(u32, offset)
-		__field(void *, alist)
+		__field(void *, buffer)
 		__field(int, bufsize)
 		__field(int, count)
 		__field(int, firstu)
@@ -184,7 +184,7 @@ TRACE_EVENT(xfs_attr_list_node_descend,
 		__entry->hashval = ctx->cursor->hashval;
 		__entry->blkno = ctx->cursor->blkno;
 		__entry->offset = ctx->cursor->offset;
-		__entry->alist = ctx->alist;
+		__entry->buffer = ctx->buffer;
 		__entry->bufsize = ctx->bufsize;
 		__entry->count = ctx->count;
 		__entry->firstu = ctx->firstu;
@@ -193,7 +193,7 @@ TRACE_EVENT(xfs_attr_list_node_descend,
 		__entry->bt_before = be32_to_cpu(btree->before);
 	),
 	TP_printk("dev %d:%d ino 0x%llx cursor h/b/o 0x%x/0x%x/%u dupcnt %u "
-		  "alist %p size %u count %u firstu %u flags %d %s "
+		  "buffer %p size %u count %u firstu %u flags %d %s "
 		  "node hashval %u, node before %u",
 		  MAJOR(__entry->dev), MINOR(__entry->dev),
 		   __entry->ino,
@@ -201,7 +201,7 @@ TRACE_EVENT(xfs_attr_list_node_descend,
 		   __entry->blkno,
 		   __entry->offset,
 		   __entry->dupcnt,
-		   __entry->alist,
+		   __entry->buffer,
 		   __entry->bufsize,
 		   __entry->count,
 		   __entry->firstu,
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
index c9c44f8aebed..8880dee3400f 100644
--- a/fs/xfs/xfs_xattr.c
+++ b/fs/xfs/xfs_xattr.c
@@ -132,7 +132,7 @@ __xfs_xattr_put_listent(
 	if (context->count < 0 || context->seen_enough)
 		return;
 
-	if (!context->alist)
+	if (!context->buffer)
 		goto compute_size;
 
 	arraytop = context->count + prefix_len + namelen + 1;
@@ -141,7 +141,7 @@ __xfs_xattr_put_listent(
 		context->seen_enough = 1;
 		return;
 	}
-	offset = (char *)context->alist + context->count;
+	offset = context->buffer + context->count;
 	strncpy(offset, prefix, prefix_len);
 	offset += prefix_len;
 	strncpy(offset, (char *)name, namelen);			/* real name */
@@ -227,7 +227,7 @@ xfs_vn_listxattr(
 	context.dp = XFS_I(inode);
 	context.cursor = &cursor;
 	context.resynch = 1;
-	context.alist = size ? data : NULL;
+	context.buffer = size ? data : NULL;
 	context.bufsize = size;
 	context.firstu = context.bufsize;
 	context.put_listent = xfs_xattr_put_listent;
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 19/30] xfs: remove the unused ATTR_ENTRY macro
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (17 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 18/30] xfs: cleanup struct xfs_attr_list_context Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-01-29 17:02 ` [PATCH 20/30] xfs: open code ATTR_ENTSIZE Christoph Hellwig
                   ` (10 subsequent siblings)
  29 siblings, 0 replies; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_attr.h | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index 0c8f7c7a6b65..31c0ffde4f59 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -69,14 +69,6 @@ typedef struct attrlist_ent {	/* data from attr_list() */
 	char	a_name[1];	/* attr name (NULL terminated) */
 } attrlist_ent_t;
 
-/*
- * Given a pointer to the (char*) buffer containing the attr_list() result,
- * and an index, return a pointer to the indicated attribute in the buffer.
- */
-#define	ATTR_ENTRY(buffer, index)		\
-	((attrlist_ent_t *)			\
-	 &((char *)buffer)[ ((attrlist_t *)(buffer))->al_offset[index] ])
-
 /*
  * Kernel-internal version of the attrlist cursor.
  */
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 20/30] xfs: open code ATTR_ENTSIZE
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (18 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 19/30] xfs: remove the unused ATTR_ENTRY macro Christoph Hellwig
@ 2020-01-29 17:02 ` Christoph Hellwig
  2020-02-09  6:57   ` Chandan Rajendra
  2020-01-29 17:03 ` [PATCH 21/30] xfs: move the legacy xfs_attr_list to xfs_ioctl.c Christoph Hellwig
                   ` (9 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:02 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins

Replace an opencoded offsetof and round_up hiden behind to macros
using the open code variant using the standard helpers.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/xfs_attr_list.c | 11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index 9c4acb6dc856..f1ca8ef8be22 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -545,12 +545,6 @@ xfs_attr_list_int(
 	return error;
 }
 
-#define	ATTR_ENTBASESIZE		/* minimum bytes used by an attr */ \
-	(((struct attrlist_ent *) 0)->a_name - (char *) 0)
-#define	ATTR_ENTSIZE(namelen)		/* actual bytes used by an attr */ \
-	((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(uint32_t)-1) \
-	 & ~(sizeof(uint32_t)-1))
-
 /*
  * Format an attribute and copy it out to the user's buffer.
  * Take care to check values and protect against them changing later,
@@ -586,7 +580,10 @@ xfs_attr_put_listent(
 
 	arraytop = sizeof(*alist) +
 			context->count * sizeof(alist->al_offset[0]);
-	context->firstu -= ATTR_ENTSIZE(namelen);
+
+	/* decrement by the actual bytes used by the attr */
+	context->firstu -= round_up(offsetof(struct attrlist_ent, a_name) +
+			namelen + 1, sizeof(uint32_t));
 	if (context->firstu < arraytop) {
 		trace_xfs_attr_list_full(context);
 		alist->al_more = 1;
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 21/30] xfs: move the legacy xfs_attr_list to xfs_ioctl.c
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (19 preceding siblings ...)
  2020-01-29 17:02 ` [PATCH 20/30] xfs: open code ATTR_ENTSIZE Christoph Hellwig
@ 2020-01-29 17:03 ` Christoph Hellwig
  2020-02-09  7:44   ` Chandan Rajendra
  2020-01-29 17:03 ` [PATCH 22/30] xfs: rename xfs_attr_list_int to xfs_attr_list Christoph Hellwig
                   ` (8 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:03 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins

The old xfs_attr_list code is only used by the attrlist by handle
ioctl.  Move it to xfs_ioctl.c with its user.  Also move the
attrlist and attrlist_ent structure to xfs_fs.h, as they are exposed
user ABIs.  They are used through libattr headers with the same name
by at least xfsdump.  Also document this relation so that it doesn't
require a research project to figure out.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_attr.h |  23 --------
 fs/xfs/libxfs/xfs_fs.h   |  26 +++++++++
 fs/xfs/xfs_attr_list.c   | 113 ---------------------------------------
 fs/xfs/xfs_ioctl.c       | 110 ++++++++++++++++++++++++++++++++++++-
 fs/xfs/xfs_ioctl.h       |  12 +++--
 fs/xfs/xfs_ioctl32.c     |   4 +-
 6 files changed, 144 insertions(+), 144 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index 31c0ffde4f59..0e3c213f78ce 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -48,27 +48,6 @@ struct xfs_attr_list_context;
  */
 #define	ATTR_MAX_VALUELEN	(64*1024)	/* max length of a value */
 
-/*
- * Define how lists of attribute names are returned to the user from
- * the attr_list() call.  A large, 32bit aligned, buffer is passed in
- * along with its size.  We put an array of offsets at the top that each
- * reference an attrlist_ent_t and pack the attrlist_ent_t's at the bottom.
- */
-typedef struct attrlist {
-	__s32	al_count;	/* number of entries in attrlist */
-	__s32	al_more;	/* T/F: more attrs (do call again) */
-	__s32	al_offset[1];	/* byte offsets of attrs [var-sized] */
-} attrlist_t;
-
-/*
- * Show the interesting info about one attribute.  This is what the
- * al_offset[i] entry points to.
- */
-typedef struct attrlist_ent {	/* data from attr_list() */
-	__u32	a_valuelen;	/* number bytes in value of attr */
-	char	a_name[1];	/* attr name (NULL terminated) */
-} attrlist_ent_t;
-
 /*
  * Kernel-internal version of the attrlist cursor.
  */
@@ -131,8 +110,6 @@ int xfs_attr_get(struct xfs_da_args *args);
 int xfs_attr_set(struct xfs_da_args *args);
 int xfs_attr_set_args(struct xfs_da_args *args);
 int xfs_attr_remove_args(struct xfs_da_args *args);
-int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
-		  int flags, struct attrlist_cursor_kern *cursor);
 bool xfs_attr_namecheck(const void *name, size_t length);
 
 #endif	/* __XFS_ATTR_H__ */
diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index ef95ca07d084..2c2b6e2b58f4 100644
--- a/fs/xfs/libxfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
@@ -572,6 +572,32 @@ typedef struct xfs_attrlist_cursor {
 	__u32		opaque[4];
 } xfs_attrlist_cursor_t;
 
+/*
+ * Define how lists of attribute names are returned to the user from
+ * the attr_list() call.  A large, 32bit aligned, buffer is passed in
+ * along with its size.  We put an array of offsets at the top that each
+ * reference an attrlist_ent_t and pack the attrlist_ent_t's at the bottom.
+ *
+ * NOTE: struct xfs_attrlist must match struct attrlist defined in libattr.
+ */
+struct xfs_attrlist {
+	__s32	al_count;	/* number of entries in attrlist */
+	__s32	al_more;	/* T/F: more attrs (do call again) */
+	__s32	al_offset[1];	/* byte offsets of attrs [var-sized] */
+};
+
+/*
+ * Show the interesting info about one attribute.  This is what the
+ * al_offset[i] entry points to.
+ *
+ * NOTE: struct xfs_attrlist_ent must match struct attrlist_ent defined in
+ * libattr.
+ */
+struct xfs_attrlist_ent {	/* data from attr_list() */
+	__u32	a_valuelen;	/* number bytes in value of attr */
+	char	a_name[1];	/* attr name (NULL terminated) */
+};
+
 typedef struct xfs_fsop_attrlist_handlereq {
 	struct xfs_fsop_handlereq	hreq; /* handle interface structure */
 	struct xfs_attrlist_cursor	pos; /* opaque cookie, list offset */
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index f1ca8ef8be22..369ce1d3dd45 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -544,116 +544,3 @@ xfs_attr_list_int(
 	xfs_iunlock(dp, lock_mode);
 	return error;
 }
-
-/*
- * Format an attribute and copy it out to the user's buffer.
- * Take care to check values and protect against them changing later,
- * we may be reading them directly out of a user buffer.
- */
-STATIC void
-xfs_attr_put_listent(
-	struct xfs_attr_list_context	*context,
-	int			flags,
-	unsigned char		*name,
-	int			namelen,
-	int			valuelen)
-{
-	struct attrlist		*alist = context->buffer;
-	struct attrlist_ent	*aep;
-	int			arraytop;
-
-	ASSERT(!context->seen_enough);
-	ASSERT(context->count >= 0);
-	ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
-	ASSERT(context->firstu >= sizeof(*alist));
-	ASSERT(context->firstu <= context->bufsize);
-
-	/*
-	 * Only list entries in the right namespace.
-	 */
-	if (((context->flags & ATTR_SECURE) == 0) !=
-	    ((flags & XFS_ATTR_SECURE) == 0))
-		return;
-	if (((context->flags & ATTR_ROOT) == 0) !=
-	    ((flags & XFS_ATTR_ROOT) == 0))
-		return;
-
-	arraytop = sizeof(*alist) +
-			context->count * sizeof(alist->al_offset[0]);
-
-	/* decrement by the actual bytes used by the attr */
-	context->firstu -= round_up(offsetof(struct attrlist_ent, a_name) +
-			namelen + 1, sizeof(uint32_t));
-	if (context->firstu < arraytop) {
-		trace_xfs_attr_list_full(context);
-		alist->al_more = 1;
-		context->seen_enough = 1;
-		return;
-	}
-
-	aep = context->buffer + context->firstu;
-	aep->a_valuelen = valuelen;
-	memcpy(aep->a_name, name, namelen);
-	aep->a_name[namelen] = 0;
-	alist->al_offset[context->count++] = context->firstu;
-	alist->al_count = context->count;
-	trace_xfs_attr_list_add(context);
-	return;
-}
-
-/*
- * Generate a list of extended attribute names and optionally
- * also value lengths.  Positive return value follows the XFS
- * convention of being an error, zero or negative return code
- * is the length of the buffer returned (negated), indicating
- * success.
- */
-int
-xfs_attr_list(
-	struct xfs_inode		*dp,
-	char				*buffer,
-	int				bufsize,
-	int				flags,
-	struct attrlist_cursor_kern	*cursor)
-{
-	struct xfs_attr_list_context	context;
-	struct attrlist			*alist;
-	int				error;
-
-	/*
-	 * Validate the cursor.
-	 */
-	if (cursor->pad1 || cursor->pad2)
-		return -EINVAL;
-	if ((cursor->initted == 0) &&
-	    (cursor->hashval || cursor->blkno || cursor->offset))
-		return -EINVAL;
-
-	/*
-	 * Check for a properly aligned buffer.
-	 */
-	if (((long)buffer) & (sizeof(int)-1))
-		return -EFAULT;
-
-	/*
-	 * Initialize the output buffer.
-	 */
-	memset(&context, 0, sizeof(context));
-	context.dp = dp;
-	context.cursor = cursor;
-	context.resynch = 1;
-	context.flags = flags;
-	context.buffer = buffer;
-	context.bufsize = (bufsize & ~(sizeof(int)-1));  /* align */
-	context.firstu = context.bufsize;
-	context.put_listent = xfs_attr_put_listent;
-
-	alist = context.buffer;
-	alist->al_count = 0;
-	alist->al_more = 0;
-	alist->al_offset[0] = context.bufsize;
-
-	error = xfs_attr_list_int(&context);
-	ASSERT(error <= 0);
-	return error;
-}
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index dd1cb8c50518..47c39895977b 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -35,6 +35,7 @@
 #include "xfs_health.h"
 #include "xfs_reflink.h"
 #include "xfs_ioctl.h"
+#include "xfs_da_format.h"
 
 #include <linux/mount.h>
 #include <linux/namei.h>
@@ -292,6 +293,111 @@ xfs_readlink_by_handle(
 	return error;
 }
 
+/*
+ * Format an attribute and copy it out to the user's buffer.
+ * Take care to check values and protect against them changing later,
+ * we may be reading them directly out of a user buffer.
+ */
+static void
+xfs_ioc_attr_put_listent(
+	struct xfs_attr_list_context *context,
+	int			flags,
+	unsigned char		*name,
+	int			namelen,
+	int			valuelen)
+{
+	struct xfs_attrlist	*alist = context->buffer;
+	struct xfs_attrlist_ent	*aep;
+	int			arraytop;
+
+	ASSERT(!context->seen_enough);
+	ASSERT(context->count >= 0);
+	ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
+	ASSERT(context->firstu >= sizeof(*alist));
+	ASSERT(context->firstu <= context->bufsize);
+
+	/*
+	 * Only list entries in the right namespace.
+	 */
+	if (((context->flags & ATTR_SECURE) == 0) !=
+	    ((flags & XFS_ATTR_SECURE) == 0))
+		return;
+	if (((context->flags & ATTR_ROOT) == 0) !=
+	    ((flags & XFS_ATTR_ROOT) == 0))
+		return;
+
+	arraytop = sizeof(*alist) +
+			context->count * sizeof(alist->al_offset[0]);
+
+	/* decrement by the actual bytes used by the attr */
+	context->firstu -= round_up(offsetof(struct xfs_attrlist_ent, a_name) +
+			namelen + 1, sizeof(uint32_t));
+	if (context->firstu < arraytop) {
+		trace_xfs_attr_list_full(context);
+		alist->al_more = 1;
+		context->seen_enough = 1;
+		return;
+	}
+
+	aep = context->buffer + context->firstu;
+	aep->a_valuelen = valuelen;
+	memcpy(aep->a_name, name, namelen);
+	aep->a_name[namelen] = 0;
+	alist->al_offset[context->count++] = context->firstu;
+	alist->al_count = context->count;
+	trace_xfs_attr_list_add(context);
+}
+
+int
+xfs_ioc_attr_list(
+	struct xfs_inode		*dp,
+	char				*buffer,
+	int				bufsize,
+	int				flags,
+	struct attrlist_cursor_kern	*cursor)
+{
+	struct xfs_attr_list_context	context;
+	struct xfs_attrlist		*alist;
+	int				error;
+
+	/*
+	 * Validate the cursor.
+	 */
+	if (cursor->pad1 || cursor->pad2)
+		return -EINVAL;
+	if ((cursor->initted == 0) &&
+	    (cursor->hashval || cursor->blkno || cursor->offset))
+		return -EINVAL;
+
+	/*
+	 * Check for a properly aligned buffer.
+	 */
+	if (((long)buffer) & (sizeof(int)-1))
+		return -EFAULT;
+
+	/*
+	 * Initialize the output buffer.
+	 */
+	memset(&context, 0, sizeof(context));
+	context.dp = dp;
+	context.cursor = cursor;
+	context.resynch = 1;
+	context.flags = flags;
+	context.buffer = buffer;
+	context.bufsize = (bufsize & ~(sizeof(int)-1));  /* align */
+	context.firstu = context.bufsize;
+	context.put_listent = xfs_ioc_attr_put_listent;
+
+	alist = context.buffer;
+	alist->al_count = 0;
+	alist->al_more = 0;
+	alist->al_offset[0] = context.bufsize;
+
+	error = xfs_attr_list_int(&context);
+	ASSERT(error <= 0);
+	return error;
+}
+
 STATIC int
 xfs_attrlist_by_handle(
 	struct file		*parfilp,
@@ -308,7 +414,7 @@ xfs_attrlist_by_handle(
 		return -EPERM;
 	if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
 		return -EFAULT;
-	if (al_hreq.buflen < sizeof(struct attrlist) ||
+	if (al_hreq.buflen < sizeof(struct xfs_attrlist) ||
 	    al_hreq.buflen > XFS_XATTR_LIST_MAX)
 		return -EINVAL;
 
@@ -329,7 +435,7 @@ xfs_attrlist_by_handle(
 		goto out_dput;
 
 	cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
-	error = xfs_attr_list(XFS_I(d_inode(dentry)), kbuf, al_hreq.buflen,
+	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), kbuf, al_hreq.buflen,
 					al_hreq.flags, cursor);
 	if (error)
 		goto out_kfree;
diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
index bb50cb3dc61f..cb7b94c576a7 100644
--- a/fs/xfs/xfs_ioctl.h
+++ b/fs/xfs/xfs_ioctl.h
@@ -6,6 +6,12 @@
 #ifndef __XFS_IOCTL_H__
 #define __XFS_IOCTL_H__
 
+struct attrlist_cursor_kern;
+struct xfs_bstat;
+struct xfs_ibulk;
+struct xfs_inogrp;
+
+
 extern int
 xfs_ioc_space(
 	struct file		*filp,
@@ -33,6 +39,8 @@ xfs_readlink_by_handle(
 int xfs_ioc_attrmulti_one(struct file *parfilp, struct inode *inode,
 		uint32_t opcode, void __user *uname, void __user *value,
 		uint32_t *len, uint32_t flags);
+int xfs_ioc_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
+	int flags, struct attrlist_cursor_kern *cursor);
 
 extern struct dentry *
 xfs_handle_to_dentry(
@@ -52,10 +60,6 @@ xfs_file_compat_ioctl(
 	unsigned int		cmd,
 	unsigned long		arg);
 
-struct xfs_ibulk;
-struct xfs_bstat;
-struct xfs_inogrp;
-
 int xfs_fsbulkstat_one_fmt(struct xfs_ibulk *breq,
 			   const struct xfs_bulkstat *bstat);
 int xfs_fsinumbers_fmt(struct xfs_ibulk *breq, const struct xfs_inumbers *igrp);
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index e1daf095c585..10ea0222954c 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -366,7 +366,7 @@ xfs_compat_attrlist_by_handle(
 	if (copy_from_user(&al_hreq, arg,
 			   sizeof(compat_xfs_fsop_attrlist_handlereq_t)))
 		return -EFAULT;
-	if (al_hreq.buflen < sizeof(struct attrlist) ||
+	if (al_hreq.buflen < sizeof(struct xfs_attrlist) ||
 	    al_hreq.buflen > XFS_XATTR_LIST_MAX)
 		return -EINVAL;
 
@@ -388,7 +388,7 @@ xfs_compat_attrlist_by_handle(
 		goto out_dput;
 
 	cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
-	error = xfs_attr_list(XFS_I(d_inode(dentry)), kbuf, al_hreq.buflen,
+	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), kbuf, al_hreq.buflen,
 					al_hreq.flags, cursor);
 	if (error)
 		goto out_kfree;
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 22/30] xfs: rename xfs_attr_list_int to xfs_attr_list
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (20 preceding siblings ...)
  2020-01-29 17:03 ` [PATCH 21/30] xfs: move the legacy xfs_attr_list to xfs_ioctl.c Christoph Hellwig
@ 2020-01-29 17:03 ` Christoph Hellwig
  2020-02-09  7:52   ` Chandan Rajendra
  2020-01-29 17:03 ` [PATCH 23/30] xfs: lift common checks into xfs_ioc_attr_list Christoph Hellwig
                   ` (7 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:03 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

The version taking the context structure is the main interface to list
attributes, so drop the _int postfix.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_attr.h | 4 ++--
 fs/xfs/scrub/attr.c      | 4 ++--
 fs/xfs/xfs_attr_list.c   | 6 +++---
 fs/xfs/xfs_ioctl.c       | 2 +-
 fs/xfs/xfs_xattr.c       | 2 +-
 5 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index 0e3c213f78ce..8d42f5782ff7 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -102,8 +102,8 @@ struct xfs_attr_list_context {
  * Overall external interface routines.
  */
 int xfs_attr_inactive(struct xfs_inode *dp);
-int xfs_attr_list_int_ilocked(struct xfs_attr_list_context *);
-int xfs_attr_list_int(struct xfs_attr_list_context *);
+int xfs_attr_list_ilocked(struct xfs_attr_list_context *);
+int xfs_attr_list(struct xfs_attr_list_context *);
 int xfs_inode_hasattr(struct xfs_inode *ip);
 int xfs_attr_get_ilocked(struct xfs_da_args *args);
 int xfs_attr_get(struct xfs_da_args *args);
diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
index 05537627211d..9e336d797616 100644
--- a/fs/xfs/scrub/attr.c
+++ b/fs/xfs/scrub/attr.c
@@ -98,7 +98,7 @@ struct xchk_xattr {
 /*
  * Check that an extended attribute key can be looked up by hash.
  *
- * We use the XFS attribute list iterator (i.e. xfs_attr_list_int_ilocked)
+ * We use the XFS attribute list iterator (i.e. xfs_attr_list_ilocked)
  * to call this function for every attribute key in an inode.  Once
  * we're here, we load the attribute value to see if any errors happen,
  * or if we get more or less data than we expected.
@@ -516,7 +516,7 @@ xchk_xattr(
 	 * iteration, which doesn't really follow the usual buffer
 	 * locking order.
 	 */
-	error = xfs_attr_list_int_ilocked(&sx.context);
+	error = xfs_attr_list_ilocked(&sx.context);
 	if (!xchk_fblock_process_error(sc, XFS_ATTR_FORK, 0, &error))
 		goto out;
 
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index 369ce1d3dd45..ea79219859a0 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -507,7 +507,7 @@ xfs_attr_leaf_list(
 }
 
 int
-xfs_attr_list_int_ilocked(
+xfs_attr_list_ilocked(
 	struct xfs_attr_list_context	*context)
 {
 	struct xfs_inode		*dp = context->dp;
@@ -527,7 +527,7 @@ xfs_attr_list_int_ilocked(
 }
 
 int
-xfs_attr_list_int(
+xfs_attr_list(
 	struct xfs_attr_list_context	*context)
 {
 	struct xfs_inode		*dp = context->dp;
@@ -540,7 +540,7 @@ xfs_attr_list_int(
 		return -EIO;
 
 	lock_mode = xfs_ilock_attr_map_shared(dp);
-	error = xfs_attr_list_int_ilocked(context);
+	error = xfs_attr_list_ilocked(context);
 	xfs_iunlock(dp, lock_mode);
 	return error;
 }
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 47c39895977b..0f9326bc055c 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -393,7 +393,7 @@ xfs_ioc_attr_list(
 	alist->al_more = 0;
 	alist->al_offset[0] = context.bufsize;
 
-	error = xfs_attr_list_int(&context);
+	error = xfs_attr_list(&context);
 	ASSERT(error <= 0);
 	return error;
 }
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
index 8880dee3400f..e1951d2b878e 100644
--- a/fs/xfs/xfs_xattr.c
+++ b/fs/xfs/xfs_xattr.c
@@ -232,7 +232,7 @@ xfs_vn_listxattr(
 	context.firstu = context.bufsize;
 	context.put_listent = xfs_xattr_put_listent;
 
-	error = xfs_attr_list_int(&context);
+	error = xfs_attr_list(&context);
 	if (error)
 		return error;
 	if (context.count < 0)
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 23/30] xfs: lift common checks into xfs_ioc_attr_list
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (21 preceding siblings ...)
  2020-01-29 17:03 ` [PATCH 22/30] xfs: rename xfs_attr_list_int to xfs_attr_list Christoph Hellwig
@ 2020-01-29 17:03 ` Christoph Hellwig
  2020-02-09  8:03   ` Chandan Rajendra
  2020-01-29 17:03 ` [PATCH 24/30] xfs: lift buffer allocation " Christoph Hellwig
                   ` (6 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:03 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

Lift the flags and bufsize checks from both callers into the common code
in xfs_ioc_attr_list.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_ioctl.c   | 23 ++++++++++++-----------
 fs/xfs/xfs_ioctl32.c | 11 -----------
 2 files changed, 12 insertions(+), 22 deletions(-)

diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 0f9326bc055c..c8814808a551 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -360,6 +360,18 @@ xfs_ioc_attr_list(
 	struct xfs_attrlist		*alist;
 	int				error;
 
+	if (bufsize < sizeof(struct xfs_attrlist) ||
+	    bufsize > XFS_XATTR_LIST_MAX)
+		return -EINVAL;
+
+	/*
+	 * Reject flags, only allow namespaces.
+	 */
+	if (flags & ~(ATTR_ROOT | ATTR_SECURE))
+		return -EINVAL;
+	if (flags == (ATTR_ROOT | ATTR_SECURE))
+		return -EINVAL;
+
 	/*
 	 * Validate the cursor.
 	 */
@@ -414,17 +426,6 @@ xfs_attrlist_by_handle(
 		return -EPERM;
 	if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
 		return -EFAULT;
-	if (al_hreq.buflen < sizeof(struct xfs_attrlist) ||
-	    al_hreq.buflen > XFS_XATTR_LIST_MAX)
-		return -EINVAL;
-
-	/*
-	 * Reject flags, only allow namespaces.
-	 */
-	if (al_hreq.flags & ~(ATTR_ROOT | ATTR_SECURE))
-		return -EINVAL;
-	if (al_hreq.flags == (ATTR_ROOT | ATTR_SECURE))
-		return -EINVAL;
 
 	dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
 	if (IS_ERR(dentry))
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index 10ea0222954c..840d17951407 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -366,17 +366,6 @@ xfs_compat_attrlist_by_handle(
 	if (copy_from_user(&al_hreq, arg,
 			   sizeof(compat_xfs_fsop_attrlist_handlereq_t)))
 		return -EFAULT;
-	if (al_hreq.buflen < sizeof(struct xfs_attrlist) ||
-	    al_hreq.buflen > XFS_XATTR_LIST_MAX)
-		return -EINVAL;
-
-	/*
-	 * Reject flags, only allow namespaces.
-	 */
-	if (al_hreq.flags & ~(ATTR_ROOT | ATTR_SECURE))
-		return -EINVAL;
-	if (al_hreq.flags == (ATTR_ROOT | ATTR_SECURE))
-		return -EINVAL;
 
 	dentry = xfs_compat_handlereq_to_dentry(parfilp, &al_hreq.hreq);
 	if (IS_ERR(dentry))
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 24/30] xfs: lift buffer allocation into xfs_ioc_attr_list
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (22 preceding siblings ...)
  2020-01-29 17:03 ` [PATCH 23/30] xfs: lift common checks into xfs_ioc_attr_list Christoph Hellwig
@ 2020-01-29 17:03 ` " Christoph Hellwig
  2020-02-09  8:24   ` Chandan Rajendra
  2020-01-29 17:03 ` [PATCH 25/30] xfs: lift cursor copy in/out " Christoph Hellwig
                   ` (5 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:03 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

Lift the buffer allocation from the two callers into xfs_ioc_attr_list.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_ioctl.c   | 39 ++++++++++++++++-----------------------
 fs/xfs/xfs_ioctl.h   |  2 +-
 fs/xfs/xfs_ioctl32.c | 22 +++++-----------------
 3 files changed, 22 insertions(+), 41 deletions(-)

diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index c8814808a551..cdb3800dfcef 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -351,13 +351,14 @@ xfs_ioc_attr_put_listent(
 int
 xfs_ioc_attr_list(
 	struct xfs_inode		*dp,
-	char				*buffer,
+	void __user			*ubuf,
 	int				bufsize,
 	int				flags,
 	struct attrlist_cursor_kern	*cursor)
 {
 	struct xfs_attr_list_context	context;
 	struct xfs_attrlist		*alist;
+	void				*buffer;
 	int				error;
 
 	if (bufsize < sizeof(struct xfs_attrlist) ||
@@ -381,11 +382,9 @@ xfs_ioc_attr_list(
 	    (cursor->hashval || cursor->blkno || cursor->offset))
 		return -EINVAL;
 
-	/*
-	 * Check for a properly aligned buffer.
-	 */
-	if (((long)buffer) & (sizeof(int)-1))
-		return -EFAULT;
+	buffer = kmem_zalloc_large(bufsize, 0);
+	if (!buffer)
+		return -ENOMEM;
 
 	/*
 	 * Initialize the output buffer.
@@ -406,7 +405,13 @@ xfs_ioc_attr_list(
 	alist->al_offset[0] = context.bufsize;
 
 	error = xfs_attr_list(&context);
-	ASSERT(error <= 0);
+	if (error)
+		goto out_free;
+
+	if (copy_to_user(ubuf, buffer, bufsize))
+		error = -EFAULT;
+out_free:
+	kmem_free(buffer);
 	return error;
 }
 
@@ -420,7 +425,6 @@ xfs_attrlist_by_handle(
 	struct xfs_fsop_attrlist_handlereq __user	*p = arg;
 	xfs_fsop_attrlist_handlereq_t al_hreq;
 	struct dentry		*dentry;
-	char			*kbuf;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
@@ -431,26 +435,15 @@ xfs_attrlist_by_handle(
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
-	kbuf = kmem_zalloc_large(al_hreq.buflen, 0);
-	if (!kbuf)
-		goto out_dput;
-
 	cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
-	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), kbuf, al_hreq.buflen,
-					al_hreq.flags, cursor);
+	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), al_hreq.buffer,
+				  al_hreq.buflen, al_hreq.flags, cursor);
 	if (error)
-		goto out_kfree;
-
-	if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t))) {
-		error = -EFAULT;
-		goto out_kfree;
-	}
+		goto out_dput;
 
-	if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen))
+	if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t)))
 		error = -EFAULT;
 
-out_kfree:
-	kmem_free(kbuf);
 out_dput:
 	dput(dentry);
 	return error;
diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
index cb7b94c576a7..ec6448b259fb 100644
--- a/fs/xfs/xfs_ioctl.h
+++ b/fs/xfs/xfs_ioctl.h
@@ -39,7 +39,7 @@ xfs_readlink_by_handle(
 int xfs_ioc_attrmulti_one(struct file *parfilp, struct inode *inode,
 		uint32_t opcode, void __user *uname, void __user *value,
 		uint32_t *len, uint32_t flags);
-int xfs_ioc_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
+int xfs_ioc_attr_list(struct xfs_inode *dp, void __user *ubuf, int bufsize,
 	int flags, struct attrlist_cursor_kern *cursor);
 
 extern struct dentry *
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index 840d17951407..17e14916757b 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -359,7 +359,6 @@ xfs_compat_attrlist_by_handle(
 	compat_xfs_fsop_attrlist_handlereq_t __user *p = arg;
 	compat_xfs_fsop_attrlist_handlereq_t al_hreq;
 	struct dentry		*dentry;
-	char			*kbuf;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
@@ -371,27 +370,16 @@ xfs_compat_attrlist_by_handle(
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
-	error = -ENOMEM;
-	kbuf = kmem_zalloc_large(al_hreq.buflen, 0);
-	if (!kbuf)
-		goto out_dput;
-
 	cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
-	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), kbuf, al_hreq.buflen,
-					al_hreq.flags, cursor);
+	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)),
+			compat_ptr(al_hreq.buffer), al_hreq.buflen,
+			al_hreq.flags, cursor);
 	if (error)
-		goto out_kfree;
-
-	if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t))) {
-		error = -EFAULT;
-		goto out_kfree;
-	}
+		goto out_dput;
 
-	if (copy_to_user(compat_ptr(al_hreq.buffer), kbuf, al_hreq.buflen))
+	if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t)))
 		error = -EFAULT;
 
-out_kfree:
-	kmem_free(kbuf);
 out_dput:
 	dput(dentry);
 	return error;
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 25/30] xfs: lift cursor copy in/out into xfs_ioc_attr_list
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (23 preceding siblings ...)
  2020-01-29 17:03 ` [PATCH 24/30] xfs: lift buffer allocation " Christoph Hellwig
@ 2020-01-29 17:03 ` " Christoph Hellwig
  2020-02-10  6:02   ` Chandan Rajendra
  2020-01-29 17:03 ` [PATCH 26/30] xfs: improve xfs_forget_acl Christoph Hellwig
                   ` (4 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:03 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

Lift the common code to copy the cursor from and to user space into
xfs_ioc_attr_list.  Note that this means we copy in twice now as
the cursor is in the middle of the conaining structure, but we never
touch the memory for the original copy.  Doing so keeps the cursor
handling isolated in the common helper.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_ioctl.c   | 36 +++++++++++++++---------------------
 fs/xfs/xfs_ioctl.h   |  2 +-
 fs/xfs/xfs_ioctl32.c | 19 ++++---------------
 3 files changed, 20 insertions(+), 37 deletions(-)

diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index cdb3800dfcef..5d160e82778e 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -354,9 +354,10 @@ xfs_ioc_attr_list(
 	void __user			*ubuf,
 	int				bufsize,
 	int				flags,
-	struct attrlist_cursor_kern	*cursor)
+	struct xfs_attrlist_cursor __user *ucursor)
 {
 	struct xfs_attr_list_context	context;
+	struct attrlist_cursor_kern	cursor;
 	struct xfs_attrlist		*alist;
 	void				*buffer;
 	int				error;
@@ -376,10 +377,12 @@ xfs_ioc_attr_list(
 	/*
 	 * Validate the cursor.
 	 */
-	if (cursor->pad1 || cursor->pad2)
+	if (copy_from_user(&cursor, ucursor, sizeof(cursor)))
+		return -EFAULT;
+	if (cursor.pad1 || cursor.pad2)
 		return -EINVAL;
-	if ((cursor->initted == 0) &&
-	    (cursor->hashval || cursor->blkno || cursor->offset))
+	if ((cursor.initted == 0) &&
+	    (cursor.hashval || cursor.blkno || cursor.offset))
 		return -EINVAL;
 
 	buffer = kmem_zalloc_large(bufsize, 0);
@@ -391,7 +394,7 @@ xfs_ioc_attr_list(
 	 */
 	memset(&context, 0, sizeof(context));
 	context.dp = dp;
-	context.cursor = cursor;
+	context.cursor = &cursor;
 	context.resynch = 1;
 	context.flags = flags;
 	context.buffer = buffer;
@@ -408,7 +411,8 @@ xfs_ioc_attr_list(
 	if (error)
 		goto out_free;
 
-	if (copy_to_user(ubuf, buffer, bufsize))
+	if (copy_to_user(ubuf, buffer, bufsize) ||
+	    copy_to_user(ucursor, &cursor, sizeof(cursor)))
 		error = -EFAULT;
 out_free:
 	kmem_free(buffer);
@@ -418,33 +422,23 @@ xfs_ioc_attr_list(
 STATIC int
 xfs_attrlist_by_handle(
 	struct file		*parfilp,
-	void			__user *arg)
+	struct xfs_fsop_attrlist_handlereq __user *p)
 {
-	int			error = -ENOMEM;
-	attrlist_cursor_kern_t	*cursor;
-	struct xfs_fsop_attrlist_handlereq __user	*p = arg;
-	xfs_fsop_attrlist_handlereq_t al_hreq;
+	struct xfs_fsop_attrlist_handlereq al_hreq;
 	struct dentry		*dentry;
+	int			error = -ENOMEM;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
-	if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
+	if (copy_from_user(&al_hreq, p, sizeof(al_hreq)))
 		return -EFAULT;
 
 	dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
-	cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
 	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), al_hreq.buffer,
-				  al_hreq.buflen, al_hreq.flags, cursor);
-	if (error)
-		goto out_dput;
-
-	if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t)))
-		error = -EFAULT;
-
-out_dput:
+				  al_hreq.buflen, al_hreq.flags, &p->pos);
 	dput(dentry);
 	return error;
 }
diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
index ec6448b259fb..d6e8000ad825 100644
--- a/fs/xfs/xfs_ioctl.h
+++ b/fs/xfs/xfs_ioctl.h
@@ -40,7 +40,7 @@ int xfs_ioc_attrmulti_one(struct file *parfilp, struct inode *inode,
 		uint32_t opcode, void __user *uname, void __user *value,
 		uint32_t *len, uint32_t flags);
 int xfs_ioc_attr_list(struct xfs_inode *dp, void __user *ubuf, int bufsize,
-	int flags, struct attrlist_cursor_kern *cursor);
+	int flags, struct xfs_attrlist_cursor __user *ucursor);
 
 extern struct dentry *
 xfs_handle_to_dentry(
diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
index 17e14916757b..c1771e728117 100644
--- a/fs/xfs/xfs_ioctl32.c
+++ b/fs/xfs/xfs_ioctl32.c
@@ -352,35 +352,24 @@ xfs_compat_handlereq_to_dentry(
 STATIC int
 xfs_compat_attrlist_by_handle(
 	struct file		*parfilp,
-	void			__user *arg)
+	compat_xfs_fsop_attrlist_handlereq_t __user *p)
 {
-	int			error;
-	attrlist_cursor_kern_t	*cursor;
-	compat_xfs_fsop_attrlist_handlereq_t __user *p = arg;
 	compat_xfs_fsop_attrlist_handlereq_t al_hreq;
 	struct dentry		*dentry;
+	int			error;
 
 	if (!capable(CAP_SYS_ADMIN))
 		return -EPERM;
-	if (copy_from_user(&al_hreq, arg,
-			   sizeof(compat_xfs_fsop_attrlist_handlereq_t)))
+	if (copy_from_user(&al_hreq, p, sizeof(al_hreq)))
 		return -EFAULT;
 
 	dentry = xfs_compat_handlereq_to_dentry(parfilp, &al_hreq.hreq);
 	if (IS_ERR(dentry))
 		return PTR_ERR(dentry);
 
-	cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
 	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)),
 			compat_ptr(al_hreq.buffer), al_hreq.buflen,
-			al_hreq.flags, cursor);
-	if (error)
-		goto out_dput;
-
-	if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t)))
-		error = -EFAULT;
-
-out_dput:
+			al_hreq.flags, &p->pos);
 	dput(dentry);
 	return error;
 }
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 26/30] xfs: improve xfs_forget_acl
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (24 preceding siblings ...)
  2020-01-29 17:03 ` [PATCH 25/30] xfs: lift cursor copy in/out " Christoph Hellwig
@ 2020-01-29 17:03 ` Christoph Hellwig
  2020-02-10  6:45   ` Chandan Rajendra
  2020-01-29 17:03 ` [PATCH 27/30] xfs: clean up the ATTR_REPLACE checks Christoph Hellwig
                   ` (3 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:03 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

Move the function to xfs_acl.c and provide a proper stub for the
!CONFIG_XFS_POSIX_ACL case.  Lift the flags check to the caller as it
nicely fits in there.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/xfs_acl.c   | 16 ++++++++++++++++
 fs/xfs/xfs_acl.h   |  4 ++--
 fs/xfs/xfs_ioctl.c |  4 ++--
 fs/xfs/xfs_xattr.c | 26 ++------------------------
 4 files changed, 22 insertions(+), 28 deletions(-)

diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index bc78b7c33401..e9a48d718c3a 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -264,3 +264,19 @@ xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 
 	return error;
 }
+
+/*
+ * Invalidate any cached ACLs if the user has bypassed the ACL interface.
+ * We don't validate the content whatsoever so it is caller responsibility to
+ * provide data in valid format and ensure i_mode is consistent.
+ */
+void
+xfs_forget_acl(
+	struct inode		*inode,
+	const char		*name)
+{
+	if (!strcmp(name, SGI_ACL_FILE))
+		forget_cached_acl(inode, ACL_TYPE_ACCESS);
+	else if (!strcmp(name, SGI_ACL_DEFAULT))
+		forget_cached_acl(inode, ACL_TYPE_DEFAULT);
+}
diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h
index 94615e34bc86..bd8a306046a9 100644
--- a/fs/xfs/xfs_acl.h
+++ b/fs/xfs/xfs_acl.h
@@ -13,14 +13,14 @@ struct posix_acl;
 extern struct posix_acl *xfs_get_acl(struct inode *inode, int type);
 extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
 extern int __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
+void xfs_forget_acl(struct inode *inode, const char *name);
 #else
 static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type)
 {
 	return NULL;
 }
 # define xfs_set_acl					NULL
+# define xfs_forget_acl(inode, name)			0
 #endif /* CONFIG_XFS_POSIX_ACL */
 
-extern void xfs_forget_acl(struct inode *inode, const char *name, int xflags);
-
 #endif	/* __XFS_ACL_H__ */
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 5d160e82778e..4f26c3962215 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -509,8 +509,8 @@ xfs_attrmulti_attr_set(
 	}
 
 	error = xfs_attr_set(&args);
-	if (!error)
-		xfs_forget_acl(inode, name, flags);
+	if (!error && (flags & ATTR_ROOT))
+		xfs_forget_acl(inode, name);
 	kfree(args.value);
 	return error;
 }
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
index e1951d2b878e..863e9fdec162 100644
--- a/fs/xfs/xfs_xattr.c
+++ b/fs/xfs/xfs_xattr.c
@@ -37,28 +37,6 @@ xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
 	return args.valuelen;
 }
 
-void
-xfs_forget_acl(
-	struct inode		*inode,
-	const char		*name,
-	int			xflags)
-{
-	/*
-	 * Invalidate any cached ACLs if the user has bypassed the ACL
-	 * interface. We don't validate the content whatsoever so it is caller
-	 * responsibility to provide data in valid format and ensure i_mode is
-	 * consistent.
-	 */
-	if (xflags & ATTR_ROOT) {
-#ifdef CONFIG_XFS_POSIX_ACL
-		if (!strcmp(name, SGI_ACL_FILE))
-			forget_cached_acl(inode, ACL_TYPE_ACCESS);
-		else if (!strcmp(name, SGI_ACL_DEFAULT))
-			forget_cached_acl(inode, ACL_TYPE_DEFAULT);
-#endif
-	}
-}
-
 static int
 xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
 		struct inode *inode, const char *name, const void *value,
@@ -81,8 +59,8 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
 		args.flags |= ATTR_REPLACE;
 
 	error = xfs_attr_set(&args);
-	if (!error)
-		xfs_forget_acl(inode, name, args.flags);
+	if (!error && (flags & ATTR_ROOT))
+		xfs_forget_acl(inode, name);
 	return error;
 }
 
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 27/30] xfs: clean up the ATTR_REPLACE checks
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (25 preceding siblings ...)
  2020-01-29 17:03 ` [PATCH 26/30] xfs: improve xfs_forget_acl Christoph Hellwig
@ 2020-01-29 17:03 ` Christoph Hellwig
  2020-02-10  6:57   ` Chandan Rajendra
  2020-01-29 17:03 ` [PATCH 28/30] xfs: clean up the attr flag confusion Christoph Hellwig
                   ` (2 subsequent siblings)
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:03 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

Remove superflous braces, elses after return statements and use a goto
label to merge common error handling.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_attr.c | 24 ++++++++++++------------
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 3b1db2afb104..9c629c7c912d 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -423,9 +423,9 @@ xfs_attr_shortform_addname(xfs_da_args_t *args)
 	trace_xfs_attr_sf_addname(args);
 
 	retval = xfs_attr_shortform_lookup(args);
-	if ((args->flags & ATTR_REPLACE) && (retval == -ENOATTR)) {
+	if ((args->flags & ATTR_REPLACE) && retval == -ENOATTR)
 		return retval;
-	} else if (retval == -EEXIST) {
+	if (retval == -EEXIST) {
 		if (args->flags & ATTR_CREATE)
 			return retval;
 		retval = xfs_attr_shortform_remove(args);
@@ -489,14 +489,11 @@ xfs_attr_leaf_addname(
 	 * the given flags produce an error or call for an atomic rename.
 	 */
 	retval = xfs_attr3_leaf_lookup_int(bp, args);
-	if ((args->flags & ATTR_REPLACE) && (retval == -ENOATTR)) {
-		xfs_trans_brelse(args->trans, bp);
-		return retval;
-	} else if (retval == -EEXIST) {
-		if (args->flags & ATTR_CREATE) {	/* pure create op */
-			xfs_trans_brelse(args->trans, bp);
-			return retval;
-		}
+	if ((args->flags & ATTR_REPLACE) && retval == -ENOATTR)
+		goto out_brelse;
+	if (retval == -EEXIST) {
+		if (args->flags & ATTR_CREATE)	/* pure create op */
+			goto out_brelse;
 
 		trace_xfs_attr_leaf_replace(args);
 
@@ -637,6 +634,9 @@ xfs_attr_leaf_addname(
 		error = xfs_attr3_leaf_clearflag(args);
 	}
 	return error;
+out_brelse:
+	xfs_trans_brelse(args->trans, bp);
+	return retval;
 }
 
 /*
@@ -763,9 +763,9 @@ xfs_attr_node_addname(
 		goto out;
 	blk = &state->path.blk[ state->path.active-1 ];
 	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
-	if ((args->flags & ATTR_REPLACE) && (retval == -ENOATTR)) {
+	if ((args->flags & ATTR_REPLACE) && retval == -ENOATTR)
 		goto out;
-	} else if (retval == -EEXIST) {
+	if (retval == -EEXIST) {
 		if (args->flags & ATTR_CREATE)
 			goto out;
 
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 28/30] xfs: clean up the attr flag confusion
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (26 preceding siblings ...)
  2020-01-29 17:03 ` [PATCH 27/30] xfs: clean up the ATTR_REPLACE checks Christoph Hellwig
@ 2020-01-29 17:03 ` Christoph Hellwig
  2020-02-10 13:19   ` Chandan Rajendra
  2020-01-29 17:03 ` [PATCH 29/30] xfs: remove XFS_DA_OP_INCOMPLETE Christoph Hellwig
  2020-01-29 17:03 ` [PATCH 30/30] xfs: embedded the attrlist cursor into struct xfs_attr_list_context Christoph Hellwig
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:03 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins

The ATTR_* flags have a long IRIX history, where they a userspace
interface, the on-disk format and an internal interface.  We've split
out the on-disk interface to the XFS_ATTR_* values, but despite (or
because?) of that the flag have still been a mess.  Switch the
internal interface to pass the on-disk XFS_ATTR_* flags for the
namespace and the Linux XATTR_* flags for the actual flags instead.
The ATTR_* values that are actually used are move to xfs_fs.h with a
new XFS_IOC_* prefix to not conflict with the userspace version that
has the same name and must have the same value.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_attr.c      | 16 ++++++-------
 fs/xfs/libxfs/xfs_attr.h      | 22 +-----------------
 fs/xfs/libxfs/xfs_attr_leaf.c | 14 +++++------
 fs/xfs/libxfs/xfs_da_format.h | 12 ----------
 fs/xfs/libxfs/xfs_fs.h        | 31 +++++++++++++-----------
 fs/xfs/libxfs/xfs_types.h     |  3 ++-
 fs/xfs/scrub/attr.c           |  5 +---
 fs/xfs/xfs_acl.c              |  5 ++--
 fs/xfs/xfs_ioctl.c            | 44 +++++++++++++++++++++++++----------
 fs/xfs/xfs_iops.c             |  3 +--
 fs/xfs/xfs_linux.h            |  1 +
 fs/xfs/xfs_trace.h            | 35 +++++++++++++++++-----------
 fs/xfs/xfs_xattr.c            | 18 +++++---------
 13 files changed, 100 insertions(+), 109 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index 9c629c7c912d..d5c112b6dcdd 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -295,7 +295,7 @@ xfs_attr_set(
 	struct xfs_inode	*dp = args->dp;
 	struct xfs_mount	*mp = dp->i_mount;
 	struct xfs_trans_res	tres;
-	int			rsvd = (args->flags & ATTR_ROOT) != 0;
+	bool			rsvd = (args->attr_namespace & XFS_ATTR_ROOT);
 	int			error, local;
 	unsigned int		total;
 
@@ -423,10 +423,10 @@ xfs_attr_shortform_addname(xfs_da_args_t *args)
 	trace_xfs_attr_sf_addname(args);
 
 	retval = xfs_attr_shortform_lookup(args);
-	if ((args->flags & ATTR_REPLACE) && retval == -ENOATTR)
+	if ((args->attr_flags & XATTR_REPLACE) && retval == -ENOATTR)
 		return retval;
 	if (retval == -EEXIST) {
-		if (args->flags & ATTR_CREATE)
+		if (args->attr_flags & XATTR_CREATE)
 			return retval;
 		retval = xfs_attr_shortform_remove(args);
 		if (retval)
@@ -436,7 +436,7 @@ xfs_attr_shortform_addname(xfs_da_args_t *args)
 		 * that the leaf format add routine won't trip over the attr
 		 * not being around.
 		 */
-		args->flags &= ~ATTR_REPLACE;
+		args->attr_flags &= ~XATTR_REPLACE;
 	}
 
 	if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
@@ -489,10 +489,10 @@ xfs_attr_leaf_addname(
 	 * the given flags produce an error or call for an atomic rename.
 	 */
 	retval = xfs_attr3_leaf_lookup_int(bp, args);
-	if ((args->flags & ATTR_REPLACE) && retval == -ENOATTR)
+	if ((args->attr_flags & XATTR_REPLACE) && retval == -ENOATTR)
 		goto out_brelse;
 	if (retval == -EEXIST) {
-		if (args->flags & ATTR_CREATE)	/* pure create op */
+		if (args->attr_flags & XATTR_CREATE)	/* pure create op */
 			goto out_brelse;
 
 		trace_xfs_attr_leaf_replace(args);
@@ -763,10 +763,10 @@ xfs_attr_node_addname(
 		goto out;
 	blk = &state->path.blk[ state->path.active-1 ];
 	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
-	if ((args->flags & ATTR_REPLACE) && retval == -ENOATTR)
+	if ((args->attr_flags & XATTR_REPLACE) && retval == -ENOATTR)
 		goto out;
 	if (retval == -EEXIST) {
-		if (args->flags & ATTR_CREATE)
+		if (args->attr_flags & XATTR_CREATE)
 			goto out;
 
 		trace_xfs_attr_node_replace(args);
diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index 8d42f5782ff7..7a3525dff411 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -21,26 +21,6 @@ struct xfs_attr_list_context;
  * as possible so as to fit into the literal area of the inode.
  */
 
-/*========================================================================
- * External interfaces
- *========================================================================*/
-
-
-#define ATTR_DONTFOLLOW	0x0001	/* -- ignored, from IRIX -- */
-#define ATTR_ROOT	0x0002	/* use attrs in root (trusted) namespace */
-#define ATTR_TRUST	0x0004	/* -- unused, from IRIX -- */
-#define ATTR_SECURE	0x0008	/* use attrs in security namespace */
-#define ATTR_CREATE	0x0010	/* pure create: fail if attr already exists */
-#define ATTR_REPLACE	0x0020	/* pure set: fail if attr does not exist */
-
-#define XFS_ATTR_FLAGS \
-	{ ATTR_DONTFOLLOW, 	"DONTFOLLOW" }, \
-	{ ATTR_ROOT,		"ROOT" }, \
-	{ ATTR_TRUST,		"TRUST" }, \
-	{ ATTR_SECURE,		"SECURE" }, \
-	{ ATTR_CREATE,		"CREATE" }, \
-	{ ATTR_REPLACE,		"REPLACE" }
-
 /*
  * The maximum size (into the kernel or returned from the kernel) of an
  * attribute value or the buffer used for an attr_list() call.  Larger
@@ -87,7 +67,7 @@ struct xfs_attr_list_context {
 	int			dupcnt;		/* count dup hashvals seen */
 	int			bufsize;	/* total buffer size */
 	int			firstu;		/* first used byte in buffer */
-	int			flags;		/* from VOP call */
+	unsigned int		attr_namespace;	/* XFS_ATTR_{ROOT,SECURE} */
 	int			resynch;	/* T/F: resynch with cursor */
 	put_listent_func_t	put_listent;	/* list output fmt function */
 	int			index;		/* index into output buffer */
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index 8852754153ba..9081ba7af90a 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -456,8 +456,7 @@ xfs_attr_match(
 		return false;
 	if (memcmp(args->name, name, namelen) != 0)
 		return false;
-	if (XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags) !=
-	    XFS_ATTR_NSP_ONDISK(flags))
+	if (args->attr_namespace != (flags & XFS_ATTR_NSP_ONDISK_MASK))
 		return false;
 	return true;
 }
@@ -697,7 +696,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
 
 	sfe->namelen = args->namelen;
 	sfe->valuelen = args->valuelen;
-	sfe->flags = XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags);
+	sfe->flags = args->attr_namespace;
 	memcpy(sfe->nameval, args->name, args->namelen);
 	memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
 	sf->hdr.count++;
@@ -906,7 +905,7 @@ xfs_attr_shortform_to_leaf(
 		nargs.valuelen = sfe->valuelen;
 		nargs.hashval = xfs_da_hashname(sfe->nameval,
 						sfe->namelen);
-		nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags);
+		nargs.attr_namespace = sfe->flags & XFS_ATTR_NSP_ONDISK_MASK;
 		error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */
 		ASSERT(error == -ENOATTR);
 		error = xfs_attr3_leaf_add(bp, &nargs);
@@ -1112,7 +1111,7 @@ xfs_attr3_leaf_to_shortform(
 		nargs.value = &name_loc->nameval[nargs.namelen];
 		nargs.valuelen = be16_to_cpu(name_loc->valuelen);
 		nargs.hashval = be32_to_cpu(entry->hashval);
-		nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(entry->flags);
+		nargs.attr_namespace = entry->flags & XFS_ATTR_NSP_ONDISK_MASK;
 		xfs_attr_shortform_add(&nargs, forkoff);
 	}
 	error = 0;
@@ -1437,8 +1436,9 @@ xfs_attr3_leaf_add_work(
 	entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base +
 				     ichdr->freemap[mapindex].size);
 	entry->hashval = cpu_to_be32(args->hashval);
-	entry->flags = tmp ? XFS_ATTR_LOCAL : 0;
-	entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags);
+	entry->flags = args->attr_namespace;
+	if (tmp)
+		entry->flags |= XFS_ATTR_LOCAL;
 	if (args->op_flags & XFS_DA_OP_RENAME) {
 		entry->flags |= XFS_ATTR_INCOMPLETE;
 		if ((args->blkno2 == args->blkno) &&
diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h
index 734837a9b51a..08c0a4d98b89 100644
--- a/fs/xfs/libxfs/xfs_da_format.h
+++ b/fs/xfs/libxfs/xfs_da_format.h
@@ -692,19 +692,7 @@ struct xfs_attr3_leafblock {
 #define XFS_ATTR_ROOT		(1 << XFS_ATTR_ROOT_BIT)
 #define XFS_ATTR_SECURE		(1 << XFS_ATTR_SECURE_BIT)
 #define XFS_ATTR_INCOMPLETE	(1 << XFS_ATTR_INCOMPLETE_BIT)
-
-/*
- * Conversion macros for converting namespace bits from argument flags
- * to ondisk flags.
- */
-#define XFS_ATTR_NSP_ARGS_MASK		(ATTR_ROOT | ATTR_SECURE)
 #define XFS_ATTR_NSP_ONDISK_MASK	(XFS_ATTR_ROOT | XFS_ATTR_SECURE)
-#define XFS_ATTR_NSP_ONDISK(flags)	((flags) & XFS_ATTR_NSP_ONDISK_MASK)
-#define XFS_ATTR_NSP_ARGS(flags)	((flags) & XFS_ATTR_NSP_ARGS_MASK)
-#define XFS_ATTR_NSP_ARGS_TO_ONDISK(x)	(((x) & ATTR_ROOT ? XFS_ATTR_ROOT : 0) |\
-					 ((x) & ATTR_SECURE ? XFS_ATTR_SECURE : 0))
-#define XFS_ATTR_NSP_ONDISK_TO_ARGS(x)	(((x) & XFS_ATTR_ROOT ? ATTR_ROOT : 0) |\
-					 ((x) & XFS_ATTR_SECURE ? ATTR_SECURE : 0))
 
 /*
  * Alignment for namelist and valuelist entries (since they are mixed
diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index 2c2b6e2b58f4..b22f73fccf25 100644
--- a/fs/xfs/libxfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
@@ -568,17 +568,27 @@ typedef struct xfs_fsop_setdm_handlereq {
 	struct fsdmidata		__user *data;	/* DMAPI data	*/
 } xfs_fsop_setdm_handlereq_t;
 
+/*
+ * Flags passed in xfs_attr_multiop.am_flags for the attr ioctl interface.
+ * NOTE: Must match the values declared in libattr without the XFS_IOC_ prefix.
+ */
+#define XFS_IOC_ATTR_ROOT	0x0002	/* use attrs in root namespace */
+#define XFS_IOC_ATTR_SECURE	0x0008	/* use attrs in security namespace */
+#define XFS_IOC_ATTR_CREATE	0x0010	/* fail if attr already exists */
+#define XFS_IOC_ATTR_REPLACE	0x0020	/* fail if attr does not exist */
+
 typedef struct xfs_attrlist_cursor {
 	__u32		opaque[4];
 } xfs_attrlist_cursor_t;
 
 /*
- * Define how lists of attribute names are returned to the user from
- * the attr_list() call.  A large, 32bit aligned, buffer is passed in
- * along with its size.  We put an array of offsets at the top that each
- * reference an attrlist_ent_t and pack the attrlist_ent_t's at the bottom.
+ * Define how lists of attribute names are returned to userspace from the
+ * XFS_IOC_ATTRLIST_BY_HANDLE ioctl.  struct xfs_attrlist is the header at the
+ * beginning of the returned buffer, and a each entry in al_offset contains the
+ * relative offset of an xfs_attrlist_ent containing the actual entry.
  *
- * NOTE: struct xfs_attrlist must match struct attrlist defined in libattr.
+ * NOTE: struct xfs_attrlist must match struct attrlist defined in libattr, and
+ * struct xfs_attrlist_ent must match struct attrlist_ent defined in libattr.
  */
 struct xfs_attrlist {
 	__s32	al_count;	/* number of entries in attrlist */
@@ -586,13 +596,6 @@ struct xfs_attrlist {
 	__s32	al_offset[1];	/* byte offsets of attrs [var-sized] */
 };
 
-/*
- * Show the interesting info about one attribute.  This is what the
- * al_offset[i] entry points to.
- *
- * NOTE: struct xfs_attrlist_ent must match struct attrlist_ent defined in
- * libattr.
- */
 struct xfs_attrlist_ent {	/* data from attr_list() */
 	__u32	a_valuelen;	/* number bytes in value of attr */
 	char	a_name[1];	/* attr name (NULL terminated) */
@@ -603,7 +606,7 @@ typedef struct xfs_fsop_attrlist_handlereq {
 	struct xfs_attrlist_cursor	pos; /* opaque cookie, list offset */
 	__u32				flags;	/* which namespace to use */
 	__u32				buflen;	/* length of buffer supplied */
-	void				__user *buffer;	/* returned names */
+	struct xfs_attrlist __user	*buffer;/* returned names */
 } xfs_fsop_attrlist_handlereq_t;
 
 typedef struct xfs_attr_multiop {
@@ -615,7 +618,7 @@ typedef struct xfs_attr_multiop {
 	void		__user *am_attrname;
 	void		__user *am_attrvalue;
 	__u32		am_length;
-	__u32		am_flags;
+	__u32		am_flags; /* XFS_IOC_ATTR_* */
 } xfs_attr_multiop_t;
 
 typedef struct xfs_fsop_attrmulti_handlereq {
diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
index 1594325d7742..2b02f854ebaf 100644
--- a/fs/xfs/libxfs/xfs_types.h
+++ b/fs/xfs/libxfs/xfs_types.h
@@ -194,7 +194,8 @@ typedef struct xfs_da_args {
 	uint8_t		filetype;	/* filetype of inode for directories */
 	void		*value;		/* set of bytes (maybe contain NULLs) */
 	int		valuelen;	/* length of value */
-	int		flags;		/* argument flags (eg: ATTR_NOCREATE) */
+	unsigned int	attr_namespace;	/* XFS_ATTR_{ROOT,SECURE} */
+	unsigned int	attr_flags;	/* XATTR_{CREATE,REPLACE} */
 	xfs_dahash_t	hashval;	/* hash value of name */
 	xfs_ino_t	inumber;	/* input/output inode number */
 	struct xfs_inode *dp;		/* directory inode to manipulate */
diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
index 9e336d797616..d84237af5455 100644
--- a/fs/xfs/scrub/attr.c
+++ b/fs/xfs/scrub/attr.c
@@ -148,10 +148,7 @@ xchk_xattr_listent(
 	}
 
 	args.op_flags = XFS_DA_OP_NOTIME;
-	if (flags & XFS_ATTR_ROOT)
-		args.flags |= ATTR_ROOT;
-	else if (flags & XFS_ATTR_SECURE)
-		args.flags |= ATTR_SECURE;
+	args.attr_namespace = flags & XFS_ATTR_NSP_ONDISK_MASK;
 	args.geo = context->dp->i_mount->m_attr_geo;
 	args.whichfork = XFS_ATTR_FORK;
 	args.dp = context->dp;
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index e9a48d718c3a..6690906cd16f 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -14,6 +14,7 @@
 #include "xfs_trace.h"
 #include "xfs_error.h"
 #include "xfs_acl.h"
+#include "xfs_da_format.h"
 
 #include <linux/posix_acl_xattr.h>
 
@@ -125,7 +126,7 @@ xfs_get_acl(struct inode *inode, int type)
 	struct posix_acl	*acl = NULL;
 	struct xfs_da_args	args = {
 		.dp		= ip,
-		.flags		= ATTR_ROOT,
+		.attr_namespace	= XFS_ATTR_ROOT,
 		.valuelen	= XFS_ACL_MAX_SIZE(mp),
 	};
 	int			error;
@@ -166,7 +167,7 @@ __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
 	struct xfs_inode	*ip = XFS_I(inode);
 	struct xfs_da_args	args = {
 		.dp		= ip,
-		.flags		= ATTR_ROOT,
+		.attr_namespace	= XFS_ATTR_ROOT,
 	};
 	int			error;
 
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index 4f26c3962215..d2318857497b 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -319,11 +319,7 @@ xfs_ioc_attr_put_listent(
 	/*
 	 * Only list entries in the right namespace.
 	 */
-	if (((context->flags & ATTR_SECURE) == 0) !=
-	    ((flags & XFS_ATTR_SECURE) == 0))
-		return;
-	if (((context->flags & ATTR_ROOT) == 0) !=
-	    ((flags & XFS_ATTR_ROOT) == 0))
+	if (context->attr_namespace != (flags & XFS_ATTR_NSP_ONDISK_MASK))
 		return;
 
 	arraytop = sizeof(*alist) +
@@ -348,6 +344,28 @@ xfs_ioc_attr_put_listent(
 	trace_xfs_attr_list_add(context);
 }
 
+static unsigned int
+xfs_attr_namespace(
+	u32			ioc_flags)
+{
+	if (ioc_flags & XFS_IOC_ATTR_ROOT)
+		return XFS_ATTR_ROOT;
+	if (ioc_flags & XFS_IOC_ATTR_SECURE)
+		return XFS_ATTR_SECURE;
+	return 0;
+}
+
+static unsigned int
+xfs_attr_flags(
+	u32			ioc_flags)
+{
+	if (ioc_flags & XFS_IOC_ATTR_CREATE)
+		return XATTR_CREATE;
+	if (ioc_flags & XFS_IOC_ATTR_REPLACE)
+		return XATTR_REPLACE;
+	return 0;
+}
+
 int
 xfs_ioc_attr_list(
 	struct xfs_inode		*dp,
@@ -369,9 +387,9 @@ xfs_ioc_attr_list(
 	/*
 	 * Reject flags, only allow namespaces.
 	 */
-	if (flags & ~(ATTR_ROOT | ATTR_SECURE))
+	if (flags & ~(XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE))
 		return -EINVAL;
-	if (flags == (ATTR_ROOT | ATTR_SECURE))
+	if (flags == (XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE))
 		return -EINVAL;
 
 	/*
@@ -396,7 +414,7 @@ xfs_ioc_attr_list(
 	context.dp = dp;
 	context.cursor = &cursor;
 	context.resynch = 1;
-	context.flags = flags;
+	context.attr_namespace = xfs_attr_namespace(flags);
 	context.buffer = buffer;
 	context.bufsize = (bufsize & ~(sizeof(int)-1));  /* align */
 	context.firstu = context.bufsize;
@@ -453,7 +471,8 @@ xfs_attrmulti_attr_get(
 {
 	struct xfs_da_args	args = {
 		.dp		= XFS_I(inode),
-		.flags		= flags,
+		.attr_namespace	= xfs_attr_namespace(flags),
+		.attr_flags	= xfs_attr_flags(flags),
 		.name		= name,
 		.namelen	= strlen(name),
 		.valuelen	= *len,
@@ -490,7 +509,8 @@ xfs_attrmulti_attr_set(
 {
 	struct xfs_da_args	args = {
 		.dp		= XFS_I(inode),
-		.flags		= flags,
+		.attr_namespace	= xfs_attr_namespace(flags),
+		.attr_flags	= xfs_attr_flags(flags),
 		.name		= name,
 		.namelen	= strlen(name),
 	};
@@ -509,7 +529,7 @@ xfs_attrmulti_attr_set(
 	}
 
 	error = xfs_attr_set(&args);
-	if (!error && (flags & ATTR_ROOT))
+	if (!error && (flags & XFS_IOC_ATTR_ROOT))
 		xfs_forget_acl(inode, name);
 	kfree(args.value);
 	return error;
@@ -528,7 +548,7 @@ xfs_ioc_attrmulti_one(
 	unsigned char		*name;
 	int			error;
 
-	if ((flags & ATTR_ROOT) && (flags & ATTR_SECURE))
+	if ((flags & XFS_IOC_ATTR_ROOT) && (flags & XFS_IOC_ATTR_SECURE))
 		return -EINVAL;
 
 	name = strndup_user(uname, MAXNAMELEN);
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 94cd4254656c..8b1a3e7d83e6 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -22,7 +22,6 @@
 #include "xfs_iomap.h"
 #include "xfs_error.h"
 
-#include <linux/xattr.h>
 #include <linux/posix_acl.h>
 #include <linux/security.h>
 #include <linux/iversion.h>
@@ -52,7 +51,7 @@ xfs_initxattrs(
 	for (xattr = xattr_array; xattr->name != NULL; xattr++) {
 		struct xfs_da_args	args = {
 			.dp		= ip,
-			.flags		= ATTR_SECURE,
+			.attr_namespace	= XFS_ATTR_SECURE,
 			.name		= xattr->name,
 			.namelen	= strlen(xattr->name),
 			.value		= xattr->value,
diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h
index 8738bb03f253..8c0070a797de 100644
--- a/fs/xfs/xfs_linux.h
+++ b/fs/xfs/xfs_linux.h
@@ -60,6 +60,7 @@ typedef __u32			xfs_nlink_t;
 #include <linux/list_sort.h>
 #include <linux/ratelimit.h>
 #include <linux/rhashtable.h>
+#include <linux/xattr.h>
 
 #include <asm/page.h>
 #include <asm/div64.h>
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index 8358a92987f9..a064b1523fa5 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -36,6 +36,10 @@ struct xfs_owner_info;
 struct xfs_trans_res;
 struct xfs_inobt_rec_incore;
 
+#define XFS_ATTR_NSP_FLAGS \
+	{ XFS_ATTR_ROOT,	"ROOT" }, \
+	{ XFS_ATTR_SECURE,	"SECURE" }
+
 DECLARE_EVENT_CLASS(xfs_attr_list_class,
 	TP_PROTO(struct xfs_attr_list_context *ctx),
 	TP_ARGS(ctx),
@@ -50,7 +54,7 @@ DECLARE_EVENT_CLASS(xfs_attr_list_class,
 		__field(int, count)
 		__field(int, firstu)
 		__field(int, dupcnt)
-		__field(int, flags)
+		__field(int, attr_namespace)
 	),
 	TP_fast_assign(
 		__entry->dev = VFS_I(ctx->dp)->i_sb->s_dev;
@@ -62,10 +66,10 @@ DECLARE_EVENT_CLASS(xfs_attr_list_class,
 		__entry->bufsize = ctx->bufsize;
 		__entry->count = ctx->count;
 		__entry->firstu = ctx->firstu;
-		__entry->flags = ctx->flags;
+		__entry->attr_namespace = ctx->attr_namespace;
 	),
 	TP_printk("dev %d:%d ino 0x%llx cursor h/b/o 0x%x/0x%x/%u dupcnt %u "
-		  "buffer %p size %u count %u firstu %u flags %d %s",
+		  "buffer %p size %u count %u firstu %u namespace %d %s",
 		  MAJOR(__entry->dev), MINOR(__entry->dev),
 		   __entry->ino,
 		   __entry->hashval,
@@ -76,8 +80,9 @@ DECLARE_EVENT_CLASS(xfs_attr_list_class,
 		   __entry->bufsize,
 		   __entry->count,
 		   __entry->firstu,
-		   __entry->flags,
-		   __print_flags(__entry->flags, "|", XFS_ATTR_FLAGS)
+		   __entry->attr_namespace,
+		   __print_flags(__entry->attr_namespace, "|",
+				 XFS_ATTR_NSP_FLAGS)
 	)
 )
 
@@ -174,7 +179,7 @@ TRACE_EVENT(xfs_attr_list_node_descend,
 		__field(int, count)
 		__field(int, firstu)
 		__field(int, dupcnt)
-		__field(int, flags)
+		__field(int, attr_namespace)
 		__field(u32, bt_hashval)
 		__field(u32, bt_before)
 	),
@@ -188,12 +193,12 @@ TRACE_EVENT(xfs_attr_list_node_descend,
 		__entry->bufsize = ctx->bufsize;
 		__entry->count = ctx->count;
 		__entry->firstu = ctx->firstu;
-		__entry->flags = ctx->flags;
+		__entry->attr_namespace = ctx->attr_namespace;
 		__entry->bt_hashval = be32_to_cpu(btree->hashval);
 		__entry->bt_before = be32_to_cpu(btree->before);
 	),
 	TP_printk("dev %d:%d ino 0x%llx cursor h/b/o 0x%x/0x%x/%u dupcnt %u "
-		  "buffer %p size %u count %u firstu %u flags %d %s "
+		  "buffer %p size %u count %u firstu %u namespae %d %s "
 		  "node hashval %u, node before %u",
 		  MAJOR(__entry->dev), MINOR(__entry->dev),
 		   __entry->ino,
@@ -205,8 +210,9 @@ TRACE_EVENT(xfs_attr_list_node_descend,
 		   __entry->bufsize,
 		   __entry->count,
 		   __entry->firstu,
-		   __entry->flags,
-		   __print_flags(__entry->flags, "|", XFS_ATTR_FLAGS),
+		   __entry->attr_namespace,
+		   __print_flags(__entry->attr_namespace, "|",
+				 XFS_ATTR_NSP_FLAGS),
 		   __entry->bt_hashval,
 		   __entry->bt_before)
 );
@@ -1701,7 +1707,7 @@ DECLARE_EVENT_CLASS(xfs_attr_class,
 		__field(int, namelen)
 		__field(int, valuelen)
 		__field(xfs_dahash_t, hashval)
-		__field(int, flags)
+		__field(int, attr_namespace)
 		__field(int, op_flags)
 	),
 	TP_fast_assign(
@@ -1712,11 +1718,11 @@ DECLARE_EVENT_CLASS(xfs_attr_class,
 		__entry->namelen = args->namelen;
 		__entry->valuelen = args->valuelen;
 		__entry->hashval = args->hashval;
-		__entry->flags = args->flags;
+		__entry->attr_namespace = args->attr_namespace;
 		__entry->op_flags = args->op_flags;
 	),
 	TP_printk("dev %d:%d ino 0x%llx name %.*s namelen %d valuelen %d "
-		  "hashval 0x%x flags %s op_flags %s",
+		  "hashval 0x%x namespace %s op_flags %s",
 		  MAJOR(__entry->dev), MINOR(__entry->dev),
 		  __entry->ino,
 		  __entry->namelen,
@@ -1724,7 +1730,8 @@ DECLARE_EVENT_CLASS(xfs_attr_class,
 		  __entry->namelen,
 		  __entry->valuelen,
 		  __entry->hashval,
-		  __print_flags(__entry->flags, "|", XFS_ATTR_FLAGS),
+		  __print_flags(__entry->attr_namespace, "|",
+				XFS_ATTR_NSP_FLAGS),
 		  __print_flags(__entry->op_flags, "|", XFS_DA_OP_FLAGS))
 )
 
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
index 863e9fdec162..1d2c8615b335 100644
--- a/fs/xfs/xfs_xattr.c
+++ b/fs/xfs/xfs_xattr.c
@@ -14,7 +14,6 @@
 #include "xfs_acl.h"
 
 #include <linux/posix_acl_xattr.h>
-#include <linux/xattr.h>
 
 
 static int
@@ -23,7 +22,7 @@ xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
 {
 	struct xfs_da_args	args = {
 		.dp		= XFS_I(inode),
-		.flags		= handler->flags,
+		.attr_namespace	= handler->flags,
 		.name		= name,
 		.namelen	= strlen(name),
 		.value		= value,
@@ -44,7 +43,8 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
 {
 	struct xfs_da_args	args = {
 		.dp		= XFS_I(inode),
-		.flags		= handler->flags,
+		.attr_namespace	= handler->flags,
+		.attr_flags	= flags,
 		.name		= name,
 		.namelen	= strlen(name),
 		.value		= (unsigned char *)value,
@@ -52,14 +52,8 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
 	};
 	int			error;
 
-	/* Convert Linux syscall to XFS internal ATTR flags */
-	if (flags & XATTR_CREATE)
-		args.flags |= ATTR_CREATE;
-	if (flags & XATTR_REPLACE)
-		args.flags |= ATTR_REPLACE;
-
 	error = xfs_attr_set(&args);
-	if (!error && (flags & ATTR_ROOT))
+	if (!error && (handler->flags & XFS_ATTR_ROOT))
 		xfs_forget_acl(inode, name);
 	return error;
 }
@@ -73,14 +67,14 @@ static const struct xattr_handler xfs_xattr_user_handler = {
 
 static const struct xattr_handler xfs_xattr_trusted_handler = {
 	.prefix	= XATTR_TRUSTED_PREFIX,
-	.flags	= ATTR_ROOT,
+	.flags	= XFS_ATTR_ROOT,
 	.get	= xfs_xattr_get,
 	.set	= xfs_xattr_set,
 };
 
 static const struct xattr_handler xfs_xattr_security_handler = {
 	.prefix	= XATTR_SECURITY_PREFIX,
-	.flags	= ATTR_SECURE,
+	.flags	= XFS_ATTR_SECURE,
 	.get	= xfs_xattr_get,
 	.set	= xfs_xattr_set,
 };
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 29/30] xfs: remove XFS_DA_OP_INCOMPLETE
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (27 preceding siblings ...)
  2020-01-29 17:03 ` [PATCH 28/30] xfs: clean up the attr flag confusion Christoph Hellwig
@ 2020-01-29 17:03 ` Christoph Hellwig
  2020-02-10 13:59   ` Chandan Rajendra
  2020-01-29 17:03 ` [PATCH 30/30] xfs: embedded the attrlist cursor into struct xfs_attr_list_context Christoph Hellwig
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:03 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins

Now that we use the on-disk flags field also for the interface to the
lower level attr routines we can use the XFS_ATTR_INCOMPLETE definition
from the on-disk format directly instead.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/xfs/libxfs/xfs_attr.c      |  2 +-
 fs/xfs/libxfs/xfs_attr_leaf.c | 15 ++++++---------
 fs/xfs/libxfs/xfs_types.h     |  6 ++----
 3 files changed, 9 insertions(+), 14 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
index d5c112b6dcdd..23e0d8ce39f8 100644
--- a/fs/xfs/libxfs/xfs_attr.c
+++ b/fs/xfs/libxfs/xfs_attr.c
@@ -898,7 +898,7 @@ xfs_attr_node_addname(
 		 * The INCOMPLETE flag means that we will find the "old"
 		 * attr, not the "new" one.
 		 */
-		args->op_flags |= XFS_DA_OP_INCOMPLETE;
+		args->attr_namespace |= XFS_ATTR_INCOMPLETE;
 		state = xfs_da_state_alloc();
 		state->args = args;
 		state->mp = mp;
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
index 9081ba7af90a..fae322105457 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.c
+++ b/fs/xfs/libxfs/xfs_attr_leaf.c
@@ -456,7 +456,12 @@ xfs_attr_match(
 		return false;
 	if (memcmp(args->name, name, namelen) != 0)
 		return false;
-	if (args->attr_namespace != (flags & XFS_ATTR_NSP_ONDISK_MASK))
+	/*
+	 * If we are looking for incomplete entries, show only those, else only
+	 * show complete entries.
+	 */
+	if (args->attr_namespace !=
+	    (flags & (XFS_ATTR_NSP_ONDISK_MASK | XFS_ATTR_INCOMPLETE)))
 		return false;
 	return true;
 }
@@ -2387,14 +2392,6 @@ xfs_attr3_leaf_lookup_int(
 /*
  * GROT: Add code to remove incomplete entries.
  */
-		/*
-		 * If we are looking for INCOMPLETE entries, show only those.
-		 * If we are looking for complete entries, show only those.
-		 */
-		if (!!(args->op_flags & XFS_DA_OP_INCOMPLETE) !=
-		    !!(entry->flags & XFS_ATTR_INCOMPLETE)) {
-			continue;
-		}
 		if (entry->flags & XFS_ATTR_LOCAL) {
 			name_loc = xfs_attr3_leaf_name_local(leaf, probe);
 			if (!xfs_attr_match(args, name_loc->namelen,
diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
index 2b02f854ebaf..a2005e2d3baa 100644
--- a/fs/xfs/libxfs/xfs_types.h
+++ b/fs/xfs/libxfs/xfs_types.h
@@ -194,7 +194,7 @@ typedef struct xfs_da_args {
 	uint8_t		filetype;	/* filetype of inode for directories */
 	void		*value;		/* set of bytes (maybe contain NULLs) */
 	int		valuelen;	/* length of value */
-	unsigned int	attr_namespace;	/* XFS_ATTR_{ROOT,SECURE} */
+	unsigned int	attr_namespace;	/* XFS_ATTR_{ROOT,SECURE,INCOMPLETE} */
 	unsigned int	attr_flags;	/* XATTR_{CREATE,REPLACE} */
 	xfs_dahash_t	hashval;	/* hash value of name */
 	xfs_ino_t	inumber;	/* input/output inode number */
@@ -225,7 +225,6 @@ typedef struct xfs_da_args {
 #define XFS_DA_OP_OKNOENT	0x0008	/* lookup/add op, ENOENT ok, else die */
 #define XFS_DA_OP_CILOOKUP	0x0010	/* lookup to return CI name if found */
 #define XFS_DA_OP_NOTIME	0x0020	/* don't update inode timestamps */
-#define XFS_DA_OP_INCOMPLETE	0x0040	/* lookup INCOMPLETE attr keys */
 
 #define XFS_DA_OP_FLAGS \
 	{ XFS_DA_OP_JUSTCHECK,	"JUSTCHECK" }, \
@@ -233,8 +232,7 @@ typedef struct xfs_da_args {
 	{ XFS_DA_OP_ADDNAME,	"ADDNAME" }, \
 	{ XFS_DA_OP_OKNOENT,	"OKNOENT" }, \
 	{ XFS_DA_OP_CILOOKUP,	"CILOOKUP" }, \
-	{ XFS_DA_OP_NOTIME,	"NOTIME" }, \
-	{ XFS_DA_OP_INCOMPLETE,	"INCOMPLETE" }
+	{ XFS_DA_OP_NOTIME,	"NOTIME" }
 
 /*
  * Type verifier functions
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* [PATCH 30/30] xfs: embedded the attrlist cursor into struct xfs_attr_list_context
  2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
                   ` (28 preceding siblings ...)
  2020-01-29 17:03 ` [PATCH 29/30] xfs: remove XFS_DA_OP_INCOMPLETE Christoph Hellwig
@ 2020-01-29 17:03 ` Christoph Hellwig
  2020-02-10 14:57   ` Chandan Rajendra
  29 siblings, 1 reply; 60+ messages in thread
From: Christoph Hellwig @ 2020-01-29 17:03 UTC (permalink / raw)
  To: linux-xfs; +Cc: Allison Collins, Darrick J . Wong

The attrlist cursor only exists as part of an attr list context, so
embedd the structure instead of pointing to it.  Also give it a proper
xfs_ prefix and remove the obsolete typedef.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
---
 fs/xfs/libxfs/xfs_attr.h      |  6 +++---
 fs/xfs/libxfs/xfs_attr_leaf.h |  1 -
 fs/xfs/scrub/attr.c           |  2 --
 fs/xfs/xfs_attr_list.c        | 19 ++++++-------------
 fs/xfs/xfs_ioctl.c            | 16 +++++++---------
 fs/xfs/xfs_ioctl.h            |  1 -
 fs/xfs/xfs_trace.h            | 12 ++++++------
 fs/xfs/xfs_xattr.c            |  2 --
 8 files changed, 22 insertions(+), 37 deletions(-)

diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
index 7a3525dff411..861c81f9bb91 100644
--- a/fs/xfs/libxfs/xfs_attr.h
+++ b/fs/xfs/libxfs/xfs_attr.h
@@ -31,14 +31,14 @@ struct xfs_attr_list_context;
 /*
  * Kernel-internal version of the attrlist cursor.
  */
-typedef struct attrlist_cursor_kern {
+struct xfs_attrlist_cursor_kern {
 	__u32	hashval;	/* hash value of next entry to add */
 	__u32	blkno;		/* block containing entry (suggestion) */
 	__u32	offset;		/* offset in list of equal-hashvals */
 	__u16	pad1;		/* padding to match user-level */
 	__u8	pad2;		/* padding to match user-level */
 	__u8	initted;	/* T/F: cursor has been initialized */
-} attrlist_cursor_kern_t;
+};
 
 
 /*========================================================================
@@ -53,7 +53,7 @@ typedef void (*put_listent_func_t)(struct xfs_attr_list_context *, int,
 struct xfs_attr_list_context {
 	struct xfs_trans	*tp;
 	struct xfs_inode	*dp;		/* inode */
-	struct attrlist_cursor_kern *cursor;	/* position in list */
+	struct xfs_attrlist_cursor_kern cursor;	/* position in list */
 	void			*buffer;	/* output buffer */
 
 	/*
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h
index 73615b1dd1a8..6dd2d937a42a 100644
--- a/fs/xfs/libxfs/xfs_attr_leaf.h
+++ b/fs/xfs/libxfs/xfs_attr_leaf.h
@@ -8,7 +8,6 @@
 #define	__XFS_ATTR_LEAF_H__
 
 struct attrlist;
-struct attrlist_cursor_kern;
 struct xfs_attr_list_context;
 struct xfs_da_args;
 struct xfs_da_state;
diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
index d84237af5455..6dd3f5f78251 100644
--- a/fs/xfs/scrub/attr.c
+++ b/fs/xfs/scrub/attr.c
@@ -471,7 +471,6 @@ xchk_xattr(
 	struct xfs_scrub		*sc)
 {
 	struct xchk_xattr		sx;
-	struct attrlist_cursor_kern	cursor = { 0 };
 	xfs_dablk_t			last_checked = -1U;
 	int				error = 0;
 
@@ -490,7 +489,6 @@ xchk_xattr(
 
 	/* Check that every attr key can also be looked up by hash. */
 	sx.context.dp = sc->ip;
-	sx.context.cursor = &cursor;
 	sx.context.resynch = 1;
 	sx.context.put_listent = xchk_xattr_listent;
 	sx.context.tp = sc->tp;
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
index ea79219859a0..6af71edaa30e 100644
--- a/fs/xfs/xfs_attr_list.c
+++ b/fs/xfs/xfs_attr_list.c
@@ -52,24 +52,19 @@ static int
 xfs_attr_shortform_list(
 	struct xfs_attr_list_context	*context)
 {
-	struct attrlist_cursor_kern	*cursor;
+	struct xfs_attrlist_cursor_kern	*cursor = &context->cursor;
+	struct xfs_inode		*dp = context->dp;
 	struct xfs_attr_sf_sort		*sbuf, *sbp;
 	struct xfs_attr_shortform	*sf;
 	struct xfs_attr_sf_entry	*sfe;
-	struct xfs_inode		*dp;
 	int				sbsize, nsbuf, count, i;
 	int				error = 0;
 
-	ASSERT(context != NULL);
-	dp = context->dp;
-	ASSERT(dp != NULL);
 	ASSERT(dp->i_afp != NULL);
 	sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data;
 	ASSERT(sf != NULL);
 	if (!sf->hdr.count)
 		return 0;
-	cursor = context->cursor;
-	ASSERT(cursor != NULL);
 
 	trace_xfs_attr_list_sf(context);
 
@@ -205,7 +200,7 @@ xfs_attr_shortform_list(
 STATIC int
 xfs_attr_node_list_lookup(
 	struct xfs_attr_list_context	*context,
-	struct attrlist_cursor_kern	*cursor,
+	struct xfs_attrlist_cursor_kern	*cursor,
 	struct xfs_buf			**pbp)
 {
 	struct xfs_da3_icnode_hdr	nodehdr;
@@ -288,8 +283,8 @@ STATIC int
 xfs_attr_node_list(
 	struct xfs_attr_list_context	*context)
 {
+	struct xfs_attrlist_cursor_kern	*cursor = &context->cursor;
 	struct xfs_attr3_icleaf_hdr	leafhdr;
-	struct attrlist_cursor_kern	*cursor;
 	struct xfs_attr_leafblock	*leaf;
 	struct xfs_da_intnode		*node;
 	struct xfs_buf			*bp;
@@ -299,7 +294,6 @@ xfs_attr_node_list(
 
 	trace_xfs_attr_node_list(context);
 
-	cursor = context->cursor;
 	cursor->initted = 1;
 
 	/*
@@ -394,7 +388,7 @@ xfs_attr3_leaf_list_int(
 	struct xfs_buf			*bp,
 	struct xfs_attr_list_context	*context)
 {
-	struct attrlist_cursor_kern	*cursor;
+	struct xfs_attrlist_cursor_kern	*cursor = &context->cursor;
 	struct xfs_attr_leafblock	*leaf;
 	struct xfs_attr3_icleaf_hdr	ichdr;
 	struct xfs_attr_leaf_entry	*entries;
@@ -408,7 +402,6 @@ xfs_attr3_leaf_list_int(
 	xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
 	entries = xfs_attr3_leaf_entryp(leaf);
 
-	cursor = context->cursor;
 	cursor->initted = 1;
 
 	/*
@@ -496,7 +489,7 @@ xfs_attr_leaf_list(
 
 	trace_xfs_attr_leaf_list(context);
 
-	context->cursor->blkno = 0;
+	context->cursor.blkno = 0;
 	error = xfs_attr3_leaf_read(context->tp, context->dp, 0, &bp);
 	if (error)
 		return error;
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index d2318857497b..2e8e86d5c01c 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -374,8 +374,7 @@ xfs_ioc_attr_list(
 	int				flags,
 	struct xfs_attrlist_cursor __user *ucursor)
 {
-	struct xfs_attr_list_context	context;
-	struct attrlist_cursor_kern	cursor;
+	struct xfs_attr_list_context	context = { 0 };
 	struct xfs_attrlist		*alist;
 	void				*buffer;
 	int				error;
@@ -395,12 +394,13 @@ xfs_ioc_attr_list(
 	/*
 	 * Validate the cursor.
 	 */
-	if (copy_from_user(&cursor, ucursor, sizeof(cursor)))
+	if (copy_from_user(&context.cursor, ucursor, sizeof(context.cursor)))
 		return -EFAULT;
-	if (cursor.pad1 || cursor.pad2)
+	if (context.cursor.pad1 || context.cursor.pad2)
 		return -EINVAL;
-	if ((cursor.initted == 0) &&
-	    (cursor.hashval || cursor.blkno || cursor.offset))
+	if (!context.cursor.initted &&
+	    (context.cursor.hashval || context.cursor.blkno ||
+	     context.cursor.offset))
 		return -EINVAL;
 
 	buffer = kmem_zalloc_large(bufsize, 0);
@@ -410,9 +410,7 @@ xfs_ioc_attr_list(
 	/*
 	 * Initialize the output buffer.
 	 */
-	memset(&context, 0, sizeof(context));
 	context.dp = dp;
-	context.cursor = &cursor;
 	context.resynch = 1;
 	context.attr_namespace = xfs_attr_namespace(flags);
 	context.buffer = buffer;
@@ -430,7 +428,7 @@ xfs_ioc_attr_list(
 		goto out_free;
 
 	if (copy_to_user(ubuf, buffer, bufsize) ||
-	    copy_to_user(ucursor, &cursor, sizeof(cursor)))
+	    copy_to_user(ucursor, &context.cursor, sizeof(context.cursor)))
 		error = -EFAULT;
 out_free:
 	kmem_free(buffer);
diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
index d6e8000ad825..bab6a5a92407 100644
--- a/fs/xfs/xfs_ioctl.h
+++ b/fs/xfs/xfs_ioctl.h
@@ -6,7 +6,6 @@
 #ifndef __XFS_IOCTL_H__
 #define __XFS_IOCTL_H__
 
-struct attrlist_cursor_kern;
 struct xfs_bstat;
 struct xfs_ibulk;
 struct xfs_inogrp;
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index a064b1523fa5..f886c0a5dbe1 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -59,9 +59,9 @@ DECLARE_EVENT_CLASS(xfs_attr_list_class,
 	TP_fast_assign(
 		__entry->dev = VFS_I(ctx->dp)->i_sb->s_dev;
 		__entry->ino = ctx->dp->i_ino;
-		__entry->hashval = ctx->cursor->hashval;
-		__entry->blkno = ctx->cursor->blkno;
-		__entry->offset = ctx->cursor->offset;
+		__entry->hashval = ctx->cursor.hashval;
+		__entry->blkno = ctx->cursor.blkno;
+		__entry->offset = ctx->cursor.offset;
 		__entry->buffer = ctx->buffer;
 		__entry->bufsize = ctx->bufsize;
 		__entry->count = ctx->count;
@@ -186,9 +186,9 @@ TRACE_EVENT(xfs_attr_list_node_descend,
 	TP_fast_assign(
 		__entry->dev = VFS_I(ctx->dp)->i_sb->s_dev;
 		__entry->ino = ctx->dp->i_ino;
-		__entry->hashval = ctx->cursor->hashval;
-		__entry->blkno = ctx->cursor->blkno;
-		__entry->offset = ctx->cursor->offset;
+		__entry->hashval = ctx->cursor.hashval;
+		__entry->blkno = ctx->cursor.blkno;
+		__entry->offset = ctx->cursor.offset;
 		__entry->buffer = ctx->buffer;
 		__entry->bufsize = ctx->bufsize;
 		__entry->count = ctx->count;
diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
index 1d2c8615b335..b4e740a6b372 100644
--- a/fs/xfs/xfs_xattr.c
+++ b/fs/xfs/xfs_xattr.c
@@ -188,7 +188,6 @@ xfs_vn_listxattr(
 	size_t		size)
 {
 	struct xfs_attr_list_context context;
-	struct attrlist_cursor_kern cursor = { 0 };
 	struct inode	*inode = d_inode(dentry);
 	int		error;
 
@@ -197,7 +196,6 @@ xfs_vn_listxattr(
 	 */
 	memset(&context, 0, sizeof(context));
 	context.dp = XFS_I(inode);
-	context.cursor = &cursor;
 	context.resynch = 1;
 	context.buffer = size ? data : NULL;
 	context.bufsize = size;
-- 
2.24.1


^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 01/30] xfs: reject invalid flags combinations in XFS_IOC_ATTRLIST_BY_HANDLE
  2020-01-29 17:02 ` [PATCH 01/30] xfs: reject invalid flags combinations in XFS_IOC_ATTRLIST_BY_HANDLE Christoph Hellwig
@ 2020-02-05 13:46   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-05 13:46 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins

On Wednesday, January 29, 2020 10:32 PM Christoph Hellwig wrote: 

> While the flags field in the ABI and the on-disk format allows for
> multiple namespace flags, that is a logically invalid combination and
> listing multiple namespace flags will return no results as no attr
> can have both set.  Reject this case early with -EINVAL.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/xfs_ioctl.c   | 2 ++
>  fs/xfs/xfs_ioctl32.c | 2 ++
>  2 files changed, 4 insertions(+)
> 
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index d42de92cb283..d974bf099d45 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -317,6 +317,8 @@ xfs_attrlist_by_handle(
>  	 */
>  	if (al_hreq.flags & ~(ATTR_ROOT | ATTR_SECURE))
>  		return -EINVAL;

The above statement makes sure that al_hreq.flags has only ATTR_ROOT
and/or ATTR_SECURE flags set ...

> +	if (al_hreq.flags == (ATTR_ROOT | ATTR_SECURE))
> +		return -EINVAL;
>
... Hence if the execution control arrives here, we can be sure that the
presence of no other bits need to be checked.

Therefore the code is logically correct.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

>  	dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
>  	if (IS_ERR(dentry))
> diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
> index 769581a79c58..9705172e5410 100644
> --- a/fs/xfs/xfs_ioctl32.c
> +++ b/fs/xfs/xfs_ioctl32.c
> @@ -375,6 +375,8 @@ xfs_compat_attrlist_by_handle(
>  	 */
>  	if (al_hreq.flags & ~(ATTR_ROOT | ATTR_SECURE))
>  		return -EINVAL;
> +	if (al_hreq.flags == (ATTR_ROOT | ATTR_SECURE))
> +		return -EINVAL;
> 
>  	dentry = xfs_compat_handlereq_to_dentry(parfilp, &al_hreq.hreq);
>  	if (IS_ERR(dentry))
> 

-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 03/30] xfs: merge xfs_attr_remove into xfs_attr_set
  2020-01-29 17:02 ` [PATCH 03/30] xfs: merge xfs_attr_remove into xfs_attr_set Christoph Hellwig
@ 2020-02-06  8:00   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-06  8:00 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins

On Wednesday, January 29, 2020 10:32 PM Christoph Hellwig wrote: 

> The Linux xattr and acl APIs use a single call for set an remove.  Modify
> the high-level XFS API to match that and let xfs_attr_set handle removing
> attributes as well.  With a little bit of reordering this removes a lot
> of code.
>

The newly introduced changes match with the code flow that earlier existed
separately in xfs_attr_set() and xfs_attr_remove().

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/libxfs/xfs_attr.c | 178 ++++++++++++++-------------------------
>  fs/xfs/libxfs/xfs_attr.h |   2 -
>  fs/xfs/xfs_acl.c         |  33 +++-----
>  fs/xfs/xfs_ioctl.c       |   4 +-
>  fs/xfs/xfs_xattr.c       |   9 +-
>  5 files changed, 77 insertions(+), 149 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index e6149720ce02..bb391b96cd78 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -336,6 +336,10 @@ xfs_attr_remove_args(
>  	return error;
>  }
> 
> +/*
> + * Note: If value is NULL the attribute will be removed, just like the
> + * Linux ->setattr API.
> + */
>  int
>  xfs_attr_set(
>  	struct xfs_inode	*dp,
> @@ -350,149 +354,92 @@ xfs_attr_set(
>  	struct xfs_trans_res	tres;
>  	int			rsvd = (flags & ATTR_ROOT) != 0;
>  	int			error, local;
> -
> -	XFS_STATS_INC(mp, xs_attr_set);
> +	unsigned int		total;
> 
>  	if (XFS_FORCED_SHUTDOWN(dp->i_mount))
>  		return -EIO;
> 
> -	error = xfs_attr_args_init(&args, dp, name, namelen, flags);
> -	if (error)
> -		return error;
> -
> -	args.value = value;
> -	args.valuelen = valuelen;
> -	args.op_flags = XFS_DA_OP_ADDNAME | XFS_DA_OP_OKNOENT;
> -	args.total = xfs_attr_calc_size(&args, &local);
> -
>  	error = xfs_qm_dqattach(dp);
>  	if (error)
>  		return error;
> 
> -	/*
> -	 * If the inode doesn't have an attribute fork, add one.
> -	 * (inode must not be locked when we call this routine)
> -	 */
> -	if (XFS_IFORK_Q(dp) == 0) {
> -		int sf_size = sizeof(xfs_attr_sf_hdr_t) +
> -			XFS_ATTR_SF_ENTSIZE_BYNAME(args.namelen, valuelen);
> -
> -		error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
> -		if (error)
> -			return error;
> -	}
> -
> -	tres.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
> -			 M_RES(mp)->tr_attrsetrt.tr_logres * args.total;
> -	tres.tr_logcount = XFS_ATTRSET_LOG_COUNT;
> -	tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
> -
> -	/*
> -	 * Root fork attributes can use reserved data blocks for this
> -	 * operation if necessary
> -	 */
> -	error = xfs_trans_alloc(mp, &tres, args.total, 0,
> -			rsvd ? XFS_TRANS_RESERVE : 0, &args.trans);
> +	error = xfs_attr_args_init(&args, dp, name, namelen, flags);
>  	if (error)
>  		return error;
> 
> -	xfs_ilock(dp, XFS_ILOCK_EXCL);
> -	error = xfs_trans_reserve_quota_nblks(args.trans, dp, args.total, 0,
> -				rsvd ? XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
> -				       XFS_QMOPT_RES_REGBLKS);
> -	if (error)
> -		goto out_trans_cancel;
> -
> -	xfs_trans_ijoin(args.trans, dp, 0);
> -	error = xfs_attr_set_args(&args);
> -	if (error)
> -		goto out_trans_cancel;
> -	if (!args.trans) {
> -		/* shortform attribute has already been committed */
> -		goto out_unlock;
> -	}
> -
> -	/*
> -	 * If this is a synchronous mount, make sure that the
> -	 * transaction goes to disk before returning to the user.
> -	 */
> -	if (mp->m_flags & XFS_MOUNT_WSYNC)
> -		xfs_trans_set_sync(args.trans);
> -
> -	if ((flags & ATTR_KERNOTIME) == 0)
> -		xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG);
> +	args.value = value;
> +	args.valuelen = valuelen;
> 
>  	/*
> -	 * Commit the last in the sequence of transactions.
> +	 * We have no control over the attribute names that userspace passes us
> +	 * to remove, so we have to allow the name lookup prior to attribute
> +	 * removal to fail as well.
>  	 */
> -	xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
> -	error = xfs_trans_commit(args.trans);
> -out_unlock:
> -	xfs_iunlock(dp, XFS_ILOCK_EXCL);
> -	return error;
> -
> -out_trans_cancel:
> -	if (args.trans)
> -		xfs_trans_cancel(args.trans);
> -	goto out_unlock;
> -}
> +	args.op_flags = XFS_DA_OP_OKNOENT;
> 
> -/*
> - * Generic handler routine to remove a name from an attribute list.
> - * Transitions attribute list from Btree to shortform as necessary.
> - */
> -int
> -xfs_attr_remove(
> -	struct xfs_inode	*dp,
> -	const unsigned char	*name,
> -	size_t			namelen,
> -	int			flags)
> -{
> -	struct xfs_mount	*mp = dp->i_mount;
> -	struct xfs_da_args	args;
> -	int			error;
> +	if (value) {
> +		XFS_STATS_INC(mp, xs_attr_set);
> 
> -	XFS_STATS_INC(mp, xs_attr_remove);
> +		args.op_flags |= XFS_DA_OP_ADDNAME;
> +		args.total = xfs_attr_calc_size(&args, &local);
> 
> -	if (XFS_FORCED_SHUTDOWN(dp->i_mount))
> -		return -EIO;
> +		/*
> +		 * If the inode doesn't have an attribute fork, add one.
> +		 * (inode must not be locked when we call this routine)
> +		 */
> +		if (XFS_IFORK_Q(dp) == 0) {
> +			int sf_size = sizeof(struct xfs_attr_sf_hdr) +
> +				XFS_ATTR_SF_ENTSIZE_BYNAME(args.namelen,
> +						valuelen);
> 
> -	error = xfs_attr_args_init(&args, dp, name, namelen, flags);
> -	if (error)
> -		return error;
> +			error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
> +			if (error)
> +				return error;
> +		}
> 
> -	/*
> -	 * we have no control over the attribute names that userspace passes us
> -	 * to remove, so we have to allow the name lookup prior to attribute
> -	 * removal to fail.
> -	 */
> -	args.op_flags = XFS_DA_OP_OKNOENT;
> +		tres.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
> +				 M_RES(mp)->tr_attrsetrt.tr_logres * args.total;
> +		tres.tr_logcount = XFS_ATTRSET_LOG_COUNT;
> +		tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
> +		total = args.total;
> +	} else {
> +		XFS_STATS_INC(mp, xs_attr_remove);
> 
> -	error = xfs_qm_dqattach(dp);
> -	if (error)
> -		return error;
> +		tres = M_RES(mp)->tr_attrrm;
> +		total = XFS_ATTRRM_SPACE_RES(mp);
> +	}
> 
>  	/*
>  	 * Root fork attributes can use reserved data blocks for this
>  	 * operation if necessary
>  	 */
> -	error = xfs_trans_alloc(mp, &M_RES(mp)->tr_attrrm,
> -			XFS_ATTRRM_SPACE_RES(mp), 0,
> -			(flags & ATTR_ROOT) ? XFS_TRANS_RESERVE : 0,
> -			&args.trans);
> +	error = xfs_trans_alloc(mp, &tres, total, 0,
> +			rsvd ? XFS_TRANS_RESERVE : 0, &args.trans);
>  	if (error)
>  		return error;
> 
>  	xfs_ilock(dp, XFS_ILOCK_EXCL);
> -	/*
> -	 * No need to make quota reservations here. We expect to release some
> -	 * blocks not allocate in the common case.
> -	 */
>  	xfs_trans_ijoin(args.trans, dp, 0);
> +	if (value) {
> +		unsigned int	quota_flags = XFS_QMOPT_RES_REGBLKS;
> 
> -	error = xfs_attr_remove_args(&args);
> -	if (error)
> -		goto out;
> +		if (rsvd)
> +			quota_flags |= XFS_QMOPT_FORCE_RES;
> +		error = xfs_trans_reserve_quota_nblks(args.trans, dp,
> +				args.total, 0, quota_flags);
> +		if (error)
> +			goto out_trans_cancel;
> +		error = xfs_attr_set_args(&args);
> +		if (error)
> +			goto out_trans_cancel;
> +		/* shortform attribute has already been committed */
> +		if (!args.trans)
> +			goto out_unlock;
> +	} else {
> +		error = xfs_attr_remove_args(&args);
> +		if (error)
> +			goto out_trans_cancel;
> +	}
> 
>  	/*
>  	 * If this is a synchronous mount, make sure that the
> @@ -509,15 +456,14 @@ xfs_attr_remove(
>  	 */
>  	xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
>  	error = xfs_trans_commit(args.trans);
> +out_unlock:
>  	xfs_iunlock(dp, XFS_ILOCK_EXCL);
> -
>  	return error;
> 
> -out:
> +out_trans_cancel:
>  	if (args.trans)
>  		xfs_trans_cancel(args.trans);
> -	xfs_iunlock(dp, XFS_ILOCK_EXCL);
> -	return error;
> +	goto out_unlock;
>  }
> 
>  /*========================================================================
> diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
> index 71bcf1298e4c..db58a6c7dea5 100644
> --- a/fs/xfs/libxfs/xfs_attr.h
> +++ b/fs/xfs/libxfs/xfs_attr.h
> @@ -152,8 +152,6 @@ int xfs_attr_get(struct xfs_inode *ip, const unsigned char *name,
>  int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name,
>  		 size_t namelen, unsigned char *value, int valuelen, int flags);
>  int xfs_attr_set_args(struct xfs_da_args *args);
> -int xfs_attr_remove(struct xfs_inode *dp, const unsigned char *name,
> -		    size_t namelen, int flags);
>  int xfs_attr_remove_args(struct xfs_da_args *args);
>  int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
>  		  int flags, struct attrlist_cursor_kern *cursor);
> diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
> index cd743fad8478..4e76063ff956 100644
> --- a/fs/xfs/xfs_acl.c
> +++ b/fs/xfs/xfs_acl.c
> @@ -168,6 +168,8 @@ __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
>  {
>  	struct xfs_inode *ip = XFS_I(inode);
>  	unsigned char *ea_name;
> +	struct xfs_acl *xfs_acl = NULL;
> +	int len = 0;
>  	int error;
> 
>  	switch (type) {
> @@ -184,9 +186,7 @@ __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
>  	}
> 
>  	if (acl) {
> -		struct xfs_acl *xfs_acl;
> -		int len = XFS_ACL_MAX_SIZE(ip->i_mount);
> -
> +		len = XFS_ACL_MAX_SIZE(ip->i_mount);
>  		xfs_acl = kmem_zalloc_large(len, 0);
>  		if (!xfs_acl)
>  			return -ENOMEM;
> @@ -196,26 +196,17 @@ __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
>  		/* subtract away the unused acl entries */
>  		len -= sizeof(struct xfs_acl_entry) *
>  			 (XFS_ACL_MAX_ENTRIES(ip->i_mount) - acl->a_count);
> -
> -		error = xfs_attr_set(ip, ea_name, strlen(ea_name),
> -				     (unsigned char *)xfs_acl, len, ATTR_ROOT);
> -
> -		kmem_free(xfs_acl);
> -	} else {
> -		/*
> -		 * A NULL ACL argument means we want to remove the ACL.
> -		 */
> -		error = xfs_attr_remove(ip, ea_name,
> -					strlen(ea_name),
> -					ATTR_ROOT);
> -
> -		/*
> -		 * If the attribute didn't exist to start with that's fine.
> -		 */
> -		if (error == -ENOATTR)
> -			error = 0;
>  	}
> 
> +	error = xfs_attr_set(ip, ea_name, strlen(ea_name),
> +			(unsigned char *)xfs_acl, len, ATTR_ROOT);
> +	kmem_free(xfs_acl);
> +
> +	/*
> +	 * If the attribute didn't exist to start with that's fine.
> +	 */
> +	if (!acl && error == -ENOATTR)
> +		error = 0;
>  	if (!error)
>  		set_cached_acl(inode, type, acl);
>  	return error;
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index d974bf099d45..79c418888e9a 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -417,12 +417,10 @@ xfs_attrmulti_attr_remove(
>  	uint32_t		flags)
>  {
>  	int			error;
> -	size_t			namelen;
> 
>  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
>  		return -EPERM;
> -	namelen = strlen(name);
> -	error = xfs_attr_remove(XFS_I(inode), name, namelen, flags);
> +	error = xfs_attr_set(XFS_I(inode), name, strlen(name), NULL, 0, flags);
>  	if (!error)
>  		xfs_forget_acl(inode, name, flags);
>  	return error;
> diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
> index b0fedb543f97..1670bfbc9ad2 100644
> --- a/fs/xfs/xfs_xattr.c
> +++ b/fs/xfs/xfs_xattr.c
> @@ -69,7 +69,6 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
>  	int			xflags = handler->flags;
>  	struct xfs_inode	*ip = XFS_I(inode);
>  	int			error;
> -	size_t			namelen = strlen(name);
> 
>  	/* Convert Linux syscall to XFS internal ATTR flags */
>  	if (flags & XATTR_CREATE)
> @@ -77,14 +76,10 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
>  	if (flags & XATTR_REPLACE)
>  		xflags |= ATTR_REPLACE;
> 
> -	if (value)
> -		error = xfs_attr_set(ip, name, namelen, (void *)value, size,
> -				xflags);
> -	else
> -		error = xfs_attr_remove(ip, name, namelen, xflags);
> +	error = xfs_attr_set(ip, (unsigned char *)name, strlen(name),
> +				(void *)value, size, xflags);
>  	if (!error)
>  		xfs_forget_acl(inode, name, xflags);
> -
>  	return error;
>  }
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 04/30] xfs: merge xfs_attrmulti_attr_remove into xfs_attrmulti_attr_set
  2020-01-29 17:02 ` [PATCH 04/30] xfs: merge xfs_attrmulti_attr_remove into xfs_attrmulti_attr_set Christoph Hellwig
@ 2020-02-06  9:21   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-06  9:21 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:32 PM Christoph Hellwig wrote: 
> Merge the ioctl handlers just like the low-level xfs_attr_set function.
>

The newly introduced changes match with the code flow that earlier existed
separately in xfs_attrmulti_attr_set() and xfs_attrmulti_attr_remove().

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_ioctl.c   | 34 ++++++++++------------------------
>  fs/xfs/xfs_ioctl.h   |  6 ------
>  fs/xfs/xfs_ioctl32.c |  4 ++--
>  3 files changed, 12 insertions(+), 32 deletions(-)
> 
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index 79c418888e9a..b806003caacd 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -389,18 +389,20 @@ xfs_attrmulti_attr_set(
>  	uint32_t		len,
>  	uint32_t		flags)
>  {
> -	unsigned char		*kbuf;
> +	unsigned char		*kbuf = NULL;
>  	int			error;
>  	size_t			namelen;
> 
>  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
>  		return -EPERM;
> -	if (len > XFS_XATTR_SIZE_MAX)
> -		return -EINVAL;
> 
> -	kbuf = memdup_user(ubuf, len);
> -	if (IS_ERR(kbuf))
> -		return PTR_ERR(kbuf);
> +	if (ubuf) {
> +		if (len > XFS_XATTR_SIZE_MAX)
> +			return -EINVAL;
> +		kbuf = memdup_user(ubuf, len);
> +		if (IS_ERR(kbuf))
> +			return PTR_ERR(kbuf);
> +	}
> 
>  	namelen = strlen(name);
>  	error = xfs_attr_set(XFS_I(inode), name, namelen, kbuf, len, flags);
> @@ -410,22 +412,6 @@ xfs_attrmulti_attr_set(
>  	return error;
>  }
> 
> -int
> -xfs_attrmulti_attr_remove(
> -	struct inode		*inode,
> -	unsigned char		*name,
> -	uint32_t		flags)
> -{
> -	int			error;
> -
> -	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
> -		return -EPERM;
> -	error = xfs_attr_set(XFS_I(inode), name, strlen(name), NULL, 0, flags);
> -	if (!error)
> -		xfs_forget_acl(inode, name, flags);
> -	return error;
> -}
> -
>  STATIC int
>  xfs_attrmulti_by_handle(
>  	struct file		*parfilp,
> @@ -504,8 +490,8 @@ xfs_attrmulti_by_handle(
>  			ops[i].am_error = mnt_want_write_file(parfilp);
>  			if (ops[i].am_error)
>  				break;
> -			ops[i].am_error = xfs_attrmulti_attr_remove(
> -					d_inode(dentry), attr_name,
> +			ops[i].am_error = xfs_attrmulti_attr_set(
> +					d_inode(dentry), attr_name, NULL, 0,
>  					ops[i].am_flags);
>  			mnt_drop_write_file(parfilp);
>  			break;
> diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
> index 420bd95dc326..819504df00ae 100644
> --- a/fs/xfs/xfs_ioctl.h
> +++ b/fs/xfs/xfs_ioctl.h
> @@ -46,12 +46,6 @@ xfs_attrmulti_attr_set(
>  	uint32_t		len,
>  	uint32_t		flags);
> 
> -extern int
> -xfs_attrmulti_attr_remove(
> -	struct inode		*inode,
> -	unsigned char		*name,
> -	uint32_t		flags);
> -
>  extern struct dentry *
>  xfs_handle_to_dentry(
>  	struct file		*parfilp,
> diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
> index 9705172e5410..e085f304e539 100644
> --- a/fs/xfs/xfs_ioctl32.c
> +++ b/fs/xfs/xfs_ioctl32.c
> @@ -488,8 +488,8 @@ xfs_compat_attrmulti_by_handle(
>  			ops[i].am_error = mnt_want_write_file(parfilp);
>  			if (ops[i].am_error)
>  				break;
> -			ops[i].am_error = xfs_attrmulti_attr_remove(
> -					d_inode(dentry), attr_name,
> +			ops[i].am_error = xfs_attrmulti_attr_set(
> +					d_inode(dentry), attr_name, NULL, 0,
>  					ops[i].am_flags);
>  			mnt_drop_write_file(parfilp);
>  			break;
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 05/30] xfs: use strndup_user in XFS_IOC_ATTRMULTI_BY_HANDLE
  2020-01-29 17:02 ` [PATCH 05/30] xfs: use strndup_user in XFS_IOC_ATTRMULTI_BY_HANDLE Christoph Hellwig
@ 2020-02-06 10:33   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-06 10:33 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:32 PM Christoph Hellwig wrote: 

> Simplify the user copy code by using strndup_user.  This means that we
> now do one memory allocation per operation instead of one per ioctl,
> but memory allocations are cheap compared to the actual file system
> operations.
>

The newly introduced changes logically match with the code flow that existed
earlier.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_ioctl.c   | 17 +++++------------
>  fs/xfs/xfs_ioctl32.c | 17 +++++------------
>  2 files changed, 10 insertions(+), 24 deletions(-)
> 
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index b806003caacd..bb490a954c0b 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -448,11 +448,6 @@ xfs_attrmulti_by_handle(
>  		goto out_dput;
>  	}
> 
> -	error = -ENOMEM;
> -	attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL);
> -	if (!attr_name)
> -		goto out_kfree_ops;
> -
>  	error = 0;
>  	for (i = 0; i < am_hreq.opcount; i++) {
>  		if ((ops[i].am_flags & ATTR_ROOT) &&
> @@ -462,12 +457,11 @@ xfs_attrmulti_by_handle(
>  		}
>  		ops[i].am_flags &= ~ATTR_KERNEL_FLAGS;
> 
> -		ops[i].am_error = strncpy_from_user((char *)attr_name,
> -				ops[i].am_attrname, MAXNAMELEN);
> -		if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN)
> -			error = -ERANGE;
> -		if (ops[i].am_error < 0)
> +		attr_name = strndup_user(ops[i].am_attrname, MAXNAMELEN);
> +		if (IS_ERR(attr_name)) {
> +			ops[i].am_error = PTR_ERR(attr_name);
>  			break;
> +		}
> 
>  		switch (ops[i].am_opcode) {
>  		case ATTR_OP_GET:
> @@ -498,13 +492,12 @@ xfs_attrmulti_by_handle(
>  		default:
>  			ops[i].am_error = -EINVAL;
>  		}
> +		kfree(attr_name);
>  	}
> 
>  	if (copy_to_user(am_hreq.ops, ops, size))
>  		error = -EFAULT;
> 
> -	kfree(attr_name);
> - out_kfree_ops:
>  	kfree(ops);
>   out_dput:
>  	dput(dentry);
> diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
> index e085f304e539..936c2f62fb6c 100644
> --- a/fs/xfs/xfs_ioctl32.c
> +++ b/fs/xfs/xfs_ioctl32.c
> @@ -445,11 +445,6 @@ xfs_compat_attrmulti_by_handle(
>  		goto out_dput;
>  	}
> 
> -	error = -ENOMEM;
> -	attr_name = kmalloc(MAXNAMELEN, GFP_KERNEL);
> -	if (!attr_name)
> -		goto out_kfree_ops;
> -
>  	error = 0;
>  	for (i = 0; i < am_hreq.opcount; i++) {
>  		if ((ops[i].am_flags & ATTR_ROOT) &&
> @@ -459,13 +454,12 @@ xfs_compat_attrmulti_by_handle(
>  		}
>  		ops[i].am_flags &= ~ATTR_KERNEL_FLAGS;
> 
> -		ops[i].am_error = strncpy_from_user((char *)attr_name,
> -				compat_ptr(ops[i].am_attrname),
> +		attr_name = strndup_user(compat_ptr(ops[i].am_attrname),
>  				MAXNAMELEN);
> -		if (ops[i].am_error == 0 || ops[i].am_error == MAXNAMELEN)
> -			error = -ERANGE;
> -		if (ops[i].am_error < 0)
> +		if (IS_ERR(attr_name)) {
> +			ops[i].am_error = PTR_ERR(attr_name);
>  			break;
> +		}
> 
>  		switch (ops[i].am_opcode) {
>  		case ATTR_OP_GET:
> @@ -496,13 +490,12 @@ xfs_compat_attrmulti_by_handle(
>  		default:
>  			ops[i].am_error = -EINVAL;
>  		}
> +		kfree(attr_name);
>  	}
> 
>  	if (copy_to_user(compat_ptr(am_hreq.ops), ops, size))
>  		error = -EFAULT;
> 
> -	kfree(attr_name);
> - out_kfree_ops:
>  	kfree(ops);
>   out_dput:
>  	dput(dentry);
> 

-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 06/30] xfs: factor out a helper for a single XFS_IOC_ATTRMULTI_BY_HANDLE op
  2020-01-29 17:02 ` [PATCH 06/30] xfs: factor out a helper for a single XFS_IOC_ATTRMULTI_BY_HANDLE op Christoph Hellwig
@ 2020-02-07  5:20   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-07  5:20 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins

On Wednesday, January 29, 2020 10:32 PM Christoph Hellwig wrote: 
> Add a new helper to handle a single attr multi ioctl operation that
> can be shared between the native and compat ioctl implementation.
> 
> There is a slight change in heavior in that we don't break out of the
> loop when copying in the attribute name fails.  The previous behavior
> was rather inconsistent here as it continued for any other kind of
> error.
>

Apart from "not breaking out of the for loop" change, The other changes
logically match with the code flow that existed earlier.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/xfs_ioctl.c   | 97 +++++++++++++++++++++++---------------------
>  fs/xfs/xfs_ioctl.h   | 18 ++------
>  fs/xfs/xfs_ioctl32.c | 50 +++--------------------
>  3 files changed, 59 insertions(+), 106 deletions(-)
> 
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index bb490a954c0b..cfdd80b4ea2d 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -349,7 +349,7 @@ xfs_attrlist_by_handle(
>  	return error;
>  }
> 
> -int
> +static int
>  xfs_attrmulti_attr_get(
>  	struct inode		*inode,
>  	unsigned char		*name,
> @@ -381,7 +381,7 @@ xfs_attrmulti_attr_get(
>  	return error;
>  }
> 
> -int
> +static int
>  xfs_attrmulti_attr_set(
>  	struct inode		*inode,
>  	unsigned char		*name,
> @@ -412,6 +412,51 @@ xfs_attrmulti_attr_set(
>  	return error;
>  }
> 
> +int
> +xfs_ioc_attrmulti_one(
> +	struct file		*parfilp,
> +	struct inode		*inode,
> +	uint32_t		opcode,
> +	void __user		*uname,
> +	void __user		*value,
> +	uint32_t		*len,
> +	uint32_t		flags)
> +{
> +	unsigned char		*name;
> +	int			error;
> +
> +	if ((flags & ATTR_ROOT) && (flags & ATTR_SECURE))
> +		return -EINVAL;
> +	flags &= ~ATTR_KERNEL_FLAGS;
> +
> +	name = strndup_user(uname, MAXNAMELEN);
> +	if (IS_ERR(name))
> +		return PTR_ERR(name);
> +
> +	switch (opcode) {
> +	case ATTR_OP_GET:
> +		error = xfs_attrmulti_attr_get(inode, name, value, len, flags);
> +		break;
> +	case ATTR_OP_REMOVE:
> +		value = NULL;
> +		*len = 0;
> +		/*FALLTHRU*/
> +	case ATTR_OP_SET:
> +		error = mnt_want_write_file(parfilp);
> +		if (error)
> +			break;
> +		error = xfs_attrmulti_attr_set(inode, name, value, *len, flags);
> +		mnt_drop_write_file(parfilp);
> +		break;
> +	default:
> +		error = -EINVAL;
> +		break;
> +	}
> +
> +	kfree(name);
> +	return error;
> +}
> +
>  STATIC int
>  xfs_attrmulti_by_handle(
>  	struct file		*parfilp,
> @@ -422,7 +467,6 @@ xfs_attrmulti_by_handle(
>  	xfs_fsop_attrmulti_handlereq_t am_hreq;
>  	struct dentry		*dentry;
>  	unsigned int		i, size;
> -	unsigned char		*attr_name;
> 
>  	if (!capable(CAP_SYS_ADMIN))
>  		return -EPERM;
> @@ -450,49 +494,10 @@ xfs_attrmulti_by_handle(
> 
>  	error = 0;
>  	for (i = 0; i < am_hreq.opcount; i++) {
> -		if ((ops[i].am_flags & ATTR_ROOT) &&
> -		    (ops[i].am_flags & ATTR_SECURE)) {
> -			ops[i].am_error = -EINVAL;
> -			continue;
> -		}
> -		ops[i].am_flags &= ~ATTR_KERNEL_FLAGS;
> -
> -		attr_name = strndup_user(ops[i].am_attrname, MAXNAMELEN);
> -		if (IS_ERR(attr_name)) {
> -			ops[i].am_error = PTR_ERR(attr_name);
> -			break;
> -		}
> -
> -		switch (ops[i].am_opcode) {
> -		case ATTR_OP_GET:
> -			ops[i].am_error = xfs_attrmulti_attr_get(
> -					d_inode(dentry), attr_name,
> -					ops[i].am_attrvalue, &ops[i].am_length,
> -					ops[i].am_flags);
> -			break;
> -		case ATTR_OP_SET:
> -			ops[i].am_error = mnt_want_write_file(parfilp);
> -			if (ops[i].am_error)
> -				break;
> -			ops[i].am_error = xfs_attrmulti_attr_set(
> -					d_inode(dentry), attr_name,
> -					ops[i].am_attrvalue, ops[i].am_length,
> -					ops[i].am_flags);
> -			mnt_drop_write_file(parfilp);
> -			break;
> -		case ATTR_OP_REMOVE:
> -			ops[i].am_error = mnt_want_write_file(parfilp);
> -			if (ops[i].am_error)
> -				break;
> -			ops[i].am_error = xfs_attrmulti_attr_set(
> -					d_inode(dentry), attr_name, NULL, 0,
> -					ops[i].am_flags);
> -			mnt_drop_write_file(parfilp);
> -			break;
> -		default:
> -			ops[i].am_error = -EINVAL;
> -		}
> -		kfree(attr_name);
> +		ops[i].am_error = xfs_ioc_attrmulti_one(parfilp,
> +				d_inode(dentry), ops[i].am_opcode,
> +				ops[i].am_attrname, ops[i].am_attrvalue,
> +				&ops[i].am_length, ops[i].am_flags);
>  	}
> 
>  	if (copy_to_user(am_hreq.ops, ops, size))
> diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
> index 819504df00ae..bb50cb3dc61f 100644
> --- a/fs/xfs/xfs_ioctl.h
> +++ b/fs/xfs/xfs_ioctl.h
> @@ -30,21 +30,9 @@ xfs_readlink_by_handle(
>  	struct file		*parfilp,
>  	xfs_fsop_handlereq_t	*hreq);
> 
> -extern int
> -xfs_attrmulti_attr_get(
> -	struct inode		*inode,
> -	unsigned char		*name,
> -	unsigned char		__user *ubuf,
> -	uint32_t		*len,
> -	uint32_t		flags);
> -
> -extern int
> -xfs_attrmulti_attr_set(
> -	struct inode		*inode,
> -	unsigned char		*name,
> -	const unsigned char	__user *ubuf,
> -	uint32_t		len,
> -	uint32_t		flags);
> +int xfs_ioc_attrmulti_one(struct file *parfilp, struct inode *inode,
> +		uint32_t opcode, void __user *uname, void __user *value,
> +		uint32_t *len, uint32_t flags);
> 
>  extern struct dentry *
>  xfs_handle_to_dentry(
> diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
> index 936c2f62fb6c..e1daf095c585 100644
> --- a/fs/xfs/xfs_ioctl32.c
> +++ b/fs/xfs/xfs_ioctl32.c
> @@ -418,7 +418,6 @@ xfs_compat_attrmulti_by_handle(
>  	compat_xfs_fsop_attrmulti_handlereq_t	am_hreq;
>  	struct dentry				*dentry;
>  	unsigned int				i, size;
> -	unsigned char				*attr_name;
> 
>  	if (!capable(CAP_SYS_ADMIN))
>  		return -EPERM;
> @@ -447,50 +446,11 @@ xfs_compat_attrmulti_by_handle(
> 
>  	error = 0;
>  	for (i = 0; i < am_hreq.opcount; i++) {
> -		if ((ops[i].am_flags & ATTR_ROOT) &&
> -		    (ops[i].am_flags & ATTR_SECURE)) {
> -			ops[i].am_error = -EINVAL;
> -			continue;
> -		}
> -		ops[i].am_flags &= ~ATTR_KERNEL_FLAGS;
> -
> -		attr_name = strndup_user(compat_ptr(ops[i].am_attrname),
> -				MAXNAMELEN);
> -		if (IS_ERR(attr_name)) {
> -			ops[i].am_error = PTR_ERR(attr_name);
> -			break;
> -		}
> -
> -		switch (ops[i].am_opcode) {
> -		case ATTR_OP_GET:
> -			ops[i].am_error = xfs_attrmulti_attr_get(
> -					d_inode(dentry), attr_name,
> -					compat_ptr(ops[i].am_attrvalue),
> -					&ops[i].am_length, ops[i].am_flags);
> -			break;
> -		case ATTR_OP_SET:
> -			ops[i].am_error = mnt_want_write_file(parfilp);
> -			if (ops[i].am_error)
> -				break;
> -			ops[i].am_error = xfs_attrmulti_attr_set(
> -					d_inode(dentry), attr_name,
> -					compat_ptr(ops[i].am_attrvalue),
> -					ops[i].am_length, ops[i].am_flags);
> -			mnt_drop_write_file(parfilp);
> -			break;
> -		case ATTR_OP_REMOVE:
> -			ops[i].am_error = mnt_want_write_file(parfilp);
> -			if (ops[i].am_error)
> -				break;
> -			ops[i].am_error = xfs_attrmulti_attr_set(
> -					d_inode(dentry), attr_name, NULL, 0,
> -					ops[i].am_flags);
> -			mnt_drop_write_file(parfilp);
> -			break;
> -		default:
> -			ops[i].am_error = -EINVAL;
> -		}
> -		kfree(attr_name);
> +		ops[i].am_error = xfs_ioc_attrmulti_one(parfilp,
> +				d_inode(dentry), ops[i].am_opcode,
> +				compat_ptr(ops[i].am_attrname),
> +				compat_ptr(ops[i].am_attrvalue),
> +				&ops[i].am_length, ops[i].am_flags);
>  	}
> 
>  	if (copy_to_user(compat_ptr(am_hreq.ops), ops, size))
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 07/30] xfs: remove the name == NULL check from xfs_attr_args_init
  2020-01-29 17:02 ` [PATCH 07/30] xfs: remove the name == NULL check from xfs_attr_args_init Christoph Hellwig
@ 2020-02-07  6:15   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-07  6:15 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:32 PM Christoph Hellwig wrote: 

> All callers provide a valid name pointer, remove the redundant check.
>

I went through the callers of xfs_attr_args_init() (and in turn to callers of
those callers) and found that 'name' arg can indeed never be NULL.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_attr.c | 4 ----
>  1 file changed, 4 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index bb391b96cd78..a968158b9bb1 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -65,10 +65,6 @@ xfs_attr_args_init(
>  	size_t			namelen,
>  	int			flags)
>  {
> -
> -	if (!name)
> -		return -EINVAL;
> -
>  	memset(args, 0, sizeof(*args));
>  	args->geo = dp->i_mount->m_attr_geo;
>  	args->whichfork = XFS_ATTR_FORK;
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 08/30] xfs: remove the MAXNAMELEN check from xfs_attr_args_init
  2020-01-29 17:02 ` [PATCH 08/30] xfs: remove the MAXNAMELEN " Christoph Hellwig
@ 2020-02-07  6:56   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-07  6:56 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:32 PM Christoph Hellwig wrote: 
> All the callers already check the length when allocating the
> in-kernel xattrs buffers.
>

I checked all the callers apart from xfs_init_security(). For the ones I
checked,

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_attr.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index a968158b9bb1..f887d62e0956 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -72,9 +72,6 @@ xfs_attr_args_init(
>  	args->flags = flags;
>  	args->name = name;
>  	args->namelen = namelen;
> -	if (args->namelen >= MAXNAMELEN)
> -		return -EFAULT;		/* match IRIX behaviour */
> -
>  	args->hashval = xfs_da_hashname(args->name, args->namelen);
>  	return 0;
>  }
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 11/30] xfs: pass an initialized xfs_da_args structure to xfs_attr_set
  2020-01-29 17:02 ` [PATCH 11/30] xfs: pass an initialized xfs_da_args structure to xfs_attr_set Christoph Hellwig
@ 2020-02-07  9:42   ` Chandan Rajendra
  2020-02-17 13:48     ` Christoph Hellwig
  0 siblings, 1 reply; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-07  9:42 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:32 PM Christoph Hellwig wrote: 
> Instead of converting from one style of arguments to another in
> xfs_attr_set, pass the structure from higher up in the call chain.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_attr.c | 69 ++++++++++++++++++----------------------
>  fs/xfs/libxfs/xfs_attr.h |  3 +-
>  fs/xfs/xfs_acl.c         | 31 +++++++++---------
>  fs/xfs/xfs_ioctl.c       | 20 +++++++-----
>  fs/xfs/xfs_iops.c        | 13 +++++---
>  fs/xfs/xfs_xattr.c       | 19 +++++++----
>  6 files changed, 81 insertions(+), 74 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index f887d62e0956..eea6d90af276 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -330,22 +330,17 @@ xfs_attr_remove_args(
>  }
> 
>  /*
> - * Note: If value is NULL the attribute will be removed, just like the
> + * Note: If args->value is NULL the attribute will be removed, just like the
>   * Linux ->setattr API.
>   */
>  int
>  xfs_attr_set(
> -	struct xfs_inode	*dp,
> -	const unsigned char	*name,
> -	size_t			namelen,
> -	unsigned char		*value,
> -	int			valuelen,
> -	int			flags)
> +	struct xfs_da_args	*args)
>  {
> +	struct xfs_inode	*dp = args->dp;
>  	struct xfs_mount	*mp = dp->i_mount;
> -	struct xfs_da_args	args;
>  	struct xfs_trans_res	tres;
> -	int			rsvd = (flags & ATTR_ROOT) != 0;
> +	int			rsvd = (args->flags & ATTR_ROOT) != 0;
>  	int			error, local;
>  	unsigned int		total;
> 
> @@ -356,25 +351,22 @@ xfs_attr_set(
>  	if (error)
>  		return error;
> 
> -	error = xfs_attr_args_init(&args, dp, name, namelen, flags);
> -	if (error)
> -		return error;
> -
> -	args.value = value;
> -	args.valuelen = valuelen;
> +	args->geo = mp->m_attr_geo;
> +	args->whichfork = XFS_ATTR_FORK;
> +	args->hashval = xfs_da_hashname(args->name, args->namelen);
> 
>  	/*
>  	 * We have no control over the attribute names that userspace passes us
>  	 * to remove, so we have to allow the name lookup prior to attribute
>  	 * removal to fail as well.
>  	 */
> -	args.op_flags = XFS_DA_OP_OKNOENT;
> +	args->op_flags = XFS_DA_OP_OKNOENT;
> 
> -	if (value) {
> +	if (args->value) {
>  		XFS_STATS_INC(mp, xs_attr_set);
> 
> -		args.op_flags |= XFS_DA_OP_ADDNAME;
> -		args.total = xfs_attr_calc_size(&args, &local);
> +		args->op_flags |= XFS_DA_OP_ADDNAME;
> +		args->total = xfs_attr_calc_size(args, &local);
> 
>  		/*
>  		 * If the inode doesn't have an attribute fork, add one.
> @@ -382,8 +374,8 @@ xfs_attr_set(
>  		 */
>  		if (XFS_IFORK_Q(dp) == 0) {
>  			int sf_size = sizeof(struct xfs_attr_sf_hdr) +
> -				XFS_ATTR_SF_ENTSIZE_BYNAME(args.namelen,
> -						valuelen);
> +				XFS_ATTR_SF_ENTSIZE_BYNAME(args->namelen,
> +						args->valuelen);
> 
>  			error = xfs_bmap_add_attrfork(dp, sf_size, rsvd);
>  			if (error)
> @@ -391,10 +383,11 @@ xfs_attr_set(
>  		}
> 
>  		tres.tr_logres = M_RES(mp)->tr_attrsetm.tr_logres +
> -				 M_RES(mp)->tr_attrsetrt.tr_logres * args.total;
> +				 M_RES(mp)->tr_attrsetrt.tr_logres *
> +					args->total;
>  		tres.tr_logcount = XFS_ATTRSET_LOG_COUNT;
>  		tres.tr_logflags = XFS_TRANS_PERM_LOG_RES;
> -		total = args.total;
> +		total = args->total;
>  	} else {
>  		XFS_STATS_INC(mp, xs_attr_remove);
> 
> @@ -407,29 +400,29 @@ xfs_attr_set(
>  	 * operation if necessary
>  	 */
>  	error = xfs_trans_alloc(mp, &tres, total, 0,
> -			rsvd ? XFS_TRANS_RESERVE : 0, &args.trans);
> +			rsvd ? XFS_TRANS_RESERVE : 0, &args->trans);
>  	if (error)
>  		return error;
> 
>  	xfs_ilock(dp, XFS_ILOCK_EXCL);
> -	xfs_trans_ijoin(args.trans, dp, 0);
> -	if (value) {
> +	xfs_trans_ijoin(args->trans, dp, 0);
> +	if (args->value) {
>  		unsigned int	quota_flags = XFS_QMOPT_RES_REGBLKS;
> 
>  		if (rsvd)
>  			quota_flags |= XFS_QMOPT_FORCE_RES;
> -		error = xfs_trans_reserve_quota_nblks(args.trans, dp,
> -				args.total, 0, quota_flags);
> +		error = xfs_trans_reserve_quota_nblks(args->trans, dp,
> +				args->total, 0, quota_flags);
>  		if (error)
>  			goto out_trans_cancel;
> -		error = xfs_attr_set_args(&args);
> +		error = xfs_attr_set_args(args);
>  		if (error)
>  			goto out_trans_cancel;
>  		/* shortform attribute has already been committed */
> -		if (!args.trans)
> +		if (!args->trans)
>  			goto out_unlock;
>  	} else {
> -		error = xfs_attr_remove_args(&args);
> +		error = xfs_attr_remove_args(args);
>  		if (error)
>  			goto out_trans_cancel;
>  	}
> @@ -439,23 +432,23 @@ xfs_attr_set(
>  	 * transaction goes to disk before returning to the user.
>  	 */
>  	if (mp->m_flags & XFS_MOUNT_WSYNC)
> -		xfs_trans_set_sync(args.trans);
> +		xfs_trans_set_sync(args->trans);
> 
> -	if ((flags & ATTR_KERNOTIME) == 0)
> -		xfs_trans_ichgtime(args.trans, dp, XFS_ICHGTIME_CHG);
> +	if ((args->flags & ATTR_KERNOTIME) == 0)
> +		xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
> 
>  	/*
>  	 * Commit the last in the sequence of transactions.
>  	 */
> -	xfs_trans_log_inode(args.trans, dp, XFS_ILOG_CORE);
> -	error = xfs_trans_commit(args.trans);
> +	xfs_trans_log_inode(args->trans, dp, XFS_ILOG_CORE);
> +	error = xfs_trans_commit(args->trans);
>  out_unlock:
>  	xfs_iunlock(dp, XFS_ILOCK_EXCL);
>  	return error;
> 
>  out_trans_cancel:
> -	if (args.trans)
> -		xfs_trans_cancel(args.trans);
> +	if (args->trans)
> +		xfs_trans_cancel(args->trans);
>  	goto out_unlock;
>  }
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
> index db58a6c7dea5..07ca543db831 100644
> --- a/fs/xfs/libxfs/xfs_attr.h
> +++ b/fs/xfs/libxfs/xfs_attr.h
> @@ -149,8 +149,7 @@ int xfs_attr_get_ilocked(struct xfs_inode *ip, struct xfs_da_args *args);
>  int xfs_attr_get(struct xfs_inode *ip, const unsigned char *name,
>  		 size_t namelen, unsigned char **value, int *valuelenp,
>  		 int flags);
> -int xfs_attr_set(struct xfs_inode *dp, const unsigned char *name,
> -		 size_t namelen, unsigned char *value, int valuelen, int flags);
> +int xfs_attr_set(struct xfs_da_args *args);
>  int xfs_attr_set_args(struct xfs_da_args *args);
>  int xfs_attr_remove_args(struct xfs_da_args *args);
>  int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
> diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
> index 4e76063ff956..e9ae7cbe1973 100644
> --- a/fs/xfs/xfs_acl.c
> +++ b/fs/xfs/xfs_acl.c
> @@ -166,41 +166,42 @@ xfs_get_acl(struct inode *inode, int type)
>  int
>  __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
>  {
> -	struct xfs_inode *ip = XFS_I(inode);
> -	unsigned char *ea_name;
> -	struct xfs_acl *xfs_acl = NULL;
> -	int len = 0;
> -	int error;
> +	struct xfs_inode	*ip = XFS_I(inode);
> +	struct xfs_da_args	args = {
> +		.dp		= ip,
> +		.flags		= ATTR_ROOT,
> +	};
> +	int			error;
> 
>  	switch (type) {
>  	case ACL_TYPE_ACCESS:
> -		ea_name = SGI_ACL_FILE;
> +		args.name = SGI_ACL_FILE;
>  		break;
>  	case ACL_TYPE_DEFAULT:
>  		if (!S_ISDIR(inode->i_mode))
>  			return acl ? -EACCES : 0;
> -		ea_name = SGI_ACL_DEFAULT;
> +		args.name = SGI_ACL_DEFAULT;
>  		break;
>  	default:
>  		return -EINVAL;
>  	}
> +	args.namelen = strlen(args.name);
> 
>  	if (acl) {
> -		len = XFS_ACL_MAX_SIZE(ip->i_mount);
> -		xfs_acl = kmem_zalloc_large(len, 0);
> -		if (!xfs_acl)
> +		args.valuelen = XFS_ACL_MAX_SIZE(ip->i_mount);
> +		args.value = kmem_zalloc_large(args.valuelen, 0);
> +		if (!args.value)
>  			return -ENOMEM;
> 
> -		xfs_acl_to_disk(xfs_acl, acl);
> +		xfs_acl_to_disk(args.value, acl);
> 
>  		/* subtract away the unused acl entries */
> -		len -= sizeof(struct xfs_acl_entry) *
> +		args.valuelen -= sizeof(struct xfs_acl_entry) *
>  			 (XFS_ACL_MAX_ENTRIES(ip->i_mount) - acl->a_count);
>  	}
> 
> -	error = xfs_attr_set(ip, ea_name, strlen(ea_name),
> -			(unsigned char *)xfs_acl, len, ATTR_ROOT);
> -	kmem_free(xfs_acl);
> +	error = xfs_attr_set(&args);
> +	kmem_free(args.value);
> 
>  	/*
>  	 * If the attribute didn't exist to start with that's fine.
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index cfdd80b4ea2d..47a88b5cfa63 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -389,9 +389,13 @@ xfs_attrmulti_attr_set(
>  	uint32_t		len,
>  	uint32_t		flags)
>  {
> -	unsigned char		*kbuf = NULL;
> +	struct xfs_da_args	args = {
> +		.dp		= XFS_I(inode),
> +		.flags		= flags,
> +		.name		= name,
> +		.namelen	= strlen(name),
> +	};
>  	int			error;
> -	size_t			namelen;
> 
>  	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
>  		return -EPERM;
> @@ -399,16 +403,16 @@ xfs_attrmulti_attr_set(
>  	if (ubuf) {
>  		if (len > XFS_XATTR_SIZE_MAX)
>  			return -EINVAL;
> -		kbuf = memdup_user(ubuf, len);
> -		if (IS_ERR(kbuf))
> -			return PTR_ERR(kbuf);
> +		args.value = memdup_user(ubuf, len);
> +		if (IS_ERR(args.value))
> +			return PTR_ERR(args.value);
> +		args.valuelen = len;
>  	}
> 
> -	namelen = strlen(name);
> -	error = xfs_attr_set(XFS_I(inode), name, namelen, kbuf, len, flags);
> +	error = xfs_attr_set(&args);
>  	if (!error)
>  		xfs_forget_acl(inode, name, flags);
> -	kfree(kbuf);
> +	kfree(args.value);
>  	return error;
>  }
> 
> diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
> index 81f2f93caec0..94cd4254656c 100644
> --- a/fs/xfs/xfs_iops.c
> +++ b/fs/xfs/xfs_iops.c
> @@ -50,10 +50,15 @@ xfs_initxattrs(
>  	int			error = 0;
> 
>  	for (xattr = xattr_array; xattr->name != NULL; xattr++) {
> -		error = xfs_attr_set(ip, xattr->name,
> -				     strlen(xattr->name),
> -				     xattr->value, xattr->value_len,
> -				     ATTR_SECURE);
> +		struct xfs_da_args	args = {
> +			.dp		= ip,
> +			.flags		= ATTR_SECURE,
> +			.name		= xattr->name,
> +			.namelen	= strlen(xattr->name),
> +			.value		= xattr->value,
> +			.valuelen	= xattr->value_len,
> +		};
> +		error = xfs_attr_set(&args);
>  		if (error < 0)
>  			break;
>  	}
> diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
> index 1670bfbc9ad2..09f967f97699 100644
> --- a/fs/xfs/xfs_xattr.c
> +++ b/fs/xfs/xfs_xattr.c
> @@ -66,20 +66,25 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
>  		struct inode *inode, const char *name, const void *value,
>  		size_t size, int flags)
>  {
> -	int			xflags = handler->flags;
> -	struct xfs_inode	*ip = XFS_I(inode);
> +	struct xfs_da_args	args = {
> +		.dp		= XFS_I(inode),
> +		.flags		= handler->flags,
> +		.name		= name,
> +		.namelen	= strlen(name),
> +		.value		= (unsigned char *)value,

Since xfs_da_args.value is of type "void *', Wouldn't it be more uniform if
'value' is typecasted with (void *)? 

Apart from the above very trival nit, the changes look good to me,

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> +		.valuelen	= size,
> +	};
>  	int			error;
> 
>  	/* Convert Linux syscall to XFS internal ATTR flags */
>  	if (flags & XATTR_CREATE)
> -		xflags |= ATTR_CREATE;
> +		args.flags |= ATTR_CREATE;
>  	if (flags & XATTR_REPLACE)
> -		xflags |= ATTR_REPLACE;
> +		args.flags |= ATTR_REPLACE;
> 
> -	error = xfs_attr_set(ip, (unsigned char *)name, strlen(name),
> -				(void *)value, size, xflags);
> +	error = xfs_attr_set(&args);
>  	if (!error)
> -		xfs_forget_acl(inode, name, xflags);
> +		xfs_forget_acl(inode, name, args.flags);
>  	return error;
>  }
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 12/30] xfs: pass an initialized xfs_da_args to xfs_attr_get
  2020-01-29 17:02 ` [PATCH 12/30] xfs: pass an initialized xfs_da_args to xfs_attr_get Christoph Hellwig
@ 2020-02-07 13:13   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-07 13:13 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:32 PM Christoph Hellwig wrote: 
> Instead of converting from one style of arguments to another in
> xfs_attr_set, pass the structure from higher up in the call chain.
>

The newly introduced changes logically match with the code flow that existed
earlier.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_attr.c | 80 ++++++++++++----------------------------
>  fs/xfs/libxfs/xfs_attr.h |  4 +-
>  fs/xfs/xfs_acl.c         | 35 ++++++++----------
>  fs/xfs/xfs_ioctl.c       | 25 ++++++++-----
>  fs/xfs/xfs_xattr.c       | 24 ++++++------
>  5 files changed, 68 insertions(+), 100 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index eea6d90af276..288b39e81efd 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -56,26 +56,6 @@ STATIC int xfs_attr_node_removename(xfs_da_args_t *args);
>  STATIC int xfs_attr_fillstate(xfs_da_state_t *state);
>  STATIC int xfs_attr_refillstate(xfs_da_state_t *state);
> 
> -
> -STATIC int
> -xfs_attr_args_init(
> -	struct xfs_da_args	*args,
> -	struct xfs_inode	*dp,
> -	const unsigned char	*name,
> -	size_t			namelen,
> -	int			flags)
> -{
> -	memset(args, 0, sizeof(*args));
> -	args->geo = dp->i_mount->m_attr_geo;
> -	args->whichfork = XFS_ATTR_FORK;
> -	args->dp = dp;
> -	args->flags = flags;
> -	args->name = name;
> -	args->namelen = namelen;
> -	args->hashval = xfs_da_hashname(args->name, args->namelen);
> -	return 0;
> -}
> -
>  int
>  xfs_inode_hasattr(
>  	struct xfs_inode	*ip)
> @@ -115,15 +95,15 @@ xfs_attr_get_ilocked(
>  /*
>   * Retrieve an extended attribute by name, and its value if requested.
>   *
> - * If ATTR_KERNOVAL is set in @flags, then the caller does not want the value,
> - * just an indication whether the attribute exists and the size of the value if
> - * it exists. The size is returned in @valuelenp,
> + * If ATTR_KERNOVAL is set in args->flags, then the caller does not want the
> + * value, just an indication whether the attribute exists and the size of the
> + * value if it exists. The size is returned in args.valuelen.
>   *
>   * If the attribute is found, but exceeds the size limit set by the caller in
> - * @valuelenp, return -ERANGE with the size of the attribute that was found in
> - * @valuelenp.
> + * args->valuelen, return -ERANGE with the size of the attribute that was found
> + * in args->valuelen.
>   *
> - * If ATTR_ALLOC is set in @flags, allocate the buffer for the value after
> + * If ATTR_ALLOC is set in args->flags, allocate the buffer for the value after
>   * existence of the attribute has been determined. On success, return that
>   * buffer to the caller and leave them to free it. On failure, free any
>   * allocated buffer and ensure the buffer pointer returned to the caller is
> @@ -131,51 +111,37 @@ xfs_attr_get_ilocked(
>   */
>  int
>  xfs_attr_get(
> -	struct xfs_inode	*ip,
> -	const unsigned char	*name,
> -	size_t			namelen,
> -	unsigned char		**value,
> -	int			*valuelenp,
> -	int			flags)
> +	struct xfs_da_args	*args)
>  {
> -	struct xfs_da_args	args;
>  	uint			lock_mode;
>  	int			error;
> 
> -	ASSERT((flags & (ATTR_ALLOC | ATTR_KERNOVAL)) || *value);
> +	ASSERT((args->flags & (ATTR_ALLOC | ATTR_KERNOVAL)) || args->value);
> 
> -	XFS_STATS_INC(ip->i_mount, xs_attr_get);
> +	XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
> 
> -	if (XFS_FORCED_SHUTDOWN(ip->i_mount))
> +	if (XFS_FORCED_SHUTDOWN(args->dp->i_mount))
>  		return -EIO;
> 
> -	error = xfs_attr_args_init(&args, ip, name, namelen, flags);
> -	if (error)
> -		return error;
> +	args->geo = args->dp->i_mount->m_attr_geo;
> +	args->whichfork = XFS_ATTR_FORK;
> +	args->hashval = xfs_da_hashname(args->name, args->namelen);
> 
>  	/* Entirely possible to look up a name which doesn't exist */
> -	args.op_flags = XFS_DA_OP_OKNOENT;
> -	if (flags & ATTR_ALLOC)
> -		args.op_flags |= XFS_DA_OP_ALLOCVAL;
> -	else
> -		args.value = *value;
> -	args.valuelen = *valuelenp;
> +	args->op_flags = XFS_DA_OP_OKNOENT;
> +	if (args->flags & ATTR_ALLOC)
> +		args->op_flags |= XFS_DA_OP_ALLOCVAL;
> 
> -	lock_mode = xfs_ilock_attr_map_shared(ip);
> -	error = xfs_attr_get_ilocked(ip, &args);
> -	xfs_iunlock(ip, lock_mode);
> -	*valuelenp = args.valuelen;
> +	lock_mode = xfs_ilock_attr_map_shared(args->dp);
> +	error = xfs_attr_get_ilocked(args->dp, args);
> +	xfs_iunlock(args->dp, lock_mode);
> 
>  	/* on error, we have to clean up allocated value buffers */
> -	if (error) {
> -		if (flags & ATTR_ALLOC) {
> -			kmem_free(args.value);
> -			*value = NULL;
> -		}
> -		return error;
> +	if (error && (args->flags & ATTR_ALLOC)) {
> +		kmem_free(args->value);
> +		args->value = NULL;
>  	}
> -	*value = args.value;
> -	return 0;
> +	return error;
>  }
> 
>  /*
> diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
> index 07ca543db831..be77d13a2902 100644
> --- a/fs/xfs/libxfs/xfs_attr.h
> +++ b/fs/xfs/libxfs/xfs_attr.h
> @@ -146,9 +146,7 @@ int xfs_attr_list_int_ilocked(struct xfs_attr_list_context *);
>  int xfs_attr_list_int(struct xfs_attr_list_context *);
>  int xfs_inode_hasattr(struct xfs_inode *ip);
>  int xfs_attr_get_ilocked(struct xfs_inode *ip, struct xfs_da_args *args);
> -int xfs_attr_get(struct xfs_inode *ip, const unsigned char *name,
> -		 size_t namelen, unsigned char **value, int *valuelenp,
> -		 int flags);
> +int xfs_attr_get(struct xfs_da_args *args);
>  int xfs_attr_set(struct xfs_da_args *args);
>  int xfs_attr_set_args(struct xfs_da_args *args);
>  int xfs_attr_remove_args(struct xfs_da_args *args);
> diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
> index e9ae7cbe1973..780924984492 100644
> --- a/fs/xfs/xfs_acl.c
> +++ b/fs/xfs/xfs_acl.c
> @@ -120,34 +120,31 @@ xfs_acl_to_disk(struct xfs_acl *aclp, const struct posix_acl *acl)
>  struct posix_acl *
>  xfs_get_acl(struct inode *inode, int type)
>  {
> -	struct xfs_inode *ip = XFS_I(inode);
> -	struct posix_acl *acl = NULL;
> -	struct xfs_acl *xfs_acl = NULL;
> -	unsigned char *ea_name;
> -	int error;
> -	int len;
> +	struct xfs_inode	*ip = XFS_I(inode);
> +	struct xfs_mount	*mp = ip->i_mount;
> +	struct posix_acl	*acl = NULL;
> +	struct xfs_da_args	args = {
> +		.dp		= ip,
> +		.flags		= ATTR_ALLOC | ATTR_ROOT,
> +		.valuelen	= XFS_ACL_MAX_SIZE(mp),
> +	};
> +	int			error;
> 
>  	trace_xfs_get_acl(ip);
> 
>  	switch (type) {
>  	case ACL_TYPE_ACCESS:
> -		ea_name = SGI_ACL_FILE;
> +		args.name = SGI_ACL_FILE;
>  		break;
>  	case ACL_TYPE_DEFAULT:
> -		ea_name = SGI_ACL_DEFAULT;
> +		args.name = SGI_ACL_DEFAULT;
>  		break;
>  	default:
>  		BUG();
>  	}
> +	args.namelen = strlen(args.name);
> 
> -	/*
> -	 * If we have a cached ACLs value just return it, not need to
> -	 * go out to the disk.
> -	 */
> -	len = XFS_ACL_MAX_SIZE(ip->i_mount);
> -	error = xfs_attr_get(ip, ea_name, strlen(ea_name),
> -				(unsigned char **)&xfs_acl, &len,
> -				ATTR_ALLOC | ATTR_ROOT);
> +	error = xfs_attr_get(&args);
>  	if (error) {
>  		/*
>  		 * If the attribute doesn't exist make sure we have a negative
> @@ -156,9 +153,9 @@ xfs_get_acl(struct inode *inode, int type)
>  		if (error != -ENOATTR)
>  			acl = ERR_PTR(error);
>  	} else  {
> -		acl = xfs_acl_from_disk(ip->i_mount, xfs_acl, len,
> -					XFS_ACL_MAX_ENTRIES(ip->i_mount));
> -		kmem_free(xfs_acl);
> +		acl = xfs_acl_from_disk(mp, args.value, args.valuelen,
> +					XFS_ACL_MAX_ENTRIES(mp));
> +		kmem_free(args.value);
>  	}
>  	return acl;
>  }
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index 47a88b5cfa63..2da22595f828 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -357,27 +357,32 @@ xfs_attrmulti_attr_get(
>  	uint32_t		*len,
>  	uint32_t		flags)
>  {
> -	unsigned char		*kbuf;
> -	int			error = -EFAULT;
> -	size_t			namelen;
> +	struct xfs_da_args	args = {
> +		.dp		= XFS_I(inode),
> +		.flags		= flags,
> +		.name		= name,
> +		.namelen	= strlen(name),
> +		.valuelen	= *len,
> +	};
> +	int			error;
> 
>  	if (*len > XFS_XATTR_SIZE_MAX)
>  		return -EINVAL;
> -	kbuf = kmem_zalloc_large(*len, 0);
> -	if (!kbuf)
> +
> +	args.value = kmem_zalloc_large(*len, 0);
> +	if (!args.value)
>  		return -ENOMEM;
> 
> -	namelen = strlen(name);
> -	error = xfs_attr_get(XFS_I(inode), name, namelen, &kbuf, (int *)len,
> -			     flags);
> +	error = xfs_attr_get(&args);
>  	if (error)
>  		goto out_kfree;
> 
> -	if (copy_to_user(ubuf, kbuf, *len))
> +	*len = args.valuelen;
> +	if (copy_to_user(ubuf, args.value, args.valuelen))
>  		error = -EFAULT;
> 
>  out_kfree:
> -	kmem_free(kbuf);
> +	kmem_free(args.value);
>  	return error;
>  }
> 
> diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
> index 09f967f97699..b3ce5e8777f9 100644
> --- a/fs/xfs/xfs_xattr.c
> +++ b/fs/xfs/xfs_xattr.c
> @@ -21,22 +21,24 @@ static int
>  xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
>  		struct inode *inode, const char *name, void *value, size_t size)
>  {
> -	int xflags = handler->flags;
> -	struct xfs_inode *ip = XFS_I(inode);
> -	int error, asize = size;
> -	size_t namelen = strlen(name);
> +	struct xfs_da_args	args = {
> +		.dp		= XFS_I(inode),
> +		.flags		= handler->flags,
> +		.name		= name,
> +		.namelen	= strlen(name),
> +		.value		= value,
> +		.valuelen	= size,
> +	};
> +	int			error;
> 
>  	/* Convert Linux syscall to XFS internal ATTR flags */
> -	if (!size) {
> -		xflags |= ATTR_KERNOVAL;
> -		value = NULL;
> -	}
> +	if (!size)
> +		args.flags |= ATTR_KERNOVAL;
> 
> -	error = xfs_attr_get(ip, name, namelen, (unsigned char **)&value,
> -			     &asize, xflags);
> +	error = xfs_attr_get(&args);
>  	if (error)
>  		return error;
> -	return asize;
> +	return args.valuelen;
>  }
> 
>  void
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 13/30] xfs: remove the xfs_inode argument to xfs_attr_get_ilocked
  2020-01-29 17:02 ` [PATCH 13/30] xfs: remove the xfs_inode argument to xfs_attr_get_ilocked Christoph Hellwig
@ 2020-02-07 13:19   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-07 13:19 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:32 PM Christoph Hellwig wrote: 
> The inode can easily be derived from the args structure.  Also
> don't bother with else statements after early returns.
>

The newly introduced changes logically match with the code flow that existed
earlier.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_attr.c | 15 +++++++--------
>  fs/xfs/libxfs/xfs_attr.h |  2 +-
>  fs/xfs/scrub/attr.c      |  2 +-
>  3 files changed, 9 insertions(+), 10 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index 288b39e81efd..fd095e3d4a9a 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -77,19 +77,18 @@ xfs_inode_hasattr(
>   */
>  int
>  xfs_attr_get_ilocked(
> -	struct xfs_inode	*ip,
>  	struct xfs_da_args	*args)
>  {
> -	ASSERT(xfs_isilocked(ip, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
> +	ASSERT(xfs_isilocked(args->dp, XFS_ILOCK_SHARED | XFS_ILOCK_EXCL));
> 
> -	if (!xfs_inode_hasattr(ip))
> +	if (!xfs_inode_hasattr(args->dp))
>  		return -ENOATTR;
> -	else if (ip->i_d.di_aformat == XFS_DINODE_FMT_LOCAL)
> +
> +	if (args->dp->i_d.di_aformat == XFS_DINODE_FMT_LOCAL)
>  		return xfs_attr_shortform_getvalue(args);
> -	else if (xfs_bmap_one_block(ip, XFS_ATTR_FORK))
> +	if (xfs_bmap_one_block(args->dp, XFS_ATTR_FORK))
>  		return xfs_attr_leaf_get(args);
> -	else
> -		return xfs_attr_node_get(args);
> +	return xfs_attr_node_get(args);
>  }
> 
>  /*
> @@ -133,7 +132,7 @@ xfs_attr_get(
>  		args->op_flags |= XFS_DA_OP_ALLOCVAL;
> 
>  	lock_mode = xfs_ilock_attr_map_shared(args->dp);
> -	error = xfs_attr_get_ilocked(args->dp, args);
> +	error = xfs_attr_get_ilocked(args);
>  	xfs_iunlock(args->dp, lock_mode);
> 
>  	/* on error, we have to clean up allocated value buffers */
> diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
> index be77d13a2902..b8c4ed27f626 100644
> --- a/fs/xfs/libxfs/xfs_attr.h
> +++ b/fs/xfs/libxfs/xfs_attr.h
> @@ -145,7 +145,7 @@ int xfs_attr_inactive(struct xfs_inode *dp);
>  int xfs_attr_list_int_ilocked(struct xfs_attr_list_context *);
>  int xfs_attr_list_int(struct xfs_attr_list_context *);
>  int xfs_inode_hasattr(struct xfs_inode *ip);
> -int xfs_attr_get_ilocked(struct xfs_inode *ip, struct xfs_da_args *args);
> +int xfs_attr_get_ilocked(struct xfs_da_args *args);
>  int xfs_attr_get(struct xfs_da_args *args);
>  int xfs_attr_set(struct xfs_da_args *args);
>  int xfs_attr_set_args(struct xfs_da_args *args);
> diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
> index d804558cdbca..f983c2b969e0 100644
> --- a/fs/xfs/scrub/attr.c
> +++ b/fs/xfs/scrub/attr.c
> @@ -162,7 +162,7 @@ xchk_xattr_listent(
>  	args.value = xchk_xattr_valuebuf(sx->sc);
>  	args.valuelen = valuelen;
> 
> -	error = xfs_attr_get_ilocked(context->dp, &args);
> +	error = xfs_attr_get_ilocked(&args);
>  	if (!xchk_fblock_process_error(sx->sc, XFS_ATTR_FORK, args.blkno,
>  			&error))
>  		goto fail_xref;
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 14/30] xfs: remove ATTR_KERNOVAL
  2020-01-29 17:02 ` [PATCH 14/30] xfs: remove ATTR_KERNOVAL Christoph Hellwig
@ 2020-02-08  4:36   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-08  4:36 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:32 PM Christoph Hellwig wrote: 
> We can just pass down the Linux convention of a zero valuelen to just
> query for the existance of an attribute to the low-level code instead.
> The use in the legacy xfs_attr_list code only used by the ioctl
> interface was already dead code, as the callers check that the flag
> is not present.
>

xfs_attrlist_by_handle() allows only ATTR_ROOT and ATTR_SECURE flags. Hence
the changes look good to me.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_attr.c        |  8 ++++----
>  fs/xfs/libxfs/xfs_attr.h        |  4 +---
>  fs/xfs/libxfs/xfs_attr_leaf.c   | 14 +++++++-------
>  fs/xfs/libxfs/xfs_attr_remote.c |  2 +-
>  fs/xfs/xfs_attr_list.c          |  3 ---
>  fs/xfs/xfs_xattr.c              |  4 ----
>  6 files changed, 13 insertions(+), 22 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index fd095e3d4a9a..469417786bfc 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -94,9 +94,9 @@ xfs_attr_get_ilocked(
>  /*
>   * Retrieve an extended attribute by name, and its value if requested.
>   *
> - * If ATTR_KERNOVAL is set in args->flags, then the caller does not want the
> - * value, just an indication whether the attribute exists and the size of the
> - * value if it exists. The size is returned in args.valuelen.
> + * If args->valuelen is zero, then the caller does not want the value, just an
> + * indication whether the attribute exists and the size of the value if it
> + * exists. The size is returned in args.valuelen.
>   *
>   * If the attribute is found, but exceeds the size limit set by the caller in
>   * args->valuelen, return -ERANGE with the size of the attribute that was found
> @@ -115,7 +115,7 @@ xfs_attr_get(
>  	uint			lock_mode;
>  	int			error;
> 
> -	ASSERT((args->flags & (ATTR_ALLOC | ATTR_KERNOVAL)) || args->value);
> +	ASSERT((args->flags & ATTR_ALLOC) || !args->valuelen || args->value);
> 
>  	XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
> index b8c4ed27f626..fe064cd81747 100644
> --- a/fs/xfs/libxfs/xfs_attr.h
> +++ b/fs/xfs/libxfs/xfs_attr.h
> @@ -34,12 +34,11 @@ struct xfs_attr_list_context;
>  #define ATTR_REPLACE	0x0020	/* pure set: fail if attr does not exist */
> 
>  #define ATTR_KERNOTIME	0x1000	/* [kernel] don't update inode timestamps */
> -#define ATTR_KERNOVAL	0x2000	/* [kernel] get attr size only, not value */
> 
>  #define ATTR_ALLOC	0x8000	/* [kernel] allocate xattr buffer on demand */
> 
>  #define ATTR_KERNEL_FLAGS \
> -	(ATTR_KERNOTIME | ATTR_KERNOVAL | ATTR_ALLOC)
> +	(ATTR_KERNOTIME | ATTR_ALLOC)
> 
>  #define XFS_ATTR_FLAGS \
>  	{ ATTR_DONTFOLLOW, 	"DONTFOLLOW" }, \
> @@ -49,7 +48,6 @@ struct xfs_attr_list_context;
>  	{ ATTR_CREATE,		"CREATE" }, \
>  	{ ATTR_REPLACE,		"REPLACE" }, \
>  	{ ATTR_KERNOTIME,	"KERNOTIME" }, \
> -	{ ATTR_KERNOVAL,	"KERNOVAL" }, \
>  	{ ATTR_ALLOC,		"ALLOC" }
> 
>  /*
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
> index fed537a4353d..5e700dfc48a9 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.c
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.c
> @@ -464,7 +464,7 @@ xfs_attr_copy_value(
>  	/*
>  	 * No copy if all we have to do is get the length
>  	 */
> -	if (args->flags & ATTR_KERNOVAL) {
> +	if (!args->valuelen) {
>  		args->valuelen = valuelen;
>  		return 0;
>  	}
> @@ -830,9 +830,9 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args)
>  /*
>   * Retrieve the attribute value and length.
>   *
> - * If ATTR_KERNOVAL is specified, only the length needs to be returned.
> - * Unlike a lookup, we only return an error if the attribute does not
> - * exist or we can't retrieve the value.
> + * If args->valuelen is zero, only the length needs to be returned.  Unlike a
> + * lookup, we only return an error if the attribute does not exist or we can't
> + * retrieve the value.
>   */
>  int
>  xfs_attr_shortform_getvalue(
> @@ -2444,9 +2444,9 @@ xfs_attr3_leaf_lookup_int(
>   * Get the value associated with an attribute name from a leaf attribute
>   * list structure.
>   *
> - * If ATTR_KERNOVAL is specified, only the length needs to be returned.
> - * Unlike a lookup, we only return an error if the attribute does not
> - * exist or we can't retrieve the value.
> + * If args->valuelen is zero, only the length needs to be returned.  Unlike a
> + * lookup, we only return an error if the attribute does not exist or we can't
> + * retrieve the value.
>   */
>  int
>  xfs_attr3_leaf_getvalue(
> diff --git a/fs/xfs/libxfs/xfs_attr_remote.c b/fs/xfs/libxfs/xfs_attr_remote.c
> index a266d05df146..023ac8b85b4a 100644
> --- a/fs/xfs/libxfs/xfs_attr_remote.c
> +++ b/fs/xfs/libxfs/xfs_attr_remote.c
> @@ -397,7 +397,7 @@ xfs_attr_rmtval_get(
> 
>  	trace_xfs_attr_rmtval_get(args);
> 
> -	ASSERT(!(args->flags & ATTR_KERNOVAL));
> +	ASSERT(args->valuelen != 0);
>  	ASSERT(args->rmtvaluelen == args->valuelen);
> 
>  	valuelen = args->rmtvaluelen;
> diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
> index 5139ef983cd6..ac8dc64447d6 100644
> --- a/fs/xfs/xfs_attr_list.c
> +++ b/fs/xfs/xfs_attr_list.c
> @@ -568,7 +568,6 @@ xfs_attr_put_listent(
>  	int arraytop;
> 
>  	ASSERT(!context->seen_enough);
> -	ASSERT(!(context->flags & ATTR_KERNOVAL));
>  	ASSERT(context->count >= 0);
>  	ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
>  	ASSERT(context->firstu >= sizeof(*alist));
> @@ -637,8 +636,6 @@ xfs_attr_list(
>  	 */
>  	if (((long)buffer) & (sizeof(int)-1))
>  		return -EFAULT;
> -	if (flags & ATTR_KERNOVAL)
> -		bufsize = 0;
> 
>  	/*
>  	 * Initialize the output buffer.
> diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
> index b3ce5e8777f9..c9c44f8aebed 100644
> --- a/fs/xfs/xfs_xattr.c
> +++ b/fs/xfs/xfs_xattr.c
> @@ -31,10 +31,6 @@ xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
>  	};
>  	int			error;
> 
> -	/* Convert Linux syscall to XFS internal ATTR flags */
> -	if (!size)
> -		args.flags |= ATTR_KERNOVAL;
> -
>  	error = xfs_attr_get(&args);
>  	if (error)
>  		return error;
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 15/30] xfs: remove ATTR_ALLOC and XFS_DA_OP_ALLOCVAL
  2020-01-29 17:02 ` [PATCH 15/30] xfs: remove ATTR_ALLOC and XFS_DA_OP_ALLOCVAL Christoph Hellwig
@ 2020-02-08  5:13   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-08  5:13 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins

On Wednesday, January 29, 2020 10:32 PM Christoph Hellwig wrote: 
> Use a NULL args->value as the indicator to lazily allocate a buffer
> instead, and let the caller always free args->value instead of
> duplicating the cleanup.

xfs_get_acl() now unconditionally invokes kmem_free() on args.value. This
matches the requirement set by xfs_attr_get().

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/libxfs/xfs_attr.c      | 20 +++++---------------
>  fs/xfs/libxfs/xfs_attr.h      |  7 ++-----
>  fs/xfs/libxfs/xfs_attr_leaf.c |  2 +-
>  fs/xfs/libxfs/xfs_types.h     |  2 --
>  fs/xfs/xfs_acl.c              | 20 ++++++++++----------
>  5 files changed, 18 insertions(+), 33 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index 469417786bfc..1382e51ef85e 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -98,15 +98,14 @@ xfs_attr_get_ilocked(
>   * indication whether the attribute exists and the size of the value if it
>   * exists. The size is returned in args.valuelen.
>   *
> + * If args->value is NULL but args->valuelen is non-zero, allocate the buffer
> + * for the value after existence of the attribute has been determined. The
> + * caller always has to free args->value if it is set, no matter if this
> + * function was successful or not.
> + *
>   * If the attribute is found, but exceeds the size limit set by the caller in
>   * args->valuelen, return -ERANGE with the size of the attribute that was found
>   * in args->valuelen.
> - *
> - * If ATTR_ALLOC is set in args->flags, allocate the buffer for the value after
> - * existence of the attribute has been determined. On success, return that
> - * buffer to the caller and leave them to free it. On failure, free any
> - * allocated buffer and ensure the buffer pointer returned to the caller is
> - * null.
>   */
>  int
>  xfs_attr_get(
> @@ -115,8 +114,6 @@ xfs_attr_get(
>  	uint			lock_mode;
>  	int			error;
> 
> -	ASSERT((args->flags & ATTR_ALLOC) || !args->valuelen || args->value);
> -
>  	XFS_STATS_INC(args->dp->i_mount, xs_attr_get);
> 
>  	if (XFS_FORCED_SHUTDOWN(args->dp->i_mount))
> @@ -128,18 +125,11 @@ xfs_attr_get(
> 
>  	/* Entirely possible to look up a name which doesn't exist */
>  	args->op_flags = XFS_DA_OP_OKNOENT;
> -	if (args->flags & ATTR_ALLOC)
> -		args->op_flags |= XFS_DA_OP_ALLOCVAL;
> 
>  	lock_mode = xfs_ilock_attr_map_shared(args->dp);
>  	error = xfs_attr_get_ilocked(args);
>  	xfs_iunlock(args->dp, lock_mode);
> 
> -	/* on error, we have to clean up allocated value buffers */
> -	if (error && (args->flags & ATTR_ALLOC)) {
> -		kmem_free(args->value);
> -		args->value = NULL;
> -	}
>  	return error;
>  }
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
> index fe064cd81747..a6de050675c9 100644
> --- a/fs/xfs/libxfs/xfs_attr.h
> +++ b/fs/xfs/libxfs/xfs_attr.h
> @@ -35,10 +35,8 @@ struct xfs_attr_list_context;
> 
>  #define ATTR_KERNOTIME	0x1000	/* [kernel] don't update inode timestamps */
> 
> -#define ATTR_ALLOC	0x8000	/* [kernel] allocate xattr buffer on demand */
> -
>  #define ATTR_KERNEL_FLAGS \
> -	(ATTR_KERNOTIME | ATTR_ALLOC)
> +	(ATTR_KERNOTIME)
> 
>  #define XFS_ATTR_FLAGS \
>  	{ ATTR_DONTFOLLOW, 	"DONTFOLLOW" }, \
> @@ -47,8 +45,7 @@ struct xfs_attr_list_context;
>  	{ ATTR_SECURE,		"SECURE" }, \
>  	{ ATTR_CREATE,		"CREATE" }, \
>  	{ ATTR_REPLACE,		"REPLACE" }, \
> -	{ ATTR_KERNOTIME,	"KERNOTIME" }, \
> -	{ ATTR_ALLOC,		"ALLOC" }
> +	{ ATTR_KERNOTIME,	"KERNOTIME" }
> 
>  /*
>   * The maximum size (into the kernel or returned from the kernel) of an
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
> index 5e700dfc48a9..b0658eb8fbcc 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.c
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.c
> @@ -477,7 +477,7 @@ xfs_attr_copy_value(
>  		return -ERANGE;
>  	}
> 
> -	if (args->op_flags & XFS_DA_OP_ALLOCVAL) {
> +	if (!args->value) {
>  		args->value = kmem_alloc_large(valuelen, 0);
>  		if (!args->value)
>  			return -ENOMEM;
> diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
> index 634814dd1d10..3379ebc0c7c5 100644
> --- a/fs/xfs/libxfs/xfs_types.h
> +++ b/fs/xfs/libxfs/xfs_types.h
> @@ -223,7 +223,6 @@ typedef struct xfs_da_args {
>  #define XFS_DA_OP_ADDNAME	0x0004	/* this is an add operation */
>  #define XFS_DA_OP_OKNOENT	0x0008	/* lookup/add op, ENOENT ok, else die */
>  #define XFS_DA_OP_CILOOKUP	0x0010	/* lookup to return CI name if found */
> -#define XFS_DA_OP_ALLOCVAL	0x0020	/* lookup to alloc buffer if found  */
>  #define XFS_DA_OP_INCOMPLETE	0x0040	/* lookup INCOMPLETE attr keys */
> 
>  #define XFS_DA_OP_FLAGS \
> @@ -232,7 +231,6 @@ typedef struct xfs_da_args {
>  	{ XFS_DA_OP_ADDNAME,	"ADDNAME" }, \
>  	{ XFS_DA_OP_OKNOENT,	"OKNOENT" }, \
>  	{ XFS_DA_OP_CILOOKUP,	"CILOOKUP" }, \
> -	{ XFS_DA_OP_ALLOCVAL,	"ALLOCVAL" }, \
>  	{ XFS_DA_OP_INCOMPLETE,	"INCOMPLETE" }
> 
>  /*
> diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
> index 780924984492..bc78b7c33401 100644
> --- a/fs/xfs/xfs_acl.c
> +++ b/fs/xfs/xfs_acl.c
> @@ -125,7 +125,7 @@ xfs_get_acl(struct inode *inode, int type)
>  	struct posix_acl	*acl = NULL;
>  	struct xfs_da_args	args = {
>  		.dp		= ip,
> -		.flags		= ATTR_ALLOC | ATTR_ROOT,
> +		.flags		= ATTR_ROOT,
>  		.valuelen	= XFS_ACL_MAX_SIZE(mp),
>  	};
>  	int			error;
> @@ -144,19 +144,19 @@ xfs_get_acl(struct inode *inode, int type)
>  	}
>  	args.namelen = strlen(args.name);
> 
> +	/*
> +	 * If the attribute doesn't exist make sure we have a negative cache
> +	 * entry, for any other error assume it is transient.
> +	 */
>  	error = xfs_attr_get(&args);
> -	if (error) {
> -		/*
> -		 * If the attribute doesn't exist make sure we have a negative
> -		 * cache entry, for any other error assume it is transient.
> -		 */
> -		if (error != -ENOATTR)
> -			acl = ERR_PTR(error);
> -	} else  {
> +	if (!error) {
>  		acl = xfs_acl_from_disk(mp, args.value, args.valuelen,
>  					XFS_ACL_MAX_ENTRIES(mp));
> -		kmem_free(args.value);
> +	} else if (error != -ENOATTR) {
> +		acl = ERR_PTR(error);
>  	}
> +
> +	kmem_free(args.value);
>  	return acl;
>  }
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 16/30] xfs: replace ATTR_KERNOTIME with XFS_DA_OP_NOTIME
  2020-01-29 17:02 ` [PATCH 16/30] xfs: replace ATTR_KERNOTIME with XFS_DA_OP_NOTIME Christoph Hellwig
@ 2020-02-08 11:35   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-08 11:35 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:32 PM Christoph Hellwig wrote: 
> op_flags with the XFS_DA_OP_* flags is the usual place for in-kernel
> only flags, so move the notime flag there.
>

The changes look good to me,
Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_attr.c  | 4 ++--
>  fs/xfs/libxfs/xfs_attr.h  | 8 +-------
>  fs/xfs/libxfs/xfs_types.h | 2 ++
>  fs/xfs/scrub/attr.c       | 2 +-
>  fs/xfs/xfs_ioctl.c        | 1 -
>  5 files changed, 6 insertions(+), 11 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index 1382e51ef85e..3b1db2afb104 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -186,7 +186,7 @@ xfs_attr_try_sf_addname(
>  	 * Commit the shortform mods, and we're done.
>  	 * NOTE: this is also the error path (EEXIST, etc).
>  	 */
> -	if (!error && (args->flags & ATTR_KERNOTIME) == 0)
> +	if (!error && !(args->op_flags & XFS_DA_OP_NOTIME))
>  		xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
> 
>  	if (mp->m_flags & XFS_MOUNT_WSYNC)
> @@ -389,7 +389,7 @@ xfs_attr_set(
>  	if (mp->m_flags & XFS_MOUNT_WSYNC)
>  		xfs_trans_set_sync(args->trans);
> 
> -	if ((args->flags & ATTR_KERNOTIME) == 0)
> +	if (!(args->op_flags & XFS_DA_OP_NOTIME))
>  		xfs_trans_ichgtime(args->trans, dp, XFS_ICHGTIME_CHG);
> 
>  	/*
> diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
> index a6de050675c9..0f369399effd 100644
> --- a/fs/xfs/libxfs/xfs_attr.h
> +++ b/fs/xfs/libxfs/xfs_attr.h
> @@ -33,19 +33,13 @@ struct xfs_attr_list_context;
>  #define ATTR_CREATE	0x0010	/* pure create: fail if attr already exists */
>  #define ATTR_REPLACE	0x0020	/* pure set: fail if attr does not exist */
> 
> -#define ATTR_KERNOTIME	0x1000	/* [kernel] don't update inode timestamps */
> -
> -#define ATTR_KERNEL_FLAGS \
> -	(ATTR_KERNOTIME)
> -
>  #define XFS_ATTR_FLAGS \
>  	{ ATTR_DONTFOLLOW, 	"DONTFOLLOW" }, \
>  	{ ATTR_ROOT,		"ROOT" }, \
>  	{ ATTR_TRUST,		"TRUST" }, \
>  	{ ATTR_SECURE,		"SECURE" }, \
>  	{ ATTR_CREATE,		"CREATE" }, \
> -	{ ATTR_REPLACE,		"REPLACE" }, \
> -	{ ATTR_KERNOTIME,	"KERNOTIME" }
> +	{ ATTR_REPLACE,		"REPLACE" }
> 
>  /*
>   * The maximum size (into the kernel or returned from the kernel) of an
> diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
> index 3379ebc0c7c5..1594325d7742 100644
> --- a/fs/xfs/libxfs/xfs_types.h
> +++ b/fs/xfs/libxfs/xfs_types.h
> @@ -223,6 +223,7 @@ typedef struct xfs_da_args {
>  #define XFS_DA_OP_ADDNAME	0x0004	/* this is an add operation */
>  #define XFS_DA_OP_OKNOENT	0x0008	/* lookup/add op, ENOENT ok, else die */
>  #define XFS_DA_OP_CILOOKUP	0x0010	/* lookup to return CI name if found */
> +#define XFS_DA_OP_NOTIME	0x0020	/* don't update inode timestamps */
>  #define XFS_DA_OP_INCOMPLETE	0x0040	/* lookup INCOMPLETE attr keys */
> 
>  #define XFS_DA_OP_FLAGS \
> @@ -231,6 +232,7 @@ typedef struct xfs_da_args {
>  	{ XFS_DA_OP_ADDNAME,	"ADDNAME" }, \
>  	{ XFS_DA_OP_OKNOENT,	"OKNOENT" }, \
>  	{ XFS_DA_OP_CILOOKUP,	"CILOOKUP" }, \
> +	{ XFS_DA_OP_NOTIME,	"NOTIME" }, \
>  	{ XFS_DA_OP_INCOMPLETE,	"INCOMPLETE" }
> 
>  /*
> diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
> index f983c2b969e0..05537627211d 100644
> --- a/fs/xfs/scrub/attr.c
> +++ b/fs/xfs/scrub/attr.c
> @@ -147,7 +147,7 @@ xchk_xattr_listent(
>  		return;
>  	}
> 
> -	args.flags = ATTR_KERNOTIME;
> +	args.op_flags = XFS_DA_OP_NOTIME;
>  	if (flags & XFS_ATTR_ROOT)
>  		args.flags |= ATTR_ROOT;
>  	else if (flags & XFS_ATTR_SECURE)
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index 2da22595f828..dd1cb8c50518 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -436,7 +436,6 @@ xfs_ioc_attrmulti_one(
> 
>  	if ((flags & ATTR_ROOT) && (flags & ATTR_SECURE))
>  		return -EINVAL;
> -	flags &= ~ATTR_KERNEL_FLAGS;
> 
>  	name = strndup_user(uname, MAXNAMELEN);
>  	if (IS_ERR(name))
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 17/30] xfs: factor out a xfs_attr_match helper
  2020-01-29 17:02 ` [PATCH 17/30] xfs: factor out a xfs_attr_match helper Christoph Hellwig
@ 2020-02-08 12:48   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-08 12:48 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:32 PM Christoph Hellwig wrote: 
> Factor out a helper that compares an on-disk attr vs the name, length and
> flags specified in struct xfs_da_args.
>

The newly introduced changes logically match with the code flow that existed
earlier.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_attr_leaf.c | 80 +++++++++++++----------------------
>  1 file changed, 30 insertions(+), 50 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
> index b0658eb8fbcc..8852754153ba 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.c
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.c
> @@ -445,14 +445,21 @@ xfs_attr3_leaf_read(
>   * Namespace helper routines
>   *========================================================================*/
> 
> -/*
> - * If namespace bits don't match return 0.
> - * If all match then return 1.
> - */
> -STATIC int
> -xfs_attr_namesp_match(int arg_flags, int ondisk_flags)
> +static bool
> +xfs_attr_match(
> +	struct xfs_da_args	*args,
> +	uint8_t			namelen,
> +	unsigned char		*name,
> +	int			flags)
>  {
> -	return XFS_ATTR_NSP_ONDISK(ondisk_flags) == XFS_ATTR_NSP_ARGS_TO_ONDISK(arg_flags);
> +	if (args->namelen != namelen)
> +		return false;
> +	if (memcmp(args->name, name, namelen) != 0)
> +		return false;
> +	if (XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags) !=
> +	    XFS_ATTR_NSP_ONDISK(flags))
> +		return false;
> +	return true;
>  }
> 
>  static int
> @@ -678,15 +685,8 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
>  	sf = (xfs_attr_shortform_t *)ifp->if_u1.if_data;
>  	sfe = &sf->list[0];
>  	for (i = 0; i < sf->hdr.count; sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
> -#ifdef DEBUG
> -		if (sfe->namelen != args->namelen)
> -			continue;
> -		if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
> -			continue;
> -		if (!xfs_attr_namesp_match(args->flags, sfe->flags))
> -			continue;
> -		ASSERT(0);
> -#endif
> +		ASSERT(!xfs_attr_match(args, sfe->namelen, sfe->nameval,
> +			sfe->flags));
>  	}
> 
>  	offset = (char *)sfe - (char *)sf;
> @@ -749,13 +749,9 @@ xfs_attr_shortform_remove(xfs_da_args_t *args)
>  	for (i = 0; i < end; sfe = XFS_ATTR_SF_NEXTENTRY(sfe),
>  					base += size, i++) {
>  		size = XFS_ATTR_SF_ENTSIZE(sfe);
> -		if (sfe->namelen != args->namelen)
> -			continue;
> -		if (memcmp(sfe->nameval, args->name, args->namelen) != 0)
> -			continue;
> -		if (!xfs_attr_namesp_match(args->flags, sfe->flags))
> -			continue;
> -		break;
> +		if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
> +				sfe->flags))
> +			break;
>  	}
>  	if (i == end)
>  		return -ENOATTR;
> @@ -816,13 +812,9 @@ xfs_attr_shortform_lookup(xfs_da_args_t *args)
>  	sfe = &sf->list[0];
>  	for (i = 0; i < sf->hdr.count;
>  				sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
> -		if (sfe->namelen != args->namelen)
> -			continue;
> -		if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
> -			continue;
> -		if (!xfs_attr_namesp_match(args->flags, sfe->flags))
> -			continue;
> -		return -EEXIST;
> +		if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
> +				sfe->flags))
> +			return -EEXIST;
>  	}
>  	return -ENOATTR;
>  }
> @@ -847,14 +839,10 @@ xfs_attr_shortform_getvalue(
>  	sfe = &sf->list[0];
>  	for (i = 0; i < sf->hdr.count;
>  				sfe = XFS_ATTR_SF_NEXTENTRY(sfe), i++) {
> -		if (sfe->namelen != args->namelen)
> -			continue;
> -		if (memcmp(args->name, sfe->nameval, args->namelen) != 0)
> -			continue;
> -		if (!xfs_attr_namesp_match(args->flags, sfe->flags))
> -			continue;
> -		return xfs_attr_copy_value(args, &sfe->nameval[args->namelen],
> -						sfe->valuelen);
> +		if (xfs_attr_match(args, sfe->namelen, sfe->nameval,
> +				sfe->flags))
> +			return xfs_attr_copy_value(args,
> +				&sfe->nameval[args->namelen], sfe->valuelen);
>  	}
>  	return -ENOATTR;
>  }
> @@ -2409,23 +2397,15 @@ xfs_attr3_leaf_lookup_int(
>  		}
>  		if (entry->flags & XFS_ATTR_LOCAL) {
>  			name_loc = xfs_attr3_leaf_name_local(leaf, probe);
> -			if (name_loc->namelen != args->namelen)
> -				continue;
> -			if (memcmp(args->name, name_loc->nameval,
> -							args->namelen) != 0)
> -				continue;
> -			if (!xfs_attr_namesp_match(args->flags, entry->flags))
> +			if (!xfs_attr_match(args, name_loc->namelen,
> +					name_loc->nameval, entry->flags))
>  				continue;
>  			args->index = probe;
>  			return -EEXIST;
>  		} else {
>  			name_rmt = xfs_attr3_leaf_name_remote(leaf, probe);
> -			if (name_rmt->namelen != args->namelen)
> -				continue;
> -			if (memcmp(args->name, name_rmt->name,
> -							args->namelen) != 0)
> -				continue;
> -			if (!xfs_attr_namesp_match(args->flags, entry->flags))
> +			if (!xfs_attr_match(args, name_rmt->namelen,
> +					name_rmt->name, entry->flags))
>  				continue;
>  			args->index = probe;
>  			args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen);
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 18/30] xfs: cleanup struct xfs_attr_list_context
  2020-01-29 17:02 ` [PATCH 18/30] xfs: cleanup struct xfs_attr_list_context Christoph Hellwig
@ 2020-02-08 15:53   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-08 15:53 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:32 PM Christoph Hellwig wrote: 
> Replace the alist char pointer with a void buffer given that different
> callers use it in different ways.  Use the chance to remove the typedef
> and reduce the indentation of the struct definition so that it doesn't
> overflow 80 char lines all over.
>

The behaviour of the code is logically the same as before.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>


> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_attr.h | 34 +++++++++++++-------------
>  fs/xfs/xfs_attr_list.c   | 53 ++++++++++++++++++++--------------------
>  fs/xfs/xfs_trace.h       | 16 ++++++------
>  fs/xfs/xfs_xattr.c       |  6 ++---
>  4 files changed, 55 insertions(+), 54 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
> index 0f369399effd..0c8f7c7a6b65 100644
> --- a/fs/xfs/libxfs/xfs_attr.h
> +++ b/fs/xfs/libxfs/xfs_attr.h
> @@ -99,28 +99,28 @@ typedef struct attrlist_cursor_kern {
>  typedef void (*put_listent_func_t)(struct xfs_attr_list_context *, int,
>  			      unsigned char *, int, int);
> 
> -typedef struct xfs_attr_list_context {
> -	struct xfs_trans		*tp;
> -	struct xfs_inode		*dp;		/* inode */
> -	struct attrlist_cursor_kern	*cursor;	/* position in list */
> -	char				*alist;		/* output buffer */
> +struct xfs_attr_list_context {
> +	struct xfs_trans	*tp;
> +	struct xfs_inode	*dp;		/* inode */
> +	struct attrlist_cursor_kern *cursor;	/* position in list */
> +	void			*buffer;	/* output buffer */
> 
>  	/*
>  	 * Abort attribute list iteration if non-zero.  Can be used to pass
>  	 * error values to the xfs_attr_list caller.
>  	 */
> -	int				seen_enough;
> -	bool				allow_incomplete;
> -
> -	ssize_t				count;		/* num used entries */
> -	int				dupcnt;		/* count dup hashvals seen */
> -	int				bufsize;	/* total buffer size */
> -	int				firstu;		/* first used byte in buffer */
> -	int				flags;		/* from VOP call */
> -	int				resynch;	/* T/F: resynch with cursor */
> -	put_listent_func_t		put_listent;	/* list output fmt function */
> -	int				index;		/* index into output buffer */
> -} xfs_attr_list_context_t;
> +	int			seen_enough;
> +	bool			allow_incomplete;
> +
> +	ssize_t			count;		/* num used entries */
> +	int			dupcnt;		/* count dup hashvals seen */
> +	int			bufsize;	/* total buffer size */
> +	int			firstu;		/* first used byte in buffer */
> +	int			flags;		/* from VOP call */
> +	int			resynch;	/* T/F: resynch with cursor */
> +	put_listent_func_t	put_listent;	/* list output fmt function */
> +	int			index;		/* index into output buffer */
> +};
> 
> 
>  /*========================================================================
> diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
> index ac8dc64447d6..9c4acb6dc856 100644
> --- a/fs/xfs/xfs_attr_list.c
> +++ b/fs/xfs/xfs_attr_list.c
> @@ -488,10 +488,11 @@ xfs_attr3_leaf_list_int(
>   * Copy out attribute entries for attr_list(), for leaf attribute lists.
>   */
>  STATIC int
> -xfs_attr_leaf_list(xfs_attr_list_context_t *context)
> +xfs_attr_leaf_list(
> +	struct xfs_attr_list_context	*context)
>  {
> -	int error;
> -	struct xfs_buf *bp;
> +	struct xfs_buf			*bp;
> +	int				error;
> 
>  	trace_xfs_attr_leaf_list(context);
> 
> @@ -527,11 +528,11 @@ xfs_attr_list_int_ilocked(
> 
>  int
>  xfs_attr_list_int(
> -	xfs_attr_list_context_t *context)
> +	struct xfs_attr_list_context	*context)
>  {
> -	int error;
> -	xfs_inode_t *dp = context->dp;
> -	uint		lock_mode;
> +	struct xfs_inode		*dp = context->dp;
> +	uint				lock_mode;
> +	int				error;
> 
>  	XFS_STATS_INC(dp->i_mount, xs_attr_list);
> 
> @@ -557,15 +558,15 @@ xfs_attr_list_int(
>   */
>  STATIC void
>  xfs_attr_put_listent(
> -	xfs_attr_list_context_t *context,
> -	int		flags,
> -	unsigned char	*name,
> -	int		namelen,
> -	int		valuelen)
> +	struct xfs_attr_list_context	*context,
> +	int			flags,
> +	unsigned char		*name,
> +	int			namelen,
> +	int			valuelen)
>  {
> -	struct attrlist *alist = (struct attrlist *)context->alist;
> -	attrlist_ent_t *aep;
> -	int arraytop;
> +	struct attrlist		*alist = context->buffer;
> +	struct attrlist_ent	*aep;
> +	int			arraytop;
> 
>  	ASSERT(!context->seen_enough);
>  	ASSERT(context->count >= 0);
> @@ -593,7 +594,7 @@ xfs_attr_put_listent(
>  		return;
>  	}
> 
> -	aep = (attrlist_ent_t *)&context->alist[context->firstu];
> +	aep = context->buffer + context->firstu;
>  	aep->a_valuelen = valuelen;
>  	memcpy(aep->a_name, name, namelen);
>  	aep->a_name[namelen] = 0;
> @@ -612,15 +613,15 @@ xfs_attr_put_listent(
>   */
>  int
>  xfs_attr_list(
> -	xfs_inode_t	*dp,
> -	char		*buffer,
> -	int		bufsize,
> -	int		flags,
> -	attrlist_cursor_kern_t *cursor)
> +	struct xfs_inode		*dp,
> +	char				*buffer,
> +	int				bufsize,
> +	int				flags,
> +	struct attrlist_cursor_kern	*cursor)
>  {
> -	xfs_attr_list_context_t context;
> -	struct attrlist *alist;
> -	int error;
> +	struct xfs_attr_list_context	context;
> +	struct attrlist			*alist;
> +	int				error;
> 
>  	/*
>  	 * Validate the cursor.
> @@ -645,12 +646,12 @@ xfs_attr_list(
>  	context.cursor = cursor;
>  	context.resynch = 1;
>  	context.flags = flags;
> -	context.alist = buffer;
> +	context.buffer = buffer;
>  	context.bufsize = (bufsize & ~(sizeof(int)-1));  /* align */
>  	context.firstu = context.bufsize;
>  	context.put_listent = xfs_attr_put_listent;
> 
> -	alist = (struct attrlist *)context.alist;
> +	alist = context.buffer;
>  	alist->al_count = 0;
>  	alist->al_more = 0;
>  	alist->al_offset[0] = context.bufsize;
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index a86be7f807ee..8358a92987f9 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -45,7 +45,7 @@ DECLARE_EVENT_CLASS(xfs_attr_list_class,
>  		__field(u32, hashval)
>  		__field(u32, blkno)
>  		__field(u32, offset)
> -		__field(void *, alist)
> +		__field(void *, buffer)
>  		__field(int, bufsize)
>  		__field(int, count)
>  		__field(int, firstu)
> @@ -58,21 +58,21 @@ DECLARE_EVENT_CLASS(xfs_attr_list_class,
>  		__entry->hashval = ctx->cursor->hashval;
>  		__entry->blkno = ctx->cursor->blkno;
>  		__entry->offset = ctx->cursor->offset;
> -		__entry->alist = ctx->alist;
> +		__entry->buffer = ctx->buffer;
>  		__entry->bufsize = ctx->bufsize;
>  		__entry->count = ctx->count;
>  		__entry->firstu = ctx->firstu;
>  		__entry->flags = ctx->flags;
>  	),
>  	TP_printk("dev %d:%d ino 0x%llx cursor h/b/o 0x%x/0x%x/%u dupcnt %u "
> -		  "alist %p size %u count %u firstu %u flags %d %s",
> +		  "buffer %p size %u count %u firstu %u flags %d %s",
>  		  MAJOR(__entry->dev), MINOR(__entry->dev),
>  		   __entry->ino,
>  		   __entry->hashval,
>  		   __entry->blkno,
>  		   __entry->offset,
>  		   __entry->dupcnt,
> -		   __entry->alist,
> +		   __entry->buffer,
>  		   __entry->bufsize,
>  		   __entry->count,
>  		   __entry->firstu,
> @@ -169,7 +169,7 @@ TRACE_EVENT(xfs_attr_list_node_descend,
>  		__field(u32, hashval)
>  		__field(u32, blkno)
>  		__field(u32, offset)
> -		__field(void *, alist)
> +		__field(void *, buffer)
>  		__field(int, bufsize)
>  		__field(int, count)
>  		__field(int, firstu)
> @@ -184,7 +184,7 @@ TRACE_EVENT(xfs_attr_list_node_descend,
>  		__entry->hashval = ctx->cursor->hashval;
>  		__entry->blkno = ctx->cursor->blkno;
>  		__entry->offset = ctx->cursor->offset;
> -		__entry->alist = ctx->alist;
> +		__entry->buffer = ctx->buffer;
>  		__entry->bufsize = ctx->bufsize;
>  		__entry->count = ctx->count;
>  		__entry->firstu = ctx->firstu;
> @@ -193,7 +193,7 @@ TRACE_EVENT(xfs_attr_list_node_descend,
>  		__entry->bt_before = be32_to_cpu(btree->before);
>  	),
>  	TP_printk("dev %d:%d ino 0x%llx cursor h/b/o 0x%x/0x%x/%u dupcnt %u "
> -		  "alist %p size %u count %u firstu %u flags %d %s "
> +		  "buffer %p size %u count %u firstu %u flags %d %s "
>  		  "node hashval %u, node before %u",
>  		  MAJOR(__entry->dev), MINOR(__entry->dev),
>  		   __entry->ino,
> @@ -201,7 +201,7 @@ TRACE_EVENT(xfs_attr_list_node_descend,
>  		   __entry->blkno,
>  		   __entry->offset,
>  		   __entry->dupcnt,
> -		   __entry->alist,
> +		   __entry->buffer,
>  		   __entry->bufsize,
>  		   __entry->count,
>  		   __entry->firstu,
> diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
> index c9c44f8aebed..8880dee3400f 100644
> --- a/fs/xfs/xfs_xattr.c
> +++ b/fs/xfs/xfs_xattr.c
> @@ -132,7 +132,7 @@ __xfs_xattr_put_listent(
>  	if (context->count < 0 || context->seen_enough)
>  		return;
> 
> -	if (!context->alist)
> +	if (!context->buffer)
>  		goto compute_size;
> 
>  	arraytop = context->count + prefix_len + namelen + 1;
> @@ -141,7 +141,7 @@ __xfs_xattr_put_listent(
>  		context->seen_enough = 1;
>  		return;
>  	}
> -	offset = (char *)context->alist + context->count;
> +	offset = context->buffer + context->count;
>  	strncpy(offset, prefix, prefix_len);
>  	offset += prefix_len;
>  	strncpy(offset, (char *)name, namelen);			/* real name */
> @@ -227,7 +227,7 @@ xfs_vn_listxattr(
>  	context.dp = XFS_I(inode);
>  	context.cursor = &cursor;
>  	context.resynch = 1;
> -	context.alist = size ? data : NULL;
> +	context.buffer = size ? data : NULL;
>  	context.bufsize = size;
>  	context.firstu = context.bufsize;
>  	context.put_listent = xfs_xattr_put_listent;
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 20/30] xfs: open code ATTR_ENTSIZE
  2020-01-29 17:02 ` [PATCH 20/30] xfs: open code ATTR_ENTSIZE Christoph Hellwig
@ 2020-02-09  6:57   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-09  6:57 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins

On Wednesday, January 29, 2020 10:32 PM Christoph Hellwig wrote: 
> Replace an opencoded offsetof and round_up hiden behind to macros
> using the open code variant using the standard helpers.
>

The arithmetic performed in the open coded version is correct.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/xfs_attr_list.c | 11 ++++-------
>  1 file changed, 4 insertions(+), 7 deletions(-)
> 
> diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
> index 9c4acb6dc856..f1ca8ef8be22 100644
> --- a/fs/xfs/xfs_attr_list.c
> +++ b/fs/xfs/xfs_attr_list.c
> @@ -545,12 +545,6 @@ xfs_attr_list_int(
>  	return error;
>  }
> 
> -#define	ATTR_ENTBASESIZE		/* minimum bytes used by an attr */ \
> -	(((struct attrlist_ent *) 0)->a_name - (char *) 0)
> -#define	ATTR_ENTSIZE(namelen)		/* actual bytes used by an attr */ \
> -	((ATTR_ENTBASESIZE + (namelen) + 1 + sizeof(uint32_t)-1) \
> -	 & ~(sizeof(uint32_t)-1))
> -
>  /*
>   * Format an attribute and copy it out to the user's buffer.
>   * Take care to check values and protect against them changing later,
> @@ -586,7 +580,10 @@ xfs_attr_put_listent(
> 
>  	arraytop = sizeof(*alist) +
>  			context->count * sizeof(alist->al_offset[0]);
> -	context->firstu -= ATTR_ENTSIZE(namelen);
> +
> +	/* decrement by the actual bytes used by the attr */
> +	context->firstu -= round_up(offsetof(struct attrlist_ent, a_name) +
> +			namelen + 1, sizeof(uint32_t));
>  	if (context->firstu < arraytop) {
>  		trace_xfs_attr_list_full(context);
>  		alist->al_more = 1;
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 21/30] xfs: move the legacy xfs_attr_list to xfs_ioctl.c
  2020-01-29 17:03 ` [PATCH 21/30] xfs: move the legacy xfs_attr_list to xfs_ioctl.c Christoph Hellwig
@ 2020-02-09  7:44   ` Chandan Rajendra
  2020-02-17 13:48     ` Christoph Hellwig
  0 siblings, 1 reply; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-09  7:44 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins

On Wednesday, January 29, 2020 10:33 PM Christoph Hellwig wrote:

One very trivial nit described below. Apart from that, the behavior of the
code is logically the same as before.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> The old xfs_attr_list code is only used by the attrlist by handle
> ioctl.  Move it to xfs_ioctl.c with its user.  Also move the
> attrlist and attrlist_ent structure to xfs_fs.h, as they are exposed
> user ABIs.  They are used through libattr headers with the same name
> by at least xfsdump.  Also document this relation so that it doesn't
> require a research project to figure out.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/libxfs/xfs_attr.h |  23 --------
>  fs/xfs/libxfs/xfs_fs.h   |  26 +++++++++
>  fs/xfs/xfs_attr_list.c   | 113 ---------------------------------------
>  fs/xfs/xfs_ioctl.c       | 110 ++++++++++++++++++++++++++++++++++++-
>  fs/xfs/xfs_ioctl.h       |  12 +++--
>  fs/xfs/xfs_ioctl32.c     |   4 +-
>  6 files changed, 144 insertions(+), 144 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
> index 31c0ffde4f59..0e3c213f78ce 100644
> --- a/fs/xfs/libxfs/xfs_attr.h
> +++ b/fs/xfs/libxfs/xfs_attr.h
> @@ -48,27 +48,6 @@ struct xfs_attr_list_context;
>   */
>  #define	ATTR_MAX_VALUELEN	(64*1024)	/* max length of a value */
> 
> -/*
> - * Define how lists of attribute names are returned to the user from
> - * the attr_list() call.  A large, 32bit aligned, buffer is passed in
> - * along with its size.  We put an array of offsets at the top that each
> - * reference an attrlist_ent_t and pack the attrlist_ent_t's at the bottom.
> - */
> -typedef struct attrlist {
> -	__s32	al_count;	/* number of entries in attrlist */
> -	__s32	al_more;	/* T/F: more attrs (do call again) */
> -	__s32	al_offset[1];	/* byte offsets of attrs [var-sized] */
> -} attrlist_t;
> -
> -/*
> - * Show the interesting info about one attribute.  This is what the
> - * al_offset[i] entry points to.
> - */
> -typedef struct attrlist_ent {	/* data from attr_list() */
> -	__u32	a_valuelen;	/* number bytes in value of attr */
> -	char	a_name[1];	/* attr name (NULL terminated) */
> -} attrlist_ent_t;
> -
>  /*
>   * Kernel-internal version of the attrlist cursor.
>   */
> @@ -131,8 +110,6 @@ int xfs_attr_get(struct xfs_da_args *args);
>  int xfs_attr_set(struct xfs_da_args *args);
>  int xfs_attr_set_args(struct xfs_da_args *args);
>  int xfs_attr_remove_args(struct xfs_da_args *args);
> -int xfs_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
> -		  int flags, struct attrlist_cursor_kern *cursor);
>  bool xfs_attr_namecheck(const void *name, size_t length);
> 
>  #endif	/* __XFS_ATTR_H__ */
> diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
> index ef95ca07d084..2c2b6e2b58f4 100644
> --- a/fs/xfs/libxfs/xfs_fs.h
> +++ b/fs/xfs/libxfs/xfs_fs.h
> @@ -572,6 +572,32 @@ typedef struct xfs_attrlist_cursor {
>  	__u32		opaque[4];
>  } xfs_attrlist_cursor_t;
> 
> +/*
> + * Define how lists of attribute names are returned to the user from
> + * the attr_list() call.  A large, 32bit aligned, buffer is passed in
> + * along with its size.  We put an array of offsets at the top that each
> + * reference an attrlist_ent_t and pack the attrlist_ent_t's at the bottom.

In the above comment, 'attrlist_ent_t' should be replaced with 'struct
xfs_attrlist_ent'.

> + *
> + * NOTE: struct xfs_attrlist must match struct attrlist defined in libattr.
> + */
> +struct xfs_attrlist {
> +	__s32	al_count;	/* number of entries in attrlist */
> +	__s32	al_more;	/* T/F: more attrs (do call again) */
> +	__s32	al_offset[1];	/* byte offsets of attrs [var-sized] */
> +};
> +
> +/*
> + * Show the interesting info about one attribute.  This is what the
> + * al_offset[i] entry points to.
> + *
> + * NOTE: struct xfs_attrlist_ent must match struct attrlist_ent defined in
> + * libattr.
> + */
> +struct xfs_attrlist_ent {	/* data from attr_list() */
> +	__u32	a_valuelen;	/* number bytes in value of attr */
> +	char	a_name[1];	/* attr name (NULL terminated) */
> +};
> +
>  typedef struct xfs_fsop_attrlist_handlereq {
>  	struct xfs_fsop_handlereq	hreq; /* handle interface structure */
>  	struct xfs_attrlist_cursor	pos; /* opaque cookie, list offset */
> diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
> index f1ca8ef8be22..369ce1d3dd45 100644
> --- a/fs/xfs/xfs_attr_list.c
> +++ b/fs/xfs/xfs_attr_list.c
> @@ -544,116 +544,3 @@ xfs_attr_list_int(
>  	xfs_iunlock(dp, lock_mode);
>  	return error;
>  }
> -
> -/*
> - * Format an attribute and copy it out to the user's buffer.
> - * Take care to check values and protect against them changing later,
> - * we may be reading them directly out of a user buffer.
> - */
> -STATIC void
> -xfs_attr_put_listent(
> -	struct xfs_attr_list_context	*context,
> -	int			flags,
> -	unsigned char		*name,
> -	int			namelen,
> -	int			valuelen)
> -{
> -	struct attrlist		*alist = context->buffer;
> -	struct attrlist_ent	*aep;
> -	int			arraytop;
> -
> -	ASSERT(!context->seen_enough);
> -	ASSERT(context->count >= 0);
> -	ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
> -	ASSERT(context->firstu >= sizeof(*alist));
> -	ASSERT(context->firstu <= context->bufsize);
> -
> -	/*
> -	 * Only list entries in the right namespace.
> -	 */
> -	if (((context->flags & ATTR_SECURE) == 0) !=
> -	    ((flags & XFS_ATTR_SECURE) == 0))
> -		return;
> -	if (((context->flags & ATTR_ROOT) == 0) !=
> -	    ((flags & XFS_ATTR_ROOT) == 0))
> -		return;
> -
> -	arraytop = sizeof(*alist) +
> -			context->count * sizeof(alist->al_offset[0]);
> -
> -	/* decrement by the actual bytes used by the attr */
> -	context->firstu -= round_up(offsetof(struct attrlist_ent, a_name) +
> -			namelen + 1, sizeof(uint32_t));
> -	if (context->firstu < arraytop) {
> -		trace_xfs_attr_list_full(context);
> -		alist->al_more = 1;
> -		context->seen_enough = 1;
> -		return;
> -	}
> -
> -	aep = context->buffer + context->firstu;
> -	aep->a_valuelen = valuelen;
> -	memcpy(aep->a_name, name, namelen);
> -	aep->a_name[namelen] = 0;
> -	alist->al_offset[context->count++] = context->firstu;
> -	alist->al_count = context->count;
> -	trace_xfs_attr_list_add(context);
> -	return;
> -}
> -
> -/*
> - * Generate a list of extended attribute names and optionally
> - * also value lengths.  Positive return value follows the XFS
> - * convention of being an error, zero or negative return code
> - * is the length of the buffer returned (negated), indicating
> - * success.
> - */
> -int
> -xfs_attr_list(
> -	struct xfs_inode		*dp,
> -	char				*buffer,
> -	int				bufsize,
> -	int				flags,
> -	struct attrlist_cursor_kern	*cursor)
> -{
> -	struct xfs_attr_list_context	context;
> -	struct attrlist			*alist;
> -	int				error;
> -
> -	/*
> -	 * Validate the cursor.
> -	 */
> -	if (cursor->pad1 || cursor->pad2)
> -		return -EINVAL;
> -	if ((cursor->initted == 0) &&
> -	    (cursor->hashval || cursor->blkno || cursor->offset))
> -		return -EINVAL;
> -
> -	/*
> -	 * Check for a properly aligned buffer.
> -	 */
> -	if (((long)buffer) & (sizeof(int)-1))
> -		return -EFAULT;
> -
> -	/*
> -	 * Initialize the output buffer.
> -	 */
> -	memset(&context, 0, sizeof(context));
> -	context.dp = dp;
> -	context.cursor = cursor;
> -	context.resynch = 1;
> -	context.flags = flags;
> -	context.buffer = buffer;
> -	context.bufsize = (bufsize & ~(sizeof(int)-1));  /* align */
> -	context.firstu = context.bufsize;
> -	context.put_listent = xfs_attr_put_listent;
> -
> -	alist = context.buffer;
> -	alist->al_count = 0;
> -	alist->al_more = 0;
> -	alist->al_offset[0] = context.bufsize;
> -
> -	error = xfs_attr_list_int(&context);
> -	ASSERT(error <= 0);
> -	return error;
> -}
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index dd1cb8c50518..47c39895977b 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -35,6 +35,7 @@
>  #include "xfs_health.h"
>  #include "xfs_reflink.h"
>  #include "xfs_ioctl.h"
> +#include "xfs_da_format.h"
> 
>  #include <linux/mount.h>
>  #include <linux/namei.h>
> @@ -292,6 +293,111 @@ xfs_readlink_by_handle(
>  	return error;
>  }
> 
> +/*
> + * Format an attribute and copy it out to the user's buffer.
> + * Take care to check values and protect against them changing later,
> + * we may be reading them directly out of a user buffer.
> + */
> +static void
> +xfs_ioc_attr_put_listent(
> +	struct xfs_attr_list_context *context,
> +	int			flags,
> +	unsigned char		*name,
> +	int			namelen,
> +	int			valuelen)
> +{
> +	struct xfs_attrlist	*alist = context->buffer;
> +	struct xfs_attrlist_ent	*aep;
> +	int			arraytop;
> +
> +	ASSERT(!context->seen_enough);
> +	ASSERT(context->count >= 0);
> +	ASSERT(context->count < (ATTR_MAX_VALUELEN/8));
> +	ASSERT(context->firstu >= sizeof(*alist));
> +	ASSERT(context->firstu <= context->bufsize);
> +
> +	/*
> +	 * Only list entries in the right namespace.
> +	 */
> +	if (((context->flags & ATTR_SECURE) == 0) !=
> +	    ((flags & XFS_ATTR_SECURE) == 0))
> +		return;
> +	if (((context->flags & ATTR_ROOT) == 0) !=
> +	    ((flags & XFS_ATTR_ROOT) == 0))
> +		return;
> +
> +	arraytop = sizeof(*alist) +
> +			context->count * sizeof(alist->al_offset[0]);
> +
> +	/* decrement by the actual bytes used by the attr */
> +	context->firstu -= round_up(offsetof(struct xfs_attrlist_ent, a_name) +
> +			namelen + 1, sizeof(uint32_t));
> +	if (context->firstu < arraytop) {
> +		trace_xfs_attr_list_full(context);
> +		alist->al_more = 1;
> +		context->seen_enough = 1;
> +		return;
> +	}
> +
> +	aep = context->buffer + context->firstu;
> +	aep->a_valuelen = valuelen;
> +	memcpy(aep->a_name, name, namelen);
> +	aep->a_name[namelen] = 0;
> +	alist->al_offset[context->count++] = context->firstu;
> +	alist->al_count = context->count;
> +	trace_xfs_attr_list_add(context);
> +}
> +
> +int
> +xfs_ioc_attr_list(
> +	struct xfs_inode		*dp,
> +	char				*buffer,
> +	int				bufsize,
> +	int				flags,
> +	struct attrlist_cursor_kern	*cursor)
> +{
> +	struct xfs_attr_list_context	context;
> +	struct xfs_attrlist		*alist;
> +	int				error;
> +
> +	/*
> +	 * Validate the cursor.
> +	 */
> +	if (cursor->pad1 || cursor->pad2)
> +		return -EINVAL;
> +	if ((cursor->initted == 0) &&
> +	    (cursor->hashval || cursor->blkno || cursor->offset))
> +		return -EINVAL;
> +
> +	/*
> +	 * Check for a properly aligned buffer.
> +	 */
> +	if (((long)buffer) & (sizeof(int)-1))
> +		return -EFAULT;
> +
> +	/*
> +	 * Initialize the output buffer.
> +	 */
> +	memset(&context, 0, sizeof(context));
> +	context.dp = dp;
> +	context.cursor = cursor;
> +	context.resynch = 1;
> +	context.flags = flags;
> +	context.buffer = buffer;
> +	context.bufsize = (bufsize & ~(sizeof(int)-1));  /* align */
> +	context.firstu = context.bufsize;
> +	context.put_listent = xfs_ioc_attr_put_listent;
> +
> +	alist = context.buffer;
> +	alist->al_count = 0;
> +	alist->al_more = 0;
> +	alist->al_offset[0] = context.bufsize;
> +
> +	error = xfs_attr_list_int(&context);
> +	ASSERT(error <= 0);
> +	return error;
> +}
> +
>  STATIC int
>  xfs_attrlist_by_handle(
>  	struct file		*parfilp,
> @@ -308,7 +414,7 @@ xfs_attrlist_by_handle(
>  		return -EPERM;
>  	if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
>  		return -EFAULT;
> -	if (al_hreq.buflen < sizeof(struct attrlist) ||
> +	if (al_hreq.buflen < sizeof(struct xfs_attrlist) ||
>  	    al_hreq.buflen > XFS_XATTR_LIST_MAX)
>  		return -EINVAL;
> 
> @@ -329,7 +435,7 @@ xfs_attrlist_by_handle(
>  		goto out_dput;
> 
>  	cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
> -	error = xfs_attr_list(XFS_I(d_inode(dentry)), kbuf, al_hreq.buflen,
> +	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), kbuf, al_hreq.buflen,
>  					al_hreq.flags, cursor);
>  	if (error)
>  		goto out_kfree;
> diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
> index bb50cb3dc61f..cb7b94c576a7 100644
> --- a/fs/xfs/xfs_ioctl.h
> +++ b/fs/xfs/xfs_ioctl.h
> @@ -6,6 +6,12 @@
>  #ifndef __XFS_IOCTL_H__
>  #define __XFS_IOCTL_H__
> 
> +struct attrlist_cursor_kern;
> +struct xfs_bstat;
> +struct xfs_ibulk;
> +struct xfs_inogrp;
> +
> +
>  extern int
>  xfs_ioc_space(
>  	struct file		*filp,
> @@ -33,6 +39,8 @@ xfs_readlink_by_handle(
>  int xfs_ioc_attrmulti_one(struct file *parfilp, struct inode *inode,
>  		uint32_t opcode, void __user *uname, void __user *value,
>  		uint32_t *len, uint32_t flags);
> +int xfs_ioc_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
> +	int flags, struct attrlist_cursor_kern *cursor);
> 
>  extern struct dentry *
>  xfs_handle_to_dentry(
> @@ -52,10 +60,6 @@ xfs_file_compat_ioctl(
>  	unsigned int		cmd,
>  	unsigned long		arg);
> 
> -struct xfs_ibulk;
> -struct xfs_bstat;
> -struct xfs_inogrp;
> -
>  int xfs_fsbulkstat_one_fmt(struct xfs_ibulk *breq,
>  			   const struct xfs_bulkstat *bstat);
>  int xfs_fsinumbers_fmt(struct xfs_ibulk *breq, const struct xfs_inumbers *igrp);
> diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
> index e1daf095c585..10ea0222954c 100644
> --- a/fs/xfs/xfs_ioctl32.c
> +++ b/fs/xfs/xfs_ioctl32.c
> @@ -366,7 +366,7 @@ xfs_compat_attrlist_by_handle(
>  	if (copy_from_user(&al_hreq, arg,
>  			   sizeof(compat_xfs_fsop_attrlist_handlereq_t)))
>  		return -EFAULT;
> -	if (al_hreq.buflen < sizeof(struct attrlist) ||
> +	if (al_hreq.buflen < sizeof(struct xfs_attrlist) ||
>  	    al_hreq.buflen > XFS_XATTR_LIST_MAX)
>  		return -EINVAL;
> 
> @@ -388,7 +388,7 @@ xfs_compat_attrlist_by_handle(
>  		goto out_dput;
> 
>  	cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
> -	error = xfs_attr_list(XFS_I(d_inode(dentry)), kbuf, al_hreq.buflen,
> +	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), kbuf, al_hreq.buflen,
>  					al_hreq.flags, cursor);
>  	if (error)
>  		goto out_kfree;
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 22/30] xfs: rename xfs_attr_list_int to xfs_attr_list
  2020-01-29 17:03 ` [PATCH 22/30] xfs: rename xfs_attr_list_int to xfs_attr_list Christoph Hellwig
@ 2020-02-09  7:52   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-09  7:52 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:33 PM Christoph Hellwig wrote: 
> The version taking the context structure is the main interface to list
> attributes, so drop the _int postfix.
>

Logical code flow remains the same.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_attr.h | 4 ++--
>  fs/xfs/scrub/attr.c      | 4 ++--
>  fs/xfs/xfs_attr_list.c   | 6 +++---
>  fs/xfs/xfs_ioctl.c       | 2 +-
>  fs/xfs/xfs_xattr.c       | 2 +-
>  5 files changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
> index 0e3c213f78ce..8d42f5782ff7 100644
> --- a/fs/xfs/libxfs/xfs_attr.h
> +++ b/fs/xfs/libxfs/xfs_attr.h
> @@ -102,8 +102,8 @@ struct xfs_attr_list_context {
>   * Overall external interface routines.
>   */
>  int xfs_attr_inactive(struct xfs_inode *dp);
> -int xfs_attr_list_int_ilocked(struct xfs_attr_list_context *);
> -int xfs_attr_list_int(struct xfs_attr_list_context *);
> +int xfs_attr_list_ilocked(struct xfs_attr_list_context *);
> +int xfs_attr_list(struct xfs_attr_list_context *);
>  int xfs_inode_hasattr(struct xfs_inode *ip);
>  int xfs_attr_get_ilocked(struct xfs_da_args *args);
>  int xfs_attr_get(struct xfs_da_args *args);
> diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
> index 05537627211d..9e336d797616 100644
> --- a/fs/xfs/scrub/attr.c
> +++ b/fs/xfs/scrub/attr.c
> @@ -98,7 +98,7 @@ struct xchk_xattr {
>  /*
>   * Check that an extended attribute key can be looked up by hash.
>   *
> - * We use the XFS attribute list iterator (i.e. xfs_attr_list_int_ilocked)
> + * We use the XFS attribute list iterator (i.e. xfs_attr_list_ilocked)
>   * to call this function for every attribute key in an inode.  Once
>   * we're here, we load the attribute value to see if any errors happen,
>   * or if we get more or less data than we expected.
> @@ -516,7 +516,7 @@ xchk_xattr(
>  	 * iteration, which doesn't really follow the usual buffer
>  	 * locking order.
>  	 */
> -	error = xfs_attr_list_int_ilocked(&sx.context);
> +	error = xfs_attr_list_ilocked(&sx.context);
>  	if (!xchk_fblock_process_error(sc, XFS_ATTR_FORK, 0, &error))
>  		goto out;
> 
> diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
> index 369ce1d3dd45..ea79219859a0 100644
> --- a/fs/xfs/xfs_attr_list.c
> +++ b/fs/xfs/xfs_attr_list.c
> @@ -507,7 +507,7 @@ xfs_attr_leaf_list(
>  }
> 
>  int
> -xfs_attr_list_int_ilocked(
> +xfs_attr_list_ilocked(
>  	struct xfs_attr_list_context	*context)
>  {
>  	struct xfs_inode		*dp = context->dp;
> @@ -527,7 +527,7 @@ xfs_attr_list_int_ilocked(
>  }
> 
>  int
> -xfs_attr_list_int(
> +xfs_attr_list(
>  	struct xfs_attr_list_context	*context)
>  {
>  	struct xfs_inode		*dp = context->dp;
> @@ -540,7 +540,7 @@ xfs_attr_list_int(
>  		return -EIO;
> 
>  	lock_mode = xfs_ilock_attr_map_shared(dp);
> -	error = xfs_attr_list_int_ilocked(context);
> +	error = xfs_attr_list_ilocked(context);
>  	xfs_iunlock(dp, lock_mode);
>  	return error;
>  }
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index 47c39895977b..0f9326bc055c 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -393,7 +393,7 @@ xfs_ioc_attr_list(
>  	alist->al_more = 0;
>  	alist->al_offset[0] = context.bufsize;
> 
> -	error = xfs_attr_list_int(&context);
> +	error = xfs_attr_list(&context);
>  	ASSERT(error <= 0);
>  	return error;
>  }
> diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
> index 8880dee3400f..e1951d2b878e 100644
> --- a/fs/xfs/xfs_xattr.c
> +++ b/fs/xfs/xfs_xattr.c
> @@ -232,7 +232,7 @@ xfs_vn_listxattr(
>  	context.firstu = context.bufsize;
>  	context.put_listent = xfs_xattr_put_listent;
> 
> -	error = xfs_attr_list_int(&context);
> +	error = xfs_attr_list(&context);
>  	if (error)
>  		return error;
>  	if (context.count < 0)
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 23/30] xfs: lift common checks into xfs_ioc_attr_list
  2020-01-29 17:03 ` [PATCH 23/30] xfs: lift common checks into xfs_ioc_attr_list Christoph Hellwig
@ 2020-02-09  8:03   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-09  8:03 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:33 PM Christoph Hellwig wrote: 
> Lift the flags and bufsize checks from both callers into the common code
> in xfs_ioc_attr_list.
>

Logically, code flow remains the same.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_ioctl.c   | 23 ++++++++++++-----------
>  fs/xfs/xfs_ioctl32.c | 11 -----------
>  2 files changed, 12 insertions(+), 22 deletions(-)
> 
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index 0f9326bc055c..c8814808a551 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -360,6 +360,18 @@ xfs_ioc_attr_list(
>  	struct xfs_attrlist		*alist;
>  	int				error;
> 
> +	if (bufsize < sizeof(struct xfs_attrlist) ||
> +	    bufsize > XFS_XATTR_LIST_MAX)
> +		return -EINVAL;
> +
> +	/*
> +	 * Reject flags, only allow namespaces.
> +	 */
> +	if (flags & ~(ATTR_ROOT | ATTR_SECURE))
> +		return -EINVAL;
> +	if (flags == (ATTR_ROOT | ATTR_SECURE))
> +		return -EINVAL;
> +
>  	/*
>  	 * Validate the cursor.
>  	 */
> @@ -414,17 +426,6 @@ xfs_attrlist_by_handle(
>  		return -EPERM;
>  	if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
>  		return -EFAULT;
> -	if (al_hreq.buflen < sizeof(struct xfs_attrlist) ||
> -	    al_hreq.buflen > XFS_XATTR_LIST_MAX)
> -		return -EINVAL;
> -
> -	/*
> -	 * Reject flags, only allow namespaces.
> -	 */
> -	if (al_hreq.flags & ~(ATTR_ROOT | ATTR_SECURE))
> -		return -EINVAL;
> -	if (al_hreq.flags == (ATTR_ROOT | ATTR_SECURE))
> -		return -EINVAL;
> 
>  	dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
>  	if (IS_ERR(dentry))
> diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
> index 10ea0222954c..840d17951407 100644
> --- a/fs/xfs/xfs_ioctl32.c
> +++ b/fs/xfs/xfs_ioctl32.c
> @@ -366,17 +366,6 @@ xfs_compat_attrlist_by_handle(
>  	if (copy_from_user(&al_hreq, arg,
>  			   sizeof(compat_xfs_fsop_attrlist_handlereq_t)))
>  		return -EFAULT;
> -	if (al_hreq.buflen < sizeof(struct xfs_attrlist) ||
> -	    al_hreq.buflen > XFS_XATTR_LIST_MAX)
> -		return -EINVAL;
> -
> -	/*
> -	 * Reject flags, only allow namespaces.
> -	 */
> -	if (al_hreq.flags & ~(ATTR_ROOT | ATTR_SECURE))
> -		return -EINVAL;
> -	if (al_hreq.flags == (ATTR_ROOT | ATTR_SECURE))
> -		return -EINVAL;
> 
>  	dentry = xfs_compat_handlereq_to_dentry(parfilp, &al_hreq.hreq);
>  	if (IS_ERR(dentry))
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 24/30] xfs: lift buffer allocation into xfs_ioc_attr_list
  2020-01-29 17:03 ` [PATCH 24/30] xfs: lift buffer allocation " Christoph Hellwig
@ 2020-02-09  8:24   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-09  8:24 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:33 PM Christoph Hellwig wrote: 
> Lift the buffer allocation from the two callers into xfs_ioc_attr_list.
>

Logically, code flow remains the same.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_ioctl.c   | 39 ++++++++++++++++-----------------------
>  fs/xfs/xfs_ioctl.h   |  2 +-
>  fs/xfs/xfs_ioctl32.c | 22 +++++-----------------
>  3 files changed, 22 insertions(+), 41 deletions(-)
> 
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index c8814808a551..cdb3800dfcef 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -351,13 +351,14 @@ xfs_ioc_attr_put_listent(
>  int
>  xfs_ioc_attr_list(
>  	struct xfs_inode		*dp,
> -	char				*buffer,
> +	void __user			*ubuf,
>  	int				bufsize,
>  	int				flags,
>  	struct attrlist_cursor_kern	*cursor)
>  {
>  	struct xfs_attr_list_context	context;
>  	struct xfs_attrlist		*alist;
> +	void				*buffer;
>  	int				error;
> 
>  	if (bufsize < sizeof(struct xfs_attrlist) ||
> @@ -381,11 +382,9 @@ xfs_ioc_attr_list(
>  	    (cursor->hashval || cursor->blkno || cursor->offset))
>  		return -EINVAL;
> 
> -	/*
> -	 * Check for a properly aligned buffer.
> -	 */
> -	if (((long)buffer) & (sizeof(int)-1))
> -		return -EFAULT;
> +	buffer = kmem_zalloc_large(bufsize, 0);
> +	if (!buffer)
> +		return -ENOMEM;
> 
>  	/*
>  	 * Initialize the output buffer.
> @@ -406,7 +405,13 @@ xfs_ioc_attr_list(
>  	alist->al_offset[0] = context.bufsize;
> 
>  	error = xfs_attr_list(&context);
> -	ASSERT(error <= 0);
> +	if (error)
> +		goto out_free;
> +
> +	if (copy_to_user(ubuf, buffer, bufsize))
> +		error = -EFAULT;
> +out_free:
> +	kmem_free(buffer);
>  	return error;
>  }
> 
> @@ -420,7 +425,6 @@ xfs_attrlist_by_handle(
>  	struct xfs_fsop_attrlist_handlereq __user	*p = arg;
>  	xfs_fsop_attrlist_handlereq_t al_hreq;
>  	struct dentry		*dentry;
> -	char			*kbuf;
> 
>  	if (!capable(CAP_SYS_ADMIN))
>  		return -EPERM;
> @@ -431,26 +435,15 @@ xfs_attrlist_by_handle(
>  	if (IS_ERR(dentry))
>  		return PTR_ERR(dentry);
> 
> -	kbuf = kmem_zalloc_large(al_hreq.buflen, 0);
> -	if (!kbuf)
> -		goto out_dput;
> -
>  	cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
> -	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), kbuf, al_hreq.buflen,
> -					al_hreq.flags, cursor);
> +	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), al_hreq.buffer,
> +				  al_hreq.buflen, al_hreq.flags, cursor);
>  	if (error)
> -		goto out_kfree;
> -
> -	if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t))) {
> -		error = -EFAULT;
> -		goto out_kfree;
> -	}
> +		goto out_dput;
> 
> -	if (copy_to_user(al_hreq.buffer, kbuf, al_hreq.buflen))
> +	if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t)))
>  		error = -EFAULT;
> 
> -out_kfree:
> -	kmem_free(kbuf);
>  out_dput:
>  	dput(dentry);
>  	return error;
> diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
> index cb7b94c576a7..ec6448b259fb 100644
> --- a/fs/xfs/xfs_ioctl.h
> +++ b/fs/xfs/xfs_ioctl.h
> @@ -39,7 +39,7 @@ xfs_readlink_by_handle(
>  int xfs_ioc_attrmulti_one(struct file *parfilp, struct inode *inode,
>  		uint32_t opcode, void __user *uname, void __user *value,
>  		uint32_t *len, uint32_t flags);
> -int xfs_ioc_attr_list(struct xfs_inode *dp, char *buffer, int bufsize,
> +int xfs_ioc_attr_list(struct xfs_inode *dp, void __user *ubuf, int bufsize,
>  	int flags, struct attrlist_cursor_kern *cursor);
> 
>  extern struct dentry *
> diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
> index 840d17951407..17e14916757b 100644
> --- a/fs/xfs/xfs_ioctl32.c
> +++ b/fs/xfs/xfs_ioctl32.c
> @@ -359,7 +359,6 @@ xfs_compat_attrlist_by_handle(
>  	compat_xfs_fsop_attrlist_handlereq_t __user *p = arg;
>  	compat_xfs_fsop_attrlist_handlereq_t al_hreq;
>  	struct dentry		*dentry;
> -	char			*kbuf;
> 
>  	if (!capable(CAP_SYS_ADMIN))
>  		return -EPERM;
> @@ -371,27 +370,16 @@ xfs_compat_attrlist_by_handle(
>  	if (IS_ERR(dentry))
>  		return PTR_ERR(dentry);
> 
> -	error = -ENOMEM;
> -	kbuf = kmem_zalloc_large(al_hreq.buflen, 0);
> -	if (!kbuf)
> -		goto out_dput;
> -
>  	cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
> -	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), kbuf, al_hreq.buflen,
> -					al_hreq.flags, cursor);
> +	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)),
> +			compat_ptr(al_hreq.buffer), al_hreq.buflen,
> +			al_hreq.flags, cursor);
>  	if (error)
> -		goto out_kfree;
> -
> -	if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t))) {
> -		error = -EFAULT;
> -		goto out_kfree;
> -	}
> +		goto out_dput;
> 
> -	if (copy_to_user(compat_ptr(al_hreq.buffer), kbuf, al_hreq.buflen))
> +	if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t)))
>  		error = -EFAULT;
> 
> -out_kfree:
> -	kmem_free(kbuf);
>  out_dput:
>  	dput(dentry);
>  	return error;
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 25/30] xfs: lift cursor copy in/out into xfs_ioc_attr_list
  2020-01-29 17:03 ` [PATCH 25/30] xfs: lift cursor copy in/out " Christoph Hellwig
@ 2020-02-10  6:02   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-10  6:02 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:33 PM Christoph Hellwig wrote: 
> Lift the common code to copy the cursor from and to user space into
> xfs_ioc_attr_list.  Note that this means we copy in twice now as
> the cursor is in the middle of the conaining structure, but we never
> touch the memory for the original copy.  Doing so keeps the cursor
> handling isolated in the common helper.
>

Logically, code flow remains the same.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_ioctl.c   | 36 +++++++++++++++---------------------
>  fs/xfs/xfs_ioctl.h   |  2 +-
>  fs/xfs/xfs_ioctl32.c | 19 ++++---------------
>  3 files changed, 20 insertions(+), 37 deletions(-)
> 
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index cdb3800dfcef..5d160e82778e 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -354,9 +354,10 @@ xfs_ioc_attr_list(
>  	void __user			*ubuf,
>  	int				bufsize,
>  	int				flags,
> -	struct attrlist_cursor_kern	*cursor)
> +	struct xfs_attrlist_cursor __user *ucursor)
>  {
>  	struct xfs_attr_list_context	context;
> +	struct attrlist_cursor_kern	cursor;
>  	struct xfs_attrlist		*alist;
>  	void				*buffer;
>  	int				error;
> @@ -376,10 +377,12 @@ xfs_ioc_attr_list(
>  	/*
>  	 * Validate the cursor.
>  	 */
> -	if (cursor->pad1 || cursor->pad2)
> +	if (copy_from_user(&cursor, ucursor, sizeof(cursor)))
> +		return -EFAULT;
> +	if (cursor.pad1 || cursor.pad2)
>  		return -EINVAL;
> -	if ((cursor->initted == 0) &&
> -	    (cursor->hashval || cursor->blkno || cursor->offset))
> +	if ((cursor.initted == 0) &&
> +	    (cursor.hashval || cursor.blkno || cursor.offset))
>  		return -EINVAL;
> 
>  	buffer = kmem_zalloc_large(bufsize, 0);
> @@ -391,7 +394,7 @@ xfs_ioc_attr_list(
>  	 */
>  	memset(&context, 0, sizeof(context));
>  	context.dp = dp;
> -	context.cursor = cursor;
> +	context.cursor = &cursor;
>  	context.resynch = 1;
>  	context.flags = flags;
>  	context.buffer = buffer;
> @@ -408,7 +411,8 @@ xfs_ioc_attr_list(
>  	if (error)
>  		goto out_free;
> 
> -	if (copy_to_user(ubuf, buffer, bufsize))
> +	if (copy_to_user(ubuf, buffer, bufsize) ||
> +	    copy_to_user(ucursor, &cursor, sizeof(cursor)))
>  		error = -EFAULT;
>  out_free:
>  	kmem_free(buffer);
> @@ -418,33 +422,23 @@ xfs_ioc_attr_list(
>  STATIC int
>  xfs_attrlist_by_handle(
>  	struct file		*parfilp,
> -	void			__user *arg)
> +	struct xfs_fsop_attrlist_handlereq __user *p)
>  {
> -	int			error = -ENOMEM;
> -	attrlist_cursor_kern_t	*cursor;
> -	struct xfs_fsop_attrlist_handlereq __user	*p = arg;
> -	xfs_fsop_attrlist_handlereq_t al_hreq;
> +	struct xfs_fsop_attrlist_handlereq al_hreq;
>  	struct dentry		*dentry;
> +	int			error = -ENOMEM;
> 
>  	if (!capable(CAP_SYS_ADMIN))
>  		return -EPERM;
> -	if (copy_from_user(&al_hreq, arg, sizeof(xfs_fsop_attrlist_handlereq_t)))
> +	if (copy_from_user(&al_hreq, p, sizeof(al_hreq)))
>  		return -EFAULT;
> 
>  	dentry = xfs_handlereq_to_dentry(parfilp, &al_hreq.hreq);
>  	if (IS_ERR(dentry))
>  		return PTR_ERR(dentry);
> 
> -	cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
>  	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)), al_hreq.buffer,
> -				  al_hreq.buflen, al_hreq.flags, cursor);
> -	if (error)
> -		goto out_dput;
> -
> -	if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t)))
> -		error = -EFAULT;
> -
> -out_dput:
> +				  al_hreq.buflen, al_hreq.flags, &p->pos);
>  	dput(dentry);
>  	return error;
>  }
> diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
> index ec6448b259fb..d6e8000ad825 100644
> --- a/fs/xfs/xfs_ioctl.h
> +++ b/fs/xfs/xfs_ioctl.h
> @@ -40,7 +40,7 @@ int xfs_ioc_attrmulti_one(struct file *parfilp, struct inode *inode,
>  		uint32_t opcode, void __user *uname, void __user *value,
>  		uint32_t *len, uint32_t flags);
>  int xfs_ioc_attr_list(struct xfs_inode *dp, void __user *ubuf, int bufsize,
> -	int flags, struct attrlist_cursor_kern *cursor);
> +	int flags, struct xfs_attrlist_cursor __user *ucursor);
> 
>  extern struct dentry *
>  xfs_handle_to_dentry(
> diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
> index 17e14916757b..c1771e728117 100644
> --- a/fs/xfs/xfs_ioctl32.c
> +++ b/fs/xfs/xfs_ioctl32.c
> @@ -352,35 +352,24 @@ xfs_compat_handlereq_to_dentry(
>  STATIC int
>  xfs_compat_attrlist_by_handle(
>  	struct file		*parfilp,
> -	void			__user *arg)
> +	compat_xfs_fsop_attrlist_handlereq_t __user *p)
>  {
> -	int			error;
> -	attrlist_cursor_kern_t	*cursor;
> -	compat_xfs_fsop_attrlist_handlereq_t __user *p = arg;
>  	compat_xfs_fsop_attrlist_handlereq_t al_hreq;
>  	struct dentry		*dentry;
> +	int			error;
> 
>  	if (!capable(CAP_SYS_ADMIN))
>  		return -EPERM;
> -	if (copy_from_user(&al_hreq, arg,
> -			   sizeof(compat_xfs_fsop_attrlist_handlereq_t)))
> +	if (copy_from_user(&al_hreq, p, sizeof(al_hreq)))
>  		return -EFAULT;
> 
>  	dentry = xfs_compat_handlereq_to_dentry(parfilp, &al_hreq.hreq);
>  	if (IS_ERR(dentry))
>  		return PTR_ERR(dentry);
> 
> -	cursor = (attrlist_cursor_kern_t *)&al_hreq.pos;
>  	error = xfs_ioc_attr_list(XFS_I(d_inode(dentry)),
>  			compat_ptr(al_hreq.buffer), al_hreq.buflen,
> -			al_hreq.flags, cursor);
> -	if (error)
> -		goto out_dput;
> -
> -	if (copy_to_user(&p->pos, cursor, sizeof(attrlist_cursor_kern_t)))
> -		error = -EFAULT;
> -
> -out_dput:
> +			al_hreq.flags, &p->pos);
>  	dput(dentry);
>  	return error;
>  }
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 26/30] xfs: improve xfs_forget_acl
  2020-01-29 17:03 ` [PATCH 26/30] xfs: improve xfs_forget_acl Christoph Hellwig
@ 2020-02-10  6:45   ` Chandan Rajendra
  2020-02-17 13:48     ` Christoph Hellwig
  0 siblings, 1 reply; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-10  6:45 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:33 PM Christoph Hellwig wrote: 
> Move the function to xfs_acl.c and provide a proper stub for the
> !CONFIG_XFS_POSIX_ACL case.  Lift the flags check to the caller as it
> nicely fits in there.
> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/xfs_acl.c   | 16 ++++++++++++++++
>  fs/xfs/xfs_acl.h   |  4 ++--
>  fs/xfs/xfs_ioctl.c |  4 ++--
>  fs/xfs/xfs_xattr.c | 26 ++------------------------
>  4 files changed, 22 insertions(+), 28 deletions(-)
> 
> diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
> index bc78b7c33401..e9a48d718c3a 100644
> --- a/fs/xfs/xfs_acl.c
> +++ b/fs/xfs/xfs_acl.c
> @@ -264,3 +264,19 @@ xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
> 
>  	return error;
>  }
> +
> +/*
> + * Invalidate any cached ACLs if the user has bypassed the ACL interface.
> + * We don't validate the content whatsoever so it is caller responsibility to
> + * provide data in valid format and ensure i_mode is consistent.
> + */
> +void
> +xfs_forget_acl(
> +	struct inode		*inode,
> +	const char		*name)
> +{
> +	if (!strcmp(name, SGI_ACL_FILE))
> +		forget_cached_acl(inode, ACL_TYPE_ACCESS);
> +	else if (!strcmp(name, SGI_ACL_DEFAULT))
> +		forget_cached_acl(inode, ACL_TYPE_DEFAULT);
> +}
> diff --git a/fs/xfs/xfs_acl.h b/fs/xfs/xfs_acl.h
> index 94615e34bc86..bd8a306046a9 100644
> --- a/fs/xfs/xfs_acl.h
> +++ b/fs/xfs/xfs_acl.h
> @@ -13,14 +13,14 @@ struct posix_acl;
>  extern struct posix_acl *xfs_get_acl(struct inode *inode, int type);
>  extern int xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
>  extern int __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type);
> +void xfs_forget_acl(struct inode *inode, const char *name);
>  #else
>  static inline struct posix_acl *xfs_get_acl(struct inode *inode, int type)
>  {
>  	return NULL;
>  }
>  # define xfs_set_acl					NULL
> +# define xfs_forget_acl(inode, name)			0
>  #endif /* CONFIG_XFS_POSIX_ACL */
> 
> -extern void xfs_forget_acl(struct inode *inode, const char *name, int xflags);
> -
>  #endif	/* __XFS_ACL_H__ */
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index 5d160e82778e..4f26c3962215 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -509,8 +509,8 @@ xfs_attrmulti_attr_set(
>  	}
> 
>  	error = xfs_attr_set(&args);
> -	if (!error)
> -		xfs_forget_acl(inode, name, flags);
> +	if (!error && (flags & ATTR_ROOT))
> +		xfs_forget_acl(inode, name);
>  	kfree(args.value);
>  	return error;
>  }
> diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
> index e1951d2b878e..863e9fdec162 100644
> --- a/fs/xfs/xfs_xattr.c
> +++ b/fs/xfs/xfs_xattr.c
> @@ -37,28 +37,6 @@ xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
>  	return args.valuelen;
>  }
> 
> -void
> -xfs_forget_acl(
> -	struct inode		*inode,
> -	const char		*name,
> -	int			xflags)
> -{
> -	/*
> -	 * Invalidate any cached ACLs if the user has bypassed the ACL
> -	 * interface. We don't validate the content whatsoever so it is caller
> -	 * responsibility to provide data in valid format and ensure i_mode is
> -	 * consistent.
> -	 */
> -	if (xflags & ATTR_ROOT) {
> -#ifdef CONFIG_XFS_POSIX_ACL
> -		if (!strcmp(name, SGI_ACL_FILE))
> -			forget_cached_acl(inode, ACL_TYPE_ACCESS);
> -		else if (!strcmp(name, SGI_ACL_DEFAULT))
> -			forget_cached_acl(inode, ACL_TYPE_DEFAULT);
> -#endif
> -	}
> -}
> -
>  static int
>  xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
>  		struct inode *inode, const char *name, const void *value,
> @@ -81,8 +59,8 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
>  		args.flags |= ATTR_REPLACE;
> 
>  	error = xfs_attr_set(&args);
> -	if (!error)
> -		xfs_forget_acl(inode, name, args.flags);
> +	if (!error && (flags & ATTR_ROOT))

ATTR_ROOT should be checked against args.flags.

'flags' refers to argument passed to setxattr() syscall i.e. it can have
XATTR_CREATE or XATTR_REPLACE as its value.

The remaining changes look good to me,

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>


> +		xfs_forget_acl(inode, name);
>  	return error;
>  }
> 
> 

-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 27/30] xfs: clean up the ATTR_REPLACE checks
  2020-01-29 17:03 ` [PATCH 27/30] xfs: clean up the ATTR_REPLACE checks Christoph Hellwig
@ 2020-02-10  6:57   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-10  6:57 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:33 PM Christoph Hellwig wrote: 
> Remove superflous braces, elses after return statements and use a goto
> label to merge common error handling.
>

The changes look good to me,

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_attr.c | 24 ++++++++++++------------
>  1 file changed, 12 insertions(+), 12 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index 3b1db2afb104..9c629c7c912d 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -423,9 +423,9 @@ xfs_attr_shortform_addname(xfs_da_args_t *args)
>  	trace_xfs_attr_sf_addname(args);
> 
>  	retval = xfs_attr_shortform_lookup(args);
> -	if ((args->flags & ATTR_REPLACE) && (retval == -ENOATTR)) {
> +	if ((args->flags & ATTR_REPLACE) && retval == -ENOATTR)
>  		return retval;
> -	} else if (retval == -EEXIST) {
> +	if (retval == -EEXIST) {
>  		if (args->flags & ATTR_CREATE)
>  			return retval;
>  		retval = xfs_attr_shortform_remove(args);
> @@ -489,14 +489,11 @@ xfs_attr_leaf_addname(
>  	 * the given flags produce an error or call for an atomic rename.
>  	 */
>  	retval = xfs_attr3_leaf_lookup_int(bp, args);
> -	if ((args->flags & ATTR_REPLACE) && (retval == -ENOATTR)) {
> -		xfs_trans_brelse(args->trans, bp);
> -		return retval;
> -	} else if (retval == -EEXIST) {
> -		if (args->flags & ATTR_CREATE) {	/* pure create op */
> -			xfs_trans_brelse(args->trans, bp);
> -			return retval;
> -		}
> +	if ((args->flags & ATTR_REPLACE) && retval == -ENOATTR)
> +		goto out_brelse;
> +	if (retval == -EEXIST) {
> +		if (args->flags & ATTR_CREATE)	/* pure create op */
> +			goto out_brelse;
> 
>  		trace_xfs_attr_leaf_replace(args);
> 
> @@ -637,6 +634,9 @@ xfs_attr_leaf_addname(
>  		error = xfs_attr3_leaf_clearflag(args);
>  	}
>  	return error;
> +out_brelse:
> +	xfs_trans_brelse(args->trans, bp);
> +	return retval;
>  }
> 
>  /*
> @@ -763,9 +763,9 @@ xfs_attr_node_addname(
>  		goto out;
>  	blk = &state->path.blk[ state->path.active-1 ];
>  	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
> -	if ((args->flags & ATTR_REPLACE) && (retval == -ENOATTR)) {
> +	if ((args->flags & ATTR_REPLACE) && retval == -ENOATTR)
>  		goto out;
> -	} else if (retval == -EEXIST) {
> +	if (retval == -EEXIST) {
>  		if (args->flags & ATTR_CREATE)
>  			goto out;
> 
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 28/30] xfs: clean up the attr flag confusion
  2020-01-29 17:03 ` [PATCH 28/30] xfs: clean up the attr flag confusion Christoph Hellwig
@ 2020-02-10 13:19   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-10 13:19 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins

On Wednesday, January 29, 2020 10:33 PM Christoph Hellwig wrote: 
> The ATTR_* flags have a long IRIX history, where they a userspace
> interface, the on-disk format and an internal interface.  We've split
> out the on-disk interface to the XFS_ATTR_* values, but despite (or
> because?) of that the flag have still been a mess.  Switch the
> internal interface to pass the on-disk XFS_ATTR_* flags for the
> namespace and the Linux XATTR_* flags for the actual flags instead.
> The ATTR_* values that are actually used are move to xfs_fs.h with a
> new XFS_IOC_* prefix to not conflict with the userspace version that
> has the same name and must have the same value.

The usage of various groups (XFS_IOC_ATTR_*, XFS_ATTR_* and XATTR_*) of xattr
flags looks consistent to me.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> 
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/libxfs/xfs_attr.c      | 16 ++++++-------
>  fs/xfs/libxfs/xfs_attr.h      | 22 +-----------------
>  fs/xfs/libxfs/xfs_attr_leaf.c | 14 +++++------
>  fs/xfs/libxfs/xfs_da_format.h | 12 ----------
>  fs/xfs/libxfs/xfs_fs.h        | 31 +++++++++++++-----------
>  fs/xfs/libxfs/xfs_types.h     |  3 ++-
>  fs/xfs/scrub/attr.c           |  5 +---
>  fs/xfs/xfs_acl.c              |  5 ++--
>  fs/xfs/xfs_ioctl.c            | 44 +++++++++++++++++++++++++----------
>  fs/xfs/xfs_iops.c             |  3 +--
>  fs/xfs/xfs_linux.h            |  1 +
>  fs/xfs/xfs_trace.h            | 35 +++++++++++++++++-----------
>  fs/xfs/xfs_xattr.c            | 18 +++++---------
>  13 files changed, 100 insertions(+), 109 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index 9c629c7c912d..d5c112b6dcdd 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -295,7 +295,7 @@ xfs_attr_set(
>  	struct xfs_inode	*dp = args->dp;
>  	struct xfs_mount	*mp = dp->i_mount;
>  	struct xfs_trans_res	tres;
> -	int			rsvd = (args->flags & ATTR_ROOT) != 0;
> +	bool			rsvd = (args->attr_namespace & XFS_ATTR_ROOT);
>  	int			error, local;
>  	unsigned int		total;
> 
> @@ -423,10 +423,10 @@ xfs_attr_shortform_addname(xfs_da_args_t *args)
>  	trace_xfs_attr_sf_addname(args);
> 
>  	retval = xfs_attr_shortform_lookup(args);
> -	if ((args->flags & ATTR_REPLACE) && retval == -ENOATTR)
> +	if ((args->attr_flags & XATTR_REPLACE) && retval == -ENOATTR)
>  		return retval;
>  	if (retval == -EEXIST) {
> -		if (args->flags & ATTR_CREATE)
> +		if (args->attr_flags & XATTR_CREATE)
>  			return retval;
>  		retval = xfs_attr_shortform_remove(args);
>  		if (retval)
> @@ -436,7 +436,7 @@ xfs_attr_shortform_addname(xfs_da_args_t *args)
>  		 * that the leaf format add routine won't trip over the attr
>  		 * not being around.
>  		 */
> -		args->flags &= ~ATTR_REPLACE;
> +		args->attr_flags &= ~XATTR_REPLACE;
>  	}
> 
>  	if (args->namelen >= XFS_ATTR_SF_ENTSIZE_MAX ||
> @@ -489,10 +489,10 @@ xfs_attr_leaf_addname(
>  	 * the given flags produce an error or call for an atomic rename.
>  	 */
>  	retval = xfs_attr3_leaf_lookup_int(bp, args);
> -	if ((args->flags & ATTR_REPLACE) && retval == -ENOATTR)
> +	if ((args->attr_flags & XATTR_REPLACE) && retval == -ENOATTR)
>  		goto out_brelse;
>  	if (retval == -EEXIST) {
> -		if (args->flags & ATTR_CREATE)	/* pure create op */
> +		if (args->attr_flags & XATTR_CREATE)	/* pure create op */
>  			goto out_brelse;
> 
>  		trace_xfs_attr_leaf_replace(args);
> @@ -763,10 +763,10 @@ xfs_attr_node_addname(
>  		goto out;
>  	blk = &state->path.blk[ state->path.active-1 ];
>  	ASSERT(blk->magic == XFS_ATTR_LEAF_MAGIC);
> -	if ((args->flags & ATTR_REPLACE) && retval == -ENOATTR)
> +	if ((args->attr_flags & XATTR_REPLACE) && retval == -ENOATTR)
>  		goto out;
>  	if (retval == -EEXIST) {
> -		if (args->flags & ATTR_CREATE)
> +		if (args->attr_flags & XATTR_CREATE)
>  			goto out;
> 
>  		trace_xfs_attr_node_replace(args);
> diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
> index 8d42f5782ff7..7a3525dff411 100644
> --- a/fs/xfs/libxfs/xfs_attr.h
> +++ b/fs/xfs/libxfs/xfs_attr.h
> @@ -21,26 +21,6 @@ struct xfs_attr_list_context;
>   * as possible so as to fit into the literal area of the inode.
>   */
> 
> -/*========================================================================
> - * External interfaces
> - *========================================================================*/
> -
> -
> -#define ATTR_DONTFOLLOW	0x0001	/* -- ignored, from IRIX -- */
> -#define ATTR_ROOT	0x0002	/* use attrs in root (trusted) namespace */
> -#define ATTR_TRUST	0x0004	/* -- unused, from IRIX -- */
> -#define ATTR_SECURE	0x0008	/* use attrs in security namespace */
> -#define ATTR_CREATE	0x0010	/* pure create: fail if attr already exists */
> -#define ATTR_REPLACE	0x0020	/* pure set: fail if attr does not exist */
> -
> -#define XFS_ATTR_FLAGS \
> -	{ ATTR_DONTFOLLOW, 	"DONTFOLLOW" }, \
> -	{ ATTR_ROOT,		"ROOT" }, \
> -	{ ATTR_TRUST,		"TRUST" }, \
> -	{ ATTR_SECURE,		"SECURE" }, \
> -	{ ATTR_CREATE,		"CREATE" }, \
> -	{ ATTR_REPLACE,		"REPLACE" }
> -
>  /*
>   * The maximum size (into the kernel or returned from the kernel) of an
>   * attribute value or the buffer used for an attr_list() call.  Larger
> @@ -87,7 +67,7 @@ struct xfs_attr_list_context {
>  	int			dupcnt;		/* count dup hashvals seen */
>  	int			bufsize;	/* total buffer size */
>  	int			firstu;		/* first used byte in buffer */
> -	int			flags;		/* from VOP call */
> +	unsigned int		attr_namespace;	/* XFS_ATTR_{ROOT,SECURE} */
>  	int			resynch;	/* T/F: resynch with cursor */
>  	put_listent_func_t	put_listent;	/* list output fmt function */
>  	int			index;		/* index into output buffer */
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
> index 8852754153ba..9081ba7af90a 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.c
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.c
> @@ -456,8 +456,7 @@ xfs_attr_match(
>  		return false;
>  	if (memcmp(args->name, name, namelen) != 0)
>  		return false;
> -	if (XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags) !=
> -	    XFS_ATTR_NSP_ONDISK(flags))
> +	if (args->attr_namespace != (flags & XFS_ATTR_NSP_ONDISK_MASK))
>  		return false;
>  	return true;
>  }
> @@ -697,7 +696,7 @@ xfs_attr_shortform_add(xfs_da_args_t *args, int forkoff)
> 
>  	sfe->namelen = args->namelen;
>  	sfe->valuelen = args->valuelen;
> -	sfe->flags = XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags);
> +	sfe->flags = args->attr_namespace;
>  	memcpy(sfe->nameval, args->name, args->namelen);
>  	memcpy(&sfe->nameval[args->namelen], args->value, args->valuelen);
>  	sf->hdr.count++;
> @@ -906,7 +905,7 @@ xfs_attr_shortform_to_leaf(
>  		nargs.valuelen = sfe->valuelen;
>  		nargs.hashval = xfs_da_hashname(sfe->nameval,
>  						sfe->namelen);
> -		nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(sfe->flags);
> +		nargs.attr_namespace = sfe->flags & XFS_ATTR_NSP_ONDISK_MASK;
>  		error = xfs_attr3_leaf_lookup_int(bp, &nargs); /* set a->index */
>  		ASSERT(error == -ENOATTR);
>  		error = xfs_attr3_leaf_add(bp, &nargs);
> @@ -1112,7 +1111,7 @@ xfs_attr3_leaf_to_shortform(
>  		nargs.value = &name_loc->nameval[nargs.namelen];
>  		nargs.valuelen = be16_to_cpu(name_loc->valuelen);
>  		nargs.hashval = be32_to_cpu(entry->hashval);
> -		nargs.flags = XFS_ATTR_NSP_ONDISK_TO_ARGS(entry->flags);
> +		nargs.attr_namespace = entry->flags & XFS_ATTR_NSP_ONDISK_MASK;
>  		xfs_attr_shortform_add(&nargs, forkoff);
>  	}
>  	error = 0;
> @@ -1437,8 +1436,9 @@ xfs_attr3_leaf_add_work(
>  	entry->nameidx = cpu_to_be16(ichdr->freemap[mapindex].base +
>  				     ichdr->freemap[mapindex].size);
>  	entry->hashval = cpu_to_be32(args->hashval);
> -	entry->flags = tmp ? XFS_ATTR_LOCAL : 0;
> -	entry->flags |= XFS_ATTR_NSP_ARGS_TO_ONDISK(args->flags);
> +	entry->flags = args->attr_namespace;
> +	if (tmp)
> +		entry->flags |= XFS_ATTR_LOCAL;
>  	if (args->op_flags & XFS_DA_OP_RENAME) {
>  		entry->flags |= XFS_ATTR_INCOMPLETE;
>  		if ((args->blkno2 == args->blkno) &&
> diff --git a/fs/xfs/libxfs/xfs_da_format.h b/fs/xfs/libxfs/xfs_da_format.h
> index 734837a9b51a..08c0a4d98b89 100644
> --- a/fs/xfs/libxfs/xfs_da_format.h
> +++ b/fs/xfs/libxfs/xfs_da_format.h
> @@ -692,19 +692,7 @@ struct xfs_attr3_leafblock {
>  #define XFS_ATTR_ROOT		(1 << XFS_ATTR_ROOT_BIT)
>  #define XFS_ATTR_SECURE		(1 << XFS_ATTR_SECURE_BIT)
>  #define XFS_ATTR_INCOMPLETE	(1 << XFS_ATTR_INCOMPLETE_BIT)
> -
> -/*
> - * Conversion macros for converting namespace bits from argument flags
> - * to ondisk flags.
> - */
> -#define XFS_ATTR_NSP_ARGS_MASK		(ATTR_ROOT | ATTR_SECURE)
>  #define XFS_ATTR_NSP_ONDISK_MASK	(XFS_ATTR_ROOT | XFS_ATTR_SECURE)
> -#define XFS_ATTR_NSP_ONDISK(flags)	((flags) & XFS_ATTR_NSP_ONDISK_MASK)
> -#define XFS_ATTR_NSP_ARGS(flags)	((flags) & XFS_ATTR_NSP_ARGS_MASK)
> -#define XFS_ATTR_NSP_ARGS_TO_ONDISK(x)	(((x) & ATTR_ROOT ? XFS_ATTR_ROOT : 0) |\
> -					 ((x) & ATTR_SECURE ? XFS_ATTR_SECURE : 0))
> -#define XFS_ATTR_NSP_ONDISK_TO_ARGS(x)	(((x) & XFS_ATTR_ROOT ? ATTR_ROOT : 0) |\
> -					 ((x) & XFS_ATTR_SECURE ? ATTR_SECURE : 0))
> 
>  /*
>   * Alignment for namelist and valuelist entries (since they are mixed
> diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
> index 2c2b6e2b58f4..b22f73fccf25 100644
> --- a/fs/xfs/libxfs/xfs_fs.h
> +++ b/fs/xfs/libxfs/xfs_fs.h
> @@ -568,17 +568,27 @@ typedef struct xfs_fsop_setdm_handlereq {
>  	struct fsdmidata		__user *data;	/* DMAPI data	*/
>  } xfs_fsop_setdm_handlereq_t;
> 
> +/*
> + * Flags passed in xfs_attr_multiop.am_flags for the attr ioctl interface.
> + * NOTE: Must match the values declared in libattr without the XFS_IOC_ prefix.
> + */
> +#define XFS_IOC_ATTR_ROOT	0x0002	/* use attrs in root namespace */
> +#define XFS_IOC_ATTR_SECURE	0x0008	/* use attrs in security namespace */
> +#define XFS_IOC_ATTR_CREATE	0x0010	/* fail if attr already exists */
> +#define XFS_IOC_ATTR_REPLACE	0x0020	/* fail if attr does not exist */
> +
>  typedef struct xfs_attrlist_cursor {
>  	__u32		opaque[4];
>  } xfs_attrlist_cursor_t;
> 
>  /*
> - * Define how lists of attribute names are returned to the user from
> - * the attr_list() call.  A large, 32bit aligned, buffer is passed in
> - * along with its size.  We put an array of offsets at the top that each
> - * reference an attrlist_ent_t and pack the attrlist_ent_t's at the bottom.
> + * Define how lists of attribute names are returned to userspace from the
> + * XFS_IOC_ATTRLIST_BY_HANDLE ioctl.  struct xfs_attrlist is the header at the
> + * beginning of the returned buffer, and a each entry in al_offset contains the
> + * relative offset of an xfs_attrlist_ent containing the actual entry.
>   *
> - * NOTE: struct xfs_attrlist must match struct attrlist defined in libattr.
> + * NOTE: struct xfs_attrlist must match struct attrlist defined in libattr, and
> + * struct xfs_attrlist_ent must match struct attrlist_ent defined in libattr.
>   */
>  struct xfs_attrlist {
>  	__s32	al_count;	/* number of entries in attrlist */
> @@ -586,13 +596,6 @@ struct xfs_attrlist {
>  	__s32	al_offset[1];	/* byte offsets of attrs [var-sized] */
>  };
> 
> -/*
> - * Show the interesting info about one attribute.  This is what the
> - * al_offset[i] entry points to.
> - *
> - * NOTE: struct xfs_attrlist_ent must match struct attrlist_ent defined in
> - * libattr.
> - */
>  struct xfs_attrlist_ent {	/* data from attr_list() */
>  	__u32	a_valuelen;	/* number bytes in value of attr */
>  	char	a_name[1];	/* attr name (NULL terminated) */
> @@ -603,7 +606,7 @@ typedef struct xfs_fsop_attrlist_handlereq {
>  	struct xfs_attrlist_cursor	pos; /* opaque cookie, list offset */
>  	__u32				flags;	/* which namespace to use */
>  	__u32				buflen;	/* length of buffer supplied */
> -	void				__user *buffer;	/* returned names */
> +	struct xfs_attrlist __user	*buffer;/* returned names */
>  } xfs_fsop_attrlist_handlereq_t;
> 
>  typedef struct xfs_attr_multiop {
> @@ -615,7 +618,7 @@ typedef struct xfs_attr_multiop {
>  	void		__user *am_attrname;
>  	void		__user *am_attrvalue;
>  	__u32		am_length;
> -	__u32		am_flags;
> +	__u32		am_flags; /* XFS_IOC_ATTR_* */
>  } xfs_attr_multiop_t;
> 
>  typedef struct xfs_fsop_attrmulti_handlereq {
> diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
> index 1594325d7742..2b02f854ebaf 100644
> --- a/fs/xfs/libxfs/xfs_types.h
> +++ b/fs/xfs/libxfs/xfs_types.h
> @@ -194,7 +194,8 @@ typedef struct xfs_da_args {
>  	uint8_t		filetype;	/* filetype of inode for directories */
>  	void		*value;		/* set of bytes (maybe contain NULLs) */
>  	int		valuelen;	/* length of value */
> -	int		flags;		/* argument flags (eg: ATTR_NOCREATE) */
> +	unsigned int	attr_namespace;	/* XFS_ATTR_{ROOT,SECURE} */
> +	unsigned int	attr_flags;	/* XATTR_{CREATE,REPLACE} */
>  	xfs_dahash_t	hashval;	/* hash value of name */
>  	xfs_ino_t	inumber;	/* input/output inode number */
>  	struct xfs_inode *dp;		/* directory inode to manipulate */
> diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
> index 9e336d797616..d84237af5455 100644
> --- a/fs/xfs/scrub/attr.c
> +++ b/fs/xfs/scrub/attr.c
> @@ -148,10 +148,7 @@ xchk_xattr_listent(
>  	}
> 
>  	args.op_flags = XFS_DA_OP_NOTIME;
> -	if (flags & XFS_ATTR_ROOT)
> -		args.flags |= ATTR_ROOT;
> -	else if (flags & XFS_ATTR_SECURE)
> -		args.flags |= ATTR_SECURE;
> +	args.attr_namespace = flags & XFS_ATTR_NSP_ONDISK_MASK;
>  	args.geo = context->dp->i_mount->m_attr_geo;
>  	args.whichfork = XFS_ATTR_FORK;
>  	args.dp = context->dp;
> diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
> index e9a48d718c3a..6690906cd16f 100644
> --- a/fs/xfs/xfs_acl.c
> +++ b/fs/xfs/xfs_acl.c
> @@ -14,6 +14,7 @@
>  #include "xfs_trace.h"
>  #include "xfs_error.h"
>  #include "xfs_acl.h"
> +#include "xfs_da_format.h"
> 
>  #include <linux/posix_acl_xattr.h>
> 
> @@ -125,7 +126,7 @@ xfs_get_acl(struct inode *inode, int type)
>  	struct posix_acl	*acl = NULL;
>  	struct xfs_da_args	args = {
>  		.dp		= ip,
> -		.flags		= ATTR_ROOT,
> +		.attr_namespace	= XFS_ATTR_ROOT,
>  		.valuelen	= XFS_ACL_MAX_SIZE(mp),
>  	};
>  	int			error;
> @@ -166,7 +167,7 @@ __xfs_set_acl(struct inode *inode, struct posix_acl *acl, int type)
>  	struct xfs_inode	*ip = XFS_I(inode);
>  	struct xfs_da_args	args = {
>  		.dp		= ip,
> -		.flags		= ATTR_ROOT,
> +		.attr_namespace	= XFS_ATTR_ROOT,
>  	};
>  	int			error;
> 
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index 4f26c3962215..d2318857497b 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -319,11 +319,7 @@ xfs_ioc_attr_put_listent(
>  	/*
>  	 * Only list entries in the right namespace.
>  	 */
> -	if (((context->flags & ATTR_SECURE) == 0) !=
> -	    ((flags & XFS_ATTR_SECURE) == 0))
> -		return;
> -	if (((context->flags & ATTR_ROOT) == 0) !=
> -	    ((flags & XFS_ATTR_ROOT) == 0))
> +	if (context->attr_namespace != (flags & XFS_ATTR_NSP_ONDISK_MASK))
>  		return;
> 
>  	arraytop = sizeof(*alist) +
> @@ -348,6 +344,28 @@ xfs_ioc_attr_put_listent(
>  	trace_xfs_attr_list_add(context);
>  }
> 
> +static unsigned int
> +xfs_attr_namespace(
> +	u32			ioc_flags)
> +{
> +	if (ioc_flags & XFS_IOC_ATTR_ROOT)
> +		return XFS_ATTR_ROOT;
> +	if (ioc_flags & XFS_IOC_ATTR_SECURE)
> +		return XFS_ATTR_SECURE;
> +	return 0;
> +}
> +
> +static unsigned int
> +xfs_attr_flags(
> +	u32			ioc_flags)
> +{
> +	if (ioc_flags & XFS_IOC_ATTR_CREATE)
> +		return XATTR_CREATE;
> +	if (ioc_flags & XFS_IOC_ATTR_REPLACE)
> +		return XATTR_REPLACE;
> +	return 0;
> +}
> +
>  int
>  xfs_ioc_attr_list(
>  	struct xfs_inode		*dp,
> @@ -369,9 +387,9 @@ xfs_ioc_attr_list(
>  	/*
>  	 * Reject flags, only allow namespaces.
>  	 */
> -	if (flags & ~(ATTR_ROOT | ATTR_SECURE))
> +	if (flags & ~(XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE))
>  		return -EINVAL;
> -	if (flags == (ATTR_ROOT | ATTR_SECURE))
> +	if (flags == (XFS_IOC_ATTR_ROOT | XFS_IOC_ATTR_SECURE))
>  		return -EINVAL;
> 
>  	/*
> @@ -396,7 +414,7 @@ xfs_ioc_attr_list(
>  	context.dp = dp;
>  	context.cursor = &cursor;
>  	context.resynch = 1;
> -	context.flags = flags;
> +	context.attr_namespace = xfs_attr_namespace(flags);
>  	context.buffer = buffer;
>  	context.bufsize = (bufsize & ~(sizeof(int)-1));  /* align */
>  	context.firstu = context.bufsize;
> @@ -453,7 +471,8 @@ xfs_attrmulti_attr_get(
>  {
>  	struct xfs_da_args	args = {
>  		.dp		= XFS_I(inode),
> -		.flags		= flags,
> +		.attr_namespace	= xfs_attr_namespace(flags),
> +		.attr_flags	= xfs_attr_flags(flags),
>  		.name		= name,
>  		.namelen	= strlen(name),
>  		.valuelen	= *len,
> @@ -490,7 +509,8 @@ xfs_attrmulti_attr_set(
>  {
>  	struct xfs_da_args	args = {
>  		.dp		= XFS_I(inode),
> -		.flags		= flags,
> +		.attr_namespace	= xfs_attr_namespace(flags),
> +		.attr_flags	= xfs_attr_flags(flags),
>  		.name		= name,
>  		.namelen	= strlen(name),
>  	};
> @@ -509,7 +529,7 @@ xfs_attrmulti_attr_set(
>  	}
> 
>  	error = xfs_attr_set(&args);
> -	if (!error && (flags & ATTR_ROOT))
> +	if (!error && (flags & XFS_IOC_ATTR_ROOT))
>  		xfs_forget_acl(inode, name);
>  	kfree(args.value);
>  	return error;
> @@ -528,7 +548,7 @@ xfs_ioc_attrmulti_one(
>  	unsigned char		*name;
>  	int			error;
> 
> -	if ((flags & ATTR_ROOT) && (flags & ATTR_SECURE))
> +	if ((flags & XFS_IOC_ATTR_ROOT) && (flags & XFS_IOC_ATTR_SECURE))
>  		return -EINVAL;
> 
>  	name = strndup_user(uname, MAXNAMELEN);
> diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
> index 94cd4254656c..8b1a3e7d83e6 100644
> --- a/fs/xfs/xfs_iops.c
> +++ b/fs/xfs/xfs_iops.c
> @@ -22,7 +22,6 @@
>  #include "xfs_iomap.h"
>  #include "xfs_error.h"
> 
> -#include <linux/xattr.h>
>  #include <linux/posix_acl.h>
>  #include <linux/security.h>
>  #include <linux/iversion.h>
> @@ -52,7 +51,7 @@ xfs_initxattrs(
>  	for (xattr = xattr_array; xattr->name != NULL; xattr++) {
>  		struct xfs_da_args	args = {
>  			.dp		= ip,
> -			.flags		= ATTR_SECURE,
> +			.attr_namespace	= XFS_ATTR_SECURE,
>  			.name		= xattr->name,
>  			.namelen	= strlen(xattr->name),
>  			.value		= xattr->value,
> diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h
> index 8738bb03f253..8c0070a797de 100644
> --- a/fs/xfs/xfs_linux.h
> +++ b/fs/xfs/xfs_linux.h
> @@ -60,6 +60,7 @@ typedef __u32			xfs_nlink_t;
>  #include <linux/list_sort.h>
>  #include <linux/ratelimit.h>
>  #include <linux/rhashtable.h>
> +#include <linux/xattr.h>
> 
>  #include <asm/page.h>
>  #include <asm/div64.h>
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index 8358a92987f9..a064b1523fa5 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -36,6 +36,10 @@ struct xfs_owner_info;
>  struct xfs_trans_res;
>  struct xfs_inobt_rec_incore;
> 
> +#define XFS_ATTR_NSP_FLAGS \
> +	{ XFS_ATTR_ROOT,	"ROOT" }, \
> +	{ XFS_ATTR_SECURE,	"SECURE" }
> +
>  DECLARE_EVENT_CLASS(xfs_attr_list_class,
>  	TP_PROTO(struct xfs_attr_list_context *ctx),
>  	TP_ARGS(ctx),
> @@ -50,7 +54,7 @@ DECLARE_EVENT_CLASS(xfs_attr_list_class,
>  		__field(int, count)
>  		__field(int, firstu)
>  		__field(int, dupcnt)
> -		__field(int, flags)
> +		__field(int, attr_namespace)
>  	),
>  	TP_fast_assign(
>  		__entry->dev = VFS_I(ctx->dp)->i_sb->s_dev;
> @@ -62,10 +66,10 @@ DECLARE_EVENT_CLASS(xfs_attr_list_class,
>  		__entry->bufsize = ctx->bufsize;
>  		__entry->count = ctx->count;
>  		__entry->firstu = ctx->firstu;
> -		__entry->flags = ctx->flags;
> +		__entry->attr_namespace = ctx->attr_namespace;
>  	),
>  	TP_printk("dev %d:%d ino 0x%llx cursor h/b/o 0x%x/0x%x/%u dupcnt %u "
> -		  "buffer %p size %u count %u firstu %u flags %d %s",
> +		  "buffer %p size %u count %u firstu %u namespace %d %s",
>  		  MAJOR(__entry->dev), MINOR(__entry->dev),
>  		   __entry->ino,
>  		   __entry->hashval,
> @@ -76,8 +80,9 @@ DECLARE_EVENT_CLASS(xfs_attr_list_class,
>  		   __entry->bufsize,
>  		   __entry->count,
>  		   __entry->firstu,
> -		   __entry->flags,
> -		   __print_flags(__entry->flags, "|", XFS_ATTR_FLAGS)
> +		   __entry->attr_namespace,
> +		   __print_flags(__entry->attr_namespace, "|",
> +				 XFS_ATTR_NSP_FLAGS)
>  	)
>  )
> 
> @@ -174,7 +179,7 @@ TRACE_EVENT(xfs_attr_list_node_descend,
>  		__field(int, count)
>  		__field(int, firstu)
>  		__field(int, dupcnt)
> -		__field(int, flags)
> +		__field(int, attr_namespace)
>  		__field(u32, bt_hashval)
>  		__field(u32, bt_before)
>  	),
> @@ -188,12 +193,12 @@ TRACE_EVENT(xfs_attr_list_node_descend,
>  		__entry->bufsize = ctx->bufsize;
>  		__entry->count = ctx->count;
>  		__entry->firstu = ctx->firstu;
> -		__entry->flags = ctx->flags;
> +		__entry->attr_namespace = ctx->attr_namespace;
>  		__entry->bt_hashval = be32_to_cpu(btree->hashval);
>  		__entry->bt_before = be32_to_cpu(btree->before);
>  	),
>  	TP_printk("dev %d:%d ino 0x%llx cursor h/b/o 0x%x/0x%x/%u dupcnt %u "
> -		  "buffer %p size %u count %u firstu %u flags %d %s "
> +		  "buffer %p size %u count %u firstu %u namespae %d %s "
>  		  "node hashval %u, node before %u",
>  		  MAJOR(__entry->dev), MINOR(__entry->dev),
>  		   __entry->ino,
> @@ -205,8 +210,9 @@ TRACE_EVENT(xfs_attr_list_node_descend,
>  		   __entry->bufsize,
>  		   __entry->count,
>  		   __entry->firstu,
> -		   __entry->flags,
> -		   __print_flags(__entry->flags, "|", XFS_ATTR_FLAGS),
> +		   __entry->attr_namespace,
> +		   __print_flags(__entry->attr_namespace, "|",
> +				 XFS_ATTR_NSP_FLAGS),
>  		   __entry->bt_hashval,
>  		   __entry->bt_before)
>  );
> @@ -1701,7 +1707,7 @@ DECLARE_EVENT_CLASS(xfs_attr_class,
>  		__field(int, namelen)
>  		__field(int, valuelen)
>  		__field(xfs_dahash_t, hashval)
> -		__field(int, flags)
> +		__field(int, attr_namespace)
>  		__field(int, op_flags)
>  	),
>  	TP_fast_assign(
> @@ -1712,11 +1718,11 @@ DECLARE_EVENT_CLASS(xfs_attr_class,
>  		__entry->namelen = args->namelen;
>  		__entry->valuelen = args->valuelen;
>  		__entry->hashval = args->hashval;
> -		__entry->flags = args->flags;
> +		__entry->attr_namespace = args->attr_namespace;
>  		__entry->op_flags = args->op_flags;
>  	),
>  	TP_printk("dev %d:%d ino 0x%llx name %.*s namelen %d valuelen %d "
> -		  "hashval 0x%x flags %s op_flags %s",
> +		  "hashval 0x%x namespace %s op_flags %s",
>  		  MAJOR(__entry->dev), MINOR(__entry->dev),
>  		  __entry->ino,
>  		  __entry->namelen,
> @@ -1724,7 +1730,8 @@ DECLARE_EVENT_CLASS(xfs_attr_class,
>  		  __entry->namelen,
>  		  __entry->valuelen,
>  		  __entry->hashval,
> -		  __print_flags(__entry->flags, "|", XFS_ATTR_FLAGS),
> +		  __print_flags(__entry->attr_namespace, "|",
> +				XFS_ATTR_NSP_FLAGS),
>  		  __print_flags(__entry->op_flags, "|", XFS_DA_OP_FLAGS))
>  )
> 
> diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
> index 863e9fdec162..1d2c8615b335 100644
> --- a/fs/xfs/xfs_xattr.c
> +++ b/fs/xfs/xfs_xattr.c
> @@ -14,7 +14,6 @@
>  #include "xfs_acl.h"
> 
>  #include <linux/posix_acl_xattr.h>
> -#include <linux/xattr.h>
> 
> 
>  static int
> @@ -23,7 +22,7 @@ xfs_xattr_get(const struct xattr_handler *handler, struct dentry *unused,
>  {
>  	struct xfs_da_args	args = {
>  		.dp		= XFS_I(inode),
> -		.flags		= handler->flags,
> +		.attr_namespace	= handler->flags,
>  		.name		= name,
>  		.namelen	= strlen(name),
>  		.value		= value,
> @@ -44,7 +43,8 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
>  {
>  	struct xfs_da_args	args = {
>  		.dp		= XFS_I(inode),
> -		.flags		= handler->flags,
> +		.attr_namespace	= handler->flags,
> +		.attr_flags	= flags,
>  		.name		= name,
>  		.namelen	= strlen(name),
>  		.value		= (unsigned char *)value,
> @@ -52,14 +52,8 @@ xfs_xattr_set(const struct xattr_handler *handler, struct dentry *unused,
>  	};
>  	int			error;
> 
> -	/* Convert Linux syscall to XFS internal ATTR flags */
> -	if (flags & XATTR_CREATE)
> -		args.flags |= ATTR_CREATE;
> -	if (flags & XATTR_REPLACE)
> -		args.flags |= ATTR_REPLACE;
> -
>  	error = xfs_attr_set(&args);
> -	if (!error && (flags & ATTR_ROOT))
> +	if (!error && (handler->flags & XFS_ATTR_ROOT))
>  		xfs_forget_acl(inode, name);
>  	return error;
>  }
> @@ -73,14 +67,14 @@ static const struct xattr_handler xfs_xattr_user_handler = {
> 
>  static const struct xattr_handler xfs_xattr_trusted_handler = {
>  	.prefix	= XATTR_TRUSTED_PREFIX,
> -	.flags	= ATTR_ROOT,
> +	.flags	= XFS_ATTR_ROOT,
>  	.get	= xfs_xattr_get,
>  	.set	= xfs_xattr_set,
>  };
> 
>  static const struct xattr_handler xfs_xattr_security_handler = {
>  	.prefix	= XATTR_SECURITY_PREFIX,
> -	.flags	= ATTR_SECURE,
> +	.flags	= XFS_ATTR_SECURE,
>  	.get	= xfs_xattr_get,
>  	.set	= xfs_xattr_set,
>  };
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 29/30] xfs: remove XFS_DA_OP_INCOMPLETE
  2020-01-29 17:03 ` [PATCH 29/30] xfs: remove XFS_DA_OP_INCOMPLETE Christoph Hellwig
@ 2020-02-10 13:59   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-10 13:59 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins

On Wednesday, January 29, 2020 10:33 PM Christoph Hellwig wrote: 
> Now that we use the on-disk flags field also for the interface to the
> lower level attr routines we can use the XFS_ATTR_INCOMPLETE definition
> from the on-disk format directly instead.
>

The combination of args->attr_namespace and XFS_ATTR_INCOMPLETE correctly
replaces that of args->op_flags and XFS_DA_OP_INCOMPLETE.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
>  fs/xfs/libxfs/xfs_attr.c      |  2 +-
>  fs/xfs/libxfs/xfs_attr_leaf.c | 15 ++++++---------
>  fs/xfs/libxfs/xfs_types.h     |  6 ++----
>  3 files changed, 9 insertions(+), 14 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.c b/fs/xfs/libxfs/xfs_attr.c
> index d5c112b6dcdd..23e0d8ce39f8 100644
> --- a/fs/xfs/libxfs/xfs_attr.c
> +++ b/fs/xfs/libxfs/xfs_attr.c
> @@ -898,7 +898,7 @@ xfs_attr_node_addname(
>  		 * The INCOMPLETE flag means that we will find the "old"
>  		 * attr, not the "new" one.
>  		 */
> -		args->op_flags |= XFS_DA_OP_INCOMPLETE;
> +		args->attr_namespace |= XFS_ATTR_INCOMPLETE;
>  		state = xfs_da_state_alloc();
>  		state->args = args;
>  		state->mp = mp;
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c
> index 9081ba7af90a..fae322105457 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.c
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.c
> @@ -456,7 +456,12 @@ xfs_attr_match(
>  		return false;
>  	if (memcmp(args->name, name, namelen) != 0)
>  		return false;
> -	if (args->attr_namespace != (flags & XFS_ATTR_NSP_ONDISK_MASK))
> +	/*
> +	 * If we are looking for incomplete entries, show only those, else only
> +	 * show complete entries.
> +	 */
> +	if (args->attr_namespace !=
> +	    (flags & (XFS_ATTR_NSP_ONDISK_MASK | XFS_ATTR_INCOMPLETE)))
>  		return false;
>  	return true;
>  }
> @@ -2387,14 +2392,6 @@ xfs_attr3_leaf_lookup_int(
>  /*
>   * GROT: Add code to remove incomplete entries.
>   */
> -		/*
> -		 * If we are looking for INCOMPLETE entries, show only those.
> -		 * If we are looking for complete entries, show only those.
> -		 */
> -		if (!!(args->op_flags & XFS_DA_OP_INCOMPLETE) !=
> -		    !!(entry->flags & XFS_ATTR_INCOMPLETE)) {
> -			continue;
> -		}
>  		if (entry->flags & XFS_ATTR_LOCAL) {
>  			name_loc = xfs_attr3_leaf_name_local(leaf, probe);
>  			if (!xfs_attr_match(args, name_loc->namelen,
> diff --git a/fs/xfs/libxfs/xfs_types.h b/fs/xfs/libxfs/xfs_types.h
> index 2b02f854ebaf..a2005e2d3baa 100644
> --- a/fs/xfs/libxfs/xfs_types.h
> +++ b/fs/xfs/libxfs/xfs_types.h
> @@ -194,7 +194,7 @@ typedef struct xfs_da_args {
>  	uint8_t		filetype;	/* filetype of inode for directories */
>  	void		*value;		/* set of bytes (maybe contain NULLs) */
>  	int		valuelen;	/* length of value */
> -	unsigned int	attr_namespace;	/* XFS_ATTR_{ROOT,SECURE} */
> +	unsigned int	attr_namespace;	/* XFS_ATTR_{ROOT,SECURE,INCOMPLETE} */
>  	unsigned int	attr_flags;	/* XATTR_{CREATE,REPLACE} */
>  	xfs_dahash_t	hashval;	/* hash value of name */
>  	xfs_ino_t	inumber;	/* input/output inode number */
> @@ -225,7 +225,6 @@ typedef struct xfs_da_args {
>  #define XFS_DA_OP_OKNOENT	0x0008	/* lookup/add op, ENOENT ok, else die */
>  #define XFS_DA_OP_CILOOKUP	0x0010	/* lookup to return CI name if found */
>  #define XFS_DA_OP_NOTIME	0x0020	/* don't update inode timestamps */
> -#define XFS_DA_OP_INCOMPLETE	0x0040	/* lookup INCOMPLETE attr keys */
> 
>  #define XFS_DA_OP_FLAGS \
>  	{ XFS_DA_OP_JUSTCHECK,	"JUSTCHECK" }, \
> @@ -233,8 +232,7 @@ typedef struct xfs_da_args {
>  	{ XFS_DA_OP_ADDNAME,	"ADDNAME" }, \
>  	{ XFS_DA_OP_OKNOENT,	"OKNOENT" }, \
>  	{ XFS_DA_OP_CILOOKUP,	"CILOOKUP" }, \
> -	{ XFS_DA_OP_NOTIME,	"NOTIME" }, \
> -	{ XFS_DA_OP_INCOMPLETE,	"INCOMPLETE" }
> +	{ XFS_DA_OP_NOTIME,	"NOTIME" }
> 
>  /*
>   * Type verifier functions
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 30/30] xfs: embedded the attrlist cursor into struct xfs_attr_list_context
  2020-01-29 17:03 ` [PATCH 30/30] xfs: embedded the attrlist cursor into struct xfs_attr_list_context Christoph Hellwig
@ 2020-02-10 14:57   ` Chandan Rajendra
  0 siblings, 0 replies; 60+ messages in thread
From: Chandan Rajendra @ 2020-02-10 14:57 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-xfs, Allison Collins, Darrick J . Wong

On Wednesday, January 29, 2020 10:33 PM Christoph Hellwig wrote: 
> The attrlist cursor only exists as part of an attr list context, so
> embedd the structure instead of pointing to it.  Also give it a proper
> xfs_ prefix and remove the obsolete typedef.
>

The changes look good to me.

Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>

> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
> ---
>  fs/xfs/libxfs/xfs_attr.h      |  6 +++---
>  fs/xfs/libxfs/xfs_attr_leaf.h |  1 -
>  fs/xfs/scrub/attr.c           |  2 --
>  fs/xfs/xfs_attr_list.c        | 19 ++++++-------------
>  fs/xfs/xfs_ioctl.c            | 16 +++++++---------
>  fs/xfs/xfs_ioctl.h            |  1 -
>  fs/xfs/xfs_trace.h            | 12 ++++++------
>  fs/xfs/xfs_xattr.c            |  2 --
>  8 files changed, 22 insertions(+), 37 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_attr.h b/fs/xfs/libxfs/xfs_attr.h
> index 7a3525dff411..861c81f9bb91 100644
> --- a/fs/xfs/libxfs/xfs_attr.h
> +++ b/fs/xfs/libxfs/xfs_attr.h
> @@ -31,14 +31,14 @@ struct xfs_attr_list_context;
>  /*
>   * Kernel-internal version of the attrlist cursor.
>   */
> -typedef struct attrlist_cursor_kern {
> +struct xfs_attrlist_cursor_kern {
>  	__u32	hashval;	/* hash value of next entry to add */
>  	__u32	blkno;		/* block containing entry (suggestion) */
>  	__u32	offset;		/* offset in list of equal-hashvals */
>  	__u16	pad1;		/* padding to match user-level */
>  	__u8	pad2;		/* padding to match user-level */
>  	__u8	initted;	/* T/F: cursor has been initialized */
> -} attrlist_cursor_kern_t;
> +};
> 
> 
>  /*========================================================================
> @@ -53,7 +53,7 @@ typedef void (*put_listent_func_t)(struct xfs_attr_list_context *, int,
>  struct xfs_attr_list_context {
>  	struct xfs_trans	*tp;
>  	struct xfs_inode	*dp;		/* inode */
> -	struct attrlist_cursor_kern *cursor;	/* position in list */
> +	struct xfs_attrlist_cursor_kern cursor;	/* position in list */
>  	void			*buffer;	/* output buffer */
> 
>  	/*
> diff --git a/fs/xfs/libxfs/xfs_attr_leaf.h b/fs/xfs/libxfs/xfs_attr_leaf.h
> index 73615b1dd1a8..6dd2d937a42a 100644
> --- a/fs/xfs/libxfs/xfs_attr_leaf.h
> +++ b/fs/xfs/libxfs/xfs_attr_leaf.h
> @@ -8,7 +8,6 @@
>  #define	__XFS_ATTR_LEAF_H__
> 
>  struct attrlist;
> -struct attrlist_cursor_kern;
>  struct xfs_attr_list_context;
>  struct xfs_da_args;
>  struct xfs_da_state;
> diff --git a/fs/xfs/scrub/attr.c b/fs/xfs/scrub/attr.c
> index d84237af5455..6dd3f5f78251 100644
> --- a/fs/xfs/scrub/attr.c
> +++ b/fs/xfs/scrub/attr.c
> @@ -471,7 +471,6 @@ xchk_xattr(
>  	struct xfs_scrub		*sc)
>  {
>  	struct xchk_xattr		sx;
> -	struct attrlist_cursor_kern	cursor = { 0 };
>  	xfs_dablk_t			last_checked = -1U;
>  	int				error = 0;
> 
> @@ -490,7 +489,6 @@ xchk_xattr(
> 
>  	/* Check that every attr key can also be looked up by hash. */
>  	sx.context.dp = sc->ip;
> -	sx.context.cursor = &cursor;
>  	sx.context.resynch = 1;
>  	sx.context.put_listent = xchk_xattr_listent;
>  	sx.context.tp = sc->tp;
> diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c
> index ea79219859a0..6af71edaa30e 100644
> --- a/fs/xfs/xfs_attr_list.c
> +++ b/fs/xfs/xfs_attr_list.c
> @@ -52,24 +52,19 @@ static int
>  xfs_attr_shortform_list(
>  	struct xfs_attr_list_context	*context)
>  {
> -	struct attrlist_cursor_kern	*cursor;
> +	struct xfs_attrlist_cursor_kern	*cursor = &context->cursor;
> +	struct xfs_inode		*dp = context->dp;
>  	struct xfs_attr_sf_sort		*sbuf, *sbp;
>  	struct xfs_attr_shortform	*sf;
>  	struct xfs_attr_sf_entry	*sfe;
> -	struct xfs_inode		*dp;
>  	int				sbsize, nsbuf, count, i;
>  	int				error = 0;
> 
> -	ASSERT(context != NULL);
> -	dp = context->dp;
> -	ASSERT(dp != NULL);
>  	ASSERT(dp->i_afp != NULL);
>  	sf = (xfs_attr_shortform_t *)dp->i_afp->if_u1.if_data;
>  	ASSERT(sf != NULL);
>  	if (!sf->hdr.count)
>  		return 0;
> -	cursor = context->cursor;
> -	ASSERT(cursor != NULL);
> 
>  	trace_xfs_attr_list_sf(context);
> 
> @@ -205,7 +200,7 @@ xfs_attr_shortform_list(
>  STATIC int
>  xfs_attr_node_list_lookup(
>  	struct xfs_attr_list_context	*context,
> -	struct attrlist_cursor_kern	*cursor,
> +	struct xfs_attrlist_cursor_kern	*cursor,
>  	struct xfs_buf			**pbp)
>  {
>  	struct xfs_da3_icnode_hdr	nodehdr;
> @@ -288,8 +283,8 @@ STATIC int
>  xfs_attr_node_list(
>  	struct xfs_attr_list_context	*context)
>  {
> +	struct xfs_attrlist_cursor_kern	*cursor = &context->cursor;
>  	struct xfs_attr3_icleaf_hdr	leafhdr;
> -	struct attrlist_cursor_kern	*cursor;
>  	struct xfs_attr_leafblock	*leaf;
>  	struct xfs_da_intnode		*node;
>  	struct xfs_buf			*bp;
> @@ -299,7 +294,6 @@ xfs_attr_node_list(
> 
>  	trace_xfs_attr_node_list(context);
> 
> -	cursor = context->cursor;
>  	cursor->initted = 1;
> 
>  	/*
> @@ -394,7 +388,7 @@ xfs_attr3_leaf_list_int(
>  	struct xfs_buf			*bp,
>  	struct xfs_attr_list_context	*context)
>  {
> -	struct attrlist_cursor_kern	*cursor;
> +	struct xfs_attrlist_cursor_kern	*cursor = &context->cursor;
>  	struct xfs_attr_leafblock	*leaf;
>  	struct xfs_attr3_icleaf_hdr	ichdr;
>  	struct xfs_attr_leaf_entry	*entries;
> @@ -408,7 +402,6 @@ xfs_attr3_leaf_list_int(
>  	xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf);
>  	entries = xfs_attr3_leaf_entryp(leaf);
> 
> -	cursor = context->cursor;
>  	cursor->initted = 1;
> 
>  	/*
> @@ -496,7 +489,7 @@ xfs_attr_leaf_list(
> 
>  	trace_xfs_attr_leaf_list(context);
> 
> -	context->cursor->blkno = 0;
> +	context->cursor.blkno = 0;
>  	error = xfs_attr3_leaf_read(context->tp, context->dp, 0, &bp);
>  	if (error)
>  		return error;
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index d2318857497b..2e8e86d5c01c 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -374,8 +374,7 @@ xfs_ioc_attr_list(
>  	int				flags,
>  	struct xfs_attrlist_cursor __user *ucursor)
>  {
> -	struct xfs_attr_list_context	context;
> -	struct attrlist_cursor_kern	cursor;
> +	struct xfs_attr_list_context	context = { 0 };
>  	struct xfs_attrlist		*alist;
>  	void				*buffer;
>  	int				error;
> @@ -395,12 +394,13 @@ xfs_ioc_attr_list(
>  	/*
>  	 * Validate the cursor.
>  	 */
> -	if (copy_from_user(&cursor, ucursor, sizeof(cursor)))
> +	if (copy_from_user(&context.cursor, ucursor, sizeof(context.cursor)))
>  		return -EFAULT;
> -	if (cursor.pad1 || cursor.pad2)
> +	if (context.cursor.pad1 || context.cursor.pad2)
>  		return -EINVAL;
> -	if ((cursor.initted == 0) &&
> -	    (cursor.hashval || cursor.blkno || cursor.offset))
> +	if (!context.cursor.initted &&
> +	    (context.cursor.hashval || context.cursor.blkno ||
> +	     context.cursor.offset))
>  		return -EINVAL;
> 
>  	buffer = kmem_zalloc_large(bufsize, 0);
> @@ -410,9 +410,7 @@ xfs_ioc_attr_list(
>  	/*
>  	 * Initialize the output buffer.
>  	 */
> -	memset(&context, 0, sizeof(context));
>  	context.dp = dp;
> -	context.cursor = &cursor;
>  	context.resynch = 1;
>  	context.attr_namespace = xfs_attr_namespace(flags);
>  	context.buffer = buffer;
> @@ -430,7 +428,7 @@ xfs_ioc_attr_list(
>  		goto out_free;
> 
>  	if (copy_to_user(ubuf, buffer, bufsize) ||
> -	    copy_to_user(ucursor, &cursor, sizeof(cursor)))
> +	    copy_to_user(ucursor, &context.cursor, sizeof(context.cursor)))
>  		error = -EFAULT;
>  out_free:
>  	kmem_free(buffer);
> diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
> index d6e8000ad825..bab6a5a92407 100644
> --- a/fs/xfs/xfs_ioctl.h
> +++ b/fs/xfs/xfs_ioctl.h
> @@ -6,7 +6,6 @@
>  #ifndef __XFS_IOCTL_H__
>  #define __XFS_IOCTL_H__
> 
> -struct attrlist_cursor_kern;
>  struct xfs_bstat;
>  struct xfs_ibulk;
>  struct xfs_inogrp;
> diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
> index a064b1523fa5..f886c0a5dbe1 100644
> --- a/fs/xfs/xfs_trace.h
> +++ b/fs/xfs/xfs_trace.h
> @@ -59,9 +59,9 @@ DECLARE_EVENT_CLASS(xfs_attr_list_class,
>  	TP_fast_assign(
>  		__entry->dev = VFS_I(ctx->dp)->i_sb->s_dev;
>  		__entry->ino = ctx->dp->i_ino;
> -		__entry->hashval = ctx->cursor->hashval;
> -		__entry->blkno = ctx->cursor->blkno;
> -		__entry->offset = ctx->cursor->offset;
> +		__entry->hashval = ctx->cursor.hashval;
> +		__entry->blkno = ctx->cursor.blkno;
> +		__entry->offset = ctx->cursor.offset;
>  		__entry->buffer = ctx->buffer;
>  		__entry->bufsize = ctx->bufsize;
>  		__entry->count = ctx->count;
> @@ -186,9 +186,9 @@ TRACE_EVENT(xfs_attr_list_node_descend,
>  	TP_fast_assign(
>  		__entry->dev = VFS_I(ctx->dp)->i_sb->s_dev;
>  		__entry->ino = ctx->dp->i_ino;
> -		__entry->hashval = ctx->cursor->hashval;
> -		__entry->blkno = ctx->cursor->blkno;
> -		__entry->offset = ctx->cursor->offset;
> +		__entry->hashval = ctx->cursor.hashval;
> +		__entry->blkno = ctx->cursor.blkno;
> +		__entry->offset = ctx->cursor.offset;
>  		__entry->buffer = ctx->buffer;
>  		__entry->bufsize = ctx->bufsize;
>  		__entry->count = ctx->count;
> diff --git a/fs/xfs/xfs_xattr.c b/fs/xfs/xfs_xattr.c
> index 1d2c8615b335..b4e740a6b372 100644
> --- a/fs/xfs/xfs_xattr.c
> +++ b/fs/xfs/xfs_xattr.c
> @@ -188,7 +188,6 @@ xfs_vn_listxattr(
>  	size_t		size)
>  {
>  	struct xfs_attr_list_context context;
> -	struct attrlist_cursor_kern cursor = { 0 };
>  	struct inode	*inode = d_inode(dentry);
>  	int		error;
> 
> @@ -197,7 +196,6 @@ xfs_vn_listxattr(
>  	 */
>  	memset(&context, 0, sizeof(context));
>  	context.dp = XFS_I(inode);
> -	context.cursor = &cursor;
>  	context.resynch = 1;
>  	context.buffer = size ? data : NULL;
>  	context.bufsize = size;
> 


-- 
chandan




^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 11/30] xfs: pass an initialized xfs_da_args structure to xfs_attr_set
  2020-02-07  9:42   ` Chandan Rajendra
@ 2020-02-17 13:48     ` Christoph Hellwig
  0 siblings, 0 replies; 60+ messages in thread
From: Christoph Hellwig @ 2020-02-17 13:48 UTC (permalink / raw)
  To: Chandan Rajendra
  Cc: Christoph Hellwig, linux-xfs, Allison Collins, Darrick J . Wong

On Fri, Feb 07, 2020 at 03:12:06PM +0530, Chandan Rajendra wrote:
> >  		struct inode *inode, const char *name, const void *value,
> >  		size_t size, int flags)
> >  {
> > -	int			xflags = handler->flags;
> > -	struct xfs_inode	*ip = XFS_I(inode);
> > +	struct xfs_da_args	args = {
> > +		.dp		= XFS_I(inode),
> > +		.flags		= handler->flags,
> > +		.name		= name,
> > +		.namelen	= strlen(name),
> > +		.value		= (unsigned char *)value,
> 
> Since xfs_da_args.value is of type "void *', Wouldn't it be more uniform if
> 'value' is typecasted with (void *)? 

Yes, fixed.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 21/30] xfs: move the legacy xfs_attr_list to xfs_ioctl.c
  2020-02-09  7:44   ` Chandan Rajendra
@ 2020-02-17 13:48     ` Christoph Hellwig
  0 siblings, 0 replies; 60+ messages in thread
From: Christoph Hellwig @ 2020-02-17 13:48 UTC (permalink / raw)
  To: Chandan Rajendra; +Cc: Christoph Hellwig, linux-xfs, Allison Collins

On Sun, Feb 09, 2020 at 01:14:18PM +0530, Chandan Rajendra wrote:
> > +/*
> > + * Define how lists of attribute names are returned to the user from
> > + * the attr_list() call.  A large, 32bit aligned, buffer is passed in
> > + * along with its size.  We put an array of offsets at the top that each
> > + * reference an attrlist_ent_t and pack the attrlist_ent_t's at the bottom.
> 
> In the above comment, 'attrlist_ent_t' should be replaced with 'struct
> xfs_attrlist_ent'.

Fixed, thanks.

^ permalink raw reply	[flat|nested] 60+ messages in thread

* Re: [PATCH 26/30] xfs: improve xfs_forget_acl
  2020-02-10  6:45   ` Chandan Rajendra
@ 2020-02-17 13:48     ` Christoph Hellwig
  0 siblings, 0 replies; 60+ messages in thread
From: Christoph Hellwig @ 2020-02-17 13:48 UTC (permalink / raw)
  To: Chandan Rajendra
  Cc: Christoph Hellwig, linux-xfs, Allison Collins, Darrick J . Wong

On Mon, Feb 10, 2020 at 12:15:34PM +0530, Chandan Rajendra wrote:
> >  	error = xfs_attr_set(&args);
> > -	if (!error)
> > -		xfs_forget_acl(inode, name, args.flags);
> > +	if (!error && (flags & ATTR_ROOT))
> 
> ATTR_ROOT should be checked against args.flags.
> 
> 'flags' refers to argument passed to setxattr() syscall i.e. it can have
> XATTR_CREATE or XATTR_REPLACE as its value.

Fixed, thanks.

^ permalink raw reply	[flat|nested] 60+ messages in thread

end of thread, back to index

Thread overview: 60+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-29 17:02 clean up the attr interface v3 Christoph Hellwig
2020-01-29 17:02 ` [PATCH 01/30] xfs: reject invalid flags combinations in XFS_IOC_ATTRLIST_BY_HANDLE Christoph Hellwig
2020-02-05 13:46   ` Chandan Rajendra
2020-01-29 17:02 ` [PATCH 02/30] xfs: remove the ATTR_INCOMPLETE flag Christoph Hellwig
2020-01-29 17:02 ` [PATCH 03/30] xfs: merge xfs_attr_remove into xfs_attr_set Christoph Hellwig
2020-02-06  8:00   ` Chandan Rajendra
2020-01-29 17:02 ` [PATCH 04/30] xfs: merge xfs_attrmulti_attr_remove into xfs_attrmulti_attr_set Christoph Hellwig
2020-02-06  9:21   ` Chandan Rajendra
2020-01-29 17:02 ` [PATCH 05/30] xfs: use strndup_user in XFS_IOC_ATTRMULTI_BY_HANDLE Christoph Hellwig
2020-02-06 10:33   ` Chandan Rajendra
2020-01-29 17:02 ` [PATCH 06/30] xfs: factor out a helper for a single XFS_IOC_ATTRMULTI_BY_HANDLE op Christoph Hellwig
2020-02-07  5:20   ` Chandan Rajendra
2020-01-29 17:02 ` [PATCH 07/30] xfs: remove the name == NULL check from xfs_attr_args_init Christoph Hellwig
2020-02-07  6:15   ` Chandan Rajendra
2020-01-29 17:02 ` [PATCH 08/30] xfs: remove the MAXNAMELEN " Christoph Hellwig
2020-02-07  6:56   ` Chandan Rajendra
2020-01-29 17:02 ` [PATCH 09/30] xfs: move struct xfs_da_args to xfs_types.h Christoph Hellwig
2020-01-29 17:02 ` [PATCH 10/30] xfs: turn xfs_da_args.value into a void pointer Christoph Hellwig
2020-01-29 17:02 ` [PATCH 11/30] xfs: pass an initialized xfs_da_args structure to xfs_attr_set Christoph Hellwig
2020-02-07  9:42   ` Chandan Rajendra
2020-02-17 13:48     ` Christoph Hellwig
2020-01-29 17:02 ` [PATCH 12/30] xfs: pass an initialized xfs_da_args to xfs_attr_get Christoph Hellwig
2020-02-07 13:13   ` Chandan Rajendra
2020-01-29 17:02 ` [PATCH 13/30] xfs: remove the xfs_inode argument to xfs_attr_get_ilocked Christoph Hellwig
2020-02-07 13:19   ` Chandan Rajendra
2020-01-29 17:02 ` [PATCH 14/30] xfs: remove ATTR_KERNOVAL Christoph Hellwig
2020-02-08  4:36   ` Chandan Rajendra
2020-01-29 17:02 ` [PATCH 15/30] xfs: remove ATTR_ALLOC and XFS_DA_OP_ALLOCVAL Christoph Hellwig
2020-02-08  5:13   ` Chandan Rajendra
2020-01-29 17:02 ` [PATCH 16/30] xfs: replace ATTR_KERNOTIME with XFS_DA_OP_NOTIME Christoph Hellwig
2020-02-08 11:35   ` Chandan Rajendra
2020-01-29 17:02 ` [PATCH 17/30] xfs: factor out a xfs_attr_match helper Christoph Hellwig
2020-02-08 12:48   ` Chandan Rajendra
2020-01-29 17:02 ` [PATCH 18/30] xfs: cleanup struct xfs_attr_list_context Christoph Hellwig
2020-02-08 15:53   ` Chandan Rajendra
2020-01-29 17:02 ` [PATCH 19/30] xfs: remove the unused ATTR_ENTRY macro Christoph Hellwig
2020-01-29 17:02 ` [PATCH 20/30] xfs: open code ATTR_ENTSIZE Christoph Hellwig
2020-02-09  6:57   ` Chandan Rajendra
2020-01-29 17:03 ` [PATCH 21/30] xfs: move the legacy xfs_attr_list to xfs_ioctl.c Christoph Hellwig
2020-02-09  7:44   ` Chandan Rajendra
2020-02-17 13:48     ` Christoph Hellwig
2020-01-29 17:03 ` [PATCH 22/30] xfs: rename xfs_attr_list_int to xfs_attr_list Christoph Hellwig
2020-02-09  7:52   ` Chandan Rajendra
2020-01-29 17:03 ` [PATCH 23/30] xfs: lift common checks into xfs_ioc_attr_list Christoph Hellwig
2020-02-09  8:03   ` Chandan Rajendra
2020-01-29 17:03 ` [PATCH 24/30] xfs: lift buffer allocation " Christoph Hellwig
2020-02-09  8:24   ` Chandan Rajendra
2020-01-29 17:03 ` [PATCH 25/30] xfs: lift cursor copy in/out " Christoph Hellwig
2020-02-10  6:02   ` Chandan Rajendra
2020-01-29 17:03 ` [PATCH 26/30] xfs: improve xfs_forget_acl Christoph Hellwig
2020-02-10  6:45   ` Chandan Rajendra
2020-02-17 13:48     ` Christoph Hellwig
2020-01-29 17:03 ` [PATCH 27/30] xfs: clean up the ATTR_REPLACE checks Christoph Hellwig
2020-02-10  6:57   ` Chandan Rajendra
2020-01-29 17:03 ` [PATCH 28/30] xfs: clean up the attr flag confusion Christoph Hellwig
2020-02-10 13:19   ` Chandan Rajendra
2020-01-29 17:03 ` [PATCH 29/30] xfs: remove XFS_DA_OP_INCOMPLETE Christoph Hellwig
2020-02-10 13:59   ` Chandan Rajendra
2020-01-29 17:03 ` [PATCH 30/30] xfs: embedded the attrlist cursor into struct xfs_attr_list_context Christoph Hellwig
2020-02-10 14:57   ` Chandan Rajendra

Linux-XFS Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-xfs/0 linux-xfs/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 linux-xfs linux-xfs/ https://lore.kernel.org/linux-xfs \
		linux-xfs@vger.kernel.org
	public-inbox-index linux-xfs

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.linux-xfs


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git