aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-07-31 21:45:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-07-31 21:45:44 -0400
commit6dbb35b0a74b44b2a48a5373d48074c5aa69fdf5 (patch)
tree4afb5eec521659e19c9d2343c2431054a082eb06 /fs
parentfd37ce34bd512f2b1a503f82abf8768da556a955 (diff)
parentad0fcd4eb68059de02e1766948263c71b8a5b1dc (diff)
Merge tag 'nfs-for-3.6-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull second wave of NFS client updates from Trond Myklebust: - Patches from Bryan to allow splitting of the NFSv2/v3/v4 code into separate modules. - Fix Oopses in the NFSv4 idmapper - Fix a deadlock whereby rpciod tries to allocate a new socket and ends up recursing into the NFS code due to memory reclaim. - Increase the number of permitted callback connections. * tag 'nfs-for-3.6-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: nfs: explicitly reject LOCK_MAND flock() requests nfs: increase number of permitted callback connections. SUNRPC: return negative value in case rpcbind client creation error NFS: Convert v4 into a module NFS: Convert v3 into a module NFS: Convert v2 into a module NFS: Keep module parameters in the generic NFS client NFS: Split out remaining NFS v4 inode functions NFS: Pass super operations and xattr handlers in the nfs_subversion NFS: Only initialize the ACL client in the v3 case NFS: Create a try_mount rpc op NFS: Remove the NFS v4 xdev mount function NFS: Add version registering framework NFS: Fix a number of bugs in the idmapper nfs: skip commit in releasepage if we're freeing memory for fs-related reasons sunrpc: clarify comments on rpc_make_runnable pnfsblock: bail out partial page IO
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/Kconfig6
-rw-r--r--fs/nfs/Makefile27
-rw-r--r--fs/nfs/blocklayout/blocklayout.c39
-rw-r--r--fs/nfs/callback.c28
-rw-r--r--fs/nfs/callback.h2
-rw-r--r--fs/nfs/client.c191
-rw-r--r--fs/nfs/delegation.h2
-rw-r--r--fs/nfs/dir.c20
-rw-r--r--fs/nfs/direct.c2
-rw-r--r--fs/nfs/dns_resolve.c4
-rw-r--r--fs/nfs/file.c31
-rw-r--r--fs/nfs/idmap.c29
-rw-r--r--fs/nfs/inode.c105
-rw-r--r--fs/nfs/internal.h38
-rw-r--r--fs/nfs/namespace.c17
-rw-r--r--fs/nfs/netns.h2
-rw-r--r--fs/nfs/nfs.h29
-rw-r--r--fs/nfs/nfs2super.c31
-rw-r--r--fs/nfs/nfs3client.c65
-rw-r--r--fs/nfs/nfs3proc.c3
-rw-r--r--fs/nfs/nfs3super.c31
-rw-r--r--fs/nfs/nfs4_fs.h13
-rw-r--r--fs/nfs/nfs4client.c23
-rw-r--r--fs/nfs/nfs4proc.c9
-rw-r--r--fs/nfs/nfs4super.c106
-rw-r--r--fs/nfs/nfs4xdr.c6
-rw-r--r--fs/nfs/pagelist.c4
-rw-r--r--fs/nfs/pnfs.c2
-rw-r--r--fs/nfs/proc.c3
-rw-r--r--fs/nfs/read.c5
-rw-r--r--fs/nfs/super.c172
-rw-r--r--fs/nfs/write.c35
32 files changed, 690 insertions, 390 deletions
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig
index 404c6a8ac394..195c1ea6151a 100644
--- a/fs/nfs/Kconfig
+++ b/fs/nfs/Kconfig
@@ -30,7 +30,7 @@ config NFS_FS
30 If unsure, say N. 30 If unsure, say N.
31 31
32config NFS_V2 32config NFS_V2
33 bool "NFS client support for NFS version 2" 33 tristate "NFS client support for NFS version 2"
34 depends on NFS_FS 34 depends on NFS_FS
35 default y 35 default y
36 help 36 help
@@ -40,7 +40,7 @@ config NFS_V2
40 If unsure, say Y. 40 If unsure, say Y.
41 41
42config NFS_V3 42config NFS_V3
43 bool "NFS client support for NFS version 3" 43 tristate "NFS client support for NFS version 3"
44 depends on NFS_FS 44 depends on NFS_FS
45 default y 45 default y
46 help 46 help
@@ -72,7 +72,7 @@ config NFS_V3_ACL
72 If unsure, say N. 72 If unsure, say N.
73 73
74config NFS_V4 74config NFS_V4
75 bool "NFS client support for NFS version 4" 75 tristate "NFS client support for NFS version 4"
76 depends on NFS_FS 76 depends on NFS_FS
77 select SUNRPC_GSS 77 select SUNRPC_GSS
78 select KEYS 78 select KEYS
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index 0b96c2038346..8bf3a3f6925a 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -9,21 +9,22 @@ nfs-y := client.o dir.o file.o getroot.o inode.o super.o \
9 write.o namespace.o mount_clnt.o \ 9 write.o namespace.o mount_clnt.o \
10 dns_resolve.o cache_lib.o 10 dns_resolve.o cache_lib.o
11nfs-$(CONFIG_ROOT_NFS) += nfsroot.o 11nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
12nfs-$(CONFIG_NFS_V2) += proc.o nfs2xdr.o 12nfs-$(CONFIG_SYSCTL) += sysctl.o
13nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o 13nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
14nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
15nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
16 nfs4super.o nfs4file.o delegation.o idmap.o \
17 callback.o callback_xdr.o callback_proc.o \
18 nfs4namespace.o nfs4getroot.o nfs4client.o
19nfs-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o
20 14
21ifeq ($(CONFIG_SYSCTL), y) 15obj-$(CONFIG_NFS_V2) += nfs2.o
22nfs-y += sysctl.o 16nfs2-y := nfs2super.o proc.o nfs2xdr.o
23nfs-$(CONFIG_NFS_V4) += nfs4sysctl.o
24endif
25 17
26nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o 18obj-$(CONFIG_NFS_V3) += nfs3.o
19nfs3-y := nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o
20nfs3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
21
22obj-$(CONFIG_NFS_V4) += nfs4.o
23nfs4-y := nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o nfs4super.o nfs4file.o \
24 delegation.o idmap.o callback.o callback_xdr.o callback_proc.o \
25 nfs4namespace.o nfs4getroot.o nfs4client.o
26nfs4-$(CONFIG_SYSCTL) += nfs4sysctl.o
27nfs4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o
27 28
28obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o 29obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o
29nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o 30nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index 7ae8a608956f..dd392ed5f2e2 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -228,6 +228,14 @@ bl_end_par_io_read(void *data, int unused)
228 schedule_work(&rdata->task.u.tk_work); 228 schedule_work(&rdata->task.u.tk_work);
229} 229}
230 230
231static bool
232bl_check_alignment(u64 offset, u32 len, unsigned long blkmask)
233{
234 if ((offset & blkmask) || (len & blkmask))
235 return false;
236 return true;
237}
238
231static enum pnfs_try_status 239static enum pnfs_try_status
232bl_read_pagelist(struct nfs_read_data *rdata) 240bl_read_pagelist(struct nfs_read_data *rdata)
233{ 241{
@@ -244,6 +252,9 @@ bl_read_pagelist(struct nfs_read_data *rdata)
244 dprintk("%s enter nr_pages %u offset %lld count %u\n", __func__, 252 dprintk("%s enter nr_pages %u offset %lld count %u\n", __func__,
245 rdata->pages.npages, f_offset, (unsigned int)rdata->args.count); 253 rdata->pages.npages, f_offset, (unsigned int)rdata->args.count);
246 254
255 if (!bl_check_alignment(f_offset, rdata->args.count, PAGE_CACHE_MASK))
256 goto use_mds;
257
247 par = alloc_parallel(rdata); 258 par = alloc_parallel(rdata);
248 if (!par) 259 if (!par)
249 goto use_mds; 260 goto use_mds;
@@ -552,7 +563,7 @@ bl_write_pagelist(struct nfs_write_data *wdata, int sync)
552 struct bio *bio = NULL; 563 struct bio *bio = NULL;
553 struct pnfs_block_extent *be = NULL, *cow_read = NULL; 564 struct pnfs_block_extent *be = NULL, *cow_read = NULL;
554 sector_t isect, last_isect = 0, extent_length = 0; 565 sector_t isect, last_isect = 0, extent_length = 0;
555 struct parallel_io *par; 566 struct parallel_io *par = NULL;
556 loff_t offset = wdata->args.offset; 567 loff_t offset = wdata->args.offset;
557 size_t count = wdata->args.count; 568 size_t count = wdata->args.count;
558 struct page **pages = wdata->args.pages; 569 struct page **pages = wdata->args.pages;
@@ -563,6 +574,10 @@ bl_write_pagelist(struct nfs_write_data *wdata, int sync)
563 NFS_SERVER(header->inode)->pnfs_blksize >> PAGE_CACHE_SHIFT; 574 NFS_SERVER(header->inode)->pnfs_blksize >> PAGE_CACHE_SHIFT;
564 575
565 dprintk("%s enter, %Zu@%lld\n", __func__, count, offset); 576 dprintk("%s enter, %Zu@%lld\n", __func__, count, offset);
577 /* Check for alignment first */
578 if (!bl_check_alignment(offset, count, PAGE_CACHE_MASK))
579 goto out_mds;
580
566 /* At this point, wdata->pages is a (sequential) list of nfs_pages. 581 /* At this point, wdata->pages is a (sequential) list of nfs_pages.
567 * We want to write each, and if there is an error set pnfs_error 582 * We want to write each, and if there is an error set pnfs_error
568 * to have it redone using nfs. 583 * to have it redone using nfs.
@@ -996,14 +1011,32 @@ bl_clear_layoutdriver(struct nfs_server *server)
996 return 0; 1011 return 0;
997} 1012}
998 1013
1014static void
1015bl_pg_init_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
1016{
1017 if (!bl_check_alignment(req->wb_offset, req->wb_bytes, PAGE_CACHE_MASK))
1018 nfs_pageio_reset_read_mds(pgio);
1019 else
1020 pnfs_generic_pg_init_read(pgio, req);
1021}
1022
1023static void
1024bl_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
1025{
1026 if (!bl_check_alignment(req->wb_offset, req->wb_bytes, PAGE_CACHE_MASK))
1027 nfs_pageio_reset_write_mds(pgio);
1028 else
1029 pnfs_generic_pg_init_write(pgio, req);
1030}
1031
999static const struct nfs_pageio_ops bl_pg_read_ops = { 1032static const struct nfs_pageio_ops bl_pg_read_ops = {
1000 .pg_init = pnfs_generic_pg_init_read, 1033 .pg_init = bl_pg_init_read,
1001 .pg_test = pnfs_generic_pg_test, 1034 .pg_test = pnfs_generic_pg_test,
1002 .pg_doio = pnfs_generic_pg_readpages, 1035 .pg_doio = pnfs_generic_pg_readpages,
1003}; 1036};
1004 1037
1005static const struct nfs_pageio_ops bl_pg_write_ops = { 1038static const struct nfs_pageio_ops bl_pg_write_ops = {
1006 .pg_init = pnfs_generic_pg_init_write, 1039 .pg_init = bl_pg_init_write,
1007 .pg_test = pnfs_generic_pg_test, 1040 .pg_test = pnfs_generic_pg_test,
1008 .pg_doio = pnfs_generic_pg_writepages, 1041 .pg_doio = pnfs_generic_pg_writepages,
1009}; 1042};
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 23ff18fe080a..4c8459e5bdee 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -37,31 +37,7 @@ static struct nfs_callback_data nfs_callback_info[NFS4_MAX_MINOR_VERSION + 1];
37static DEFINE_MUTEX(nfs_callback_mutex); 37static DEFINE_MUTEX(nfs_callback_mutex);
38static struct svc_program nfs4_callback_program; 38static struct svc_program nfs4_callback_program;
39 39
40unsigned int nfs_callback_set_tcpport;
41unsigned short nfs_callback_tcpport;
42unsigned short nfs_callback_tcpport6; 40unsigned short nfs_callback_tcpport6;
43#define NFS_CALLBACK_MAXPORTNR (65535U)
44
45static int param_set_portnr(const char *val, const struct kernel_param *kp)
46{
47 unsigned long num;
48 int ret;
49
50 if (!val)
51 return -EINVAL;
52 ret = strict_strtoul(val, 0, &num);
53 if (ret == -EINVAL || num > NFS_CALLBACK_MAXPORTNR)
54 return -EINVAL;
55 *((unsigned int *)kp->arg) = num;
56 return 0;
57}
58static struct kernel_param_ops param_ops_portnr = {
59 .set = param_set_portnr,
60 .get = param_get_uint,
61};
62#define param_check_portnr(name, p) __param_check(name, p, unsigned int);
63
64module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644);
65 41
66/* 42/*
67 * This is the NFSv4 callback kernel thread. 43 * This is the NFSv4 callback kernel thread.
@@ -265,6 +241,10 @@ int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt)
265 ret = -ENOMEM; 241 ret = -ENOMEM;
266 goto out_err; 242 goto out_err;
267 } 243 }
244 /* As there is only one thread we need to over-ride the
245 * default maximum of 80 connections
246 */
247 serv->sv_maxconn = 1024;
268 248
269 ret = svc_bind(serv, net); 249 ret = svc_bind(serv, net);
270 if (ret < 0) { 250 if (ret < 0) {
diff --git a/fs/nfs/callback.h b/fs/nfs/callback.h
index a5527c90a5aa..b44d7b128b71 100644
--- a/fs/nfs/callback.h
+++ b/fs/nfs/callback.h
@@ -192,7 +192,7 @@ extern __be32 nfs4_callback_getattr(struct cb_getattrargs *args,
192 struct cb_process_state *cps); 192 struct cb_process_state *cps);
193extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy, 193extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy,
194 struct cb_process_state *cps); 194 struct cb_process_state *cps);
195#ifdef CONFIG_NFS_V4 195#if IS_ENABLED(CONFIG_NFS_V4)
196extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt); 196extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt);
197extern void nfs_callback_down(int minorversion); 197extern void nfs_callback_down(int minorversion);
198extern int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation, 198extern int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation,
diff --git a/fs/nfs/client.c b/fs/nfs/client.c
index 65afa382c5e3..9fc0d9dfc91b 100644
--- a/fs/nfs/client.c
+++ b/fs/nfs/client.c
@@ -51,25 +51,23 @@
51#include "internal.h" 51#include "internal.h"
52#include "fscache.h" 52#include "fscache.h"
53#include "pnfs.h" 53#include "pnfs.h"
54#include "nfs.h"
54#include "netns.h" 55#include "netns.h"
55 56
56#define NFSDBG_FACILITY NFSDBG_CLIENT 57#define NFSDBG_FACILITY NFSDBG_CLIENT
57 58
58static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq); 59static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq);
60static DEFINE_SPINLOCK(nfs_version_lock);
61static DEFINE_MUTEX(nfs_version_mutex);
62static LIST_HEAD(nfs_versions);
59 63
60/* 64/*
61 * RPC cruft for NFS 65 * RPC cruft for NFS
62 */ 66 */
63static const struct rpc_version *nfs_version[5] = { 67static const struct rpc_version *nfs_version[5] = {
64#ifdef CONFIG_NFS_V2 68 [2] = NULL,
65 [2] = &nfs_version2, 69 [3] = NULL,
66#endif 70 [4] = NULL,
67#ifdef CONFIG_NFS_V3
68 [3] = &nfs_version3,
69#endif
70#ifdef CONFIG_NFS_V4
71 [4] = &nfs_version4,
72#endif
73}; 71};
74 72
75const struct rpc_program nfs_program = { 73const struct rpc_program nfs_program = {
@@ -85,21 +83,64 @@ struct rpc_stat nfs_rpcstat = {
85 .program = &nfs_program 83 .program = &nfs_program
86}; 84};
87 85
86static struct nfs_subversion *find_nfs_version(unsigned int version)
87{
88 struct nfs_subversion *nfs;
89 spin_lock(&nfs_version_lock);
88 90
89#ifdef CONFIG_NFS_V3_ACL 91 list_for_each_entry(nfs, &nfs_versions, list) {
90static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program }; 92 if (nfs->rpc_ops->version == version) {
91static const struct rpc_version *nfsacl_version[] = { 93 spin_unlock(&nfs_version_lock);
92 [3] = &nfsacl_version3, 94 return nfs;
93}; 95 }
96 };
94 97
95const struct rpc_program nfsacl_program = { 98 spin_unlock(&nfs_version_lock);
96 .name = "nfsacl", 99 return ERR_PTR(-EPROTONOSUPPORT);;
97 .number = NFS_ACL_PROGRAM, 100}
98 .nrvers = ARRAY_SIZE(nfsacl_version), 101
99 .version = nfsacl_version, 102struct nfs_subversion *get_nfs_version(unsigned int version)
100 .stats = &nfsacl_rpcstat, 103{
101}; 104 struct nfs_subversion *nfs = find_nfs_version(version);
102#endif /* CONFIG_NFS_V3_ACL */ 105
106 if (IS_ERR(nfs)) {
107 mutex_lock(&nfs_version_mutex);
108 request_module("nfs%d", version);
109 nfs = find_nfs_version(version);
110 mutex_unlock(&nfs_version_mutex);
111 }
112
113 if (!IS_ERR(nfs))
114 try_module_get(nfs->owner);
115 return nfs;
116}
117
118void put_nfs_version(struct nfs_subversion *nfs)
119{
120 module_put(nfs->owner);
121}
122
123void register_nfs_version(struct nfs_subversion *nfs)
124{
125 spin_lock(&nfs_version_lock);
126
127 list_add(&nfs->list, &nfs_versions);
128 nfs_version[nfs->rpc_ops->version] = nfs->rpc_vers;
129
130 spin_unlock(&nfs_version_lock);
131}
132EXPORT_SYMBOL_GPL(register_nfs_version);
133
134void unregister_nfs_version(struct nfs_subversion *nfs)
135{
136 spin_lock(&nfs_version_lock);
137
138 nfs_version[nfs->rpc_ops->version] = NULL;
139 list_del(&nfs->list);
140
141 spin_unlock(&nfs_version_lock);
142}
143EXPORT_SYMBOL_GPL(unregister_nfs_version);
103 144
104/* 145/*
105 * Allocate a shared client record 146 * Allocate a shared client record
@@ -116,7 +157,10 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
116 if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL) 157 if ((clp = kzalloc(sizeof(*clp), GFP_KERNEL)) == NULL)
117 goto error_0; 158 goto error_0;
118 159
119 clp->rpc_ops = cl_init->rpc_ops; 160 clp->cl_nfs_mod = cl_init->nfs_mod;
161 try_module_get(clp->cl_nfs_mod->owner);
162
163 clp->rpc_ops = clp->cl_nfs_mod->rpc_ops;
120 164
121 atomic_set(&clp->cl_count, 1); 165 atomic_set(&clp->cl_count, 1);
122 clp->cl_cons_state = NFS_CS_INITING; 166 clp->cl_cons_state = NFS_CS_INITING;
@@ -145,12 +189,14 @@ struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_init)
145 return clp; 189 return clp;
146 190
147error_cleanup: 191error_cleanup:
192 put_nfs_version(clp->cl_nfs_mod);
148 kfree(clp); 193 kfree(clp);
149error_0: 194error_0:
150 return ERR_PTR(err); 195 return ERR_PTR(err);
151} 196}
197EXPORT_SYMBOL_GPL(nfs_alloc_client);
152 198
153#ifdef CONFIG_NFS_V4 199#if IS_ENABLED(CONFIG_NFS_V4)
154/* idr_remove_all is not needed as all id's are removed by nfs_put_client */ 200/* idr_remove_all is not needed as all id's are removed by nfs_put_client */
155void nfs_cleanup_cb_ident_idr(struct net *net) 201void nfs_cleanup_cb_ident_idr(struct net *net)
156{ 202{
@@ -205,11 +251,13 @@ void nfs_free_client(struct nfs_client *clp)
205 put_rpccred(clp->cl_machine_cred); 251 put_rpccred(clp->cl_machine_cred);
206 252
207 put_net(clp->cl_net); 253 put_net(clp->cl_net);
254 put_nfs_version(clp->cl_nfs_mod);
208 kfree(clp->cl_hostname); 255 kfree(clp->cl_hostname);
209 kfree(clp); 256 kfree(clp);
210 257
211 dprintk("<-- nfs_free_client()\n"); 258 dprintk("<-- nfs_free_client()\n");
212} 259}
260EXPORT_SYMBOL_GPL(nfs_free_client);
213 261
214/* 262/*
215 * Release a reference to a shared client record 263 * Release a reference to a shared client record
@@ -324,6 +372,7 @@ int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1,
324 } 372 }
325 return 0; 373 return 0;
326} 374}
375EXPORT_SYMBOL_GPL(nfs_sockaddr_match_ipaddr);
327#endif /* CONFIG_NFS_V4_1 */ 376#endif /* CONFIG_NFS_V4_1 */
328 377
329/* 378/*
@@ -362,7 +411,7 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat
362 continue; 411 continue;
363 412
364 /* Different NFS versions cannot share the same nfs_client */ 413 /* Different NFS versions cannot share the same nfs_client */
365 if (clp->rpc_ops != data->rpc_ops) 414 if (clp->rpc_ops != data->nfs_mod->rpc_ops)
366 continue; 415 continue;
367 416
368 if (clp->cl_proto != data->proto) 417 if (clp->cl_proto != data->proto)
@@ -390,6 +439,7 @@ int nfs_wait_client_init_complete(const struct nfs_client *clp)
390 return wait_event_killable(nfs_client_active_wq, 439 return wait_event_killable(nfs_client_active_wq,
391 nfs_client_init_is_complete(clp)); 440 nfs_client_init_is_complete(clp));
392} 441}
442EXPORT_SYMBOL_GPL(nfs_wait_client_init_complete);
393 443
394/* 444/*
395 * Found an existing client. Make sure it's ready before returning. 445 * Found an existing client. Make sure it's ready before returning.
@@ -431,9 +481,10 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
431{ 481{
432 struct nfs_client *clp, *new = NULL; 482 struct nfs_client *clp, *new = NULL;
433 struct nfs_net *nn = net_generic(cl_init->net, nfs_net_id); 483 struct nfs_net *nn = net_generic(cl_init->net, nfs_net_id);
484 const struct nfs_rpc_ops *rpc_ops = cl_init->nfs_mod->rpc_ops;
434 485
435 dprintk("--> nfs_get_client(%s,v%u)\n", 486 dprintk("--> nfs_get_client(%s,v%u)\n",
436 cl_init->hostname ?: "", cl_init->rpc_ops->version); 487 cl_init->hostname ?: "", rpc_ops->version);
437 488
438 /* see if the client already exists */ 489 /* see if the client already exists */
439 do { 490 do {
@@ -450,20 +501,20 @@ nfs_get_client(const struct nfs_client_initdata *cl_init,
450 list_add(&new->cl_share_link, &nn->nfs_client_list); 501 list_add(&new->cl_share_link, &nn->nfs_client_list);
451 spin_unlock(&nn->nfs_client_lock); 502 spin_unlock(&nn->nfs_client_lock);
452 new->cl_flags = cl_init->init_flags; 503 new->cl_flags = cl_init->init_flags;
453 return cl_init->rpc_ops->init_client(new, 504 return rpc_ops->init_client(new, timeparms, ip_addr,
454 timeparms, ip_addr, 505 authflavour);
455 authflavour);
456 } 506 }
457 507
458 spin_unlock(&nn->nfs_client_lock); 508 spin_unlock(&nn->nfs_client_lock);
459 509
460 new = cl_init->rpc_ops->alloc_client(cl_init); 510 new = rpc_ops->alloc_client(cl_init);
461 } while (!IS_ERR(new)); 511 } while (!IS_ERR(new));
462 512
463 dprintk("<-- nfs_get_client() Failed to find %s (%ld)\n", 513 dprintk("<-- nfs_get_client() Failed to find %s (%ld)\n",
464 cl_init->hostname ?: "", PTR_ERR(new)); 514 cl_init->hostname ?: "", PTR_ERR(new));
465 return new; 515 return new;
466} 516}
517EXPORT_SYMBOL_GPL(nfs_get_client);
467 518
468/* 519/*
469 * Mark a server as ready or failed 520 * Mark a server as ready or failed
@@ -474,6 +525,7 @@ void nfs_mark_client_ready(struct nfs_client *clp, int state)
474 clp->cl_cons_state = state; 525 clp->cl_cons_state = state;
475 wake_up_all(&nfs_client_active_wq); 526 wake_up_all(&nfs_client_active_wq);
476} 527}
528EXPORT_SYMBOL_GPL(nfs_mark_client_ready);
477 529
478/* 530/*
479 * Initialise the timeout values for a connection 531 * Initialise the timeout values for a connection
@@ -515,6 +567,7 @@ void nfs_init_timeout_values(struct rpc_timeout *to, int proto,
515 BUG(); 567 BUG();
516 } 568 }
517} 569}
570EXPORT_SYMBOL_GPL(nfs_init_timeout_values);
518 571
519/* 572/*
520 * Create an RPC client handle 573 * Create an RPC client handle
@@ -554,6 +607,7 @@ int nfs_create_rpc_client(struct nfs_client *clp,
554 clp->cl_rpcclient = clnt; 607 clp->cl_rpcclient = clnt;
555 return 0; 608 return 0;
556} 609}
610EXPORT_SYMBOL_GPL(nfs_create_rpc_client);
557 611
558/* 612/*
559 * Version 2 or 3 client destruction 613 * Version 2 or 3 client destruction
@@ -606,36 +660,6 @@ static int nfs_start_lockd(struct nfs_server *server)
606} 660}
607 661
608/* 662/*
609 * Initialise an NFSv3 ACL client connection
610 */
611#ifdef CONFIG_NFS_V3_ACL
612static void nfs_init_server_aclclient(struct nfs_server *server)
613{
614 if (server->nfs_client->rpc_ops->version != 3)
615 goto out_noacl;
616 if (server->flags & NFS_MOUNT_NOACL)
617 goto out_noacl;
618
619 server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
620 if (IS_ERR(server->client_acl))
621 goto out_noacl;
622
623 /* No errors! Assume that Sun nfsacls are supported */
624 server->caps |= NFS_CAP_ACLS;
625 return;
626
627out_noacl:
628 server->caps &= ~NFS_CAP_ACLS;
629}
630#else
631static inline void nfs_init_server_aclclient(struct nfs_server *server)
632{
633 server->flags &= ~NFS_MOUNT_NOACL;
634 server->caps &= ~NFS_CAP_ACLS;
635}
636#endif
637
638/*
639 * Create a general RPC client 663 * Create a general RPC client
640 */ 664 */
641int nfs_init_server_rpcclient(struct nfs_server *server, 665int nfs_init_server_rpcclient(struct nfs_server *server,
@@ -670,6 +694,7 @@ int nfs_init_server_rpcclient(struct nfs_server *server,
670 694
671 return 0; 695 return 0;
672} 696}
697EXPORT_SYMBOL_GPL(nfs_init_server_rpcclient);
673 698
674/** 699/**
675 * nfs_init_client - Initialise an NFS2 or NFS3 client 700 * nfs_init_client - Initialise an NFS2 or NFS3 client
@@ -709,18 +734,20 @@ error:
709 dprintk("<-- nfs_init_client() = xerror %d\n", error); 734 dprintk("<-- nfs_init_client() = xerror %d\n", error);
710 return ERR_PTR(error); 735 return ERR_PTR(error);
711} 736}
737EXPORT_SYMBOL_GPL(nfs_init_client);
712 738
713/* 739/*
714 * Create a version 2 or 3 client 740 * Create a version 2 or 3 client
715 */ 741 */
716static int nfs_init_server(struct nfs_server *server, 742static int nfs_init_server(struct nfs_server *server,
717 const struct nfs_parsed_mount_data *data) 743 const struct nfs_parsed_mount_data *data,
744 struct nfs_subversion *nfs_mod)
718{ 745{
719 struct nfs_client_initdata cl_init = { 746 struct nfs_client_initdata cl_init = {
720 .hostname = data->nfs_server.hostname, 747 .hostname = data->nfs_server.hostname,
721 .addr = (const struct sockaddr *)&data->nfs_server.address, 748 .addr = (const struct sockaddr *)&data->nfs_server.address,
722 .addrlen = data->nfs_server.addrlen, 749 .addrlen = data->nfs_server.addrlen,
723 .rpc_ops = NULL, 750 .nfs_mod = nfs_mod,
724 .proto = data->nfs_server.protocol, 751 .proto = data->nfs_server.protocol,
725 .net = data->net, 752 .net = data->net,
726 }; 753 };
@@ -730,21 +757,6 @@ static int nfs_init_server(struct nfs_server *server,
730 757
731 dprintk("--> nfs_init_server()\n"); 758 dprintk("--> nfs_init_server()\n");
732 759
733 switch (data->version) {
734#ifdef CONFIG_NFS_V2
735 case 2:
736 cl_init.rpc_ops = &nfs_v2_clientops;
737 break;
738#endif
739#ifdef CONFIG_NFS_V3
740 case 3:
741 cl_init.rpc_ops = &nfs_v3_clientops;
742 break;
743#endif
744 default:
745 return -EPROTONOSUPPORT;
746 }
747
748 nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, 760 nfs_init_timeout_values(&timeparms, data->nfs_server.protocol,
749 data->timeo, data->retrans); 761 data->timeo, data->retrans);
750 if (data->flags & NFS_MOUNT_NORESVPORT) 762 if (data->flags & NFS_MOUNT_NORESVPORT)
@@ -798,8 +810,6 @@ static int nfs_init_server(struct nfs_server *server,
798 server->mountd_protocol = data->mount_server.protocol; 810 server->mountd_protocol = data->mount_server.protocol;
799 811
800 server->namelen = data->namlen; 812 server->namelen = data->namlen;
801 /* Create a client RPC handle for the NFSv3 ACL management interface */
802 nfs_init_server_aclclient(server);
803 dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp); 813 dprintk("<-- nfs_init_server() = 0 [new %p]\n", clp);
804 return 0; 814 return 0;
805 815
@@ -911,6 +921,7 @@ out_error:
911 dprintk("nfs_probe_fsinfo: error = %d\n", -error); 921 dprintk("nfs_probe_fsinfo: error = %d\n", -error);
912 return error; 922 return error;
913} 923}
924EXPORT_SYMBOL_GPL(nfs_probe_fsinfo);
914 925
915/* 926/*
916 * Copy useful information when duplicating a server record 927 * Copy useful information when duplicating a server record
@@ -927,6 +938,7 @@ void nfs_server_copy_userdata(struct nfs_server *target, struct nfs_server *sour
927 target->caps = source->caps; 938 target->caps = source->caps;
928 target->options = source->options; 939 target->options = source->options;
929} 940}
941EXPORT_SYMBOL_GPL(nfs_server_copy_userdata);
930 942
931void nfs_server_insert_lists(struct nfs_server *server) 943void nfs_server_insert_lists(struct nfs_server *server)
932{ 944{
@@ -940,6 +952,7 @@ void nfs_server_insert_lists(struct nfs_server *server)
940 spin_unlock(&nn->nfs_client_lock); 952 spin_unlock(&nn->nfs_client_lock);
941 953
942} 954}
955EXPORT_SYMBOL_GPL(nfs_server_insert_lists);
943 956
944static void nfs_server_remove_lists(struct nfs_server *server) 957static void nfs_server_remove_lists(struct nfs_server *server)
945{ 958{
@@ -999,6 +1012,7 @@ struct nfs_server *nfs_alloc_server(void)
999 1012
1000 return server; 1013 return server;
1001} 1014}
1015EXPORT_SYMBOL_GPL(nfs_alloc_server);
1002 1016
1003/* 1017/*
1004 * Free up a server record 1018 * Free up a server record
@@ -1027,13 +1041,14 @@ void nfs_free_server(struct nfs_server *server)
1027 nfs_release_automount_timer(); 1041 nfs_release_automount_timer();
1028 dprintk("<-- nfs_free_server()\n"); 1042 dprintk("<-- nfs_free_server()\n");
1029} 1043}
1044EXPORT_SYMBOL_GPL(nfs_free_server);
1030 1045
1031/* 1046/*
1032 * Create a version 2 or 3 volume record 1047 * Create a version 2 or 3 volume record
1033 * - keyed on server and FSID 1048 * - keyed on server and FSID
1034 */ 1049 */
1035struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data, 1050struct nfs_server *nfs_create_server(struct nfs_mount_info *mount_info,
1036 struct nfs_fh *mntfh) 1051 struct nfs_subversion *nfs_mod)
1037{ 1052{
1038 struct nfs_server *server; 1053 struct nfs_server *server;
1039 struct nfs_fattr *fattr; 1054 struct nfs_fattr *fattr;
@@ -1049,7 +1064,7 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
1049 goto error; 1064 goto error;
1050 1065
1051 /* Get a client representation */ 1066 /* Get a client representation */
1052 error = nfs_init_server(server, data); 1067 error = nfs_init_server(server, mount_info->parsed, nfs_mod);
1053 if (error < 0) 1068 if (error < 0)
1054 goto error; 1069 goto error;
1055 1070
@@ -1058,13 +1073,13 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
1058 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops); 1073 BUG_ON(!server->nfs_client->rpc_ops->file_inode_ops);
1059 1074
1060 /* Probe the root fh to retrieve its FSID */ 1075 /* Probe the root fh to retrieve its FSID */
1061 error = nfs_probe_fsinfo(server, mntfh, fattr); 1076 error = nfs_probe_fsinfo(server, mount_info->mntfh, fattr);
1062 if (error < 0) 1077 if (error < 0)
1063 goto error; 1078 goto error;
1064 if (server->nfs_client->rpc_ops->version == 3) { 1079 if (server->nfs_client->rpc_ops->version == 3) {
1065 if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN) 1080 if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
1066 server->namelen = NFS3_MAXNAMLEN; 1081 server->namelen = NFS3_MAXNAMLEN;
1067 if (!(data->flags & NFS_MOUNT_NORDIRPLUS)) 1082 if (!(mount_info->parsed->flags & NFS_MOUNT_NORDIRPLUS))
1068 server->caps |= NFS_CAP_READDIRPLUS; 1083 server->caps |= NFS_CAP_READDIRPLUS;
1069 } else { 1084 } else {
1070 if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN) 1085 if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
@@ -1072,7 +1087,7 @@ struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data,
1072 } 1087 }
1073 1088
1074 if (!(fattr->valid & NFS_ATTR_FATTR)) { 1089 if (!(fattr->valid & NFS_ATTR_FATTR)) {
1075 error = server->nfs_client->rpc_ops->getattr(server, mntfh, fattr); 1090 error = nfs_mod->rpc_ops->getattr(server, mount_info->mntfh, fattr);
1076 if (error < 0) { 1091 if (error < 0) {
1077 dprintk("nfs_create_server: getattr error = %d\n", -error); 1092 dprintk("nfs_create_server: getattr error = %d\n", -error);
1078 goto error; 1093 goto error;
@@ -1094,6 +1109,7 @@ error:
1094 nfs_free_server(server); 1109 nfs_free_server(server);
1095 return ERR_PTR(error); 1110 return ERR_PTR(error);
1096} 1111}
1112EXPORT_SYMBOL_GPL(nfs_create_server);
1097 1113
1098/* 1114/*
1099 * Clone an NFS2, NFS3 or NFS4 server record 1115 * Clone an NFS2, NFS3 or NFS4 server record
@@ -1133,8 +1149,6 @@ struct nfs_server *nfs_clone_server(struct nfs_server *source,
1133 flavor); 1149 flavor);
1134 if (error < 0) 1150 if (error < 0)
1135 goto out_free_server; 1151 goto out_free_server;
1136 if (!IS_ERR(source->client_acl))
1137 nfs_init_server_aclclient(server);
1138 1152
1139 /* probe the filesystem info for this server filesystem */ 1153 /* probe the filesystem info for this server filesystem */
1140 error = nfs_probe_fsinfo(server, fh, fattr_fsinfo); 1154 error = nfs_probe_fsinfo(server, fh, fattr_fsinfo);
@@ -1165,6 +1179,7 @@ out_free_server:
1165 dprintk("<-- nfs_clone_server() = error %d\n", error); 1179 dprintk("<-- nfs_clone_server() = error %d\n", error);
1166 return ERR_PTR(error); 1180 return ERR_PTR(error);
1167} 1181}
1182EXPORT_SYMBOL_GPL(nfs_clone_server);
1168 1183
1169void nfs_clients_init(struct net *net) 1184void nfs_clients_init(struct net *net)
1170{ 1185{
@@ -1172,7 +1187,7 @@ void nfs_clients_init(struct net *net)
1172 1187
1173 INIT_LIST_HEAD(&nn->nfs_client_list); 1188 INIT_LIST_HEAD(&nn->nfs_client_list);
1174 INIT_LIST_HEAD(&nn->nfs_volume_list); 1189 INIT_LIST_HEAD(&nn->nfs_volume_list);
1175#ifdef CONFIG_NFS_V4 1190#if IS_ENABLED(CONFIG_NFS_V4)
1176 idr_init(&nn->cb_ident_idr); 1191 idr_init(&nn->cb_ident_idr);
1177#endif 1192#endif
1178 spin_lock_init(&nn->nfs_client_lock); 1193 spin_lock_init(&nn->nfs_client_lock);
diff --git a/fs/nfs/delegation.h b/fs/nfs/delegation.h
index 1f3ccd934635..bbc6a4dba0d8 100644
--- a/fs/nfs/delegation.h
+++ b/fs/nfs/delegation.h
@@ -8,7 +8,7 @@
8#ifndef FS_NFS_DELEGATION_H 8#ifndef FS_NFS_DELEGATION_H
9#define FS_NFS_DELEGATION_H 9#define FS_NFS_DELEGATION_H
10 10
11#if defined(CONFIG_NFS_V4) 11#if IS_ENABLED(CONFIG_NFS_V4)
12/* 12/*
13 * NFSv4 delegation 13 * NFSv4 delegation
14 */ 14 */
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index d49f1b9cd3fd..627f108ede23 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -17,6 +17,7 @@
17 * 6 Jun 1999 Cache readdir lookups in the page cache. -DaveM 17 * 6 Jun 1999 Cache readdir lookups in the page cache. -DaveM
18 */ 18 */
19 19
20#include <linux/module.h>
20#include <linux/time.h> 21#include <linux/time.h>
21#include <linux/errno.h> 22#include <linux/errno.h>
22#include <linux/stat.h> 23#include <linux/stat.h>
@@ -935,6 +936,7 @@ void nfs_force_lookup_revalidate(struct inode *dir)
935{ 936{
936 NFS_I(dir)->cache_change_attribute++; 937 NFS_I(dir)->cache_change_attribute++;
937} 938}
939EXPORT_SYMBOL_GPL(nfs_force_lookup_revalidate);
938 940
939/* 941/*
940 * A check for whether or not the parent directory has changed. 942 * A check for whether or not the parent directory has changed.
@@ -1196,6 +1198,7 @@ const struct dentry_operations nfs_dentry_operations = {
1196 .d_automount = nfs_d_automount, 1198 .d_automount = nfs_d_automount,
1197 .d_release = nfs_d_release, 1199 .d_release = nfs_d_release,
1198}; 1200};
1201EXPORT_SYMBOL_GPL(nfs_dentry_operations);
1199 1202
1200struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags) 1203struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags)
1201{ 1204{
@@ -1263,8 +1266,9 @@ out:
1263 nfs_free_fhandle(fhandle); 1266 nfs_free_fhandle(fhandle);
1264 return res; 1267 return res;
1265} 1268}
1269EXPORT_SYMBOL_GPL(nfs_lookup);
1266 1270
1267#ifdef CONFIG_NFS_V4 1271#if IS_ENABLED(CONFIG_NFS_V4)
1268static int nfs4_lookup_revalidate(struct dentry *, unsigned int); 1272static int nfs4_lookup_revalidate(struct dentry *, unsigned int);
1269 1273
1270const struct dentry_operations nfs4_dentry_operations = { 1274const struct dentry_operations nfs4_dentry_operations = {
@@ -1274,6 +1278,7 @@ const struct dentry_operations nfs4_dentry_operations = {
1274 .d_automount = nfs_d_automount, 1278 .d_automount = nfs_d_automount,
1275 .d_release = nfs_d_release, 1279 .d_release = nfs_d_release,
1276}; 1280};
1281EXPORT_SYMBOL_GPL(nfs4_dentry_operations);
1277 1282
1278static fmode_t flags_to_mode(int flags) 1283static fmode_t flags_to_mode(int flags)
1279{ 1284{
@@ -1416,6 +1421,7 @@ no_open:
1416 1421
1417 return finish_no_open(file, res); 1422 return finish_no_open(file, res);
1418} 1423}
1424EXPORT_SYMBOL_GPL(nfs_atomic_open);
1419 1425
1420static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags) 1426static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags)
1421{ 1427{
@@ -1508,6 +1514,7 @@ out_error:
1508 dput(parent); 1514 dput(parent);
1509 return error; 1515 return error;
1510} 1516}
1517EXPORT_SYMBOL_GPL(nfs_instantiate);
1511 1518
1512/* 1519/*
1513 * Following a failed create operation, we drop the dentry rather 1520 * Following a failed create operation, we drop the dentry rather
@@ -1536,6 +1543,7 @@ out_err:
1536 d_drop(dentry); 1543 d_drop(dentry);
1537 return error; 1544 return error;
1538} 1545}
1546EXPORT_SYMBOL_GPL(nfs_create);
1539 1547
1540/* 1548/*
1541 * See comments for nfs_proc_create regarding failed operations. 1549 * See comments for nfs_proc_create regarding failed operations.
@@ -1563,6 +1571,7 @@ out_err:
1563 d_drop(dentry); 1571 d_drop(dentry);
1564 return status; 1572 return status;
1565} 1573}
1574EXPORT_SYMBOL_GPL(nfs_mknod);
1566 1575
1567/* 1576/*
1568 * See comments for nfs_proc_create regarding failed operations. 1577 * See comments for nfs_proc_create regarding failed operations.
@@ -1586,6 +1595,7 @@ out_err:
1586 d_drop(dentry); 1595 d_drop(dentry);
1587 return error; 1596 return error;
1588} 1597}
1598EXPORT_SYMBOL_GPL(nfs_mkdir);
1589 1599
1590static void nfs_dentry_handle_enoent(struct dentry *dentry) 1600static void nfs_dentry_handle_enoent(struct dentry *dentry)
1591{ 1601{
@@ -1609,6 +1619,7 @@ int nfs_rmdir(struct inode *dir, struct dentry *dentry)
1609 1619
1610 return error; 1620 return error;
1611} 1621}
1622EXPORT_SYMBOL_GPL(nfs_rmdir);
1612 1623
1613/* 1624/*
1614 * Remove a file after making sure there are no pending writes, 1625 * Remove a file after making sure there are no pending writes,
@@ -1680,6 +1691,7 @@ int nfs_unlink(struct inode *dir, struct dentry *dentry)
1680 d_rehash(dentry); 1691 d_rehash(dentry);
1681 return error; 1692 return error;
1682} 1693}
1694EXPORT_SYMBOL_GPL(nfs_unlink);
1683 1695
1684/* 1696/*
1685 * To create a symbolic link, most file systems instantiate a new inode, 1697 * To create a symbolic link, most file systems instantiate a new inode,
@@ -1750,6 +1762,7 @@ int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
1750 1762
1751 return 0; 1763 return 0;
1752} 1764}
1765EXPORT_SYMBOL_GPL(nfs_symlink);
1753 1766
1754int 1767int
1755nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) 1768nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
@@ -1771,6 +1784,7 @@ nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
1771 } 1784 }
1772 return error; 1785 return error;
1773} 1786}
1787EXPORT_SYMBOL_GPL(nfs_link);
1774 1788
1775/* 1789/*
1776 * RENAME 1790 * RENAME
@@ -1869,6 +1883,7 @@ out:
1869 dput(dentry); 1883 dput(dentry);
1870 return error; 1884 return error;
1871} 1885}
1886EXPORT_SYMBOL_GPL(nfs_rename);
1872 1887
1873static DEFINE_SPINLOCK(nfs_access_lru_lock); 1888static DEFINE_SPINLOCK(nfs_access_lru_lock);
1874static LIST_HEAD(nfs_access_lru_list); 1889static LIST_HEAD(nfs_access_lru_list);
@@ -1969,6 +1984,7 @@ void nfs_access_zap_cache(struct inode *inode)
1969 spin_unlock(&nfs_access_lru_lock); 1984 spin_unlock(&nfs_access_lru_lock);
1970 nfs_access_free_list(&head); 1985 nfs_access_free_list(&head);
1971} 1986}
1987EXPORT_SYMBOL_GPL(nfs_access_zap_cache);
1972 1988
1973static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, struct rpc_cred *cred) 1989static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, struct rpc_cred *cred)
1974{ 1990{
@@ -2129,6 +2145,7 @@ int nfs_may_open(struct inode *inode, struct rpc_cred *cred, int openflags)
2129{ 2145{
2130 return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags)); 2146 return nfs_do_access(inode, cred, nfs_open_permission_mask(openflags));
2131} 2147}
2148EXPORT_SYMBOL_GPL(nfs_may_open);
2132 2149
2133int nfs_permission(struct inode *inode, int mask) 2150int nfs_permission(struct inode *inode, int mask)
2134{ 2151{
@@ -2188,6 +2205,7 @@ out_notsup:
2188 res = generic_permission(inode, mask); 2205 res = generic_permission(inode, mask);
2189 goto out; 2206 goto out;
2190} 2207}
2208EXPORT_SYMBOL_GPL(nfs_permission);
2191 2209
2192/* 2210/*
2193 * Local variables: 2211 * Local variables:
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 42dce909ec70..b7b4f80968b5 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -460,7 +460,7 @@ static void nfs_inode_dio_write_done(struct inode *inode)
460 inode_dio_done(inode); 460 inode_dio_done(inode);
461} 461}
462 462
463#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 463#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
464static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) 464static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq)
465{ 465{
466 struct nfs_pageio_descriptor desc; 466 struct nfs_pageio_descriptor desc;
diff --git a/fs/nfs/dns_resolve.c b/fs/nfs/dns_resolve.c
index b3924b8a6000..31c26c4dcc23 100644
--- a/fs/nfs/dns_resolve.c
+++ b/fs/nfs/dns_resolve.c
@@ -8,6 +8,7 @@
8 8
9#ifdef CONFIG_NFS_USE_KERNEL_DNS 9#ifdef CONFIG_NFS_USE_KERNEL_DNS
10 10
11#include <linux/module.h>
11#include <linux/sunrpc/clnt.h> 12#include <linux/sunrpc/clnt.h>
12#include <linux/dns_resolver.h> 13#include <linux/dns_resolver.h>
13#include "dns_resolve.h" 14#include "dns_resolve.h"
@@ -27,9 +28,11 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name, size_t namelen,
27 kfree(ip_addr); 28 kfree(ip_addr);
28 return ret; 29 return ret;
29} 30}
31EXPORT_SYMBOL_GPL(nfs_dns_resolve_name);
30 32
31#else 33#else
32 34
35#include <linux/module.h>
33#include <linux/hash.h> 36#include <linux/hash.h>
34#include <linux/string.h> 37#include <linux/string.h>
35#include <linux/kmod.h> 38#include <linux/kmod.h>
@@ -345,6 +348,7 @@ ssize_t nfs_dns_resolve_name(struct net *net, char *name,
345 ret = -ESRCH; 348 ret = -ESRCH;
346 return ret; 349 return ret;
347} 350}
351EXPORT_SYMBOL_GPL(nfs_dns_resolve_name);
348 352
349int nfs_dns_resolver_cache_init(struct net *net) 353int nfs_dns_resolver_cache_init(struct net *net)
350{ 354{
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 70d124a61b98..b039a17ee941 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -16,6 +16,7 @@
16 * nfs regular file handling functions 16 * nfs regular file handling functions
17 */ 17 */
18 18
19#include <linux/module.h>
19#include <linux/time.h> 20#include <linux/time.h>
20#include <linux/kernel.h> 21#include <linux/kernel.h>
21#include <linux/errno.h> 22#include <linux/errno.h>
@@ -52,6 +53,7 @@ int nfs_check_flags(int flags)
52 53
53 return 0; 54 return 0;
54} 55}
56EXPORT_SYMBOL_GPL(nfs_check_flags);
55 57
56/* 58/*
57 * Open file 59 * Open file
@@ -84,6 +86,7 @@ nfs_file_release(struct inode *inode, struct file *filp)
84 nfs_inc_stats(inode, NFSIOS_VFSRELEASE); 86 nfs_inc_stats(inode, NFSIOS_VFSRELEASE);
85 return nfs_release(inode, filp); 87 return nfs_release(inode, filp);
86} 88}
89EXPORT_SYMBOL_GPL(nfs_file_release);
87 90
88/** 91/**
89 * nfs_revalidate_size - Revalidate the file size 92 * nfs_revalidate_size - Revalidate the file size
@@ -137,6 +140,7 @@ loff_t nfs_file_llseek(struct file *filp, loff_t offset, int origin)
137 140
138 return generic_file_llseek(filp, offset, origin); 141 return generic_file_llseek(filp, offset, origin);
139} 142}
143EXPORT_SYMBOL_GPL(nfs_file_llseek);
140 144
141/* 145/*
142 * Flush all dirty pages, and check for write errors. 146 * Flush all dirty pages, and check for write errors.
@@ -165,6 +169,7 @@ nfs_file_flush(struct file *file, fl_owner_t id)
165 /* Flush writes to the server and return any errors */ 169 /* Flush writes to the server and return any errors */
166 return vfs_fsync(file, 0); 170 return vfs_fsync(file, 0);
167} 171}
172EXPORT_SYMBOL_GPL(nfs_file_flush);
168 173
169ssize_t 174ssize_t
170nfs_file_read(struct kiocb *iocb, const struct iovec *iov, 175nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
@@ -189,6 +194,7 @@ nfs_file_read(struct kiocb *iocb, const struct iovec *iov,
189 } 194 }
190 return result; 195 return result;
191} 196}
197EXPORT_SYMBOL_GPL(nfs_file_read);
192 198
193ssize_t 199ssize_t
194nfs_file_splice_read(struct file *filp, loff_t *ppos, 200nfs_file_splice_read(struct file *filp, loff_t *ppos,
@@ -211,6 +217,7 @@ nfs_file_splice_read(struct file *filp, loff_t *ppos,
211 } 217 }
212 return res; 218 return res;
213} 219}
220EXPORT_SYMBOL_GPL(nfs_file_splice_read);
214 221
215int 222int
216nfs_file_mmap(struct file * file, struct vm_area_struct * vma) 223nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
@@ -232,6 +239,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma)
232 } 239 }
233 return status; 240 return status;
234} 241}
242EXPORT_SYMBOL_GPL(nfs_file_mmap);
235 243
236/* 244/*
237 * Flush any dirty pages for this process, and check for write errors. 245 * Flush any dirty pages for this process, and check for write errors.
@@ -270,6 +278,7 @@ nfs_file_fsync_commit(struct file *file, loff_t start, loff_t end, int datasync)
270 ret = status; 278 ret = status;
271 return ret; 279 return ret;
272} 280}
281EXPORT_SYMBOL_GPL(nfs_file_fsync_commit);
273 282
274static int 283static int
275nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) 284nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync)
@@ -447,8 +456,11 @@ static int nfs_release_page(struct page *page, gfp_t gfp)
447 456
448 dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page); 457 dfprintk(PAGECACHE, "NFS: release_page(%p)\n", page);
449 458
450 /* Only do I/O if gfp is a superset of GFP_KERNEL */ 459 /* Only do I/O if gfp is a superset of GFP_KERNEL, and we're not
451 if (mapping && (gfp & GFP_KERNEL) == GFP_KERNEL) { 460 * doing this memory reclaim for a fs-related allocation.
461 */
462 if (mapping && (gfp & GFP_KERNEL) == GFP_KERNEL &&
463 !(current->flags & PF_FSTRANS)) {
452 int how = FLUSH_SYNC; 464 int how = FLUSH_SYNC;
453 465
454 /* Don't let kswapd deadlock waiting for OOM RPC calls */ 466 /* Don't let kswapd deadlock waiting for OOM RPC calls */
@@ -611,6 +623,7 @@ out_swapfile:
611 printk(KERN_INFO "NFS: attempt to write to active swap file!\n"); 623 printk(KERN_INFO "NFS: attempt to write to active swap file!\n");
612 goto out; 624 goto out;
613} 625}
626EXPORT_SYMBOL_GPL(nfs_file_write);
614 627
615ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe, 628ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
616 struct file *filp, loff_t *ppos, 629 struct file *filp, loff_t *ppos,
@@ -642,6 +655,7 @@ ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe,
642 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written); 655 nfs_add_stats(inode, NFSIOS_NORMALWRITTENBYTES, written);
643 return ret; 656 return ret;
644} 657}
658EXPORT_SYMBOL_GPL(nfs_file_splice_write);
645 659
646static int 660static int
647do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) 661do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local)
@@ -802,6 +816,7 @@ int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
802out_err: 816out_err:
803 return ret; 817 return ret;
804} 818}
819EXPORT_SYMBOL_GPL(nfs_lock);
805 820
806/* 821/*
807 * Lock a (portion of) a file 822 * Lock a (portion of) a file
@@ -819,6 +834,15 @@ int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
819 if (!(fl->fl_flags & FL_FLOCK)) 834 if (!(fl->fl_flags & FL_FLOCK))
820 return -ENOLCK; 835 return -ENOLCK;
821 836
837 /*
838 * The NFSv4 protocol doesn't support LOCK_MAND, which is not part of
839 * any standard. In principle we might be able to support LOCK_MAND
840 * on NFSv2/3 since NLMv3/4 support DOS share modes, but for now the
841 * NFS code is not set up for it.
842 */
843 if (fl->fl_type & LOCK_MAND)
844 return -EINVAL;
845
822 if (NFS_SERVER(inode)->flags & NFS_MOUNT_LOCAL_FLOCK) 846 if (NFS_SERVER(inode)->flags & NFS_MOUNT_LOCAL_FLOCK)
823 is_local = 1; 847 is_local = 1;
824 848
@@ -831,6 +855,7 @@ int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
831 return do_unlk(filp, cmd, fl, is_local); 855 return do_unlk(filp, cmd, fl, is_local);
832 return do_setlk(filp, cmd, fl, is_local); 856 return do_setlk(filp, cmd, fl, is_local);
833} 857}
858EXPORT_SYMBOL_GPL(nfs_flock);
834 859
835/* 860/*
836 * There is no protocol support for leases, so we have no way to implement 861 * There is no protocol support for leases, so we have no way to implement
@@ -843,6 +868,7 @@ int nfs_setlease(struct file *file, long arg, struct file_lock **fl)
843 file->f_path.dentry->d_name.name, arg); 868 file->f_path.dentry->d_name.name, arg);
844 return -EINVAL; 869 return -EINVAL;
845} 870}
871EXPORT_SYMBOL_GPL(nfs_setlease);
846 872
847const struct file_operations nfs_file_operations = { 873const struct file_operations nfs_file_operations = {
848 .llseek = nfs_file_llseek, 874 .llseek = nfs_file_llseek,
@@ -862,3 +888,4 @@ const struct file_operations nfs_file_operations = {
862 .check_flags = nfs_check_flags, 888 .check_flags = nfs_check_flags,
863 .setlease = nfs_setlease, 889 .setlease = nfs_setlease,
864}; 890};
891EXPORT_SYMBOL_GPL(nfs_file_operations);
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c
index 864c51e4b400..b701358c39c3 100644
--- a/fs/nfs/idmap.c
+++ b/fs/nfs/idmap.c
@@ -52,8 +52,6 @@
52 52
53#define NFS_UINT_MAXLEN 11 53#define NFS_UINT_MAXLEN 11
54 54
55/* Default cache timeout is 10 minutes */
56unsigned int nfs_idmap_cache_timeout = 600;
57static const struct cred *id_resolver_cache; 55static const struct cred *id_resolver_cache;
58static struct key_type key_type_id_resolver_legacy; 56static struct key_type key_type_id_resolver_legacy;
59 57
@@ -205,12 +203,18 @@ static int nfs_idmap_init_keyring(void)
205 if (ret < 0) 203 if (ret < 0)
206 goto failed_put_key; 204 goto failed_put_key;
207 205
206 ret = register_key_type(&key_type_id_resolver_legacy);
207 if (ret < 0)
208 goto failed_reg_legacy;
209
208 set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags); 210 set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
209 cred->thread_keyring = keyring; 211 cred->thread_keyring = keyring;
210 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING; 212 cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
211 id_resolver_cache = cred; 213 id_resolver_cache = cred;
212 return 0; 214 return 0;
213 215
216failed_reg_legacy:
217 unregister_key_type(&key_type_id_resolver);
214failed_put_key: 218failed_put_key:
215 key_put(keyring); 219 key_put(keyring);
216failed_put_cred: 220failed_put_cred:
@@ -222,6 +226,7 @@ static void nfs_idmap_quit_keyring(void)
222{ 226{
223 key_revoke(id_resolver_cache->thread_keyring); 227 key_revoke(id_resolver_cache->thread_keyring);
224 unregister_key_type(&key_type_id_resolver); 228 unregister_key_type(&key_type_id_resolver);
229 unregister_key_type(&key_type_id_resolver_legacy);
225 put_cred(id_resolver_cache); 230 put_cred(id_resolver_cache);
226} 231}
227 232
@@ -359,7 +364,6 @@ static int nfs_idmap_lookup_id(const char *name, size_t namelen, const char *typ
359} 364}
360 365
361/* idmap classic begins here */ 366/* idmap classic begins here */
362module_param(nfs_idmap_cache_timeout, int, 0644);
363 367
364enum { 368enum {
365 Opt_find_uid, Opt_find_gid, Opt_find_user, Opt_find_group, Opt_find_err 369 Opt_find_uid, Opt_find_gid, Opt_find_user, Opt_find_group, Opt_find_err
@@ -385,7 +389,7 @@ static const struct rpc_pipe_ops idmap_upcall_ops = {
385}; 389};
386 390
387static struct key_type key_type_id_resolver_legacy = { 391static struct key_type key_type_id_resolver_legacy = {
388 .name = "id_resolver", 392 .name = "id_legacy",
389 .instantiate = user_instantiate, 393 .instantiate = user_instantiate,
390 .match = user_match, 394 .match = user_match,
391 .revoke = user_revoke, 395 .revoke = user_revoke,
@@ -674,6 +678,7 @@ static int nfs_idmap_legacy_upcall(struct key_construction *cons,
674 if (ret < 0) 678 if (ret < 0)
675 goto out2; 679 goto out2;
676 680
681 BUG_ON(idmap->idmap_key_cons != NULL);
677 idmap->idmap_key_cons = cons; 682 idmap->idmap_key_cons = cons;
678 683
679 ret = rpc_queue_upcall(idmap->idmap_pipe, msg); 684 ret = rpc_queue_upcall(idmap->idmap_pipe, msg);
@@ -687,8 +692,7 @@ out2:
687out1: 692out1:
688 kfree(msg); 693 kfree(msg);
689out0: 694out0:
690 key_revoke(cons->key); 695 complete_request_key(cons, ret);
691 key_revoke(cons->authkey);
692 return ret; 696 return ret;
693} 697}
694 698
@@ -722,11 +726,18 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
722{ 726{
723 struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode); 727 struct rpc_inode *rpci = RPC_I(filp->f_path.dentry->d_inode);
724 struct idmap *idmap = (struct idmap *)rpci->private; 728 struct idmap *idmap = (struct idmap *)rpci->private;
725 struct key_construction *cons = idmap->idmap_key_cons; 729 struct key_construction *cons;
726 struct idmap_msg im; 730 struct idmap_msg im;
727 size_t namelen_in; 731 size_t namelen_in;
728 int ret; 732 int ret;
729 733
734 /* If instantiation is successful, anyone waiting for key construction
735 * will have been woken up and someone else may now have used
736 * idmap_key_cons - so after this point we may no longer touch it.
737 */
738 cons = ACCESS_ONCE(idmap->idmap_key_cons);
739 idmap->idmap_key_cons = NULL;
740
730 if (mlen != sizeof(im)) { 741 if (mlen != sizeof(im)) {
731 ret = -ENOSPC; 742 ret = -ENOSPC;
732 goto out; 743 goto out;
@@ -739,7 +750,7 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
739 750
740 if (!(im.im_status & IDMAP_STATUS_SUCCESS)) { 751 if (!(im.im_status & IDMAP_STATUS_SUCCESS)) {
741 ret = mlen; 752 ret = mlen;
742 complete_request_key(idmap->idmap_key_cons, -ENOKEY); 753 complete_request_key(cons, -ENOKEY);
743 goto out_incomplete; 754 goto out_incomplete;
744 } 755 }
745 756
@@ -756,7 +767,7 @@ idmap_pipe_downcall(struct file *filp, const char __user *src, size_t mlen)
756 } 767 }
757 768
758out: 769out:
759 complete_request_key(idmap->idmap_key_cons, ret); 770 complete_request_key(cons, ret);
760out_incomplete: 771out_incomplete:
761 return ret; 772 return ret;
762} 773}
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 35f7e4bc680e..2ed6138f32ad 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -50,6 +50,7 @@
50#include "fscache.h" 50#include "fscache.h"
51#include "dns_resolve.h" 51#include "dns_resolve.h"
52#include "pnfs.h" 52#include "pnfs.h"
53#include "nfs.h"
53#include "netns.h" 54#include "netns.h"
54 55
55#define NFSDBG_FACILITY NFSDBG_VFS 56#define NFSDBG_FACILITY NFSDBG_VFS
@@ -81,6 +82,7 @@ int nfs_wait_bit_killable(void *word)
81 freezable_schedule(); 82 freezable_schedule();
82 return 0; 83 return 0;
83} 84}
85EXPORT_SYMBOL_GPL(nfs_wait_bit_killable);
84 86
85/** 87/**
86 * nfs_compat_user_ino64 - returns the user-visible inode number 88 * nfs_compat_user_ino64 - returns the user-visible inode number
@@ -105,7 +107,7 @@ u64 nfs_compat_user_ino64(u64 fileid)
105 return ino; 107 return ino;
106} 108}
107 109
108static void nfs_clear_inode(struct inode *inode) 110void nfs_clear_inode(struct inode *inode)
109{ 111{
110 /* 112 /*
111 * The following should never happen... 113 * The following should never happen...
@@ -116,6 +118,7 @@ static void nfs_clear_inode(struct inode *inode)
116 nfs_access_zap_cache(inode); 118 nfs_access_zap_cache(inode);
117 nfs_fscache_release_inode_cookie(inode); 119 nfs_fscache_release_inode_cookie(inode);
118} 120}
121EXPORT_SYMBOL_GPL(nfs_clear_inode);
119 122
120void nfs_evict_inode(struct inode *inode) 123void nfs_evict_inode(struct inode *inode)
121{ 124{
@@ -185,6 +188,7 @@ void nfs_zap_acl_cache(struct inode *inode)
185 NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_ACL; 188 NFS_I(inode)->cache_validity &= ~NFS_INO_INVALID_ACL;
186 spin_unlock(&inode->i_lock); 189 spin_unlock(&inode->i_lock);
187} 190}
191EXPORT_SYMBOL_GPL(nfs_zap_acl_cache);
188 192
189void nfs_invalidate_atime(struct inode *inode) 193void nfs_invalidate_atime(struct inode *inode)
190{ 194{
@@ -192,6 +196,7 @@ void nfs_invalidate_atime(struct inode *inode)
192 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME; 196 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
193 spin_unlock(&inode->i_lock); 197 spin_unlock(&inode->i_lock);
194} 198}
199EXPORT_SYMBOL_GPL(nfs_invalidate_atime);
195 200
196/* 201/*
197 * Invalidate, but do not unhash, the inode. 202 * Invalidate, but do not unhash, the inode.
@@ -390,6 +395,7 @@ out_no_inode:
390 dprintk("nfs_fhget: iget failed with error %ld\n", PTR_ERR(inode)); 395 dprintk("nfs_fhget: iget failed with error %ld\n", PTR_ERR(inode));
391 goto out; 396 goto out;
392} 397}
398EXPORT_SYMBOL_GPL(nfs_fhget);
393 399
394#define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE|ATTR_OPEN) 400#define NFS_VALID_ATTRS (ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_SIZE|ATTR_ATIME|ATTR_ATIME_SET|ATTR_MTIME|ATTR_MTIME_SET|ATTR_FILE|ATTR_OPEN)
395 401
@@ -437,6 +443,7 @@ nfs_setattr(struct dentry *dentry, struct iattr *attr)
437out: 443out:
438 return error; 444 return error;
439} 445}
446EXPORT_SYMBOL_GPL(nfs_setattr);
440 447
441/** 448/**
442 * nfs_vmtruncate - unmap mappings "freed" by truncate() syscall 449 * nfs_vmtruncate - unmap mappings "freed" by truncate() syscall
@@ -495,6 +502,7 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
495 nfs_vmtruncate(inode, attr->ia_size); 502 nfs_vmtruncate(inode, attr->ia_size);
496 } 503 }
497} 504}
505EXPORT_SYMBOL_GPL(nfs_setattr_update_inode);
498 506
499int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) 507int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
500{ 508{
@@ -534,6 +542,7 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
534out: 542out:
535 return err; 543 return err;
536} 544}
545EXPORT_SYMBOL_GPL(nfs_getattr);
537 546
538static void nfs_init_lock_context(struct nfs_lock_context *l_ctx) 547static void nfs_init_lock_context(struct nfs_lock_context *l_ctx)
539{ 548{
@@ -622,6 +631,7 @@ void nfs_close_context(struct nfs_open_context *ctx, int is_sync)
622 return; 631 return;
623 nfs_revalidate_inode(server, inode); 632 nfs_revalidate_inode(server, inode);
624} 633}
634EXPORT_SYMBOL_GPL(nfs_close_context);
625 635
626struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode) 636struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode)
627{ 637{
@@ -648,6 +658,7 @@ struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f
648 ctx->mdsthreshold = NULL; 658 ctx->mdsthreshold = NULL;
649 return ctx; 659 return ctx;
650} 660}
661EXPORT_SYMBOL_GPL(alloc_nfs_open_context);
651 662
652struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx) 663struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
653{ 664{
@@ -655,6 +666,7 @@ struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx)
655 atomic_inc(&ctx->lock_context.count); 666 atomic_inc(&ctx->lock_context.count);
656 return ctx; 667 return ctx;
657} 668}
669EXPORT_SYMBOL_GPL(get_nfs_open_context);
658 670
659static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync) 671static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync)
660{ 672{
@@ -682,6 +694,7 @@ void put_nfs_open_context(struct nfs_open_context *ctx)
682{ 694{
683 __put_nfs_open_context(ctx, 0); 695 __put_nfs_open_context(ctx, 0);
684} 696}
697EXPORT_SYMBOL_GPL(put_nfs_open_context);
685 698
686/* 699/*
687 * Ensure that mmap has a recent RPC credential for use when writing out 700 * Ensure that mmap has a recent RPC credential for use when writing out
@@ -697,6 +710,7 @@ void nfs_file_set_open_context(struct file *filp, struct nfs_open_context *ctx)
697 list_add(&ctx->list, &nfsi->open_files); 710 list_add(&ctx->list, &nfsi->open_files);
698 spin_unlock(&inode->i_lock); 711 spin_unlock(&inode->i_lock);
699} 712}
713EXPORT_SYMBOL_GPL(nfs_file_set_open_context);
700 714
701/* 715/*
702 * Given an inode, search for an open context with the desired characteristics 716 * Given an inode, search for an open context with the desired characteristics
@@ -841,6 +855,7 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
841 return NFS_STALE(inode) ? -ESTALE : 0; 855 return NFS_STALE(inode) ? -ESTALE : 0;
842 return __nfs_revalidate_inode(server, inode); 856 return __nfs_revalidate_inode(server, inode);
843} 857}
858EXPORT_SYMBOL_GPL(nfs_revalidate_inode);
844 859
845static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping) 860static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping)
846{ 861{
@@ -1027,6 +1042,7 @@ void nfs_fattr_init(struct nfs_fattr *fattr)
1027 fattr->owner_name = NULL; 1042 fattr->owner_name = NULL;
1028 fattr->group_name = NULL; 1043 fattr->group_name = NULL;
1029} 1044}
1045EXPORT_SYMBOL_GPL(nfs_fattr_init);
1030 1046
1031struct nfs_fattr *nfs_alloc_fattr(void) 1047struct nfs_fattr *nfs_alloc_fattr(void)
1032{ 1048{
@@ -1037,6 +1053,7 @@ struct nfs_fattr *nfs_alloc_fattr(void)
1037 nfs_fattr_init(fattr); 1053 nfs_fattr_init(fattr);
1038 return fattr; 1054 return fattr;
1039} 1055}
1056EXPORT_SYMBOL_GPL(nfs_alloc_fattr);
1040 1057
1041struct nfs_fh *nfs_alloc_fhandle(void) 1058struct nfs_fh *nfs_alloc_fhandle(void)
1042{ 1059{
@@ -1047,6 +1064,7 @@ struct nfs_fh *nfs_alloc_fhandle(void)
1047 fh->size = 0; 1064 fh->size = 0;
1048 return fh; 1065 return fh;
1049} 1066}
1067EXPORT_SYMBOL_GPL(nfs_alloc_fhandle);
1050 1068
1051#ifdef NFS_DEBUG 1069#ifdef NFS_DEBUG
1052/* 1070/*
@@ -1167,6 +1185,7 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr)
1167 1185
1168 return status; 1186 return status;
1169} 1187}
1188EXPORT_SYMBOL_GPL(nfs_refresh_inode);
1170 1189
1171static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr) 1190static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr)
1172{ 1191{
@@ -1203,6 +1222,7 @@ int nfs_post_op_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1203 spin_unlock(&inode->i_lock); 1222 spin_unlock(&inode->i_lock);
1204 return status; 1223 return status;
1205} 1224}
1225EXPORT_SYMBOL_GPL(nfs_post_op_update_inode);
1206 1226
1207/** 1227/**
1208 * nfs_post_op_update_inode_force_wcc - try to update the inode attribute cache 1228 * nfs_post_op_update_inode_force_wcc - try to update the inode attribute cache
@@ -1254,6 +1274,7 @@ out_noforce:
1254 spin_unlock(&inode->i_lock); 1274 spin_unlock(&inode->i_lock);
1255 return status; 1275 return status;
1256} 1276}
1277EXPORT_SYMBOL_GPL(nfs_post_op_update_inode_force_wcc);
1257 1278
1258/* 1279/*
1259 * Many nfs protocol calls return the new file attributes after 1280 * Many nfs protocol calls return the new file attributes after
@@ -1471,27 +1492,6 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1471 return -ESTALE; 1492 return -ESTALE;
1472} 1493}
1473 1494
1474
1475#ifdef CONFIG_NFS_V4
1476
1477/*
1478 * Clean out any remaining NFSv4 state that might be left over due
1479 * to open() calls that passed nfs_atomic_lookup, but failed to call
1480 * nfs_open().
1481 */
1482void nfs4_evict_inode(struct inode *inode)
1483{
1484 truncate_inode_pages(&inode->i_data, 0);
1485 clear_inode(inode);
1486 pnfs_return_layout(inode);
1487 pnfs_destroy_layout(NFS_I(inode));
1488 /* If we are holding a delegation, return it! */
1489 nfs_inode_return_delegation_noreclaim(inode);
1490 /* First call standard NFS clear_inode() code */
1491 nfs_clear_inode(inode);
1492}
1493#endif
1494
1495struct inode *nfs_alloc_inode(struct super_block *sb) 1495struct inode *nfs_alloc_inode(struct super_block *sb)
1496{ 1496{
1497 struct nfs_inode *nfsi; 1497 struct nfs_inode *nfsi;
@@ -1504,11 +1504,12 @@ struct inode *nfs_alloc_inode(struct super_block *sb)
1504 nfsi->acl_access = ERR_PTR(-EAGAIN); 1504 nfsi->acl_access = ERR_PTR(-EAGAIN);
1505 nfsi->acl_default = ERR_PTR(-EAGAIN); 1505 nfsi->acl_default = ERR_PTR(-EAGAIN);
1506#endif 1506#endif
1507#ifdef CONFIG_NFS_V4 1507#if IS_ENABLED(CONFIG_NFS_V4)
1508 nfsi->nfs4_acl = NULL; 1508 nfsi->nfs4_acl = NULL;
1509#endif /* CONFIG_NFS_V4 */ 1509#endif /* CONFIG_NFS_V4 */
1510 return &nfsi->vfs_inode; 1510 return &nfsi->vfs_inode;
1511} 1511}
1512EXPORT_SYMBOL_GPL(nfs_alloc_inode);
1512 1513
1513static void nfs_i_callback(struct rcu_head *head) 1514static void nfs_i_callback(struct rcu_head *head)
1514{ 1515{
@@ -1520,10 +1521,11 @@ void nfs_destroy_inode(struct inode *inode)
1520{ 1521{
1521 call_rcu(&inode->i_rcu, nfs_i_callback); 1522 call_rcu(&inode->i_rcu, nfs_i_callback);
1522} 1523}
1524EXPORT_SYMBOL_GPL(nfs_destroy_inode);
1523 1525
1524static inline void nfs4_init_once(struct nfs_inode *nfsi) 1526static inline void nfs4_init_once(struct nfs_inode *nfsi)
1525{ 1527{
1526#ifdef CONFIG_NFS_V4 1528#if IS_ENABLED(CONFIG_NFS_V4)
1527 INIT_LIST_HEAD(&nfsi->open_states); 1529 INIT_LIST_HEAD(&nfsi->open_states);
1528 nfsi->delegation = NULL; 1530 nfsi->delegation = NULL;
1529 nfsi->delegation_state = 0; 1531 nfsi->delegation_state = 0;
@@ -1569,6 +1571,7 @@ static void nfs_destroy_inodecache(void)
1569} 1571}
1570 1572
1571struct workqueue_struct *nfsiod_workqueue; 1573struct workqueue_struct *nfsiod_workqueue;
1574EXPORT_SYMBOL_GPL(nfsiod_workqueue);
1572 1575
1573/* 1576/*
1574 * start up the nfsiod workqueue 1577 * start up the nfsiod workqueue
@@ -1629,94 +1632,80 @@ static int __init init_nfs_fs(void)
1629 1632
1630 err = nfs_dns_resolver_init(); 1633 err = nfs_dns_resolver_init();
1631 if (err < 0) 1634 if (err < 0)
1632 goto out11; 1635 goto out10;;
1633 1636
1634 err = register_pernet_subsys(&nfs_net_ops); 1637 err = register_pernet_subsys(&nfs_net_ops);
1635 if (err < 0) 1638 if (err < 0)
1636 goto out10; 1639 goto out9;
1637 1640
1638 err = nfs_fscache_register(); 1641 err = nfs_fscache_register();
1639 if (err < 0) 1642 if (err < 0)
1640 goto out9; 1643 goto out8;
1641 1644
1642 err = nfsiod_start(); 1645 err = nfsiod_start();
1643 if (err) 1646 if (err)
1644 goto out8; 1647 goto out7;
1645 1648
1646 err = nfs_fs_proc_init(); 1649 err = nfs_fs_proc_init();
1647 if (err) 1650 if (err)
1648 goto out7; 1651 goto out6;
1649 1652
1650 err = nfs_init_nfspagecache(); 1653 err = nfs_init_nfspagecache();
1651 if (err) 1654 if (err)
1652 goto out6; 1655 goto out5;
1653 1656
1654 err = nfs_init_inodecache(); 1657 err = nfs_init_inodecache();
1655 if (err) 1658 if (err)
1656 goto out5; 1659 goto out4;
1657 1660
1658 err = nfs_init_readpagecache(); 1661 err = nfs_init_readpagecache();
1659 if (err) 1662 if (err)
1660 goto out4; 1663 goto out3;
1661 1664
1662 err = nfs_init_writepagecache(); 1665 err = nfs_init_writepagecache();
1663 if (err) 1666 if (err)
1664 goto out3; 1667 goto out2;
1665 1668
1666 err = nfs_init_directcache(); 1669 err = nfs_init_directcache();
1667 if (err) 1670 if (err)
1668 goto out2; 1671 goto out1;
1669 1672
1670#ifdef CONFIG_PROC_FS 1673#ifdef CONFIG_PROC_FS
1671 rpc_proc_register(&init_net, &nfs_rpcstat); 1674 rpc_proc_register(&init_net, &nfs_rpcstat);
1672#endif 1675#endif
1673
1674#ifdef CONFIG_NFS_V4
1675 err = init_nfs_v4();
1676 if (err)
1677 goto out1;
1678#endif
1679
1680 if ((err = register_nfs_fs()) != 0) 1676 if ((err = register_nfs_fs()) != 0)
1681 goto out0; 1677 goto out0;
1682 1678
1683 return 0; 1679 return 0;
1684out0: 1680out0:
1685#ifdef CONFIG_NFS_V4
1686 exit_nfs_v4();
1687out1:
1688#endif
1689#ifdef CONFIG_PROC_FS 1681#ifdef CONFIG_PROC_FS
1690 rpc_proc_unregister(&init_net, "nfs"); 1682 rpc_proc_unregister(&init_net, "nfs");
1691#endif 1683#endif
1692 nfs_destroy_directcache(); 1684 nfs_destroy_directcache();
1693out2: 1685out1:
1694 nfs_destroy_writepagecache(); 1686 nfs_destroy_writepagecache();
1695out3: 1687out2:
1696 nfs_destroy_readpagecache(); 1688 nfs_destroy_readpagecache();
1697out4: 1689out3:
1698 nfs_destroy_inodecache(); 1690 nfs_destroy_inodecache();
1699out5: 1691out4:
1700 nfs_destroy_nfspagecache(); 1692 nfs_destroy_nfspagecache();
1701out6: 1693out5:
1702 nfs_fs_proc_exit(); 1694 nfs_fs_proc_exit();
1703out7: 1695out6:
1704 nfsiod_stop(); 1696 nfsiod_stop();
1705out8: 1697out7:
1706 nfs_fscache_unregister(); 1698 nfs_fscache_unregister();
1707out9: 1699out8:
1708 unregister_pernet_subsys(&nfs_net_ops); 1700 unregister_pernet_subsys(&nfs_net_ops);
1709out10: 1701out9:
1710 nfs_dns_resolver_destroy(); 1702 nfs_dns_resolver_destroy();
1711out11: 1703out10:
1712 return err; 1704 return err;
1713} 1705}
1714 1706
1715static void __exit exit_nfs_fs(void) 1707static void __exit exit_nfs_fs(void)
1716{ 1708{
1717#ifdef CONFIG_NFS_V4
1718 exit_nfs_v4();
1719#endif
1720 nfs_destroy_directcache(); 1709 nfs_destroy_directcache();
1721 nfs_destroy_writepagecache(); 1710 nfs_destroy_writepagecache();
1722 nfs_destroy_readpagecache(); 1711 nfs_destroy_readpagecache();
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
index cfafd13b6fe9..8865538b26b6 100644
--- a/fs/nfs/internal.h
+++ b/fs/nfs/internal.h
@@ -90,7 +90,7 @@ struct nfs_client_initdata {
90 const char *hostname; 90 const char *hostname;
91 const struct sockaddr *addr; 91 const struct sockaddr *addr;
92 size_t addrlen; 92 size_t addrlen;
93 const struct nfs_rpc_ops *rpc_ops; 93 struct nfs_subversion *nfs_mod;
94 int proto; 94 int proto;
95 u32 minorversion; 95 u32 minorversion;
96 struct net *net; 96 struct net *net;
@@ -187,12 +187,11 @@ extern struct nfs_client *nfs4_find_client_ident(struct net *, int);
187extern struct nfs_client * 187extern struct nfs_client *
188nfs4_find_client_sessionid(struct net *, const struct sockaddr *, 188nfs4_find_client_sessionid(struct net *, const struct sockaddr *,
189 struct nfs4_sessionid *); 189 struct nfs4_sessionid *);
190extern struct nfs_server *nfs_create_server( 190extern struct nfs_server *nfs_create_server(struct nfs_mount_info *,
191 const struct nfs_parsed_mount_data *, 191 struct nfs_subversion *);
192 struct nfs_fh *);
193extern struct nfs_server *nfs4_create_server( 192extern struct nfs_server *nfs4_create_server(
194 const struct nfs_parsed_mount_data *, 193 struct nfs_mount_info *,
195 struct nfs_fh *); 194 struct nfs_subversion *);
196extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *, 195extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *,
197 struct nfs_fh *); 196 struct nfs_fh *);
198extern void nfs_free_server(struct nfs_server *server); 197extern void nfs_free_server(struct nfs_server *server);
@@ -224,6 +223,13 @@ static inline void nfs_fs_proc_exit(void)
224int nfs_sockaddr_match_ipaddr(const struct sockaddr *, const struct sockaddr *); 223int nfs_sockaddr_match_ipaddr(const struct sockaddr *, const struct sockaddr *);
225#endif 224#endif
226 225
226/* nfs3client.c */
227#if IS_ENABLED(CONFIG_NFS_V3)
228struct nfs_server *nfs3_create_server(struct nfs_mount_info *, struct nfs_subversion *);
229struct nfs_server *nfs3_clone_server(struct nfs_server *, struct nfs_fh *,
230 struct nfs_fattr *, rpc_authflavor_t);
231#endif
232
227/* callback_xdr.c */ 233/* callback_xdr.c */
228extern struct svc_version nfs4_callback_version1; 234extern struct svc_version nfs4_callback_version1;
229extern struct svc_version nfs4_callback_version4; 235extern struct svc_version nfs4_callback_version4;
@@ -256,7 +262,7 @@ extern int nfs3_decode_dirent(struct xdr_stream *,
256 struct nfs_entry *, int); 262 struct nfs_entry *, int);
257 263
258/* nfs4xdr.c */ 264/* nfs4xdr.c */
259#ifdef CONFIG_NFS_V4 265#if IS_ENABLED(CONFIG_NFS_V4)
260extern int nfs4_decode_dirent(struct xdr_stream *, 266extern int nfs4_decode_dirent(struct xdr_stream *,
261 struct nfs_entry *, int); 267 struct nfs_entry *, int);
262#endif 268#endif
@@ -266,7 +272,7 @@ extern const u32 nfs41_maxwrite_overhead;
266#endif 272#endif
267 273
268/* nfs4proc.c */ 274/* nfs4proc.c */
269#ifdef CONFIG_NFS_V4 275#if IS_ENABLED(CONFIG_NFS_V4)
270extern struct rpc_procinfo nfs4_procedures[]; 276extern struct rpc_procinfo nfs4_procedures[];
271#endif 277#endif
272 278
@@ -313,24 +319,26 @@ extern struct workqueue_struct *nfsiod_workqueue;
313extern struct inode *nfs_alloc_inode(struct super_block *sb); 319extern struct inode *nfs_alloc_inode(struct super_block *sb);
314extern void nfs_destroy_inode(struct inode *); 320extern void nfs_destroy_inode(struct inode *);
315extern int nfs_write_inode(struct inode *, struct writeback_control *); 321extern int nfs_write_inode(struct inode *, struct writeback_control *);
322extern void nfs_clear_inode(struct inode *);
316extern void nfs_evict_inode(struct inode *); 323extern void nfs_evict_inode(struct inode *);
317#ifdef CONFIG_NFS_V4
318extern void nfs4_evict_inode(struct inode *);
319#endif
320void nfs_zap_acl_cache(struct inode *inode); 324void nfs_zap_acl_cache(struct inode *inode);
321extern int nfs_wait_bit_killable(void *word); 325extern int nfs_wait_bit_killable(void *word);
322 326
323/* super.c */ 327/* super.c */
328extern const struct super_operations nfs_sops;
329extern struct file_system_type nfs_fs_type;
324extern struct file_system_type nfs_xdev_fs_type; 330extern struct file_system_type nfs_xdev_fs_type;
325#ifdef CONFIG_NFS_V4 331#if IS_ENABLED(CONFIG_NFS_V4)
326extern struct file_system_type nfs4_xdev_fs_type; 332extern struct file_system_type nfs4_xdev_fs_type;
327extern struct file_system_type nfs4_referral_fs_type; 333extern struct file_system_type nfs4_referral_fs_type;
328#endif 334#endif
335struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *,
336 struct nfs_subversion *);
329void nfs_initialise_sb(struct super_block *); 337void nfs_initialise_sb(struct super_block *);
330int nfs_set_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); 338int nfs_set_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *);
331int nfs_clone_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); 339int nfs_clone_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *);
332struct dentry *nfs_fs_mount_common(struct file_system_type *, struct nfs_server *, 340struct dentry *nfs_fs_mount_common(struct nfs_server *, int, const char *,
333 int, const char *, struct nfs_mount_info *); 341 struct nfs_mount_info *, struct nfs_subversion *);
334struct dentry *nfs_fs_mount(struct file_system_type *, int, const char *, void *); 342struct dentry *nfs_fs_mount(struct file_system_type *, int, const char *, void *);
335struct dentry * nfs_xdev_mount_common(struct file_system_type *, int, 343struct dentry * nfs_xdev_mount_common(struct file_system_type *, int,
336 const char *, struct nfs_mount_info *); 344 const char *, struct nfs_mount_info *);
@@ -356,7 +364,7 @@ struct vfsmount *nfs_do_submount(struct dentry *, struct nfs_fh *,
356/* getroot.c */ 364/* getroot.c */
357extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *, 365extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *,
358 const char *); 366 const char *);
359#ifdef CONFIG_NFS_V4 367#if IS_ENABLED(CONFIG_NFS_V4)
360extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *, 368extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *,
361 const char *); 369 const char *);
362 370
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 08b9c93675da..655925373b91 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -7,6 +7,7 @@
7 * NFS namespace 7 * NFS namespace
8 */ 8 */
9 9
10#include <linux/module.h>
10#include <linux/dcache.h> 11#include <linux/dcache.h>
11#include <linux/gfp.h> 12#include <linux/gfp.h>
12#include <linux/mount.h> 13#include <linux/mount.h>
@@ -112,6 +113,7 @@ Elong_unlock:
112Elong: 113Elong:
113 return ERR_PTR(-ENAMETOOLONG); 114 return ERR_PTR(-ENAMETOOLONG);
114} 115}
116EXPORT_SYMBOL_GPL(nfs_path);
115 117
116/* 118/*
117 * nfs_d_automount - Handle crossing a mountpoint on the server 119 * nfs_d_automount - Handle crossing a mountpoint on the server
@@ -195,20 +197,7 @@ static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server,
195 const char *devname, 197 const char *devname,
196 struct nfs_clone_mount *mountdata) 198 struct nfs_clone_mount *mountdata)
197{ 199{
198#ifdef CONFIG_NFS_V4
199 struct vfsmount *mnt = ERR_PTR(-EINVAL);
200 switch (server->nfs_client->rpc_ops->version) {
201 case 2:
202 case 3:
203 mnt = vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata);
204 break;
205 case 4:
206 mnt = vfs_kern_mount(&nfs4_xdev_fs_type, 0, devname, mountdata);
207 }
208 return mnt;
209#else
210 return vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata); 200 return vfs_kern_mount(&nfs_xdev_fs_type, 0, devname, mountdata);
211#endif
212} 201}
213 202
214/** 203/**
@@ -253,6 +242,7 @@ out:
253 dprintk("<-- nfs_do_submount() = %p\n", mnt); 242 dprintk("<-- nfs_do_submount() = %p\n", mnt);
254 return mnt; 243 return mnt;
255} 244}
245EXPORT_SYMBOL_GPL(nfs_do_submount);
256 246
257struct vfsmount *nfs_submount(struct nfs_server *server, struct dentry *dentry, 247struct vfsmount *nfs_submount(struct nfs_server *server, struct dentry *dentry,
258 struct nfs_fh *fh, struct nfs_fattr *fattr) 248 struct nfs_fh *fh, struct nfs_fattr *fattr)
@@ -268,3 +258,4 @@ struct vfsmount *nfs_submount(struct nfs_server *server, struct dentry *dentry,
268 258
269 return nfs_do_submount(dentry, fh, fattr, server->client->cl_auth->au_flavor); 259 return nfs_do_submount(dentry, fh, fattr, server->client->cl_auth->au_flavor);
270} 260}
261EXPORT_SYMBOL_GPL(nfs_submount);
diff --git a/fs/nfs/netns.h b/fs/nfs/netns.h
index 8a6394edb8b0..0539de1b8d1f 100644
--- a/fs/nfs/netns.h
+++ b/fs/nfs/netns.h
@@ -20,7 +20,7 @@ struct nfs_net {
20 wait_queue_head_t bl_wq; 20 wait_queue_head_t bl_wq;
21 struct list_head nfs_client_list; 21 struct list_head nfs_client_list;
22 struct list_head nfs_volume_list; 22 struct list_head nfs_volume_list;
23#ifdef CONFIG_NFS_V4 23#if IS_ENABLED(CONFIG_NFS_V4)
24 struct idr cb_ident_idr; /* Protected by nfs_client_lock */ 24 struct idr cb_ident_idr; /* Protected by nfs_client_lock */
25#endif 25#endif
26 spinlock_t nfs_client_lock; 26 spinlock_t nfs_client_lock;
diff --git a/fs/nfs/nfs.h b/fs/nfs/nfs.h
new file mode 100644
index 000000000000..43679df56cd0
--- /dev/null
+++ b/fs/nfs/nfs.h
@@ -0,0 +1,29 @@
1/*
2 * Copyright (c) 2012 Netapp, Inc. All rights reserved.
3 *
4 * Function and structures exported by the NFS module
5 * for use by NFS version-specific modules.
6 */
7#ifndef __LINUX_INTERNAL_NFS_H
8#define __LINUX_INTERNAL_NFS_H
9
10#include <linux/fs.h>
11#include <linux/sunrpc/sched.h>
12#include <linux/nfs_xdr.h>
13
14struct nfs_subversion {
15 struct module *owner; /* THIS_MODULE pointer */
16 struct file_system_type *nfs_fs; /* NFS filesystem type */
17 const struct rpc_version *rpc_vers; /* NFS version information */
18 const struct nfs_rpc_ops *rpc_ops; /* NFS operations */
19 const struct super_operations *sops; /* NFS Super operations */
20 const struct xattr_handler **xattr; /* NFS xattr handlers */
21 struct list_head list; /* List of NFS versions */
22};
23
24struct nfs_subversion *get_nfs_version(unsigned int);
25void put_nfs_version(struct nfs_subversion *);
26void register_nfs_version(struct nfs_subversion *);
27void unregister_nfs_version(struct nfs_subversion *);
28
29#endif /* __LINUX_INTERNAL_NFS_H */
diff --git a/fs/nfs/nfs2super.c b/fs/nfs/nfs2super.c
new file mode 100644
index 000000000000..0a9782c9171a
--- /dev/null
+++ b/fs/nfs/nfs2super.c
@@ -0,0 +1,31 @@
1/*
2 * Copyright (c) 2012 Netapp, Inc. All rights reserved.
3 */
4#include <linux/module.h>
5#include <linux/nfs_fs.h>
6#include "internal.h"
7#include "nfs.h"
8
9static struct nfs_subversion nfs_v2 = {
10 .owner = THIS_MODULE,
11 .nfs_fs = &nfs_fs_type,
12 .rpc_vers = &nfs_version2,
13 .rpc_ops = &nfs_v2_clientops,
14 .sops = &nfs_sops,
15};
16
17static int __init init_nfs_v2(void)
18{
19 register_nfs_version(&nfs_v2);
20 return 0;
21}
22
23static void __exit exit_nfs_v2(void)
24{
25 unregister_nfs_version(&nfs_v2);
26}
27
28MODULE_LICENSE("GPL");
29
30module_init(init_nfs_v2);
31module_exit(exit_nfs_v2);
diff --git a/fs/nfs/nfs3client.c b/fs/nfs/nfs3client.c
new file mode 100644
index 000000000000..b3fc65ef39ca
--- /dev/null
+++ b/fs/nfs/nfs3client.c
@@ -0,0 +1,65 @@
1#include <linux/nfs_fs.h>
2#include <linux/nfs_mount.h>
3#include "internal.h"
4
5#ifdef CONFIG_NFS_V3_ACL
6static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
7static const struct rpc_version *nfsacl_version[] = {
8 [3] = &nfsacl_version3,
9};
10
11const struct rpc_program nfsacl_program = {
12 .name = "nfsacl",
13 .number = NFS_ACL_PROGRAM,
14 .nrvers = ARRAY_SIZE(nfsacl_version),
15 .version = nfsacl_version,
16 .stats = &nfsacl_rpcstat,
17};
18
19/*
20 * Initialise an NFSv3 ACL client connection
21 */
22static void nfs_init_server_aclclient(struct nfs_server *server)
23{
24 if (server->flags & NFS_MOUNT_NOACL)
25 goto out_noacl;
26
27 server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
28 if (IS_ERR(server->client_acl))
29 goto out_noacl;
30
31 /* No errors! Assume that Sun nfsacls are supported */
32 server->caps |= NFS_CAP_ACLS;
33 return;
34
35out_noacl:
36 server->caps &= ~NFS_CAP_ACLS;
37}
38#else
39static inline void nfs_init_server_aclclient(struct nfs_server *server)
40{
41 server->flags &= ~NFS_MOUNT_NOACL;
42 server->caps &= ~NFS_CAP_ACLS;
43}
44#endif
45
46struct nfs_server *nfs3_create_server(struct nfs_mount_info *mount_info,
47 struct nfs_subversion *nfs_mod)
48{
49 struct nfs_server *server = nfs_create_server(mount_info, nfs_mod);
50 /* Create a client RPC handle for the NFS v3 ACL management interface */
51 if (!IS_ERR(server))
52 nfs_init_server_aclclient(server);
53 return server;
54}
55
56struct nfs_server *nfs3_clone_server(struct nfs_server *source,
57 struct nfs_fh *fh,
58 struct nfs_fattr *fattr,
59 rpc_authflavor_t flavor)
60{
61 struct nfs_server *server = nfs_clone_server(source, fh, fattr, flavor);
62 if (!IS_ERR(server) && !IS_ERR(source->client_acl))
63 nfs_init_server_aclclient(server);
64 return server;
65}
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index 65d23eb92fe0..0952c791df36 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -925,6 +925,7 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
925 .file_ops = &nfs_file_operations, 925 .file_ops = &nfs_file_operations,
926 .getroot = nfs3_proc_get_root, 926 .getroot = nfs3_proc_get_root,
927 .submount = nfs_submount, 927 .submount = nfs_submount,
928 .try_mount = nfs_try_mount,
928 .getattr = nfs3_proc_getattr, 929 .getattr = nfs3_proc_getattr,
929 .setattr = nfs3_proc_setattr, 930 .setattr = nfs3_proc_setattr,
930 .lookup = nfs3_proc_lookup, 931 .lookup = nfs3_proc_lookup,
@@ -968,4 +969,6 @@ const struct nfs_rpc_ops nfs_v3_clientops = {
968 .alloc_client = nfs_alloc_client, 969 .alloc_client = nfs_alloc_client,
969 .init_client = nfs_init_client, 970 .init_client = nfs_init_client,
970 .free_client = nfs_free_client, 971 .free_client = nfs_free_client,
972 .create_server = nfs3_create_server,
973 .clone_server = nfs3_clone_server,
971}; 974};
diff --git a/fs/nfs/nfs3super.c b/fs/nfs/nfs3super.c
new file mode 100644
index 000000000000..cc471c725230
--- /dev/null
+++ b/fs/nfs/nfs3super.c
@@ -0,0 +1,31 @@
1/*
2 * Copyright (c) 2012 Netapp, Inc. All rights reserved.
3 */
4#include <linux/module.h>
5#include <linux/nfs_fs.h>
6#include "internal.h"
7#include "nfs.h"
8
9static struct nfs_subversion nfs_v3 = {
10 .owner = THIS_MODULE,
11 .nfs_fs = &nfs_fs_type,
12 .rpc_vers = &nfs_version3,
13 .rpc_ops = &nfs_v3_clientops,
14 .sops = &nfs_sops,
15};
16
17static int __init init_nfs_v3(void)
18{
19 register_nfs_version(&nfs_v3);
20 return 0;
21}
22
23static void __exit exit_nfs_v3(void)
24{
25 unregister_nfs_version(&nfs_v3);
26}
27
28MODULE_LICENSE("GPL");
29
30module_init(init_nfs_v3);
31module_exit(exit_nfs_v3);
diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
index 5511690de8a5..3b950dd81e81 100644
--- a/fs/nfs/nfs4_fs.h
+++ b/fs/nfs/nfs4_fs.h
@@ -9,7 +9,7 @@
9#ifndef __LINUX_FS_NFS_NFS4_FS_H 9#ifndef __LINUX_FS_NFS_NFS4_FS_H
10#define __LINUX_FS_NFS_NFS4_FS_H 10#define __LINUX_FS_NFS_NFS4_FS_H
11 11
12#ifdef CONFIG_NFS_V4 12#if IS_ENABLED(CONFIG_NFS_V4)
13 13
14struct idmap; 14struct idmap;
15 15
@@ -205,9 +205,6 @@ extern const struct dentry_operations nfs4_dentry_operations;
205int nfs_atomic_open(struct inode *, struct dentry *, struct file *, 205int nfs_atomic_open(struct inode *, struct dentry *, struct file *,
206 unsigned, umode_t, int *); 206 unsigned, umode_t, int *);
207 207
208/* write.c */
209int nfs4_write_inode(struct inode *, struct writeback_control *);
210
211/* nfs4namespace.c */ 208/* nfs4namespace.c */
212rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *); 209rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *);
213struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *); 210struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *);
@@ -366,9 +363,11 @@ extern const nfs4_stateid zero_stateid;
366 363
367/* nfs4super.c */ 364/* nfs4super.c */
368struct nfs_mount_info; 365struct nfs_mount_info;
369struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *); 366extern struct nfs_subversion nfs_v4;
370int init_nfs_v4(void); 367struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *, struct nfs_subversion *);
371void exit_nfs_v4(void); 368extern bool nfs4_disable_idmapping;
369extern unsigned short max_session_slots;
370extern unsigned short send_implementation_id;
372 371
373/* nfs4sysctl.c */ 372/* nfs4sysctl.c */
374#ifdef CONFIG_SYSCTL 373#ifdef CONFIG_SYSCTL
diff --git a/fs/nfs/nfs4client.c b/fs/nfs/nfs4client.c
index 1c3f13c8e472..cbcdfaf32505 100644
--- a/fs/nfs/nfs4client.c
+++ b/fs/nfs/nfs4client.c
@@ -18,11 +18,6 @@
18#define NFSDBG_FACILITY NFSDBG_CLIENT 18#define NFSDBG_FACILITY NFSDBG_CLIENT
19 19
20/* 20/*
21 * Turn off NFSv4 uid/gid mapping when using AUTH_SYS
22 */
23static bool nfs4_disable_idmapping = true;
24
25/*
26 * Get a unique NFSv4.0 callback identifier which will be used 21 * Get a unique NFSv4.0 callback identifier which will be used
27 * by the V4.0 callback service to lookup the nfs_client struct 22 * by the V4.0 callback service to lookup the nfs_client struct
28 */ 23 */
@@ -357,7 +352,7 @@ static int nfs4_set_client(struct nfs_server *server,
357 .hostname = hostname, 352 .hostname = hostname,
358 .addr = addr, 353 .addr = addr,
359 .addrlen = addrlen, 354 .addrlen = addrlen,
360 .rpc_ops = &nfs_v4_clientops, 355 .nfs_mod = &nfs_v4,
361 .proto = proto, 356 .proto = proto,
362 .minorversion = minorversion, 357 .minorversion = minorversion,
363 .net = net, 358 .net = net,
@@ -411,7 +406,7 @@ struct nfs_client *nfs4_set_ds_client(struct nfs_client* mds_clp,
411 struct nfs_client_initdata cl_init = { 406 struct nfs_client_initdata cl_init = {
412 .addr = ds_addr, 407 .addr = ds_addr,
413 .addrlen = ds_addrlen, 408 .addrlen = ds_addrlen,
414 .rpc_ops = &nfs_v4_clientops, 409 .nfs_mod = &nfs_v4,
415 .proto = ds_proto, 410 .proto = ds_proto,
416 .minorversion = mds_clp->cl_minorversion, 411 .minorversion = mds_clp->cl_minorversion,
417 .net = mds_clp->cl_net, 412 .net = mds_clp->cl_net,
@@ -574,8 +569,10 @@ error:
574 * Create a version 4 volume record 569 * Create a version 4 volume record
575 * - keyed on server and FSID 570 * - keyed on server and FSID
576 */ 571 */
577struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data, 572/*struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
578 struct nfs_fh *mntfh) 573 struct nfs_fh *mntfh)*/
574struct nfs_server *nfs4_create_server(struct nfs_mount_info *mount_info,
575 struct nfs_subversion *nfs_mod)
579{ 576{
580 struct nfs_server *server; 577 struct nfs_server *server;
581 int error; 578 int error;
@@ -587,11 +584,11 @@ struct nfs_server *nfs4_create_server(const struct nfs_parsed_mount_data *data,
587 return ERR_PTR(-ENOMEM); 584 return ERR_PTR(-ENOMEM);
588 585
589 /* set up the general RPC client */ 586 /* set up the general RPC client */
590 error = nfs4_init_server(server, data); 587 error = nfs4_init_server(server, mount_info->parsed);
591 if (error < 0) 588 if (error < 0)
592 goto error; 589 goto error;
593 590
594 error = nfs4_server_common_setup(server, mntfh); 591 error = nfs4_server_common_setup(server, mount_info->mntfh);
595 if (error < 0) 592 if (error < 0)
596 goto error; 593 goto error;
597 594
@@ -657,7 +654,3 @@ error:
657 dprintk("<-- nfs4_create_referral_server() = error %d\n", error); 654 dprintk("<-- nfs4_create_referral_server() = error %d\n", error);
658 return ERR_PTR(error); 655 return ERR_PTR(error);
659} 656}
660
661module_param(nfs4_disable_idmapping, bool, 0644);
662MODULE_PARM_DESC(nfs4_disable_idmapping,
663 "Turn off NFSv4 idmapping when using 'sec=sys'");
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 6843e0a37de8..a99a8d948721 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -72,8 +72,6 @@
72 72
73#define NFS4_MAX_LOOP_ON_RECOVER (10) 73#define NFS4_MAX_LOOP_ON_RECOVER (10)
74 74
75static unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE;
76
77struct nfs4_opendata; 75struct nfs4_opendata;
78static int _nfs4_proc_open(struct nfs4_opendata *data); 76static int _nfs4_proc_open(struct nfs4_opendata *data);
79static int _nfs4_recover_proc_open(struct nfs4_opendata *data); 77static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
@@ -6870,6 +6868,7 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
6870 .file_ops = &nfs4_file_operations, 6868 .file_ops = &nfs4_file_operations,
6871 .getroot = nfs4_proc_get_root, 6869 .getroot = nfs4_proc_get_root,
6872 .submount = nfs4_submount, 6870 .submount = nfs4_submount,
6871 .try_mount = nfs4_try_mount,
6873 .getattr = nfs4_proc_getattr, 6872 .getattr = nfs4_proc_getattr,
6874 .setattr = nfs4_proc_setattr, 6873 .setattr = nfs4_proc_setattr,
6875 .lookup = nfs4_proc_lookup, 6874 .lookup = nfs4_proc_lookup,
@@ -6915,6 +6914,8 @@ const struct nfs_rpc_ops nfs_v4_clientops = {
6915 .alloc_client = nfs4_alloc_client, 6914 .alloc_client = nfs4_alloc_client,
6916 .init_client = nfs4_init_client, 6915 .init_client = nfs4_init_client,
6917 .free_client = nfs4_free_client, 6916 .free_client = nfs4_free_client,
6917 .create_server = nfs4_create_server,
6918 .clone_server = nfs_clone_server,
6918}; 6919};
6919 6920
6920static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { 6921static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = {
@@ -6929,10 +6930,6 @@ const struct xattr_handler *nfs4_xattr_handlers[] = {
6929 NULL 6930 NULL
6930}; 6931};
6931 6932
6932module_param(max_session_slots, ushort, 0644);
6933MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 "
6934 "requests the client will negotiate");
6935
6936/* 6933/*
6937 * Local variables: 6934 * Local variables:
6938 * c-basic-offset: 8 6935 * c-basic-offset: 8
diff --git a/fs/nfs/nfs4super.c b/fs/nfs/nfs4super.c
index 59264fb335c8..12a31a9dbcdd 100644
--- a/fs/nfs/nfs4super.c
+++ b/fs/nfs/nfs4super.c
@@ -6,15 +6,18 @@
6#include <linux/nfs_idmap.h> 6#include <linux/nfs_idmap.h>
7#include <linux/nfs4_mount.h> 7#include <linux/nfs4_mount.h>
8#include <linux/nfs_fs.h> 8#include <linux/nfs_fs.h>
9#include "delegation.h"
9#include "internal.h" 10#include "internal.h"
10#include "nfs4_fs.h" 11#include "nfs4_fs.h"
12#include "pnfs.h"
13#include "nfs.h"
11 14
12#define NFSDBG_FACILITY NFSDBG_VFS 15#define NFSDBG_FACILITY NFSDBG_VFS
13 16
17static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc);
18static void nfs4_evict_inode(struct inode *inode);
14static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type, 19static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type,
15 int flags, const char *dev_name, void *raw_data); 20 int flags, const char *dev_name, void *raw_data);
16static struct dentry *nfs4_xdev_mount(struct file_system_type *fs_type,
17 int flags, const char *dev_name, void *raw_data);
18static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, 21static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
19 int flags, const char *dev_name, void *raw_data); 22 int flags, const char *dev_name, void *raw_data);
20static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type, 23static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type,
@@ -36,14 +39,6 @@ static struct file_system_type nfs4_remote_fs_type = {
36 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 39 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
37}; 40};
38 41
39struct file_system_type nfs4_xdev_fs_type = {
40 .owner = THIS_MODULE,
41 .name = "nfs4",
42 .mount = nfs4_xdev_mount,
43 .kill_sb = nfs_kill_super,
44 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
45};
46
47static struct file_system_type nfs4_remote_referral_fs_type = { 42static struct file_system_type nfs4_remote_referral_fs_type = {
48 .owner = THIS_MODULE, 43 .owner = THIS_MODULE,
49 .name = "nfs4", 44 .name = "nfs4",
@@ -75,21 +70,48 @@ static const struct super_operations nfs4_sops = {
75 .remount_fs = nfs_remount, 70 .remount_fs = nfs_remount,
76}; 71};
77 72
73struct nfs_subversion nfs_v4 = {
74 .owner = THIS_MODULE,
75 .nfs_fs = &nfs4_fs_type,
76 .rpc_vers = &nfs_version4,
77 .rpc_ops = &nfs_v4_clientops,
78 .sops = &nfs4_sops,
79 .xattr = nfs4_xattr_handlers,
80};
81
82static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc)
83{
84 int ret = nfs_write_inode(inode, wbc);
85
86 if (ret >= 0 && test_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags)) {
87 int status;
88 bool sync = true;
89
90 if (wbc->sync_mode == WB_SYNC_NONE)
91 sync = false;
92
93 status = pnfs_layoutcommit_inode(inode, sync);
94 if (status < 0)
95 return status;
96 }
97 return ret;
98}
99
78/* 100/*
79 * Set up an NFS4 superblock 101 * Clean out any remaining NFSv4 state that might be left over due
102 * to open() calls that passed nfs_atomic_lookup, but failed to call
103 * nfs_open().
80 */ 104 */
81static void nfs4_fill_super(struct super_block *sb, 105static void nfs4_evict_inode(struct inode *inode)
82 struct nfs_mount_info *mount_info)
83{ 106{
84 sb->s_time_gran = 1; 107 truncate_inode_pages(&inode->i_data, 0);
85 sb->s_op = &nfs4_sops; 108 clear_inode(inode);
86 /* 109 pnfs_return_layout(inode);
87 * The VFS shouldn't apply the umask to mode bits. We will do 110 pnfs_destroy_layout(NFS_I(inode));
88 * so ourselves when necessary. 111 /* If we are holding a delegation, return it! */
89 */ 112 nfs_inode_return_delegation_noreclaim(inode);
90 sb->s_flags |= MS_POSIXACL; 113 /* First call standard NFS clear_inode() code */
91 sb->s_xattr = nfs4_xattr_handlers; 114 nfs_clear_inode(inode);
92 nfs_initialise_sb(sb);
93} 115}
94 116
95/* 117/*
@@ -103,17 +125,16 @@ nfs4_remote_mount(struct file_system_type *fs_type, int flags,
103 struct nfs_server *server; 125 struct nfs_server *server;
104 struct dentry *mntroot = ERR_PTR(-ENOMEM); 126 struct dentry *mntroot = ERR_PTR(-ENOMEM);
105 127
106 mount_info->fill_super = nfs4_fill_super;
107 mount_info->set_security = nfs_set_sb_security; 128 mount_info->set_security = nfs_set_sb_security;
108 129
109 /* Get a volume representation */ 130 /* Get a volume representation */
110 server = nfs4_create_server(mount_info->parsed, mount_info->mntfh); 131 server = nfs4_create_server(mount_info, &nfs_v4);
111 if (IS_ERR(server)) { 132 if (IS_ERR(server)) {
112 mntroot = ERR_CAST(server); 133 mntroot = ERR_CAST(server);
113 goto out; 134 goto out;
114 } 135 }
115 136
116 mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, mount_info); 137 mntroot = nfs_fs_mount_common(server, flags, dev_name, mount_info, &nfs_v4);
117 138
118out: 139out:
119 return mntroot; 140 return mntroot;
@@ -228,7 +249,8 @@ static struct dentry *nfs_follow_remote_path(struct vfsmount *root_mnt,
228} 249}
229 250
230struct dentry *nfs4_try_mount(int flags, const char *dev_name, 251struct dentry *nfs4_try_mount(int flags, const char *dev_name,
231 struct nfs_mount_info *mount_info) 252 struct nfs_mount_info *mount_info,
253 struct nfs_subversion *nfs_mod)
232{ 254{
233 char *export_path; 255 char *export_path;
234 struct vfsmount *root_mnt; 256 struct vfsmount *root_mnt;
@@ -237,8 +259,6 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name,
237 259
238 dfprintk(MOUNT, "--> nfs4_try_mount()\n"); 260 dfprintk(MOUNT, "--> nfs4_try_mount()\n");
239 261
240 mount_info->fill_super = nfs4_fill_super;
241
242 export_path = data->nfs_server.export_path; 262 export_path = data->nfs_server.export_path;
243 data->nfs_server.export_path = "/"; 263 data->nfs_server.export_path = "/";
244 root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info, 264 root_mnt = nfs_do_root_mount(&nfs4_remote_fs_type, flags, mount_info,
@@ -253,27 +273,12 @@ struct dentry *nfs4_try_mount(int flags, const char *dev_name,
253 return res; 273 return res;
254} 274}
255 275
256/*
257 * Clone an NFS4 server record on xdev traversal (FSID-change)
258 */
259static struct dentry *
260nfs4_xdev_mount(struct file_system_type *fs_type, int flags,
261 const char *dev_name, void *raw_data)
262{
263 struct nfs_mount_info mount_info = {
264 .fill_super = nfs_clone_super,
265 .set_security = nfs_clone_sb_security,
266 .cloned = raw_data,
267 };
268 return nfs_xdev_mount_common(&nfs4_fs_type, flags, dev_name, &mount_info);
269}
270
271static struct dentry * 276static struct dentry *
272nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, 277nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
273 const char *dev_name, void *raw_data) 278 const char *dev_name, void *raw_data)
274{ 279{
275 struct nfs_mount_info mount_info = { 280 struct nfs_mount_info mount_info = {
276 .fill_super = nfs4_fill_super, 281 .fill_super = nfs_fill_super,
277 .set_security = nfs_clone_sb_security, 282 .set_security = nfs_clone_sb_security,
278 .cloned = raw_data, 283 .cloned = raw_data,
279 }; 284 };
@@ -293,7 +298,7 @@ nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags,
293 goto out; 298 goto out;
294 } 299 }
295 300
296 mntroot = nfs_fs_mount_common(&nfs4_fs_type, server, flags, dev_name, &mount_info); 301 mntroot = nfs_fs_mount_common(server, flags, dev_name, &mount_info, &nfs_v4);
297out: 302out:
298 nfs_free_fhandle(mount_info.mntfh); 303 nfs_free_fhandle(mount_info.mntfh);
299 return mntroot; 304 return mntroot;
@@ -327,7 +332,7 @@ static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type,
327} 332}
328 333
329 334
330int __init init_nfs_v4(void) 335static int __init init_nfs_v4(void)
331{ 336{
332 int err; 337 int err;
333 338
@@ -343,6 +348,7 @@ int __init init_nfs_v4(void)
343 if (err < 0) 348 if (err < 0)
344 goto out2; 349 goto out2;
345 350
351 register_nfs_version(&nfs_v4);
346 return 0; 352 return 0;
347out2: 353out2:
348 nfs4_unregister_sysctl(); 354 nfs4_unregister_sysctl();
@@ -352,9 +358,15 @@ out:
352 return err; 358 return err;
353} 359}
354 360
355void exit_nfs_v4(void) 361static void __exit exit_nfs_v4(void)
356{ 362{
363 unregister_nfs_version(&nfs_v4);
357 unregister_filesystem(&nfs4_fs_type); 364 unregister_filesystem(&nfs4_fs_type);
358 nfs4_unregister_sysctl(); 365 nfs4_unregister_sysctl();
359 nfs_idmap_quit(); 366 nfs_idmap_quit();
360} 367}
368
369MODULE_LICENSE("GPL");
370
371module_init(init_nfs_v4);
372module_exit(exit_nfs_v4);
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 6cbd602e26d5..ca13483edd60 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -852,12 +852,6 @@ const u32 nfs41_maxread_overhead = ((RPC_MAX_HEADER_WITH_AUTH +
852 XDR_UNIT); 852 XDR_UNIT);
853#endif /* CONFIG_NFS_V4_1 */ 853#endif /* CONFIG_NFS_V4_1 */
854 854
855static unsigned short send_implementation_id = 1;
856
857module_param(send_implementation_id, ushort, 0644);
858MODULE_PARM_DESC(send_implementation_id,
859 "Send implementation ID with NFSv4.1 exchange_id");
860
861static const umode_t nfs_type2fmt[] = { 855static const umode_t nfs_type2fmt[] = {
862 [NF4BAD] = 0, 856 [NF4BAD] = 0,
863 [NF4REG] = S_IFREG, 857 [NF4REG] = S_IFREG,
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index aed913c833f4..1e7d8879dae6 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -54,6 +54,7 @@ void nfs_pgheader_init(struct nfs_pageio_descriptor *desc,
54 if (hdr->completion_ops->init_hdr) 54 if (hdr->completion_ops->init_hdr)
55 hdr->completion_ops->init_hdr(hdr); 55 hdr->completion_ops->init_hdr(hdr);
56} 56}
57EXPORT_SYMBOL_GPL(nfs_pgheader_init);
57 58
58void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos) 59void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos)
59{ 60{
@@ -268,6 +269,7 @@ void nfs_pageio_init(struct nfs_pageio_descriptor *desc,
268 desc->pg_lseg = NULL; 269 desc->pg_lseg = NULL;
269 desc->pg_dreq = NULL; 270 desc->pg_dreq = NULL;
270} 271}
272EXPORT_SYMBOL_GPL(nfs_pageio_init);
271 273
272/** 274/**
273 * nfs_can_coalesce_requests - test two requests for compatibility 275 * nfs_can_coalesce_requests - test two requests for compatibility
@@ -409,6 +411,7 @@ int nfs_pageio_add_request(struct nfs_pageio_descriptor *desc,
409 } while (ret); 411 } while (ret);
410 return ret; 412 return ret;
411} 413}
414EXPORT_SYMBOL_GPL(nfs_pageio_add_request);
412 415
413/** 416/**
414 * nfs_pageio_complete - Complete I/O on an nfs_pageio_descriptor 417 * nfs_pageio_complete - Complete I/O on an nfs_pageio_descriptor
@@ -424,6 +427,7 @@ void nfs_pageio_complete(struct nfs_pageio_descriptor *desc)
424 break; 427 break;
425 } 428 }
426} 429}
430EXPORT_SYMBOL_GPL(nfs_pageio_complete);
427 431
428/** 432/**
429 * nfs_pageio_cond_complete - Conditional I/O completion 433 * nfs_pageio_cond_complete - Conditional I/O completion
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 7fbd25afe418..76875bfcf19c 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -1407,6 +1407,7 @@ static void pnfs_writehdr_free(struct nfs_pgio_header *hdr)
1407 put_lseg(hdr->lseg); 1407 put_lseg(hdr->lseg);
1408 nfs_writehdr_free(hdr); 1408 nfs_writehdr_free(hdr);
1409} 1409}
1410EXPORT_SYMBOL_GPL(pnfs_writehdr_free);
1410 1411
1411int 1412int
1412pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc) 1413pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
@@ -1561,6 +1562,7 @@ static void pnfs_readhdr_free(struct nfs_pgio_header *hdr)
1561 put_lseg(hdr->lseg); 1562 put_lseg(hdr->lseg);
1562 nfs_readhdr_free(hdr); 1563 nfs_readhdr_free(hdr);
1563} 1564}
1565EXPORT_SYMBOL_GPL(pnfs_readhdr_free);
1564 1566
1565int 1567int
1566pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc) 1568pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 4d3356af3309..50a88c3546ed 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -774,6 +774,7 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
774 .file_ops = &nfs_file_operations, 774 .file_ops = &nfs_file_operations,
775 .getroot = nfs_proc_get_root, 775 .getroot = nfs_proc_get_root,
776 .submount = nfs_submount, 776 .submount = nfs_submount,
777 .try_mount = nfs_try_mount,
777 .getattr = nfs_proc_getattr, 778 .getattr = nfs_proc_getattr,
778 .setattr = nfs_proc_setattr, 779 .setattr = nfs_proc_setattr,
779 .lookup = nfs_proc_lookup, 780 .lookup = nfs_proc_lookup,
@@ -816,4 +817,6 @@ const struct nfs_rpc_ops nfs_v2_clientops = {
816 .alloc_client = nfs_alloc_client, 817 .alloc_client = nfs_alloc_client,
817 .init_client = nfs_init_client, 818 .init_client = nfs_init_client,
818 .free_client = nfs_free_client, 819 .free_client = nfs_free_client,
820 .create_server = nfs_create_server,
821 .clone_server = nfs_clone_server,
819}; 822};
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index 6267b873bbcb..6935e401ad76 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -48,6 +48,7 @@ struct nfs_read_header *nfs_readhdr_alloc(void)
48 } 48 }
49 return rhdr; 49 return rhdr;
50} 50}
51EXPORT_SYMBOL_GPL(nfs_readhdr_alloc);
51 52
52static struct nfs_read_data *nfs_readdata_alloc(struct nfs_pgio_header *hdr, 53static struct nfs_read_data *nfs_readdata_alloc(struct nfs_pgio_header *hdr,
53 unsigned int pagecount) 54 unsigned int pagecount)
@@ -80,6 +81,7 @@ void nfs_readhdr_free(struct nfs_pgio_header *hdr)
80 81
81 kmem_cache_free(nfs_rdata_cachep, rhdr); 82 kmem_cache_free(nfs_rdata_cachep, rhdr);
82} 83}
84EXPORT_SYMBOL_GPL(nfs_readhdr_free);
83 85
84void nfs_readdata_release(struct nfs_read_data *rdata) 86void nfs_readdata_release(struct nfs_read_data *rdata)
85{ 87{
@@ -96,6 +98,7 @@ void nfs_readdata_release(struct nfs_read_data *rdata)
96 if (atomic_dec_and_test(&hdr->refcnt)) 98 if (atomic_dec_and_test(&hdr->refcnt))
97 hdr->completion_ops->completion(hdr); 99 hdr->completion_ops->completion(hdr);
98} 100}
101EXPORT_SYMBOL_GPL(nfs_readdata_release);
99 102
100static 103static
101int nfs_return_empty_page(struct page *page) 104int nfs_return_empty_page(struct page *page)
@@ -113,6 +116,7 @@ void nfs_pageio_init_read(struct nfs_pageio_descriptor *pgio,
113 nfs_pageio_init(pgio, inode, &nfs_pageio_read_ops, compl_ops, 116 nfs_pageio_init(pgio, inode, &nfs_pageio_read_ops, compl_ops,
114 NFS_SERVER(inode)->rsize, 0); 117 NFS_SERVER(inode)->rsize, 0);
115} 118}
119EXPORT_SYMBOL_GPL(nfs_pageio_init_read);
116 120
117void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio) 121void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio)
118{ 122{
@@ -397,6 +401,7 @@ int nfs_generic_pagein(struct nfs_pageio_descriptor *desc,
397 return nfs_pagein_multi(desc, hdr); 401 return nfs_pagein_multi(desc, hdr);
398 return nfs_pagein_one(desc, hdr); 402 return nfs_pagein_one(desc, hdr);
399} 403}
404EXPORT_SYMBOL_GPL(nfs_generic_pagein);
400 405
401static int nfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc) 406static int nfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc)
402{ 407{
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
index 95866a8c21bb..ac6a3c55dce4 100644
--- a/fs/nfs/super.c
+++ b/fs/nfs/super.c
@@ -64,11 +64,12 @@
64#include "internal.h" 64#include "internal.h"
65#include "fscache.h" 65#include "fscache.h"
66#include "pnfs.h" 66#include "pnfs.h"
67#include "nfs.h"
67 68
68#define NFSDBG_FACILITY NFSDBG_VFS 69#define NFSDBG_FACILITY NFSDBG_VFS
69#define NFS_TEXT_DATA 1 70#define NFS_TEXT_DATA 1
70 71
71#ifdef CONFIG_NFS_V3 72#if IS_ENABLED(CONFIG_NFS_V3)
72#define NFS_DEFAULT_VERSION 3 73#define NFS_DEFAULT_VERSION 3
73#else 74#else
74#define NFS_DEFAULT_VERSION 2 75#define NFS_DEFAULT_VERSION 2
@@ -281,13 +282,14 @@ static match_table_t nfs_vers_tokens = {
281static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type, 282static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type,
282 int flags, const char *dev_name, void *raw_data); 283 int flags, const char *dev_name, void *raw_data);
283 284
284static struct file_system_type nfs_fs_type = { 285struct file_system_type nfs_fs_type = {
285 .owner = THIS_MODULE, 286 .owner = THIS_MODULE,
286 .name = "nfs", 287 .name = "nfs",
287 .mount = nfs_fs_mount, 288 .mount = nfs_fs_mount,
288 .kill_sb = nfs_kill_super, 289 .kill_sb = nfs_kill_super,
289 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 290 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
290}; 291};
292EXPORT_SYMBOL_GPL(nfs_fs_type);
291 293
292struct file_system_type nfs_xdev_fs_type = { 294struct file_system_type nfs_xdev_fs_type = {
293 .owner = THIS_MODULE, 295 .owner = THIS_MODULE,
@@ -297,7 +299,7 @@ struct file_system_type nfs_xdev_fs_type = {
297 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA, 299 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
298}; 300};
299 301
300static const struct super_operations nfs_sops = { 302const struct super_operations nfs_sops = {
301 .alloc_inode = nfs_alloc_inode, 303 .alloc_inode = nfs_alloc_inode,
302 .destroy_inode = nfs_destroy_inode, 304 .destroy_inode = nfs_destroy_inode,
303 .write_inode = nfs_write_inode, 305 .write_inode = nfs_write_inode,
@@ -311,8 +313,9 @@ static const struct super_operations nfs_sops = {
311 .show_stats = nfs_show_stats, 313 .show_stats = nfs_show_stats,
312 .remount_fs = nfs_remount, 314 .remount_fs = nfs_remount,
313}; 315};
316EXPORT_SYMBOL_GPL(nfs_sops);
314 317
315#ifdef CONFIG_NFS_V4 318#if IS_ENABLED(CONFIG_NFS_V4)
316static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *); 319static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *);
317static int nfs4_validate_mount_data(void *options, 320static int nfs4_validate_mount_data(void *options,
318 struct nfs_parsed_mount_data *args, const char *dev_name); 321 struct nfs_parsed_mount_data *args, const char *dev_name);
@@ -363,6 +366,7 @@ void nfs_sb_active(struct super_block *sb)
363 if (atomic_inc_return(&server->active) == 1) 366 if (atomic_inc_return(&server->active) == 1)
364 atomic_inc(&sb->s_active); 367 atomic_inc(&sb->s_active);
365} 368}
369EXPORT_SYMBOL_GPL(nfs_sb_active);
366 370
367void nfs_sb_deactive(struct super_block *sb) 371void nfs_sb_deactive(struct super_block *sb)
368{ 372{
@@ -371,6 +375,7 @@ void nfs_sb_deactive(struct super_block *sb)
371 if (atomic_dec_and_test(&server->active)) 375 if (atomic_dec_and_test(&server->active))
372 deactivate_super(sb); 376 deactivate_super(sb);
373} 377}
378EXPORT_SYMBOL_GPL(nfs_sb_deactive);
374 379
375/* 380/*
376 * Deliver file system statistics to userspace 381 * Deliver file system statistics to userspace
@@ -436,6 +441,7 @@ int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
436 dprintk("%s: statfs error = %d\n", __func__, -error); 441 dprintk("%s: statfs error = %d\n", __func__, -error);
437 return error; 442 return error;
438} 443}
444EXPORT_SYMBOL_GPL(nfs_statfs);
439 445
440/* 446/*
441 * Map the security flavour number to a name 447 * Map the security flavour number to a name
@@ -541,7 +547,7 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss,
541 nfs_show_mountd_netid(m, nfss, showdefaults); 547 nfs_show_mountd_netid(m, nfss, showdefaults);
542} 548}
543 549
544#ifdef CONFIG_NFS_V4 550#if IS_ENABLED(CONFIG_NFS_V4)
545static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss, 551static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss,
546 int showdefaults) 552 int showdefaults)
547{ 553{
@@ -672,8 +678,9 @@ int nfs_show_options(struct seq_file *m, struct dentry *root)
672 678
673 return 0; 679 return 0;
674} 680}
681EXPORT_SYMBOL_GPL(nfs_show_options);
675 682
676#ifdef CONFIG_NFS_V4 683#if IS_ENABLED(CONFIG_NFS_V4)
677#ifdef CONFIG_NFS_V4_1 684#ifdef CONFIG_NFS_V4_1
678static void show_sessions(struct seq_file *m, struct nfs_server *server) 685static void show_sessions(struct seq_file *m, struct nfs_server *server)
679{ 686{
@@ -706,7 +713,7 @@ static void show_implementation_id(struct seq_file *m, struct nfs_server *nfss)
706 } 713 }
707} 714}
708#else 715#else
709#ifdef CONFIG_NFS_V4 716#if IS_ENABLED(CONFIG_NFS_V4)
710static void show_pnfs(struct seq_file *m, struct nfs_server *server) 717static void show_pnfs(struct seq_file *m, struct nfs_server *server)
711{ 718{
712} 719}
@@ -731,12 +738,14 @@ int nfs_show_devname(struct seq_file *m, struct dentry *root)
731 free_page((unsigned long)page); 738 free_page((unsigned long)page);
732 return err; 739 return err;
733} 740}
741EXPORT_SYMBOL_GPL(nfs_show_devname);
734 742
735int nfs_show_path(struct seq_file *m, struct dentry *dentry) 743int nfs_show_path(struct seq_file *m, struct dentry *dentry)
736{ 744{
737 seq_puts(m, "/"); 745 seq_puts(m, "/");
738 return 0; 746 return 0;
739} 747}
748EXPORT_SYMBOL_GPL(nfs_show_path);
740 749
741/* 750/*
742 * Present statistical information for this VFS mountpoint 751 * Present statistical information for this VFS mountpoint
@@ -771,7 +780,7 @@ int nfs_show_stats(struct seq_file *m, struct dentry *root)
771 seq_printf(m, ",bsize=%u", nfss->bsize); 780 seq_printf(m, ",bsize=%u", nfss->bsize);
772 seq_printf(m, ",namlen=%u", nfss->namelen); 781 seq_printf(m, ",namlen=%u", nfss->namelen);
773 782
774#ifdef CONFIG_NFS_V4 783#if IS_ENABLED(CONFIG_NFS_V4)
775 if (nfss->nfs_client->rpc_ops->version == 4) { 784 if (nfss->nfs_client->rpc_ops->version == 4) {
776 seq_printf(m, "\n\tnfsv4:\t"); 785 seq_printf(m, "\n\tnfsv4:\t");
777 seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]); 786 seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]);
@@ -829,6 +838,7 @@ int nfs_show_stats(struct seq_file *m, struct dentry *root)
829 838
830 return 0; 839 return 0;
831} 840}
841EXPORT_SYMBOL_GPL(nfs_show_stats);
832 842
833/* 843/*
834 * Begin unmount by attempting to remove all automounted mountpoints we added 844 * Begin unmount by attempting to remove all automounted mountpoints we added
@@ -848,6 +858,7 @@ void nfs_umount_begin(struct super_block *sb)
848 if (!IS_ERR(rpc)) 858 if (!IS_ERR(rpc))
849 rpc_killall_tasks(rpc); 859 rpc_killall_tasks(rpc);
850} 860}
861EXPORT_SYMBOL_GPL(nfs_umount_begin);
851 862
852static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void) 863static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void)
853{ 864{
@@ -1649,8 +1660,9 @@ static int nfs_request_mount(struct nfs_parsed_mount_data *args,
1649 return nfs_walk_authlist(args, &request); 1660 return nfs_walk_authlist(args, &request);
1650} 1661}
1651 1662
1652static struct dentry *nfs_try_mount(int flags, const char *dev_name, 1663struct dentry *nfs_try_mount(int flags, const char *dev_name,
1653 struct nfs_mount_info *mount_info) 1664 struct nfs_mount_info *mount_info,
1665 struct nfs_subversion *nfs_mod)
1654{ 1666{
1655 int status; 1667 int status;
1656 struct nfs_server *server; 1668 struct nfs_server *server;
@@ -1662,12 +1674,13 @@ static struct dentry *nfs_try_mount(int flags, const char *dev_name,
1662 } 1674 }
1663 1675
1664 /* Get a volume representation */ 1676 /* Get a volume representation */
1665 server = nfs_create_server(mount_info->parsed, mount_info->mntfh); 1677 server = nfs_mod->rpc_ops->create_server(mount_info, nfs_mod);
1666 if (IS_ERR(server)) 1678 if (IS_ERR(server))
1667 return ERR_CAST(server); 1679 return ERR_CAST(server);
1668 1680
1669 return nfs_fs_mount_common(&nfs_fs_type, server, flags, dev_name, mount_info); 1681 return nfs_fs_mount_common(server, flags, dev_name, mount_info, nfs_mod);
1670} 1682}
1683EXPORT_SYMBOL_GPL(nfs_try_mount);
1671 1684
1672/* 1685/*
1673 * Split "dev_name" into "hostname:export_path". 1686 * Split "dev_name" into "hostname:export_path".
@@ -1871,7 +1884,7 @@ static int nfs23_validate_mount_data(void *options,
1871 return NFS_TEXT_DATA; 1884 return NFS_TEXT_DATA;
1872 } 1885 }
1873 1886
1874#ifndef CONFIG_NFS_V3 1887#if !IS_ENABLED(CONFIG_NFS_V3)
1875 if (args->version == 3) 1888 if (args->version == 3)
1876 goto out_v3_not_compiled; 1889 goto out_v3_not_compiled;
1877#endif /* !CONFIG_NFS_V3 */ 1890#endif /* !CONFIG_NFS_V3 */
@@ -1891,7 +1904,7 @@ out_no_sec:
1891 dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n"); 1904 dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n");
1892 return -EINVAL; 1905 return -EINVAL;
1893 1906
1894#ifndef CONFIG_NFS_V3 1907#if !IS_ENABLED(CONFIG_NFS_V3)
1895out_v3_not_compiled: 1908out_v3_not_compiled:
1896 dfprintk(MOUNT, "NFS: NFSv3 is not compiled into kernel\n"); 1909 dfprintk(MOUNT, "NFS: NFSv3 is not compiled into kernel\n");
1897 return -EPROTONOSUPPORT; 1910 return -EPROTONOSUPPORT;
@@ -1910,7 +1923,7 @@ out_invalid_fh:
1910 return -EINVAL; 1923 return -EINVAL;
1911} 1924}
1912 1925
1913#ifdef CONFIG_NFS_V4 1926#if IS_ENABLED(CONFIG_NFS_V4)
1914static int nfs_validate_mount_data(struct file_system_type *fs_type, 1927static int nfs_validate_mount_data(struct file_system_type *fs_type,
1915 void *options, 1928 void *options,
1916 struct nfs_parsed_mount_data *args, 1929 struct nfs_parsed_mount_data *args,
@@ -1948,7 +1961,7 @@ static int nfs_validate_text_mount_data(void *options,
1948 goto out_no_address; 1961 goto out_no_address;
1949 1962
1950 if (args->version == 4) { 1963 if (args->version == 4) {
1951#ifdef CONFIG_NFS_V4 1964#if IS_ENABLED(CONFIG_NFS_V4)
1952 port = NFS_PORT; 1965 port = NFS_PORT;
1953 max_namelen = NFS4_MAXNAMLEN; 1966 max_namelen = NFS4_MAXNAMLEN;
1954 max_pathlen = NFS4_MAXPATHLEN; 1967 max_pathlen = NFS4_MAXPATHLEN;
@@ -1971,7 +1984,7 @@ static int nfs_validate_text_mount_data(void *options,
1971 &args->nfs_server.export_path, 1984 &args->nfs_server.export_path,
1972 max_pathlen); 1985 max_pathlen);
1973 1986
1974#ifndef CONFIG_NFS_V4 1987#if !IS_ENABLED(CONFIG_NFS_V4)
1975out_v4_not_compiled: 1988out_v4_not_compiled:
1976 dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n"); 1989 dfprintk(MOUNT, "NFS: NFSv4 is not compiled into kernel\n");
1977 return -EPROTONOSUPPORT; 1990 return -EPROTONOSUPPORT;
@@ -2070,6 +2083,7 @@ out:
2070 kfree(data); 2083 kfree(data);
2071 return error; 2084 return error;
2072} 2085}
2086EXPORT_SYMBOL_GPL(nfs_remount);
2073 2087
2074/* 2088/*
2075 * Initialise the common bits of the superblock 2089 * Initialise the common bits of the superblock
@@ -2103,10 +2117,12 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info)
2103 2117
2104 sb->s_blocksize_bits = 0; 2118 sb->s_blocksize_bits = 0;
2105 sb->s_blocksize = 0; 2119 sb->s_blocksize = 0;
2106 if (data->bsize) 2120 sb->s_xattr = server->nfs_client->cl_nfs_mod->xattr;
2121 sb->s_op = server->nfs_client->cl_nfs_mod->sops;
2122 if (data && data->bsize)
2107 sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits); 2123 sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
2108 2124
2109 if (server->nfs_client->rpc_ops->version == 3) { 2125 if (server->nfs_client->rpc_ops->version != 2) {
2110 /* The VFS shouldn't apply the umask to mode bits. We will do 2126 /* The VFS shouldn't apply the umask to mode bits. We will do
2111 * so ourselves when necessary. 2127 * so ourselves when necessary.
2112 */ 2128 */
@@ -2114,9 +2130,9 @@ void nfs_fill_super(struct super_block *sb, struct nfs_mount_info *mount_info)
2114 sb->s_time_gran = 1; 2130 sb->s_time_gran = 1;
2115 } 2131 }
2116 2132
2117 sb->s_op = &nfs_sops;
2118 nfs_initialise_sb(sb); 2133 nfs_initialise_sb(sb);
2119} 2134}
2135EXPORT_SYMBOL_GPL(nfs_fill_super);
2120 2136
2121/* 2137/*
2122 * Finish setting up a cloned NFS2/3/4 superblock 2138 * Finish setting up a cloned NFS2/3/4 superblock
@@ -2286,6 +2302,7 @@ int nfs_set_sb_security(struct super_block *s, struct dentry *mntroot,
2286{ 2302{
2287 return security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts); 2303 return security_sb_set_mnt_opts(s, &mount_info->parsed->lsm_opts);
2288} 2304}
2305EXPORT_SYMBOL_GPL(nfs_set_sb_security);
2289 2306
2290int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot, 2307int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot,
2291 struct nfs_mount_info *mount_info) 2308 struct nfs_mount_info *mount_info)
@@ -2296,11 +2313,12 @@ int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot,
2296 return -ESTALE; 2313 return -ESTALE;
2297 return 0; 2314 return 0;
2298} 2315}
2316EXPORT_SYMBOL_GPL(nfs_clone_sb_security);
2299 2317
2300struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type, 2318struct dentry *nfs_fs_mount_common(struct nfs_server *server,
2301 struct nfs_server *server,
2302 int flags, const char *dev_name, 2319 int flags, const char *dev_name,
2303 struct nfs_mount_info *mount_info) 2320 struct nfs_mount_info *mount_info,
2321 struct nfs_subversion *nfs_mod)
2304{ 2322{
2305 struct super_block *s; 2323 struct super_block *s;
2306 struct dentry *mntroot = ERR_PTR(-ENOMEM); 2324 struct dentry *mntroot = ERR_PTR(-ENOMEM);
@@ -2319,7 +2337,7 @@ struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type,
2319 sb_mntdata.mntflags |= MS_SYNCHRONOUS; 2337 sb_mntdata.mntflags |= MS_SYNCHRONOUS;
2320 2338
2321 /* Get a superblock - note that we may end up sharing one that already exists */ 2339 /* Get a superblock - note that we may end up sharing one that already exists */
2322 s = sget(fs_type, compare_super, nfs_set_super, flags, &sb_mntdata); 2340 s = sget(nfs_mod->nfs_fs, compare_super, nfs_set_super, flags, &sb_mntdata);
2323 if (IS_ERR(s)) { 2341 if (IS_ERR(s)) {
2324 mntroot = ERR_CAST(s); 2342 mntroot = ERR_CAST(s);
2325 goto out_err_nosb; 2343 goto out_err_nosb;
@@ -2369,6 +2387,7 @@ error_splat_bdi:
2369 deactivate_locked_super(s); 2387 deactivate_locked_super(s);
2370 goto out; 2388 goto out;
2371} 2389}
2390EXPORT_SYMBOL_GPL(nfs_fs_mount_common);
2372 2391
2373struct dentry *nfs_fs_mount(struct file_system_type *fs_type, 2392struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
2374 int flags, const char *dev_name, void *raw_data) 2393 int flags, const char *dev_name, void *raw_data)
@@ -2378,6 +2397,7 @@ struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
2378 .set_security = nfs_set_sb_security, 2397 .set_security = nfs_set_sb_security,
2379 }; 2398 };
2380 struct dentry *mntroot = ERR_PTR(-ENOMEM); 2399 struct dentry *mntroot = ERR_PTR(-ENOMEM);
2400 struct nfs_subversion *nfs_mod;
2381 int error; 2401 int error;
2382 2402
2383 mount_info.parsed = nfs_alloc_parsed_mount_data(); 2403 mount_info.parsed = nfs_alloc_parsed_mount_data();
@@ -2394,18 +2414,21 @@ struct dentry *nfs_fs_mount(struct file_system_type *fs_type,
2394 goto out; 2414 goto out;
2395 } 2415 }
2396 2416
2397#ifdef CONFIG_NFS_V4 2417 nfs_mod = get_nfs_version(mount_info.parsed->version);
2398 if (mount_info.parsed->version == 4) 2418 if (IS_ERR(nfs_mod)) {
2399 mntroot = nfs4_try_mount(flags, dev_name, &mount_info); 2419 mntroot = ERR_CAST(nfs_mod);
2400 else 2420 goto out;
2401#endif /* CONFIG_NFS_V4 */ 2421 }
2402 mntroot = nfs_try_mount(flags, dev_name, &mount_info);
2403 2422
2423 mntroot = nfs_mod->rpc_ops->try_mount(flags, dev_name, &mount_info, nfs_mod);
2424
2425 put_nfs_version(nfs_mod);
2404out: 2426out:
2405 nfs_free_parsed_mount_data(mount_info.parsed); 2427 nfs_free_parsed_mount_data(mount_info.parsed);
2406 nfs_free_fhandle(mount_info.mntfh); 2428 nfs_free_fhandle(mount_info.mntfh);
2407 return mntroot; 2429 return mntroot;
2408} 2430}
2431EXPORT_SYMBOL_GPL(nfs_fs_mount);
2409 2432
2410/* 2433/*
2411 * Ensure that we unregister the bdi before kill_anon_super 2434 * Ensure that we unregister the bdi before kill_anon_super
@@ -2417,6 +2440,7 @@ void nfs_put_super(struct super_block *s)
2417 2440
2418 bdi_unregister(&server->backing_dev_info); 2441 bdi_unregister(&server->backing_dev_info);
2419} 2442}
2443EXPORT_SYMBOL_GPL(nfs_put_super);
2420 2444
2421/* 2445/*
2422 * Destroy an NFS2/3 superblock 2446 * Destroy an NFS2/3 superblock
@@ -2429,31 +2453,38 @@ void nfs_kill_super(struct super_block *s)
2429 nfs_fscache_release_super_cookie(s); 2453 nfs_fscache_release_super_cookie(s);
2430 nfs_free_server(server); 2454 nfs_free_server(server);
2431} 2455}
2456EXPORT_SYMBOL_GPL(nfs_kill_super);
2432 2457
2433/* 2458/*
2434 * Clone an NFS2/3/4 server record on xdev traversal (FSID-change) 2459 * Clone an NFS2/3/4 server record on xdev traversal (FSID-change)
2435 */ 2460 */
2436struct dentry * 2461struct dentry *
2437nfs_xdev_mount_common(struct file_system_type *fs_type, int flags, 2462nfs_xdev_mount(struct file_system_type *fs_type, int flags,
2438 const char *dev_name, struct nfs_mount_info *mount_info) 2463 const char *dev_name, void *raw_data)
2439{ 2464{
2440 struct nfs_clone_mount *data = mount_info->cloned; 2465 struct nfs_clone_mount *data = raw_data;
2466 struct nfs_mount_info mount_info = {
2467 .fill_super = nfs_clone_super,
2468 .set_security = nfs_clone_sb_security,
2469 .cloned = data,
2470 };
2441 struct nfs_server *server; 2471 struct nfs_server *server;
2442 struct dentry *mntroot = ERR_PTR(-ENOMEM); 2472 struct dentry *mntroot = ERR_PTR(-ENOMEM);
2473 struct nfs_subversion *nfs_mod = NFS_SB(data->sb)->nfs_client->cl_nfs_mod;
2443 int error; 2474 int error;
2444 2475
2445 dprintk("--> nfs_xdev_mount_common()\n"); 2476 dprintk("--> nfs_xdev_mount_common()\n");
2446 2477
2447 mount_info->mntfh = data->fh; 2478 mount_info.mntfh = mount_info.cloned->fh;
2448 2479
2449 /* create a new volume representation */ 2480 /* create a new volume representation */
2450 server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor); 2481 server = nfs_mod->rpc_ops->clone_server(NFS_SB(data->sb), data->fh, data->fattr, data->authflavor);
2451 if (IS_ERR(server)) { 2482 if (IS_ERR(server)) {
2452 error = PTR_ERR(server); 2483 error = PTR_ERR(server);
2453 goto out_err; 2484 goto out_err;
2454 } 2485 }
2455 2486
2456 mntroot = nfs_fs_mount_common(fs_type, server, flags, dev_name, mount_info); 2487 mntroot = nfs_fs_mount_common(server, flags, dev_name, &mount_info, nfs_mod);
2457 dprintk("<-- nfs_xdev_mount_common() = 0\n"); 2488 dprintk("<-- nfs_xdev_mount_common() = 0\n");
2458out: 2489out:
2459 return mntroot; 2490 return mntroot;
@@ -2463,22 +2494,7 @@ out_err:
2463 goto out; 2494 goto out;
2464} 2495}
2465 2496
2466/* 2497#if IS_ENABLED(CONFIG_NFS_V4)
2467 * Clone an NFS2/3 server record on xdev traversal (FSID-change)
2468 */
2469static struct dentry *
2470nfs_xdev_mount(struct file_system_type *fs_type, int flags,
2471 const char *dev_name, void *raw_data)
2472{
2473 struct nfs_mount_info mount_info = {
2474 .fill_super = nfs_clone_super,
2475 .set_security = nfs_clone_sb_security,
2476 .cloned = raw_data,
2477 };
2478 return nfs_xdev_mount_common(&nfs_fs_type, flags, dev_name, &mount_info);
2479}
2480
2481#ifdef CONFIG_NFS_V4
2482 2498
2483static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args) 2499static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args)
2484{ 2500{
@@ -2577,4 +2593,56 @@ out_no_address:
2577 return -EINVAL; 2593 return -EINVAL;
2578} 2594}
2579 2595
2596/*
2597 * NFS v4 module parameters need to stay in the
2598 * NFS client for backwards compatibility
2599 */
2600unsigned int nfs_callback_set_tcpport;
2601unsigned short nfs_callback_tcpport;
2602/* Default cache timeout is 10 minutes */
2603unsigned int nfs_idmap_cache_timeout = 600;
2604/* Turn off NFSv4 uid/gid mapping when using AUTH_SYS */
2605bool nfs4_disable_idmapping = true;
2606unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE;
2607unsigned short send_implementation_id = 1;
2608
2609EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport);
2610EXPORT_SYMBOL_GPL(nfs_callback_tcpport);
2611EXPORT_SYMBOL_GPL(nfs_idmap_cache_timeout);
2612EXPORT_SYMBOL_GPL(nfs4_disable_idmapping);
2613EXPORT_SYMBOL_GPL(max_session_slots);
2614EXPORT_SYMBOL_GPL(send_implementation_id);
2615
2616#define NFS_CALLBACK_MAXPORTNR (65535U)
2617
2618static int param_set_portnr(const char *val, const struct kernel_param *kp)
2619{
2620 unsigned long num;
2621 int ret;
2622
2623 if (!val)
2624 return -EINVAL;
2625 ret = strict_strtoul(val, 0, &num);
2626 if (ret == -EINVAL || num > NFS_CALLBACK_MAXPORTNR)
2627 return -EINVAL;
2628 *((unsigned int *)kp->arg) = num;
2629 return 0;
2630}
2631static struct kernel_param_ops param_ops_portnr = {
2632 .set = param_set_portnr,
2633 .get = param_get_uint,
2634};
2635#define param_check_portnr(name, p) __param_check(name, p, unsigned int);
2636
2637module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644);
2638module_param(nfs_idmap_cache_timeout, int, 0644);
2639module_param(nfs4_disable_idmapping, bool, 0644);
2640MODULE_PARM_DESC(nfs4_disable_idmapping,
2641 "Turn off NFSv4 idmapping when using 'sec=sys'");
2642module_param(max_session_slots, ushort, 0644);
2643MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 "
2644 "requests the client will negotiate");
2645module_param(send_implementation_id, ushort, 0644);
2646MODULE_PARM_DESC(send_implementation_id,
2647 "Send implementation ID with NFSv4.1 exchange_id");
2580#endif /* CONFIG_NFS_V4 */ 2648#endif /* CONFIG_NFS_V4 */
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index f312860c15d0..e4a2ad2059bd 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -84,6 +84,7 @@ struct nfs_write_header *nfs_writehdr_alloc(void)
84 } 84 }
85 return p; 85 return p;
86} 86}
87EXPORT_SYMBOL_GPL(nfs_writehdr_alloc);
87 88
88static struct nfs_write_data *nfs_writedata_alloc(struct nfs_pgio_header *hdr, 89static struct nfs_write_data *nfs_writedata_alloc(struct nfs_pgio_header *hdr,
89 unsigned int pagecount) 90 unsigned int pagecount)
@@ -115,6 +116,7 @@ void nfs_writehdr_free(struct nfs_pgio_header *hdr)
115 struct nfs_write_header *whdr = container_of(hdr, struct nfs_write_header, header); 116 struct nfs_write_header *whdr = container_of(hdr, struct nfs_write_header, header);
116 mempool_free(whdr, nfs_wdata_mempool); 117 mempool_free(whdr, nfs_wdata_mempool);
117} 118}
119EXPORT_SYMBOL_GPL(nfs_writehdr_free);
118 120
119void nfs_writedata_release(struct nfs_write_data *wdata) 121void nfs_writedata_release(struct nfs_write_data *wdata)
120{ 122{
@@ -131,6 +133,7 @@ void nfs_writedata_release(struct nfs_write_data *wdata)
131 if (atomic_dec_and_test(&hdr->refcnt)) 133 if (atomic_dec_and_test(&hdr->refcnt))
132 hdr->completion_ops->completion(hdr); 134 hdr->completion_ops->completion(hdr);
133} 135}
136EXPORT_SYMBOL_GPL(nfs_writedata_release);
134 137
135static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error) 138static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error)
136{ 139{
@@ -446,7 +449,7 @@ nfs_mark_request_dirty(struct nfs_page *req)
446 __set_page_dirty_nobuffers(req->wb_page); 449 __set_page_dirty_nobuffers(req->wb_page);
447} 450}
448 451
449#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 452#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
450/** 453/**
451 * nfs_request_add_commit_list - add request to a commit list 454 * nfs_request_add_commit_list - add request to a commit list
452 * @req: pointer to a struct nfs_page 455 * @req: pointer to a struct nfs_page
@@ -636,7 +639,7 @@ out:
636 hdr->release(hdr); 639 hdr->release(hdr);
637} 640}
638 641
639#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 642#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
640static unsigned long 643static unsigned long
641nfs_reqs_to_commit(struct nfs_commit_info *cinfo) 644nfs_reqs_to_commit(struct nfs_commit_info *cinfo)
642{ 645{
@@ -1173,6 +1176,7 @@ int nfs_generic_flush(struct nfs_pageio_descriptor *desc,
1173 return nfs_flush_multi(desc, hdr); 1176 return nfs_flush_multi(desc, hdr);
1174 return nfs_flush_one(desc, hdr); 1177 return nfs_flush_one(desc, hdr);
1175} 1178}
1179EXPORT_SYMBOL_GPL(nfs_generic_flush);
1176 1180
1177static int nfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc) 1181static int nfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc)
1178{ 1182{
@@ -1210,6 +1214,7 @@ void nfs_pageio_init_write(struct nfs_pageio_descriptor *pgio,
1210 nfs_pageio_init(pgio, inode, &nfs_pageio_write_ops, compl_ops, 1214 nfs_pageio_init(pgio, inode, &nfs_pageio_write_ops, compl_ops,
1211 NFS_SERVER(inode)->wsize, ioflags); 1215 NFS_SERVER(inode)->wsize, ioflags);
1212} 1216}
1217EXPORT_SYMBOL_GPL(nfs_pageio_init_write);
1213 1218
1214void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio) 1219void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio)
1215{ 1220{
@@ -1297,7 +1302,7 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1297 return; 1302 return;
1298 nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, resp->count); 1303 nfs_add_stats(inode, NFSIOS_SERVERWRITTENBYTES, resp->count);
1299 1304
1300#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 1305#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
1301 if (resp->verf->committed < argp->stable && task->tk_status >= 0) { 1306 if (resp->verf->committed < argp->stable && task->tk_status >= 0) {
1302 /* We tried a write call, but the server did not 1307 /* We tried a write call, but the server did not
1303 * commit data to stable storage even though we 1308 * commit data to stable storage even though we
@@ -1357,7 +1362,7 @@ void nfs_writeback_done(struct rpc_task *task, struct nfs_write_data *data)
1357} 1362}
1358 1363
1359 1364
1360#if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) 1365#if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4)
1361static int nfs_commit_set_lock(struct nfs_inode *nfsi, int may_wait) 1366static int nfs_commit_set_lock(struct nfs_inode *nfsi, int may_wait)
1362{ 1367{
1363 int ret; 1368 int ret;
@@ -1673,26 +1678,7 @@ int nfs_write_inode(struct inode *inode, struct writeback_control *wbc)
1673{ 1678{
1674 return nfs_commit_unstable_pages(inode, wbc); 1679 return nfs_commit_unstable_pages(inode, wbc);
1675} 1680}
1676 1681EXPORT_SYMBOL_GPL(nfs_write_inode);
1677#ifdef CONFIG_NFS_V4
1678int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc)
1679{
1680 int ret = nfs_write_inode(inode, wbc);
1681
1682 if (ret >= 0 && test_bit(NFS_INO_LAYOUTCOMMIT, &NFS_I(inode)->flags)) {
1683 int status;
1684 bool sync = true;
1685
1686 if (wbc->sync_mode == WB_SYNC_NONE)
1687 sync = false;
1688
1689 status = pnfs_layoutcommit_inode(inode, sync);
1690 if (status < 0)
1691 return status;
1692 }
1693 return ret;
1694}
1695#endif
1696 1682
1697/* 1683/*
1698 * flush the inode to disk. 1684 * flush the inode to disk.
@@ -1708,6 +1694,7 @@ int nfs_wb_all(struct inode *inode)
1708 1694
1709 return sync_inode(inode, &wbc); 1695 return sync_inode(inode, &wbc);
1710} 1696}
1697EXPORT_SYMBOL_GPL(nfs_wb_all);
1711 1698
1712int nfs_wb_page_cancel(struct inode *inode, struct page *page) 1699int nfs_wb_page_cancel(struct inode *inode, struct page *page)
1713{ 1700{