Linux-NFS Archive on lore.kernel.org
 help / color / Atom feed
From: Frank van der Linden <fllinden@amazon.com>
To: <linux-nfs@vger.kernel.org>, <linux-fsdevel@vger.kernel.org>
Subject: [RFC PATCH 16/35] NFSv4.2: add the extended attribute proc functions.
Date: Fri, 30 Aug 2019 23:15:10 +0000
Message-ID: <d6c681bfa00a527d1a48b42844fd414f95f65123.1568309119.git.fllinden@amazon.com> (raw)
In-Reply-To: <cover.1568309119.git.fllinden@amazon.com>

Implement the extended attribute procedures for NFSv4.2 extended
attribute support (RFC 8276).

Signed-off-by: Frank van der Linden <fllinden@amazon.com>
---
 fs/nfs/nfs42.h     |   9 ++
 fs/nfs/nfs42proc.c | 242 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 251 insertions(+)

diff --git a/fs/nfs/nfs42.h b/fs/nfs/nfs42.h
index 935651345be7..96834d172269 100644
--- a/fs/nfs/nfs42.h
+++ b/fs/nfs/nfs42.h
@@ -29,6 +29,15 @@ int nfs42_proc_layouterror(struct pnfs_layout_segment *lseg,
 			   size_t n);
 
 #ifdef CONFIG_NFS_V4_XATTR
+
+ssize_t nfs42_proc_getxattr(struct inode *inode, const char *name,
+			void *buf, size_t buflen);
+int nfs42_proc_setxattr(struct inode *inode, const char *name,
+			const void *buf, size_t buflen, int flags);
+ssize_t nfs42_proc_listxattrs(struct inode *inode, void *buf,
+			  size_t buflen, u64 *cookiep, bool *eofp);
+int nfs42_proc_removexattr(struct inode *inode, const char *name);
+
 /*
  * Maximum XDR buffer size needed for a listxattr buffer of buflen size.
  *
diff --git a/fs/nfs/nfs42proc.c b/fs/nfs/nfs42proc.c
index 5196bfa7894d..1c7081f35401 100644
--- a/fs/nfs/nfs42proc.c
+++ b/fs/nfs/nfs42proc.c
@@ -933,3 +933,245 @@ int nfs42_proc_clone(struct file *src_f, struct file *dst_f,
 	nfs_put_lock_context(src_lock);
 	return err;
 }
+
+#ifdef CONFIG_NFS_V4_XATTR
+
+#define NFS4XATTR_MAXPAGES DIV_ROUND_UP(XATTR_SIZE_MAX, PAGE_SIZE)
+
+static int _nfs42_proc_removexattr(struct inode *inode, const char *name)
+{
+	struct nfs_server *server = NFS_SERVER(inode);
+	struct nfs42_removexattrargs args = {
+		.fh = NFS_FH(inode),
+		.xattr_name = name,
+	};
+	struct nfs42_removexattrres res;
+	struct rpc_message msg = {
+		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_REMOVEXATTR],
+		.rpc_argp = &args,
+		.rpc_resp = &res,
+	};
+	int ret;
+	unsigned long timestamp = jiffies;
+
+	ret = nfs4_call_sync(server->client, server, &msg, &args.seq_args,
+	    &res.seq_res, 1);
+	if (!ret)
+		nfs4_update_changeattr(inode, &res.cinfo, timestamp,
+		    NFS_INO_INVALID_XATTR);
+
+	return ret;
+}
+
+static int _nfs42_proc_setxattr(struct inode *inode, const char *name,
+				const void *buf, size_t buflen, int flags)
+{
+	struct nfs_server *server = NFS_SERVER(inode);
+	struct page *pages[NFS4XATTR_MAXPAGES];
+	struct nfs42_setxattrargs arg = {
+		.fh		= NFS_FH(inode),
+		.xattr_pages	= pages,
+		.xattr_len	= buflen,
+		.xattr_name	= name,
+		.xattr_flags	= flags,
+	};
+	struct nfs42_setxattrres res;
+	struct rpc_message msg = {
+		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_SETXATTR],
+		.rpc_argp	= &arg,
+		.rpc_resp	= &res,
+	};
+	int ret, np;
+	unsigned long timestamp = jiffies;
+
+	if (buflen > server->sxasize)
+		return -ERANGE;
+
+	if (buflen > 0) {
+		np = nfs4_buf_to_pages_noslab(buf, buflen, arg.xattr_pages);
+		if (np < 0)
+			return np;
+	} else
+		np = 0;
+
+	ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args,
+	    &res.seq_res, 1);
+
+	for (; np > 0; np--)
+		put_page(pages[np - 1]);
+
+	if (!ret)
+		nfs4_update_changeattr(inode, &res.cinfo, timestamp,
+		    NFS_INO_INVALID_XATTR);
+
+	return ret;
+}
+
+static ssize_t _nfs42_proc_getxattr(struct inode *inode, const char *name,
+				void *buf, size_t buflen)
+{
+	struct nfs_server *server = NFS_SERVER(inode);
+	struct page *pages[NFS4XATTR_MAXPAGES] = {};
+	struct nfs42_getxattrargs arg = {
+		.fh		= NFS_FH(inode),
+		.xattr_pages	= pages,
+		.xattr_len	= buflen,
+		.xattr_name	= name,
+	};
+	struct nfs42_getxattrres res;
+	struct rpc_message msg = {
+		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_GETXATTR],
+		.rpc_argp	= &arg,
+		.rpc_resp	= &res,
+	};
+	int ret, np;
+
+	ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args,
+	    &res.seq_res, 0);
+	if (ret < 0)
+		return ret;
+
+	if (buflen) {
+		if (res.xattr_len > buflen)
+			return -ERANGE;
+		_copy_from_pages(buf, pages, 0, res.xattr_len);
+	}
+
+	np = DIV_ROUND_UP(res.xattr_len, PAGE_SIZE);
+	while (--np >= 0)
+		__free_page(pages[np]);
+
+	return res.xattr_len;
+}
+
+static ssize_t _nfs42_proc_listxattrs(struct inode *inode, void *buf,
+				 size_t buflen, u64 *cookiep, bool *eofp)
+{
+	struct nfs_server *server = NFS_SERVER(inode);
+	struct page **pages;
+	struct nfs42_listxattrsargs arg = {
+		.fh		= NFS_FH(inode),
+		.cookie		= *cookiep,
+	};
+	struct nfs42_listxattrsres res = {
+		.eof = false,
+		.xattr_buf = buf,
+		.xattr_len = buflen,
+	};
+	struct rpc_message msg = {
+		.rpc_proc	= &nfs4_procedures[NFSPROC4_CLNT_LISTXATTRS],
+		.rpc_argp	= &arg,
+		.rpc_resp	= &res,
+	};
+	u32 xdrlen;
+	int ret, np;
+
+
+	res.scratch = alloc_page(GFP_KERNEL);
+	if (!res.scratch)
+		return -ENOMEM;
+
+	xdrlen = nfs42_listxattr_xdrsize(buflen);
+	if (xdrlen > server->lxasize)
+		xdrlen = server->lxasize;
+	np = xdrlen / PAGE_SIZE + 1;
+
+	pages = kzalloc(np * sizeof (struct page *), GFP_KERNEL);
+	if (pages == NULL) {
+		__free_page(res.scratch);
+		return -ENOMEM;
+	}
+
+	arg.xattr_pages = pages;
+	arg.count = xdrlen;
+
+	ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args,
+	    &res.seq_res, 0);
+
+	if (ret >= 0) {
+		ret = res.copied;
+		*cookiep = res.cookie;
+		*eofp = res.eof;
+	}
+
+	while (--np >= 0) {
+		if (pages[np])
+			__free_page(pages[np]);
+	}
+
+	__free_page(res.scratch);
+	kfree(pages);
+
+	return ret;
+
+}
+
+ssize_t nfs42_proc_getxattr(struct inode *inode, const char *name,
+			      void *buf, size_t buflen)
+{
+	struct nfs4_exception exception = { };
+	ssize_t err;
+
+	do {
+		err = _nfs42_proc_getxattr(inode, name, buf, buflen);
+		if (err >= 0)
+			break;
+		err = nfs4_handle_exception(NFS_SERVER(inode), err,
+				&exception);
+	} while (exception.retry);
+
+	return err;
+}
+
+int nfs42_proc_setxattr(struct inode *inode, const char *name,
+			      const void *buf, size_t buflen, int flags)
+{
+	struct nfs4_exception exception = { };
+	int err;
+
+	do {
+		err = _nfs42_proc_setxattr(inode, name, buf, buflen, flags);
+		if (!err)
+			break;
+		err = nfs4_handle_exception(NFS_SERVER(inode), err,
+				&exception);
+	} while (exception.retry);
+
+	return err;
+}
+
+ssize_t nfs42_proc_listxattrs(struct inode *inode, void *buf,
+			      size_t buflen, u64 *cookiep, bool *eofp)
+{
+	struct nfs4_exception exception = { };
+	ssize_t err;
+
+	do {
+		err = _nfs42_proc_listxattrs(inode, buf, buflen,
+		    cookiep, eofp);
+		if (err >= 0)
+			break;
+		err = nfs4_handle_exception(NFS_SERVER(inode), err,
+				&exception);
+	} while (exception.retry);
+
+	return err;
+}
+
+int nfs42_proc_removexattr(struct inode *inode, const char *name)
+{
+	struct nfs4_exception exception = { };
+	int err;
+
+	do {
+		err = _nfs42_proc_removexattr(inode, name);
+		if (!err)
+			break;
+		err = nfs4_handle_exception(NFS_SERVER(inode), err,
+				&exception);
+	} while (exception.retry);
+
+	return err;
+}
+
+#endif /* CONFIG_NFS_V4_XATTR */
-- 
2.17.2


  parent reply index

Thread overview: 45+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-12 17:25 [RFC PATCH 00/35] user xattr support (RFC8276) Frank van der Linden
2019-07-01 17:56 ` [RFC PATCH 02/35] nfs/nfsd: basic NFS4 extended attribute definitions Frank van der Linden
2019-08-26 21:38 ` [RFC PATCH 03/35] NFSv4.2: query the server for extended attribute support Frank van der Linden
2019-08-26 21:53 ` [RFC PATCH 04/35] nfs: parse the {no}user_xattr option Frank van der Linden
2019-08-26 22:06 ` [RFC PATCH 05/35] NFSv4.2: define a function to compute the maximum XDR size for listxattr Frank van der Linden
2019-08-26 22:23 ` [RFC PATCH 06/35] NFSv4.2: define and set initial limits for extended attributes Frank van der Linden
2019-08-26 22:32 ` [RFC PATCH 07/35] NFSv4.2: define argument and response structures for xattr operations Frank van der Linden
2019-08-26 22:44 ` [RFC PATCH 08/35] NFSv4.2: define the encode/decode sizes for the XATTR operations Frank van der Linden
2019-08-26 23:09 ` [RFC PATCH 09/35] NFSv4.2: define and use extended attribute overhead sizes Frank van der Linden
2019-08-27 15:34 ` [RFC PATCH 10/35] NFSv4.2: add client side XDR handling for extended attributes Frank van der Linden
2019-08-27 15:46 ` [RFC PATCH 11/35] nfs: define nfs_access_get_cached function Frank van der Linden
2019-08-27 16:01 ` [RFC PATCH 12/35] NFSv4.2: query the extended attribute access bits Frank van der Linden
2019-08-27 22:51 ` [RFC PATCH 13/35] nfs: modify update_changeattr to deal with regular files Frank van der Linden
2019-08-30 22:48 ` [RFC PATCH 14/35] nfs: define and use the NFS_INO_INVALID_XATTR flag Frank van der Linden
2019-08-30 22:56 ` [RFC PATCH 15/35] nfs: make the buf_to_pages_noslab function available to the nfs code Frank van der Linden
2019-08-30 23:15 ` Frank van der Linden [this message]
2019-08-30 23:31 ` [RFC PATCH 17/35] NFSv4.2: hook in the user extended attribute handlers Frank van der Linden
2019-08-30 23:38 ` [RFC PATCH 18/35] NFSv4.2: add client side xattr caching functions Frank van der Linden
2019-08-30 23:45 ` [RFC PATCH 19/35] NFSv4.2: call the xattr cache functions Frank van der Linden
2019-08-30 23:59 ` [RFC PATCH 20/35] nfs: add the NFS_V4_XATTR config option Frank van der Linden
2019-08-31  2:12 ` [RFC PATCH 21/35] xattr: modify vfs_{set,remove}xattr for NFS server use Frank van der Linden
2019-08-31 19:00 ` [RFC PATCH 22/35] nfsd: split off the write decode code in to a seperate function Frank van der Linden
2019-08-31 19:19 ` [RFC PATCH 23/35] nfsd: add defines for NFSv4.2 extended attribute support Frank van der Linden
2019-08-31 21:35 ` [RFC PATCH 26/35] nfsd: add structure definitions for xattr requests / responses Frank van der Linden
2019-08-31 23:53 ` [RFC PATCH 24/35] nfsd: define xattr functions to call in to their vfs counterparts Frank van der Linden
2019-09-01  0:13 ` [RFC PATCH 25/35] nfsd: take xattr access bits in to account when checking Frank van der Linden
2019-09-01  1:19 ` [RFC PATCH 27/35] nfsd: implement the xattr procedure functions Frank van der Linden
2019-09-01  2:46 ` [RFC PATCH 01/35] nfsd: make sure the nfsd4_ops array has the right size Frank van der Linden
2019-09-02 19:40 ` [RFC PATCH 28/35] nfsd: define xattr reply size functions Frank van der Linden
2019-09-02 19:58 ` [RFC PATCH 29/35] nfsd: add xattr XDR decode functions Frank van der Linden
2019-09-02 20:09 ` [RFC PATCH 30/35] nfsd: add xattr XDR encode functions Frank van der Linden
2019-09-02 20:19 ` [RFC PATCH 31/35] nfsd: add xattr operations to ops array Frank van der Linden
2019-09-02 20:34 ` [RFC PATCH 32/35] xattr: add a function to check if a namespace is supported Frank van der Linden
2019-09-02 21:30 ` [RFC PATCH 33/35] nfsd: add fattr support for user extended attributes Frank van der Linden
2019-09-02 23:06 ` [RFC PATCH 34/35] nfsd: add export flag to disable " Frank van der Linden
2019-09-02 23:17 ` [RFC PATCH 35/35] nfsd: add NFSD_V4_XATTR config option Frank van der Linden
2019-10-24 20:16 ` [RFC PATCH 00/35] user xattr support (RFC8276) Chuck Lever
2019-10-24 23:15   ` Frank van der Linden
2019-10-25 19:55     ` Chuck Lever
2019-11-04  3:01       ` bfields
2019-11-04 15:36         ` Chuck Lever
2019-11-04 16:21           ` Frank van der Linden
2019-11-04 22:58             ` Bruce Fields
2019-11-05  0:06               ` Frank van der Linden
2019-11-05 15:44               ` Chuck Lever

Reply instructions:

You may reply publically to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d6c681bfa00a527d1a48b42844fd414f95f65123.1568309119.git.fllinden@amazon.com \
    --to=fllinden@amazon.com \
    --cc=linux-fsdevel@vger.kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

Linux-NFS Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/linux-nfs/0 linux-nfs/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-nfs linux-nfs/ https://lore.kernel.org/linux-nfs \
		linux-nfs@vger.kernel.org
	public-inbox-index linux-nfs

Example config snippet for mirrors

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


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