From 011e2a7fd5e9e0c2fdba6b9466d53fc437f8bfaf Mon Sep 17 00:00:00 2001
From: Bryan Schumaker <bjschuma@netapp.com>
Date: Wed, 20 Jun 2012 15:53:43 -0400
Subject: NFS: Create a have_delegation rpc_op

Delegations are a v4 feature, so push them out of the generic code.

Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
 fs/nfs/inode.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'fs/nfs/inode.c')

diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index f7296983eba..0f0b928ef25 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1457,7 +1457,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
 	if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)
 				|| S_ISLNK(inode->i_mode)))
 		invalid &= ~NFS_INO_INVALID_DATA;
-	if (!nfs_have_delegation(inode, FMODE_READ) ||
+	if (!NFS_PROTO(inode)->have_delegation(inode, FMODE_READ) ||
 			(save_cache_validity & NFS_INO_REVAL_FORCED))
 		nfsi->cache_validity |= invalid;
 
-- 
cgit v1.2.3-70-g09d2


From 57ec14c55dee2733330327499d16e40f8c23219e Mon Sep 17 00:00:00 2001
From: Bryan Schumaker <bjschuma@netapp.com>
Date: Wed, 20 Jun 2012 15:53:44 -0400
Subject: NFS: Create a return_delegation rpc op

Delegations are a v4 feature, so push return_delegation out of the
generic client by creating a new rpc_op and renaming the old function to
be in the nfs v4 "namespace"

Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
 fs/nfs/delegation.c     | 2 +-
 fs/nfs/delegation.h     | 8 +-------
 fs/nfs/dir.c            | 8 ++++----
 fs/nfs/inode.c          | 2 +-
 fs/nfs/nfs3proc.c       | 7 +++++++
 fs/nfs/nfs4proc.c       | 7 ++++---
 fs/nfs/proc.c           | 7 +++++++
 fs/nfs/unlink.c         | 2 +-
 include/linux/nfs_xdr.h | 1 +
 9 files changed, 27 insertions(+), 17 deletions(-)

(limited to 'fs/nfs/inode.c')

diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c
index 36c7c647a1d..81c5eec3cf3 100644
--- a/fs/nfs/delegation.c
+++ b/fs/nfs/delegation.c
@@ -388,7 +388,7 @@ void nfs_inode_return_delegation_noreclaim(struct inode *inode)
  *
  * Returns zero on success, or a negative errno value.
  */
-int nfs_inode_return_delegation(struct inode *inode)
+int nfs4_inode_return_delegation(struct inode *inode)
 {
 	struct nfs_server *server = NFS_SERVER(inode);
 	struct nfs_inode *nfsi = NFS_I(inode);
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index d134fc5fda7..1f3ccd93463 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -33,7 +33,7 @@ enum {
 
 int nfs_inode_set_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
 void nfs_inode_reclaim_delegation(struct inode *inode, struct rpc_cred *cred, struct nfs_openres *res);
-int nfs_inode_return_delegation(struct inode *inode);
+int nfs4_inode_return_delegation(struct inode *inode);
 int nfs_async_inode_return_delegation(struct inode *inode, const nfs4_stateid *stateid);
 void nfs_inode_return_delegation_noreclaim(struct inode *inode);
 
@@ -58,12 +58,6 @@ bool nfs4_copy_delegation_stateid(nfs4_stateid *dst, struct inode *inode, fmode_
 void nfs_mark_delegation_referenced(struct nfs_delegation *delegation);
 int nfs4_have_delegation(struct inode *inode, fmode_t flags);
 
-#else
-static inline int nfs_inode_return_delegation(struct inode *inode)
-{
-	nfs_wb_all(inode);
-	return 0;
-}
 #endif
 
 static inline int nfs_have_delegated_attributes(struct inode *inode)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 4a3e23aea14..68e451f5930 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1778,7 +1778,7 @@ static int nfs_safe_remove(struct dentry *dentry)
 	}
 
 	if (inode != NULL) {
-		nfs_inode_return_delegation(inode);
+		NFS_PROTO(inode)->return_delegation(inode);
 		error = NFS_PROTO(dir)->remove(dir, &dentry->d_name);
 		/* The VFS may want to delete this inode */
 		if (error == 0)
@@ -1906,7 +1906,7 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
 		old_dentry->d_parent->d_name.name, old_dentry->d_name.name,
 		dentry->d_parent->d_name.name, dentry->d_name.name);
 
-	nfs_inode_return_delegation(inode);
+	NFS_PROTO(inode)->return_delegation(inode);
 
 	d_drop(dentry);
 	error = NFS_PROTO(dir)->link(inode, dir, &dentry->d_name);
@@ -1990,9 +1990,9 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
 		}
 	}
 
-	nfs_inode_return_delegation(old_inode);
+	NFS_PROTO(old_inode)->return_delegation(old_inode);
 	if (new_inode != NULL)
-		nfs_inode_return_delegation(new_inode);
+		NFS_PROTO(new_inode)->return_delegation(new_inode);
 
 	error = NFS_PROTO(old_dir)->rename(old_dir, &old_dentry->d_name,
 					   new_dir, &new_dentry->d_name);
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 0f0b928ef25..28c9ebbe78a 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -430,7 +430,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
 	 * Return any delegations if we're going to change ACLs
 	 */
 	if ((attr->ia_valid & (ATTR_MODE|ATTR_UID|ATTR_GID)) != 0)
-		nfs_inode_return_delegation(inode);
+		NFS_PROTO(inode)->return_delegation(inode);
 	error = NFS_PROTO(inode)->setattr(dentry, fattr, attr);
 	if (error == 0)
 		nfs_refresh_inode(inode, fattr);
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 08f832634ef..4749a32e54b 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -882,6 +882,12 @@ static int nfs3_have_delegation(struct inode *inode, fmode_t flags)
 	return 0;
 }
 
+static int nfs3_return_delegation(struct inode *inode)
+{
+	nfs_wb_all(inode);
+	return 0;
+}
+
 const struct nfs_rpc_ops nfs_v3_clientops = {
 	.version	= 3,			/* protocol version */
 	.dentry_ops	= &nfs_dentry_operations,
@@ -927,5 +933,6 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
 	.clear_acl_cache = nfs3_forget_cached_acls,
 	.close_context	= nfs_close_context,
 	.have_delegation = nfs3_have_delegation,
+	.return_delegation = nfs3_return_delegation,
 	.init_client	= nfs_init_client,
 };
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 86f428bb5e0..035f7a0829e 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -295,7 +295,7 @@ static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struc
 			return 0;
 		case -NFS4ERR_OPENMODE:
 			if (inode && nfs4_have_delegation(inode, FMODE_READ)) {
-				nfs_inode_return_delegation(inode);
+				nfs4_inode_return_delegation(inode);
 				exception->retry = 1;
 				return 0;
 			}
@@ -1065,7 +1065,7 @@ static void nfs4_return_incompatible_delegation(struct inode *inode, fmode_t fmo
 		return;
 	}
 	rcu_read_unlock();
-	nfs_inode_return_delegation(inode);
+	nfs4_inode_return_delegation(inode);
 }
 
 static struct nfs4_state *nfs4_try_open_cached(struct nfs4_opendata *opendata)
@@ -3870,7 +3870,7 @@ static int __nfs4_proc_set_acl(struct inode *inode, const void *buf, size_t bufl
 	i = buf_to_pages_noslab(buf, buflen, arg.acl_pages, &arg.acl_pgbase);
 	if (i < 0)
 		return i;
-	nfs_inode_return_delegation(inode);
+	nfs4_inode_return_delegation(inode);
 	ret = nfs4_call_sync(server->client, server, &msg, &arg.seq_args, &res.seq_res, 1);
 
 	/*
@@ -6805,6 +6805,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
 	.close_context  = nfs4_close_context,
 	.open_context	= nfs4_atomic_open,
 	.have_delegation = nfs4_have_delegation,
+	.return_delegation = nfs4_inode_return_delegation,
 	.init_client	= nfs4_init_client,
 };
 
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 4aed3ddf9bb..16632930abd 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -739,6 +739,12 @@ static int nfs_have_delegation(struct inode *inode, fmode_t flags)
 	return 0;
 }
 
+static int nfs_return_delegation(struct inode *inode)
+{
+	nfs_wb_all(inode);
+	return 0;
+}
+
 const struct nfs_rpc_ops nfs_v2_clientops = {
 	.version	= 2,		       /* protocol version */
 	.dentry_ops	= &nfs_dentry_operations,
@@ -783,5 +789,6 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
 	.lock_check_bounds = nfs_lock_check_bounds,
 	.close_context	= nfs_close_context,
 	.have_delegation = nfs_have_delegation,
+	.return_delegation = nfs_return_delegation,
 	.init_client	= nfs_init_client,
 };
diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c
index 3210a03342f..13cea637eff 100644
--- a/fs/nfs/unlink.c
+++ b/fs/nfs/unlink.c
@@ -501,7 +501,7 @@ nfs_sillyrename(struct inode *dir, struct dentry *dentry)
 		(unsigned long long)NFS_FILEID(dentry->d_inode));
 
 	/* Return delegation in anticipation of the rename */
-	nfs_inode_return_delegation(dentry->d_inode);
+	NFS_PROTO(dentry->d_inode)->return_delegation(dentry->d_inode);
 
 	sdentry = NULL;
 	do {
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h
index 8787f77c64b..62235be07fb 100644
--- a/include/linux/nfs_xdr.h
+++ b/include/linux/nfs_xdr.h
@@ -1423,6 +1423,7 @@ struct nfs_rpc_ops {
 				int open_flags,
 				struct iattr *iattr);
 	int (*have_delegation)(struct inode *, fmode_t);
+	int (*return_delegation)(struct inode *);
 	struct nfs_client *
 		(*init_client) (struct nfs_client *, const struct rpc_timeout *,
 				const char *, rpc_authflavor_t);
-- 
cgit v1.2.3-70-g09d2


From 129d1977ed39cbb4f091a518e4a12498c04f45ba Mon Sep 17 00:00:00 2001
From: Bryan Schumaker <bjschuma@netapp.com>
Date: Mon, 16 Jul 2012 16:39:13 -0400
Subject: NFS: Create an init_nfs_v4() function

I want to initialize all of NFS v4 in a single function that will
eventually be used as the v4 module init function.

Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
---
 fs/nfs/Makefile    |  2 +-
 fs/nfs/inode.c     | 67 ++++++++++++++++++++++++++++++------------------------
 fs/nfs/nfs4_fs.h   |  4 ++++
 fs/nfs/nfs4super.c | 23 +++++++++++++++++++
 4 files changed, 65 insertions(+), 31 deletions(-)
 create mode 100644 fs/nfs/nfs4super.c

(limited to 'fs/nfs/inode.c')

diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index 7ddd45d9f17..162a699134c 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -13,7 +13,7 @@ nfs-$(CONFIG_NFS_V2)	+= proc.o nfs2xdr.o
 nfs-$(CONFIG_NFS_V3)	+= nfs3proc.o nfs3xdr.o
 nfs-$(CONFIG_NFS_V3_ACL)	+= nfs3acl.o
 nfs-$(CONFIG_NFS_V4)	+= nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
-			   delegation.o idmap.o \
+			   nfs4super.o delegation.o idmap.o \
 			   callback.o callback_xdr.o callback_proc.o \
 			   nfs4namespace.o
 nfs-$(CONFIG_NFS_V4_1)	+= pnfs.o pnfs_dev.o
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 28c9ebbe78a..35f7e4bc680 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -32,7 +32,6 @@
 #include <linux/lockd/bind.h>
 #include <linux/seq_file.h>
 #include <linux/mount.h>
-#include <linux/nfs_idmap.h>
 #include <linux/vfs.h>
 #include <linux/inet.h>
 #include <linux/nfs_xdr.h>
@@ -1628,87 +1627,96 @@ static int __init init_nfs_fs(void)
 {
 	int err;
 
-	err = nfs_idmap_init();
-	if (err < 0)
-		goto out10;
-
 	err = nfs_dns_resolver_init();
 	if (err < 0)
-		goto out9;
+		goto out11;
 
 	err = register_pernet_subsys(&nfs_net_ops);
 	if (err < 0)
-		goto out8;
+		goto out10;
 
 	err = nfs_fscache_register();
 	if (err < 0)
-		goto out7;
+		goto out9;
 
 	err = nfsiod_start();
 	if (err)
-		goto out6;
+		goto out8;
 
 	err = nfs_fs_proc_init();
 	if (err)
-		goto out5;
+		goto out7;
 
 	err = nfs_init_nfspagecache();
 	if (err)
-		goto out4;
+		goto out6;
 
 	err = nfs_init_inodecache();
 	if (err)
-		goto out3;
+		goto out5;
 
 	err = nfs_init_readpagecache();
 	if (err)
-		goto out2;
+		goto out4;
 
 	err = nfs_init_writepagecache();
 	if (err)
-		goto out1;
+		goto out3;
 
 	err = nfs_init_directcache();
 	if (err)
-		goto out0;
+		goto out2;
 
 #ifdef CONFIG_PROC_FS
 	rpc_proc_register(&init_net, &nfs_rpcstat);
 #endif
+
+#ifdef CONFIG_NFS_V4
+	err = init_nfs_v4();
+	if (err)
+		goto out1;
+#endif
+
 	if ((err = register_nfs_fs()) != 0)
-		goto out;
+		goto out0;
+
 	return 0;
-out:
+out0:
+#ifdef CONFIG_NFS_V4
+	exit_nfs_v4();
+out1:
+#endif
 #ifdef CONFIG_PROC_FS
 	rpc_proc_unregister(&init_net, "nfs");
 #endif
 	nfs_destroy_directcache();
-out0:
-	nfs_destroy_writepagecache();
-out1:
-	nfs_destroy_readpagecache();
 out2:
-	nfs_destroy_inodecache();
+	nfs_destroy_writepagecache();
 out3:
-	nfs_destroy_nfspagecache();
+	nfs_destroy_readpagecache();
 out4:
-	nfs_fs_proc_exit();
+	nfs_destroy_inodecache();
 out5:
-	nfsiod_stop();
+	nfs_destroy_nfspagecache();
 out6:
-	nfs_fscache_unregister();
+	nfs_fs_proc_exit();
 out7:
-	unregister_pernet_subsys(&nfs_net_ops);
+	nfsiod_stop();
 out8:
-	nfs_dns_resolver_destroy();
+	nfs_fscache_unregister();
 out9:
-	nfs_idmap_quit();
+	unregister_pernet_subsys(&nfs_net_ops);
 out10:
+	nfs_dns_resolver_destroy();
+out11:
 	return err;
 }
 
 static void __exit exit_nfs_fs(void)
 {
+#ifdef CONFIG_NFS_V4
+	exit_nfs_v4();
+#endif
 	nfs_destroy_directcache();
 	nfs_destroy_writepagecache();
 	nfs_destroy_readpagecache();
@@ -1717,7 +1725,6 @@ static void __exit exit_nfs_fs(void)
 	nfs_fscache_unregister();
 	unregister_pernet_subsys(&nfs_net_ops);
 	nfs_dns_resolver_destroy();
-	nfs_idmap_quit();
 #ifdef CONFIG_PROC_FS
 	rpc_proc_unregister(&init_net, "nfs");
 #endif
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index e2c4c72d386..1a6ed3f9a32 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -364,6 +364,10 @@ extern void nfs4_free_lock_state(struct nfs_server *server, struct nfs4_lock_sta
 
 extern const nfs4_stateid zero_stateid;
 
+/* nfs4super.c */
+int init_nfs_v4(void);
+void exit_nfs_v4(void);
+
 /* nfs4xdr.c */
 extern struct rpc_procinfo nfs4_procedures[];
 
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
new file mode 100644
index 00000000000..366e4145969
--- /dev/null
+++ b/fs/nfs/nfs4super.c
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2012 Bryan Schumaker <bjschuma@netapp.com>
+ */
+#include <linux/init.h>
+#include <linux/nfs_idmap.h>
+
+int __init init_nfs_v4(void)
+{
+	int err;
+
+	err = nfs_idmap_init();
+	if (err)
+		goto out;
+
+	return 0;
+out:
+	return err;
+}
+
+void __exit exit_nfs_v4(void)
+{
+	nfs_idmap_quit();
+}
-- 
cgit v1.2.3-70-g09d2