All of lore.kernel.org
 help / color / mirror / Atom feed
* open by handle support for NFS
@ 2017-06-27 15:43 Christoph Hellwig
  2017-06-27 15:44 ` [PATCH 1/4] nfs: replace d_add with d_splice_alias in atomic_open Christoph Hellwig
                   ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: Christoph Hellwig @ 2017-06-27 15:43 UTC (permalink / raw)
  To: trond.myklebust; +Cc: jlayton, linux-nfs

Hi all,

this resurrects parts of an old series to add open by handle support to
NFS.  The prime intent here is to support the actual open by handle
ioctls, although it will also allow very crude re-exporting.  Without
the other patches from Jeff's series that re-exporting will suck badly
though.


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

* [PATCH 1/4] nfs: replace d_add with d_splice_alias in atomic_open
  2017-06-27 15:43 open by handle support for NFS Christoph Hellwig
@ 2017-06-27 15:44 ` Christoph Hellwig
  2017-06-27 15:44 ` [PATCH 2/4] nfs: add a nfs_ilookup helper Christoph Hellwig
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 12+ messages in thread
From: Christoph Hellwig @ 2017-06-27 15:44 UTC (permalink / raw)
  To: trond.myklebust; +Cc: jlayton, linux-nfs

From: Peng Tao <tao.peng@primarydata.com>

It's a trival change but follows knfsd export document that asks
for d_splice_alias during lookup.

Signed-off-by: Peng Tao <tao.peng@primarydata.com>
---
 fs/nfs/dir.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 32ccd7754f8a..0296c06dcdc5 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1512,7 +1512,7 @@ int nfs_atomic_open(struct inode *dir, struct dentry *dentry,
 		d_drop(dentry);
 		switch (err) {
 		case -ENOENT:
-			d_add(dentry, NULL);
+			d_splice_alias(NULL, dentry);
 			nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
 			break;
 		case -EISDIR:
-- 
2.11.0


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

* [PATCH 2/4] nfs: add a nfs_ilookup helper
  2017-06-27 15:43 open by handle support for NFS Christoph Hellwig
  2017-06-27 15:44 ` [PATCH 1/4] nfs: replace d_add with d_splice_alias in atomic_open Christoph Hellwig
@ 2017-06-27 15:44 ` Christoph Hellwig
  2017-06-27 15:44 ` [PATCH 3/4] nfs4: add NFSv4 LOOKUPP handlers Christoph Hellwig
  2017-06-27 15:44 ` [PATCH 4/4] nfs: add export operations Christoph Hellwig
  3 siblings, 0 replies; 12+ messages in thread
From: Christoph Hellwig @ 2017-06-27 15:44 UTC (permalink / raw)
  To: trond.myklebust; +Cc: jlayton, linux-nfs

From: Peng Tao <tao.peng@primarydata.com>

This helper will allow to find an existing NFS inode by the file handle
and fattr.

Signed-off-by: Peng Tao <tao.peng@primarydata.com>
[hch: split from a larger patch]
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/nfs/inode.c         | 22 ++++++++++++++++++++++
 include/linux/nfs_fs.h |  1 +
 2 files changed, 23 insertions(+)

diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 1de93ba78dc9..a84eab1a18a7 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -386,6 +386,28 @@ void nfs_setsecurity(struct inode *inode, struct nfs_fattr *fattr,
 #endif
 EXPORT_SYMBOL_GPL(nfs_setsecurity);
 
+/* Search for inode identified by fh, fileid and i_mode in inode cache. */
+struct inode *
+nfs_ilookup(struct super_block *sb, struct nfs_fattr *fattr, struct nfs_fh *fh)
+{
+	struct nfs_find_desc desc = {
+		.fh	= fh,
+		.fattr	= fattr,
+	};
+	struct inode *inode;
+	unsigned long hash;
+
+	if (!(fattr->valid & NFS_ATTR_FATTR_FILEID) ||
+	    !(fattr->valid & NFS_ATTR_FATTR_TYPE))
+		return NULL;
+
+	hash = nfs_fattr_to_ino_t(fattr);
+	inode = ilookup5(sb, hash, nfs_find_actor, &desc);
+
+	dprintk("%s: returning %p\n", __func__, inode);
+	return inode;
+}
+
 /*
  * This is our front-end to iget that looks up inodes by file handle
  * instead of inode number.
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index bb0eb2c9acca..e52cc55ac300 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -332,6 +332,7 @@ extern void nfs_zap_caches(struct inode *);
 extern void nfs_invalidate_atime(struct inode *);
 extern struct inode *nfs_fhget(struct super_block *, struct nfs_fh *,
 				struct nfs_fattr *, struct nfs4_label *);
+struct inode *nfs_ilookup(struct super_block *sb, struct nfs_fattr *, struct nfs_fh *);
 extern int nfs_refresh_inode(struct inode *, struct nfs_fattr *);
 extern int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr);
 extern int nfs_post_op_update_inode_force_wcc(struct inode *inode, struct nfs_fattr *fattr);
-- 
2.11.0


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

* [PATCH 3/4] nfs4: add NFSv4 LOOKUPP handlers
  2017-06-27 15:43 open by handle support for NFS Christoph Hellwig
  2017-06-27 15:44 ` [PATCH 1/4] nfs: replace d_add with d_splice_alias in atomic_open Christoph Hellwig
  2017-06-27 15:44 ` [PATCH 2/4] nfs: add a nfs_ilookup helper Christoph Hellwig
@ 2017-06-27 15:44 ` Christoph Hellwig
  2017-06-28 14:55   ` Anna Schumaker
  2017-06-27 15:44 ` [PATCH 4/4] nfs: add export operations Christoph Hellwig
  3 siblings, 1 reply; 12+ messages in thread
From: Christoph Hellwig @ 2017-06-27 15:44 UTC (permalink / raw)
  To: trond.myklebust; +Cc: jlayton, linux-nfs

From: Jeff Layton <jeff.layton@primarydata.com>

This will be needed in order to implement the get_parent export op
for nfsd.

Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
---
 fs/nfs/nfs4proc.c       | 49 +++++++++++++++++++++++++++++++++
 fs/nfs/nfs4trace.h      | 29 ++++++++++++++++++++
 fs/nfs/nfs4xdr.c        | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/nfs4.h    |  1 +
 include/linux/nfs_xdr.h | 17 +++++++++++-
 5 files changed, 168 insertions(+), 1 deletion(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index c08c46a3b8cd..6fd9eee8e4ee 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3802,6 +3802,54 @@ nfs4_proc_lookup_mountpoint(struct inode *dir, const struct qstr *name,
 	return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client;
 }
 
+static int _nfs4_proc_lookupp(struct inode *inode,
+		struct nfs_fh *fhandle, struct nfs_fattr *fattr,
+		struct nfs4_label *label)
+{
+	struct rpc_clnt *clnt = NFS_CLIENT(inode);
+	struct nfs_server *server = NFS_SERVER(inode);
+	int		       status;
+	struct nfs4_lookupp_arg args = {
+		.bitmask = server->attr_bitmask,
+		.fh = NFS_FH(inode),
+	};
+	struct nfs4_lookupp_res res = {
+		.server = server,
+		.fattr = fattr,
+		.label = label,
+		.fh = fhandle,
+	};
+	struct rpc_message msg = {
+		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUPP],
+		.rpc_argp = &args,
+		.rpc_resp = &res,
+	};
+
+	args.bitmask = nfs4_bitmask(server, label);
+
+	nfs_fattr_init(fattr);
+
+	dprintk("NFS call  lookupp ino=0x%lx\n", inode->i_ino);
+	status = nfs4_call_sync(clnt, server, &msg, &args.seq_args,
+				&res.seq_res, 0);
+	dprintk("NFS reply lookupp: %d\n", status);
+	return status;
+}
+
+static int nfs4_proc_lookupp(struct inode *inode, struct nfs_fh *fhandle,
+			     struct nfs_fattr *fattr, struct nfs4_label *label)
+{
+	struct nfs4_exception exception = { };
+	int err;
+	do {
+		err = _nfs4_proc_lookupp(inode, fhandle, fattr, label);
+		trace_nfs4_lookupp(inode, err);
+		err = nfs4_handle_exception(NFS_SERVER(inode), err,
+				&exception);
+	} while (exception.retry);
+	return err;
+}
+
 static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
@@ -9312,6 +9360,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
 	.getattr	= nfs4_proc_getattr,
 	.setattr	= nfs4_proc_setattr,
 	.lookup		= nfs4_proc_lookup,
+	.lookupp	= nfs4_proc_lookupp,
 	.access		= nfs4_proc_access,
 	.readlink	= nfs4_proc_readlink,
 	.create		= nfs4_proc_create,
diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h
index 845d0eadefc9..be1da19c65d6 100644
--- a/fs/nfs/nfs4trace.h
+++ b/fs/nfs/nfs4trace.h
@@ -891,6 +891,35 @@ DEFINE_NFS4_LOOKUP_EVENT(nfs4_remove);
 DEFINE_NFS4_LOOKUP_EVENT(nfs4_get_fs_locations);
 DEFINE_NFS4_LOOKUP_EVENT(nfs4_secinfo);
 
+TRACE_EVENT(nfs4_lookupp,
+		TP_PROTO(
+			const struct inode *inode,
+			int error
+		),
+
+		TP_ARGS(inode, error),
+
+		TP_STRUCT__entry(
+			__field(dev_t, dev)
+			__field(u64, ino)
+			__field(int, error)
+		),
+
+		TP_fast_assign(
+			__entry->dev = inode->i_sb->s_dev;
+			__entry->ino = NFS_FILEID(inode);
+			__entry->error = error;
+		),
+
+		TP_printk(
+			"error=%d (%s) inode=%02x:%02x:%llu",
+			__entry->error,
+			show_nfsv4_errors(__entry->error),
+			MAJOR(__entry->dev), MINOR(__entry->dev),
+			(unsigned long long)__entry->ino
+		)
+);
+
 TRACE_EVENT(nfs4_rename,
 		TP_PROTO(
 			const struct inode *olddir,
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 3aebfdc82b30..b55017987dcd 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -159,6 +159,8 @@ static int nfs4_stat_to_errno(int);
 				(op_decode_hdr_maxsz)
 #define encode_lookup_maxsz	(op_encode_hdr_maxsz + nfs4_name_maxsz)
 #define decode_lookup_maxsz	(op_decode_hdr_maxsz)
+#define encode_lookupp_maxsz	(op_encode_hdr_maxsz)
+#define decode_lookupp_maxsz	(op_decode_hdr_maxsz)
 #define encode_share_access_maxsz \
 				(2)
 #define encode_createmode_maxsz	(1 + encode_attrs_maxsz + encode_verifier_maxsz)
@@ -618,6 +620,18 @@ static int nfs4_stat_to_errno(int);
 				decode_lookup_maxsz + \
 				decode_getattr_maxsz + \
 				decode_getfh_maxsz)
+#define NFS4_enc_lookupp_sz	(compound_encode_hdr_maxsz + \
+				encode_sequence_maxsz + \
+				encode_putfh_maxsz + \
+				encode_lookupp_maxsz + \
+				encode_getattr_maxsz + \
+				encode_getfh_maxsz)
+#define NFS4_dec_lookupp_sz	(compound_decode_hdr_maxsz + \
+				decode_sequence_maxsz + \
+				decode_putfh_maxsz + \
+				decode_lookupp_maxsz + \
+				decode_getattr_maxsz + \
+				decode_getfh_maxsz)
 #define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \
 				encode_sequence_maxsz + \
 				encode_putrootfh_maxsz + \
@@ -1368,6 +1382,11 @@ static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struc
 	encode_string(xdr, name->len, name->name);
 }
 
+static void encode_lookupp(struct xdr_stream *xdr, struct compound_hdr *hdr)
+{
+	encode_op_hdr(xdr, OP_LOOKUPP, decode_lookupp_maxsz, hdr);
+}
+
 static void encode_share_access(struct xdr_stream *xdr, u32 share_access)
 {
 	__be32 *p;
@@ -2120,6 +2139,25 @@ static void nfs4_xdr_enc_lookup(struct rpc_rqst *req, struct xdr_stream *xdr,
 }
 
 /*
+ * Encode LOOKUPP request
+ */
+static void nfs4_xdr_enc_lookupp(struct rpc_rqst *req, struct xdr_stream *xdr,
+				const struct nfs4_lookupp_arg *args)
+{
+	struct compound_hdr hdr = {
+		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
+	};
+
+	encode_compound_hdr(xdr, req, &hdr);
+	encode_sequence(xdr, &args->seq_args, &hdr);
+	encode_putfh(xdr, args->fh, &hdr);
+	encode_lookupp(xdr, &hdr);
+	encode_getfh(xdr, &hdr);
+	encode_getfattr(xdr, args->bitmask, &hdr);
+	encode_nops(&hdr);
+}
+
+/*
  * Encode LOOKUP_ROOT request
  */
 static void nfs4_xdr_enc_lookup_root(struct rpc_rqst *req,
@@ -5005,6 +5043,11 @@ static int decode_lookup(struct xdr_stream *xdr)
 	return decode_op_hdr(xdr, OP_LOOKUP);
 }
 
+static int decode_lookupp(struct xdr_stream *xdr)
+{
+	return decode_op_hdr(xdr, OP_LOOKUPP);
+}
+
 /* This is too sick! */
 static int decode_space_limit(struct xdr_stream *xdr,
 		unsigned long *pagemod_limit)
@@ -6182,6 +6225,35 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
 }
 
 /*
+ * Decode LOOKUPP response
+ */
+static int nfs4_xdr_dec_lookupp(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+				struct nfs4_lookupp_res *res)
+{
+	struct compound_hdr hdr;
+	int status;
+
+	status = decode_compound_hdr(xdr, &hdr);
+	if (status)
+		goto out;
+	status = decode_sequence(xdr, &res->seq_res, rqstp);
+	if (status)
+		goto out;
+	status = decode_putfh(xdr);
+	if (status)
+		goto out;
+	status = decode_lookupp(xdr);
+	if (status)
+		goto out;
+	status = decode_getfh(xdr, res->fh);
+	if (status)
+		goto out;
+	status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
+out:
+	return status;
+}
+
+/*
  * Decode LOOKUP_ROOT response
  */
 static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp,
@@ -7517,6 +7589,7 @@ struct rpc_procinfo	nfs4_procedures[] = {
 	PROC(ACCESS,		enc_access,		dec_access),
 	PROC(GETATTR,		enc_getattr,		dec_getattr),
 	PROC(LOOKUP,		enc_lookup,		dec_lookup),
+	PROC(LOOKUPP,		enc_lookupp,		dec_lookupp),
 	PROC(LOOKUP_ROOT,	enc_lookup_root,	dec_lookup_root),
 	PROC(REMOVE,		enc_remove,		dec_remove),
 	PROC(RENAME,		enc_rename,		dec_rename),
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 1b1ca04820a3..47239c336688 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -479,6 +479,7 @@ enum {
 	NFSPROC4_CLNT_ACCESS,
 	NFSPROC4_CLNT_GETATTR,
 	NFSPROC4_CLNT_LOOKUP,
+	NFSPROC4_CLNT_LOOKUPP,
 	NFSPROC4_CLNT_LOOKUP_ROOT,
 	NFSPROC4_CLNT_REMOVE,
 	NFSPROC4_CLNT_RENAME,
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index b28c83475ee8..7a664a5fcc25 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1012,7 +1012,6 @@ struct nfs4_link_res {
 	struct nfs_fattr *		dir_attr;
 };
 
-
 struct nfs4_lookup_arg {
 	struct nfs4_sequence_args	seq_args;
 	const struct nfs_fh *		dir_fh;
@@ -1028,6 +1027,20 @@ struct nfs4_lookup_res {
 	struct nfs4_label		*label;
 };
 
+struct nfs4_lookupp_arg {
+	struct nfs4_sequence_args	seq_args;
+	const struct nfs_fh		*fh;
+	const u32			*bitmask;
+};
+
+struct nfs4_lookupp_res {
+	struct nfs4_sequence_res	seq_res;
+	const struct nfs_server		*server;
+	struct nfs_fattr		*fattr;
+	struct nfs_fh			*fh;
+	struct nfs4_label		*label;
+};
+
 struct nfs4_lookup_root_arg {
 	struct nfs4_sequence_args	seq_args;
 	const u32 *			bitmask;
@@ -1567,6 +1580,8 @@ struct nfs_rpc_ops {
 	int	(*lookup)  (struct inode *, const struct qstr *,
 			    struct nfs_fh *, struct nfs_fattr *,
 			    struct nfs4_label *);
+	int	(*lookupp) (struct inode *, struct nfs_fh *,
+			    struct nfs_fattr *, struct nfs4_label *);
 	int	(*access)  (struct inode *, struct nfs_access_entry *);
 	int	(*readlink)(struct inode *, struct page *, unsigned int,
 			    unsigned int);
-- 
2.11.0


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

* [PATCH 4/4] nfs: add export operations
  2017-06-27 15:43 open by handle support for NFS Christoph Hellwig
                   ` (2 preceding siblings ...)
  2017-06-27 15:44 ` [PATCH 3/4] nfs4: add NFSv4 LOOKUPP handlers Christoph Hellwig
@ 2017-06-27 15:44 ` Christoph Hellwig
  3 siblings, 0 replies; 12+ messages in thread
From: Christoph Hellwig @ 2017-06-27 15:44 UTC (permalink / raw)
  To: trond.myklebust; +Cc: jlayton, linux-nfs

From: Peng Tao <tao.peng@primarydata.com>

This support for opening files on NFS by file handle, both through the
open_by_handle syscall, and for re-exporting NFS (for example using a
different version).  The support is very basic for now, as each open by
handle will have to do an NFSv4 open operation on the wire.  In the
future this will hopefully be mitigated by an open file cache, as well
as various optimizations in NFS for this specific case.

Signed-off-by: Peng Tao <tao.peng@primarydata.com>
[hch: incorporated various changes, resplit the patches, new changelog]
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 fs/nfs/Makefile   |   2 +-
 fs/nfs/export.c   | 177 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/nfs/internal.h |   2 +
 fs/nfs/super.c    |   2 +
 4 files changed, 182 insertions(+), 1 deletion(-)
 create mode 100644 fs/nfs/export.c

diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index 98f4e5728a67..1fb118902d57 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -7,7 +7,7 @@ obj-$(CONFIG_NFS_FS) += nfs.o
 CFLAGS_nfstrace.o += -I$(src)
 nfs-y 			:= client.o dir.o file.o getroot.o inode.o super.o \
 			   io.o direct.o pagelist.o read.o symlink.o unlink.o \
-			   write.o namespace.o mount_clnt.o nfstrace.o
+			   write.o namespace.o mount_clnt.o nfstrace.o export.o
 nfs-$(CONFIG_ROOT_NFS)	+= nfsroot.o
 nfs-$(CONFIG_SYSCTL)	+= sysctl.o
 nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
diff --git a/fs/nfs/export.c b/fs/nfs/export.c
new file mode 100644
index 000000000000..249cb96cc5b5
--- /dev/null
+++ b/fs/nfs/export.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2015, Primary Data, Inc. All rights reserved.
+ *
+ * Tao Peng <bergwolf@primarydata.com>
+ */
+#include <linux/dcache.h>
+#include <linux/exportfs.h>
+#include <linux/nfs.h>
+#include <linux/nfs_fs.h>
+
+#include "internal.h"
+#include "nfstrace.h"
+
+#define NFSDBG_FACILITY		NFSDBG_VFS
+
+enum {
+	FILEID_HIGH_OFF = 0,	/* inode fileid high */
+	FILEID_LOW_OFF,		/* inode fileid low */
+	FILE_I_TYPE_OFF,	/* inode type */
+	EMBED_FH_OFF		/* embeded server fh */
+};
+
+
+static struct nfs_fh *nfs_exp_embedfh(__u32 *p)
+{
+	return (struct nfs_fh *)(p + EMBED_FH_OFF);
+}
+
+/*
+ * Let's break subtree checking for now... otherwise we'll have to embed parent fh
+ * but there might not be enough space.
+ */
+static int
+nfs_encode_fh(struct inode *inode, __u32 *p, int *max_len, struct inode *parent)
+{
+	struct nfs_fh *server_fh = NFS_FH(inode);
+	struct nfs_fh *clnt_fh = nfs_exp_embedfh(p);
+	size_t fh_size = offsetof(struct nfs_fh, data) + server_fh->size;
+	int len = EMBED_FH_OFF + XDR_QUADLEN(fh_size);
+
+	dprintk("%s: max fh len %d inode %p parent %p",
+		__func__, *max_len, inode, parent);
+
+	if (*max_len < len || IS_AUTOMOUNT(inode)) {
+		dprintk("%s: fh len %d too small, required %d\n",
+			__func__, *max_len, len);
+		*max_len = len;
+		return FILEID_INVALID;
+	}
+	if (IS_AUTOMOUNT(inode)) {
+		*max_len = FILEID_INVALID;
+		goto out;
+	}
+
+	p[FILEID_HIGH_OFF] = NFS_FILEID(inode) >> 32;
+	p[FILEID_LOW_OFF] = NFS_FILEID(inode);
+	p[FILE_I_TYPE_OFF] = inode->i_mode & S_IFMT;
+	p[len - 1] = 0; /* Padding */
+	nfs_copy_fh(clnt_fh, server_fh);
+	*max_len = len;
+out:
+	dprintk("%s: result fh fileid %llu mode %u size %d\n",
+		__func__, NFS_FILEID(inode), inode->i_mode, *max_len);
+	return *max_len;
+}
+
+static struct dentry *
+nfs_fh_to_dentry(struct super_block *sb, struct fid *fid,
+		 int fh_len, int fh_type)
+{
+	struct nfs4_label *label = NULL;
+	struct nfs_fattr *fattr = NULL;
+	struct nfs_fh *server_fh = nfs_exp_embedfh(fid->raw);
+	size_t fh_size = offsetof(struct nfs_fh, data) + server_fh->size;
+	const struct nfs_rpc_ops *rpc_ops;
+	struct dentry *dentry;
+	struct inode *inode;
+	int len = EMBED_FH_OFF + XDR_QUADLEN(fh_size);
+	u32 *p = fid->raw;
+	int ret;
+
+	/* NULL translates to ESTALE */
+	if (fh_len < len || fh_type != len)
+		return NULL;
+
+	fattr = nfs_alloc_fattr();
+	if (fattr == NULL) {
+		dentry = ERR_PTR(-ENOMEM);
+		goto out;
+	}
+
+	fattr->fileid = ((u64)p[FILEID_HIGH_OFF] << 32) + p[FILEID_LOW_OFF];
+	fattr->mode = p[FILE_I_TYPE_OFF];
+	fattr->valid |= NFS_ATTR_FATTR_FILEID | NFS_ATTR_FATTR_TYPE;
+
+	dprintk("%s: fileid %llu mode %d\n", __func__, fattr->fileid, fattr->mode);
+
+	inode = nfs_ilookup(sb, fattr, server_fh);
+	if (inode)
+		goto out_found;
+
+	label = nfs4_label_alloc(NFS_SB(sb), GFP_KERNEL);
+	if (IS_ERR(label)) {
+		dentry = ERR_CAST(label);
+		goto out_free_fattr;
+	}
+
+	rpc_ops = NFS_SB(sb)->nfs_client->rpc_ops;
+	ret = rpc_ops->getattr(NFS_SB(sb), server_fh, fattr, label);
+	if (ret) {
+		dprintk("%s: getattr failed %d\n", __func__, ret);
+		dentry = ERR_PTR(ret);
+		goto out_free_label;
+	}
+
+	inode = nfs_fhget(sb, server_fh, fattr, label);
+
+out_found:
+	dentry = d_obtain_alias(inode);
+
+out_free_label:
+	nfs4_label_free(label);
+out_free_fattr:
+	nfs_free_fattr(fattr);
+out:
+	return dentry;
+}
+
+static struct dentry *
+nfs_get_parent(struct dentry *dentry)
+{
+	int ret;
+	struct inode *inode = d_inode(dentry), *pinode;
+	struct super_block *sb = inode->i_sb;
+	struct nfs_server *server = NFS_SB(sb);
+	struct nfs_fattr *fattr = NULL;
+	struct nfs4_label *label = NULL;
+	struct dentry *parent;
+	struct nfs_rpc_ops const *ops = server->nfs_client->rpc_ops;
+	struct nfs_fh fh;
+
+	if (!ops->lookupp)
+		return ERR_PTR(-EACCES);
+
+	fattr = nfs_alloc_fattr();
+	if (fattr == NULL) {
+		parent = ERR_PTR(-ENOMEM);
+		goto out;
+	}
+
+	label = nfs4_label_alloc(server, GFP_KERNEL);
+	if (IS_ERR(label)) {
+		parent = ERR_CAST(label);
+		goto out_free_fattr;
+	}
+
+	ret = ops->lookupp(inode, &fh, fattr, label);
+	if (ret) {
+		parent = ERR_PTR(ret);
+		goto out_free_label;
+	}
+
+	pinode = nfs_fhget(sb, &fh, fattr, label);
+	parent = d_obtain_alias(pinode);
+out_free_label:
+	nfs4_label_free(label);
+out_free_fattr:
+	nfs_free_fattr(fattr);
+out:
+	return parent;
+}
+
+const struct export_operations nfs_export_ops = {
+	.encode_fh = nfs_encode_fh,
+	.fh_to_dentry = nfs_fh_to_dentry,
+	.get_parent = nfs_get_parent,
+};
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index 3e24392f2caa..cb38c3cd6a49 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -10,6 +10,8 @@
 
 #define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS)
 
+extern const struct export_operations nfs_export_ops;
+
 struct nfs_string;
 
 /* Maximum number of readahead requests
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index eceb4eabb064..86781a630c22 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -2339,6 +2339,7 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info)
 		 */
 		sb->s_flags |= MS_POSIXACL;
 		sb->s_time_gran = 1;
+		sb->s_export_op = &nfs_export_ops;
 	}
 
  	nfs_initialise_sb(sb);
@@ -2360,6 +2361,7 @@ static void nfs_clone_super(struct super_block *sb,
 	sb->s_xattr = old_sb->s_xattr;
 	sb->s_op = old_sb->s_op;
 	sb->s_time_gran = 1;
+	sb->s_export_op = old_sb->s_export_op;
 
 	if (server->nfs_client->rpc_ops->version != 2) {
 		/* The VFS shouldn't apply the umask to mode bits. We will do
-- 
2.11.0


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

* Re: [PATCH 3/4] nfs4: add NFSv4 LOOKUPP handlers
  2017-06-27 15:44 ` [PATCH 3/4] nfs4: add NFSv4 LOOKUPP handlers Christoph Hellwig
@ 2017-06-28 14:55   ` Anna Schumaker
  2017-06-28 15:13     ` J. Bruce Fields
  2017-06-28 16:45     ` Christoph Hellwig
  0 siblings, 2 replies; 12+ messages in thread
From: Anna Schumaker @ 2017-06-28 14:55 UTC (permalink / raw)
  To: Christoph Hellwig, trond.myklebust, J. Bruce Fields; +Cc: jlayton, linux-nfs

Hi Christoph,

On 06/27/2017 11:44 AM, Christoph Hellwig wrote:
> From: Jeff Layton <jeff.layton@primarydata.com>
> 
> This will be needed in order to implement the get_parent export op
> for nfsd.

I think this patch conflicts with your constify and function pointer cleanups from a few weeks ago, and it may need to be updated.

Just double checking:  Bruce, are you taking the constify series for 4.13?

Thanks,
Anna

> 
> Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
> ---
>  fs/nfs/nfs4proc.c       | 49 +++++++++++++++++++++++++++++++++
>  fs/nfs/nfs4trace.h      | 29 ++++++++++++++++++++
>  fs/nfs/nfs4xdr.c        | 73 +++++++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/nfs4.h    |  1 +
>  include/linux/nfs_xdr.h | 17 +++++++++++-
>  5 files changed, 168 insertions(+), 1 deletion(-)
> 
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index c08c46a3b8cd..6fd9eee8e4ee 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -3802,6 +3802,54 @@ nfs4_proc_lookup_mountpoint(struct inode *dir, const struct qstr *name,
>  	return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client;
>  }
>  
> +static int _nfs4_proc_lookupp(struct inode *inode,
> +		struct nfs_fh *fhandle, struct nfs_fattr *fattr,
> +		struct nfs4_label *label)
> +{
> +	struct rpc_clnt *clnt = NFS_CLIENT(inode);
> +	struct nfs_server *server = NFS_SERVER(inode);
> +	int		       status;
> +	struct nfs4_lookupp_arg args = {
> +		.bitmask = server->attr_bitmask,
> +		.fh = NFS_FH(inode),
> +	};
> +	struct nfs4_lookupp_res res = {
> +		.server = server,
> +		.fattr = fattr,
> +		.label = label,
> +		.fh = fhandle,
> +	};
> +	struct rpc_message msg = {
> +		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUPP],
> +		.rpc_argp = &args,
> +		.rpc_resp = &res,
> +	};
> +
> +	args.bitmask = nfs4_bitmask(server, label);
> +
> +	nfs_fattr_init(fattr);
> +
> +	dprintk("NFS call  lookupp ino=0x%lx\n", inode->i_ino);
> +	status = nfs4_call_sync(clnt, server, &msg, &args.seq_args,
> +				&res.seq_res, 0);
> +	dprintk("NFS reply lookupp: %d\n", status);
> +	return status;
> +}
> +
> +static int nfs4_proc_lookupp(struct inode *inode, struct nfs_fh *fhandle,
> +			     struct nfs_fattr *fattr, struct nfs4_label *label)
> +{
> +	struct nfs4_exception exception = { };
> +	int err;
> +	do {
> +		err = _nfs4_proc_lookupp(inode, fhandle, fattr, label);
> +		trace_nfs4_lookupp(inode, err);
> +		err = nfs4_handle_exception(NFS_SERVER(inode), err,
> +				&exception);
> +	} while (exception.retry);
> +	return err;
> +}
> +
>  static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
>  {
>  	struct nfs_server *server = NFS_SERVER(inode);
> @@ -9312,6 +9360,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
>  	.getattr	= nfs4_proc_getattr,
>  	.setattr	= nfs4_proc_setattr,
>  	.lookup		= nfs4_proc_lookup,
> +	.lookupp	= nfs4_proc_lookupp,
>  	.access		= nfs4_proc_access,
>  	.readlink	= nfs4_proc_readlink,
>  	.create		= nfs4_proc_create,
> diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h
> index 845d0eadefc9..be1da19c65d6 100644
> --- a/fs/nfs/nfs4trace.h
> +++ b/fs/nfs/nfs4trace.h
> @@ -891,6 +891,35 @@ DEFINE_NFS4_LOOKUP_EVENT(nfs4_remove);
>  DEFINE_NFS4_LOOKUP_EVENT(nfs4_get_fs_locations);
>  DEFINE_NFS4_LOOKUP_EVENT(nfs4_secinfo);
>  
> +TRACE_EVENT(nfs4_lookupp,
> +		TP_PROTO(
> +			const struct inode *inode,
> +			int error
> +		),
> +
> +		TP_ARGS(inode, error),
> +
> +		TP_STRUCT__entry(
> +			__field(dev_t, dev)
> +			__field(u64, ino)
> +			__field(int, error)
> +		),
> +
> +		TP_fast_assign(
> +			__entry->dev = inode->i_sb->s_dev;
> +			__entry->ino = NFS_FILEID(inode);
> +			__entry->error = error;
> +		),
> +
> +		TP_printk(
> +			"error=%d (%s) inode=%02x:%02x:%llu",
> +			__entry->error,
> +			show_nfsv4_errors(__entry->error),
> +			MAJOR(__entry->dev), MINOR(__entry->dev),
> +			(unsigned long long)__entry->ino
> +		)
> +);
> +
>  TRACE_EVENT(nfs4_rename,
>  		TP_PROTO(
>  			const struct inode *olddir,
> diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
> index 3aebfdc82b30..b55017987dcd 100644
> --- a/fs/nfs/nfs4xdr.c
> +++ b/fs/nfs/nfs4xdr.c
> @@ -159,6 +159,8 @@ static int nfs4_stat_to_errno(int);
>  				(op_decode_hdr_maxsz)
>  #define encode_lookup_maxsz	(op_encode_hdr_maxsz + nfs4_name_maxsz)
>  #define decode_lookup_maxsz	(op_decode_hdr_maxsz)
> +#define encode_lookupp_maxsz	(op_encode_hdr_maxsz)
> +#define decode_lookupp_maxsz	(op_decode_hdr_maxsz)
>  #define encode_share_access_maxsz \
>  				(2)
>  #define encode_createmode_maxsz	(1 + encode_attrs_maxsz + encode_verifier_maxsz)
> @@ -618,6 +620,18 @@ static int nfs4_stat_to_errno(int);
>  				decode_lookup_maxsz + \
>  				decode_getattr_maxsz + \
>  				decode_getfh_maxsz)
> +#define NFS4_enc_lookupp_sz	(compound_encode_hdr_maxsz + \
> +				encode_sequence_maxsz + \
> +				encode_putfh_maxsz + \
> +				encode_lookupp_maxsz + \
> +				encode_getattr_maxsz + \
> +				encode_getfh_maxsz)
> +#define NFS4_dec_lookupp_sz	(compound_decode_hdr_maxsz + \
> +				decode_sequence_maxsz + \
> +				decode_putfh_maxsz + \
> +				decode_lookupp_maxsz + \
> +				decode_getattr_maxsz + \
> +				decode_getfh_maxsz)
>  #define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \
>  				encode_sequence_maxsz + \
>  				encode_putrootfh_maxsz + \
> @@ -1368,6 +1382,11 @@ static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struc
>  	encode_string(xdr, name->len, name->name);
>  }
>  
> +static void encode_lookupp(struct xdr_stream *xdr, struct compound_hdr *hdr)
> +{
> +	encode_op_hdr(xdr, OP_LOOKUPP, decode_lookupp_maxsz, hdr);
> +}
> +
>  static void encode_share_access(struct xdr_stream *xdr, u32 share_access)
>  {
>  	__be32 *p;
> @@ -2120,6 +2139,25 @@ static void nfs4_xdr_enc_lookup(struct rpc_rqst *req, struct xdr_stream *xdr,
>  }
>  
>  /*
> + * Encode LOOKUPP request
> + */
> +static void nfs4_xdr_enc_lookupp(struct rpc_rqst *req, struct xdr_stream *xdr,
> +				const struct nfs4_lookupp_arg *args)
> +{
> +	struct compound_hdr hdr = {
> +		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
> +	};
> +
> +	encode_compound_hdr(xdr, req, &hdr);
> +	encode_sequence(xdr, &args->seq_args, &hdr);
> +	encode_putfh(xdr, args->fh, &hdr);
> +	encode_lookupp(xdr, &hdr);
> +	encode_getfh(xdr, &hdr);
> +	encode_getfattr(xdr, args->bitmask, &hdr);
> +	encode_nops(&hdr);
> +}
> +
> +/*
>   * Encode LOOKUP_ROOT request
>   */
>  static void nfs4_xdr_enc_lookup_root(struct rpc_rqst *req,
> @@ -5005,6 +5043,11 @@ static int decode_lookup(struct xdr_stream *xdr)
>  	return decode_op_hdr(xdr, OP_LOOKUP);
>  }
>  
> +static int decode_lookupp(struct xdr_stream *xdr)
> +{
> +	return decode_op_hdr(xdr, OP_LOOKUPP);
> +}
> +
>  /* This is too sick! */
>  static int decode_space_limit(struct xdr_stream *xdr,
>  		unsigned long *pagemod_limit)
> @@ -6182,6 +6225,35 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
>  }
>  
>  /*
> + * Decode LOOKUPP response
> + */
> +static int nfs4_xdr_dec_lookupp(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
> +				struct nfs4_lookupp_res *res)
> +{
> +	struct compound_hdr hdr;
> +	int status;
> +
> +	status = decode_compound_hdr(xdr, &hdr);
> +	if (status)
> +		goto out;
> +	status = decode_sequence(xdr, &res->seq_res, rqstp);
> +	if (status)
> +		goto out;
> +	status = decode_putfh(xdr);
> +	if (status)
> +		goto out;
> +	status = decode_lookupp(xdr);
> +	if (status)
> +		goto out;
> +	status = decode_getfh(xdr, res->fh);
> +	if (status)
> +		goto out;
> +	status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
> +out:
> +	return status;
> +}
> +
> +/*
>   * Decode LOOKUP_ROOT response
>   */
>  static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp,
> @@ -7517,6 +7589,7 @@ struct rpc_procinfo	nfs4_procedures[] = {
>  	PROC(ACCESS,		enc_access,		dec_access),
>  	PROC(GETATTR,		enc_getattr,		dec_getattr),
>  	PROC(LOOKUP,		enc_lookup,		dec_lookup),
> +	PROC(LOOKUPP,		enc_lookupp,		dec_lookupp),
>  	PROC(LOOKUP_ROOT,	enc_lookup_root,	dec_lookup_root),
>  	PROC(REMOVE,		enc_remove,		dec_remove),
>  	PROC(RENAME,		enc_rename,		dec_rename),
> diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
> index 1b1ca04820a3..47239c336688 100644
> --- a/include/linux/nfs4.h
> +++ b/include/linux/nfs4.h
> @@ -479,6 +479,7 @@ enum {
>  	NFSPROC4_CLNT_ACCESS,
>  	NFSPROC4_CLNT_GETATTR,
>  	NFSPROC4_CLNT_LOOKUP,
> +	NFSPROC4_CLNT_LOOKUPP,
>  	NFSPROC4_CLNT_LOOKUP_ROOT,
>  	NFSPROC4_CLNT_REMOVE,
>  	NFSPROC4_CLNT_RENAME,
> diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
> index b28c83475ee8..7a664a5fcc25 100644
> --- a/include/linux/nfs_xdr.h
> +++ b/include/linux/nfs_xdr.h
> @@ -1012,7 +1012,6 @@ struct nfs4_link_res {
>  	struct nfs_fattr *		dir_attr;
>  };
>  
> -
>  struct nfs4_lookup_arg {
>  	struct nfs4_sequence_args	seq_args;
>  	const struct nfs_fh *		dir_fh;
> @@ -1028,6 +1027,20 @@ struct nfs4_lookup_res {
>  	struct nfs4_label		*label;
>  };
>  
> +struct nfs4_lookupp_arg {
> +	struct nfs4_sequence_args	seq_args;
> +	const struct nfs_fh		*fh;
> +	const u32			*bitmask;
> +};
> +
> +struct nfs4_lookupp_res {
> +	struct nfs4_sequence_res	seq_res;
> +	const struct nfs_server		*server;
> +	struct nfs_fattr		*fattr;
> +	struct nfs_fh			*fh;
> +	struct nfs4_label		*label;
> +};
> +
>  struct nfs4_lookup_root_arg {
>  	struct nfs4_sequence_args	seq_args;
>  	const u32 *			bitmask;
> @@ -1567,6 +1580,8 @@ struct nfs_rpc_ops {
>  	int	(*lookup)  (struct inode *, const struct qstr *,
>  			    struct nfs_fh *, struct nfs_fattr *,
>  			    struct nfs4_label *);
> +	int	(*lookupp) (struct inode *, struct nfs_fh *,
> +			    struct nfs_fattr *, struct nfs4_label *);
>  	int	(*access)  (struct inode *, struct nfs_access_entry *);
>  	int	(*readlink)(struct inode *, struct page *, unsigned int,
>  			    unsigned int);
> 

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

* Re: [PATCH 3/4] nfs4: add NFSv4 LOOKUPP handlers
  2017-06-28 14:55   ` Anna Schumaker
@ 2017-06-28 15:13     ` J. Bruce Fields
  2017-06-28 15:17       ` Anna Schumaker
  2017-06-28 16:45     ` Christoph Hellwig
  1 sibling, 1 reply; 12+ messages in thread
From: J. Bruce Fields @ 2017-06-28 15:13 UTC (permalink / raw)
  To: Anna Schumaker; +Cc: Christoph Hellwig, trond.myklebust, jlayton, linux-nfs

On Wed, Jun 28, 2017 at 10:55:35AM -0400, Anna Schumaker wrote:
> Hi Christoph,
> 
> On 06/27/2017 11:44 AM, Christoph Hellwig wrote:
> > From: Jeff Layton <jeff.layton@primarydata.com>
> > 
> > This will be needed in order to implement the get_parent export op
> > for nfsd.
> 
> I think this patch conflicts with your constify and function pointer cleanups from a few weeks ago, and it may need to be updated.
> 
> Just double checking:  Bruce, are you taking the constify series for 4.13?

Sorry, I haven't been paying attention--what constify series?

--b.

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

* Re: [PATCH 3/4] nfs4: add NFSv4 LOOKUPP handlers
  2017-06-28 15:13     ` J. Bruce Fields
@ 2017-06-28 15:17       ` Anna Schumaker
  2017-06-28 15:22         ` J. Bruce Fields
  0 siblings, 1 reply; 12+ messages in thread
From: Anna Schumaker @ 2017-06-28 15:17 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: Christoph Hellwig, trond.myklebust, jlayton, linux-nfs



On 06/28/2017 11:13 AM, J. Bruce Fields wrote:
> On Wed, Jun 28, 2017 at 10:55:35AM -0400, Anna Schumaker wrote:
>> Hi Christoph,
>>
>> On 06/27/2017 11:44 AM, Christoph Hellwig wrote:
>>> From: Jeff Layton <jeff.layton@primarydata.com>
>>>
>>> This will be needed in order to implement the get_parent export op
>>> for nfsd.
>>
>> I think this patch conflicts with your constify and function pointer cleanups from a few weeks ago, and it may need to be updated.
>>
>> Just double checking:  Bruce, are you taking the constify series for 4.13?
> 
> Sorry, I haven't been paying attention--what constify series?

The one Christoph sent out in May that touched all of nfs, nfsd, and sunrpc.  I wasn't sure if we had come to a decision about who is sending that in or not :)

> 
> --b.
> 

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

* Re: [PATCH 3/4] nfs4: add NFSv4 LOOKUPP handlers
  2017-06-28 15:17       ` Anna Schumaker
@ 2017-06-28 15:22         ` J. Bruce Fields
  0 siblings, 0 replies; 12+ messages in thread
From: J. Bruce Fields @ 2017-06-28 15:22 UTC (permalink / raw)
  To: Anna Schumaker; +Cc: Christoph Hellwig, trond.myklebust, jlayton, linux-nfs

On Wed, Jun 28, 2017 at 11:17:41AM -0400, Anna Schumaker wrote:
> 
> 
> On 06/28/2017 11:13 AM, J. Bruce Fields wrote:
> > On Wed, Jun 28, 2017 at 10:55:35AM -0400, Anna Schumaker wrote:
> >> Hi Christoph,
> >>
> >> On 06/27/2017 11:44 AM, Christoph Hellwig wrote:
> >>> From: Jeff Layton <jeff.layton@primarydata.com>
> >>>
> >>> This will be needed in order to implement the get_parent export op
> >>> for nfsd.
> >>
> >> I think this patch conflicts with your constify and function pointer cleanups from a few weeks ago, and it may need to be updated.
> >>
> >> Just double checking:  Bruce, are you taking the constify series for 4.13?
> > 
> > Sorry, I haven't been paying attention--what constify series?
> 
> The one Christoph sent out in May that touched all of nfs, nfsd, and sunrpc.  I wasn't sure if we had come to a decision about who is sending that in or not :)

Gah, right, sorry.  I still intend to just pull his nfs-ops branch, but
I think I got distracted by test failures caused by an unrelated vm
networking issues.  I'll take a look....

--b.

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

* Re: [PATCH 3/4] nfs4: add NFSv4 LOOKUPP handlers
  2017-06-28 14:55   ` Anna Schumaker
  2017-06-28 15:13     ` J. Bruce Fields
@ 2017-06-28 16:45     ` Christoph Hellwig
  2017-06-28 17:30       ` J. Bruce Fields
  1 sibling, 1 reply; 12+ messages in thread
From: Christoph Hellwig @ 2017-06-28 16:45 UTC (permalink / raw)
  To: Anna Schumaker
  Cc: Christoph Hellwig, trond.myklebust, J. Bruce Fields, jlayton, linux-nfs

On Wed, Jun 28, 2017 at 10:55:35AM -0400, Anna Schumaker wrote:
> Hi Christoph,
> 
> On 06/27/2017 11:44 AM, Christoph Hellwig wrote:
> > From: Jeff Layton <jeff.layton@primarydata.com>
> > 
> > This will be needed in order to implement the get_parent export op
> > for nfsd.
> 
> I think this patch conflicts with your constify and function pointer cleanups from a few weeks ago, and it may need to be updated.
> 
> Just double checking:  Bruce, are you taking the constify series for 4.13?

Seems like it's in linux-next through Bruce's tree.

I can respin these patches against it.  Anna, Trond: are you fine
with just basing the nfs tree on top of the nfsd one?  Or do we want
to take this series through the nfsd tree?

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

* Re: [PATCH 3/4] nfs4: add NFSv4 LOOKUPP handlers
  2017-06-28 16:45     ` Christoph Hellwig
@ 2017-06-28 17:30       ` J. Bruce Fields
  0 siblings, 0 replies; 12+ messages in thread
From: J. Bruce Fields @ 2017-06-28 17:30 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Anna Schumaker, trond.myklebust, jlayton, linux-nfs

On Wed, Jun 28, 2017 at 06:45:35PM +0200, Christoph Hellwig wrote:
> On Wed, Jun 28, 2017 at 10:55:35AM -0400, Anna Schumaker wrote:
> > Hi Christoph,
> > 
> > On 06/27/2017 11:44 AM, Christoph Hellwig wrote:
> > > From: Jeff Layton <jeff.layton@primarydata.com>
> > > 
> > > This will be needed in order to implement the get_parent export op
> > > for nfsd.
> > 
> > I think this patch conflicts with your constify and function pointer cleanups from a few weeks ago, and it may need to be updated.
> > 
> > Just double checking:  Bruce, are you taking the constify series for 4.13?
> 
> Seems like it's in linux-next through Bruce's tree.

That's literally just your nfs-ops branch.  I was assuming that's what
we'd both work on top of.

--b.

> I can respin these patches against it.  Anna, Trond: are you fine
> with just basing the nfs tree on top of the nfsd one?  Or do we want
> to take this series through the nfsd tree?

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

* [PATCH 3/4] nfs4: add NFSv4 LOOKUPP handlers
  2017-06-29 13:34 open by handle support for NFS V2 Christoph Hellwig
@ 2017-06-29 13:34 ` Christoph Hellwig
  0 siblings, 0 replies; 12+ messages in thread
From: Christoph Hellwig @ 2017-06-29 13:34 UTC (permalink / raw)
  To: trond.myklebust; +Cc: jlayton, schumaker.anna, bfields, linux-nfs, Jeff Layton

From: Jeff Layton <jeff.layton@primarydata.com>

This will be needed in order to implement the get_parent export op
for nfsd.

Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
---
 fs/nfs/nfs4proc.c       | 49 ++++++++++++++++++++++++++++++++
 fs/nfs/nfs4trace.h      | 29 +++++++++++++++++++
 fs/nfs/nfs4xdr.c        | 75 +++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/nfs4.h    |  1 +
 include/linux/nfs_xdr.h | 17 ++++++++++-
 5 files changed, 170 insertions(+), 1 deletion(-)

diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index c08c46a3b8cd..6fd9eee8e4ee 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -3802,6 +3802,54 @@ nfs4_proc_lookup_mountpoint(struct inode *dir, const struct qstr *name,
 	return (client == NFS_CLIENT(dir)) ? rpc_clone_client(client) : client;
 }
 
+static int _nfs4_proc_lookupp(struct inode *inode,
+		struct nfs_fh *fhandle, struct nfs_fattr *fattr,
+		struct nfs4_label *label)
+{
+	struct rpc_clnt *clnt = NFS_CLIENT(inode);
+	struct nfs_server *server = NFS_SERVER(inode);
+	int		       status;
+	struct nfs4_lookupp_arg args = {
+		.bitmask = server->attr_bitmask,
+		.fh = NFS_FH(inode),
+	};
+	struct nfs4_lookupp_res res = {
+		.server = server,
+		.fattr = fattr,
+		.label = label,
+		.fh = fhandle,
+	};
+	struct rpc_message msg = {
+		.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_LOOKUPP],
+		.rpc_argp = &args,
+		.rpc_resp = &res,
+	};
+
+	args.bitmask = nfs4_bitmask(server, label);
+
+	nfs_fattr_init(fattr);
+
+	dprintk("NFS call  lookupp ino=0x%lx\n", inode->i_ino);
+	status = nfs4_call_sync(clnt, server, &msg, &args.seq_args,
+				&res.seq_res, 0);
+	dprintk("NFS reply lookupp: %d\n", status);
+	return status;
+}
+
+static int nfs4_proc_lookupp(struct inode *inode, struct nfs_fh *fhandle,
+			     struct nfs_fattr *fattr, struct nfs4_label *label)
+{
+	struct nfs4_exception exception = { };
+	int err;
+	do {
+		err = _nfs4_proc_lookupp(inode, fhandle, fattr, label);
+		trace_nfs4_lookupp(inode, err);
+		err = nfs4_handle_exception(NFS_SERVER(inode), err,
+				&exception);
+	} while (exception.retry);
+	return err;
+}
+
 static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
@@ -9312,6 +9360,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
 	.getattr	= nfs4_proc_getattr,
 	.setattr	= nfs4_proc_setattr,
 	.lookup		= nfs4_proc_lookup,
+	.lookupp	= nfs4_proc_lookupp,
 	.access		= nfs4_proc_access,
 	.readlink	= nfs4_proc_readlink,
 	.create		= nfs4_proc_create,
diff --git a/fs/nfs/nfs4trace.h b/fs/nfs/nfs4trace.h
index 845d0eadefc9..be1da19c65d6 100644
--- a/fs/nfs/nfs4trace.h
+++ b/fs/nfs/nfs4trace.h
@@ -891,6 +891,35 @@ DEFINE_NFS4_LOOKUP_EVENT(nfs4_remove);
 DEFINE_NFS4_LOOKUP_EVENT(nfs4_get_fs_locations);
 DEFINE_NFS4_LOOKUP_EVENT(nfs4_secinfo);
 
+TRACE_EVENT(nfs4_lookupp,
+		TP_PROTO(
+			const struct inode *inode,
+			int error
+		),
+
+		TP_ARGS(inode, error),
+
+		TP_STRUCT__entry(
+			__field(dev_t, dev)
+			__field(u64, ino)
+			__field(int, error)
+		),
+
+		TP_fast_assign(
+			__entry->dev = inode->i_sb->s_dev;
+			__entry->ino = NFS_FILEID(inode);
+			__entry->error = error;
+		),
+
+		TP_printk(
+			"error=%d (%s) inode=%02x:%02x:%llu",
+			__entry->error,
+			show_nfsv4_errors(__entry->error),
+			MAJOR(__entry->dev), MINOR(__entry->dev),
+			(unsigned long long)__entry->ino
+		)
+);
+
 TRACE_EVENT(nfs4_rename,
 		TP_PROTO(
 			const struct inode *olddir,
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 0f1f290c97cd..ad50ae499b6b 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -159,6 +159,8 @@ static int nfs4_stat_to_errno(int);
 				(op_decode_hdr_maxsz)
 #define encode_lookup_maxsz	(op_encode_hdr_maxsz + nfs4_name_maxsz)
 #define decode_lookup_maxsz	(op_decode_hdr_maxsz)
+#define encode_lookupp_maxsz	(op_encode_hdr_maxsz)
+#define decode_lookupp_maxsz	(op_decode_hdr_maxsz)
 #define encode_share_access_maxsz \
 				(2)
 #define encode_createmode_maxsz	(1 + encode_attrs_maxsz + encode_verifier_maxsz)
@@ -618,6 +620,18 @@ static int nfs4_stat_to_errno(int);
 				decode_lookup_maxsz + \
 				decode_getattr_maxsz + \
 				decode_getfh_maxsz)
+#define NFS4_enc_lookupp_sz	(compound_encode_hdr_maxsz + \
+				encode_sequence_maxsz + \
+				encode_putfh_maxsz + \
+				encode_lookupp_maxsz + \
+				encode_getattr_maxsz + \
+				encode_getfh_maxsz)
+#define NFS4_dec_lookupp_sz	(compound_decode_hdr_maxsz + \
+				decode_sequence_maxsz + \
+				decode_putfh_maxsz + \
+				decode_lookupp_maxsz + \
+				decode_getattr_maxsz + \
+				decode_getfh_maxsz)
 #define NFS4_enc_lookup_root_sz (compound_encode_hdr_maxsz + \
 				encode_sequence_maxsz + \
 				encode_putrootfh_maxsz + \
@@ -1368,6 +1382,11 @@ static void encode_lookup(struct xdr_stream *xdr, const struct qstr *name, struc
 	encode_string(xdr, name->len, name->name);
 }
 
+static void encode_lookupp(struct xdr_stream *xdr, struct compound_hdr *hdr)
+{
+	encode_op_hdr(xdr, OP_LOOKUPP, decode_lookupp_maxsz, hdr);
+}
+
 static void encode_share_access(struct xdr_stream *xdr, u32 share_access)
 {
 	__be32 *p;
@@ -2123,6 +2142,26 @@ static void nfs4_xdr_enc_lookup(struct rpc_rqst *req, struct xdr_stream *xdr,
 }
 
 /*
+ * Encode LOOKUPP request
+ */
+static void nfs4_xdr_enc_lookupp(struct rpc_rqst *req, struct xdr_stream *xdr,
+		const void *data)
+{
+	const struct nfs4_lookupp_arg *args = data;
+	struct compound_hdr hdr = {
+		.minorversion = nfs4_xdr_minorversion(&args->seq_args),
+	};
+
+	encode_compound_hdr(xdr, req, &hdr);
+	encode_sequence(xdr, &args->seq_args, &hdr);
+	encode_putfh(xdr, args->fh, &hdr);
+	encode_lookupp(xdr, &hdr);
+	encode_getfh(xdr, &hdr);
+	encode_getfattr(xdr, args->bitmask, &hdr);
+	encode_nops(&hdr);
+}
+
+/*
  * Encode LOOKUP_ROOT request
  */
 static void nfs4_xdr_enc_lookup_root(struct rpc_rqst *req,
@@ -5058,6 +5097,11 @@ static int decode_lookup(struct xdr_stream *xdr)
 	return decode_op_hdr(xdr, OP_LOOKUP);
 }
 
+static int decode_lookupp(struct xdr_stream *xdr)
+{
+	return decode_op_hdr(xdr, OP_LOOKUPP);
+}
+
 /* This is too sick! */
 static int decode_space_limit(struct xdr_stream *xdr,
 		unsigned long *pagemod_limit)
@@ -6238,6 +6282,36 @@ static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
 }
 
 /*
+ * Decode LOOKUPP response
+ */
+static int nfs4_xdr_dec_lookupp(struct rpc_rqst *rqstp, struct xdr_stream *xdr,
+		void *data)
+{
+	struct nfs4_lookupp_res *res = data;
+	struct compound_hdr hdr;
+	int status;
+
+	status = decode_compound_hdr(xdr, &hdr);
+	if (status)
+		goto out;
+	status = decode_sequence(xdr, &res->seq_res, rqstp);
+	if (status)
+		goto out;
+	status = decode_putfh(xdr);
+	if (status)
+		goto out;
+	status = decode_lookupp(xdr);
+	if (status)
+		goto out;
+	status = decode_getfh(xdr, res->fh);
+	if (status)
+		goto out;
+	status = decode_getfattr_label(xdr, res->fattr, res->label, res->server);
+out:
+	return status;
+}
+
+/*
  * Decode LOOKUP_ROOT response
  */
 static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp,
@@ -7614,6 +7688,7 @@ const struct rpc_procinfo nfs4_procedures[] = {
 	PROC(ACCESS,		enc_access,		dec_access),
 	PROC(GETATTR,		enc_getattr,		dec_getattr),
 	PROC(LOOKUP,		enc_lookup,		dec_lookup),
+	PROC(LOOKUPP,		enc_lookupp,		dec_lookupp),
 	PROC(LOOKUP_ROOT,	enc_lookup_root,	dec_lookup_root),
 	PROC(REMOVE,		enc_remove,		dec_remove),
 	PROC(RENAME,		enc_rename,		dec_rename),
diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
index 1b1ca04820a3..47239c336688 100644
--- a/include/linux/nfs4.h
+++ b/include/linux/nfs4.h
@@ -479,6 +479,7 @@ enum {
 	NFSPROC4_CLNT_ACCESS,
 	NFSPROC4_CLNT_GETATTR,
 	NFSPROC4_CLNT_LOOKUP,
+	NFSPROC4_CLNT_LOOKUPP,
 	NFSPROC4_CLNT_LOOKUP_ROOT,
 	NFSPROC4_CLNT_REMOVE,
 	NFSPROC4_CLNT_RENAME,
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index b28c83475ee8..7a664a5fcc25 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1012,7 +1012,6 @@ struct nfs4_link_res {
 	struct nfs_fattr *		dir_attr;
 };
 
-
 struct nfs4_lookup_arg {
 	struct nfs4_sequence_args	seq_args;
 	const struct nfs_fh *		dir_fh;
@@ -1028,6 +1027,20 @@ struct nfs4_lookup_res {
 	struct nfs4_label		*label;
 };
 
+struct nfs4_lookupp_arg {
+	struct nfs4_sequence_args	seq_args;
+	const struct nfs_fh		*fh;
+	const u32			*bitmask;
+};
+
+struct nfs4_lookupp_res {
+	struct nfs4_sequence_res	seq_res;
+	const struct nfs_server		*server;
+	struct nfs_fattr		*fattr;
+	struct nfs_fh			*fh;
+	struct nfs4_label		*label;
+};
+
 struct nfs4_lookup_root_arg {
 	struct nfs4_sequence_args	seq_args;
 	const u32 *			bitmask;
@@ -1567,6 +1580,8 @@ struct nfs_rpc_ops {
 	int	(*lookup)  (struct inode *, const struct qstr *,
 			    struct nfs_fh *, struct nfs_fattr *,
 			    struct nfs4_label *);
+	int	(*lookupp) (struct inode *, struct nfs_fh *,
+			    struct nfs_fattr *, struct nfs4_label *);
 	int	(*access)  (struct inode *, struct nfs_access_entry *);
 	int	(*readlink)(struct inode *, struct page *, unsigned int,
 			    unsigned int);
-- 
2.11.0


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

end of thread, other threads:[~2017-06-29 13:34 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-27 15:43 open by handle support for NFS Christoph Hellwig
2017-06-27 15:44 ` [PATCH 1/4] nfs: replace d_add with d_splice_alias in atomic_open Christoph Hellwig
2017-06-27 15:44 ` [PATCH 2/4] nfs: add a nfs_ilookup helper Christoph Hellwig
2017-06-27 15:44 ` [PATCH 3/4] nfs4: add NFSv4 LOOKUPP handlers Christoph Hellwig
2017-06-28 14:55   ` Anna Schumaker
2017-06-28 15:13     ` J. Bruce Fields
2017-06-28 15:17       ` Anna Schumaker
2017-06-28 15:22         ` J. Bruce Fields
2017-06-28 16:45     ` Christoph Hellwig
2017-06-28 17:30       ` J. Bruce Fields
2017-06-27 15:44 ` [PATCH 4/4] nfs: add export operations Christoph Hellwig
2017-06-29 13:34 open by handle support for NFS V2 Christoph Hellwig
2017-06-29 13:34 ` [PATCH 3/4] nfs4: add NFSv4 LOOKUPP handlers Christoph Hellwig

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.