diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-31 21:45:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-31 21:45:44 -0400 |
commit | 6dbb35b0a74b44b2a48a5373d48074c5aa69fdf5 (patch) | |
tree | 4afb5eec521659e19c9d2343c2431054a082eb06 /fs | |
parent | fd37ce34bd512f2b1a503f82abf8768da556a955 (diff) | |
parent | ad0fcd4eb68059de02e1766948263c71b8a5b1dc (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/Kconfig | 6 | ||||
-rw-r--r-- | fs/nfs/Makefile | 27 | ||||
-rw-r--r-- | fs/nfs/blocklayout/blocklayout.c | 39 | ||||
-rw-r--r-- | fs/nfs/callback.c | 28 | ||||
-rw-r--r-- | fs/nfs/callback.h | 2 | ||||
-rw-r--r-- | fs/nfs/client.c | 191 | ||||
-rw-r--r-- | fs/nfs/delegation.h | 2 | ||||
-rw-r--r-- | fs/nfs/dir.c | 20 | ||||
-rw-r--r-- | fs/nfs/direct.c | 2 | ||||
-rw-r--r-- | fs/nfs/dns_resolve.c | 4 | ||||
-rw-r--r-- | fs/nfs/file.c | 31 | ||||
-rw-r--r-- | fs/nfs/idmap.c | 29 | ||||
-rw-r--r-- | fs/nfs/inode.c | 105 | ||||
-rw-r--r-- | fs/nfs/internal.h | 38 | ||||
-rw-r--r-- | fs/nfs/namespace.c | 17 | ||||
-rw-r--r-- | fs/nfs/netns.h | 2 | ||||
-rw-r--r-- | fs/nfs/nfs.h | 29 | ||||
-rw-r--r-- | fs/nfs/nfs2super.c | 31 | ||||
-rw-r--r-- | fs/nfs/nfs3client.c | 65 | ||||
-rw-r--r-- | fs/nfs/nfs3proc.c | 3 | ||||
-rw-r--r-- | fs/nfs/nfs3super.c | 31 | ||||
-rw-r--r-- | fs/nfs/nfs4_fs.h | 13 | ||||
-rw-r--r-- | fs/nfs/nfs4client.c | 23 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 9 | ||||
-rw-r--r-- | fs/nfs/nfs4super.c | 106 | ||||
-rw-r--r-- | fs/nfs/nfs4xdr.c | 6 | ||||
-rw-r--r-- | fs/nfs/pagelist.c | 4 | ||||
-rw-r--r-- | fs/nfs/pnfs.c | 2 | ||||
-rw-r--r-- | fs/nfs/proc.c | 3 | ||||
-rw-r--r-- | fs/nfs/read.c | 5 | ||||
-rw-r--r-- | fs/nfs/super.c | 172 | ||||
-rw-r--r-- | fs/nfs/write.c | 35 |
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 | ||
32 | config NFS_V2 | 32 | config 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 | ||
42 | config NFS_V3 | 42 | config 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 | ||
74 | config NFS_V4 | 74 | config 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 |
11 | nfs-$(CONFIG_ROOT_NFS) += nfsroot.o | 11 | nfs-$(CONFIG_ROOT_NFS) += nfsroot.o |
12 | nfs-$(CONFIG_NFS_V2) += proc.o nfs2xdr.o | 12 | nfs-$(CONFIG_SYSCTL) += sysctl.o |
13 | nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o | 13 | nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o |
14 | nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o | ||
15 | nfs-$(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 | ||
19 | nfs-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o | ||
20 | 14 | ||
21 | ifeq ($(CONFIG_SYSCTL), y) | 15 | obj-$(CONFIG_NFS_V2) += nfs2.o |
22 | nfs-y += sysctl.o | 16 | nfs2-y := nfs2super.o proc.o nfs2xdr.o |
23 | nfs-$(CONFIG_NFS_V4) += nfs4sysctl.o | ||
24 | endif | ||
25 | 17 | ||
26 | nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o | 18 | obj-$(CONFIG_NFS_V3) += nfs3.o |
19 | nfs3-y := nfs3super.o nfs3client.o nfs3proc.o nfs3xdr.o | ||
20 | nfs3-$(CONFIG_NFS_V3_ACL) += nfs3acl.o | ||
21 | |||
22 | obj-$(CONFIG_NFS_V4) += nfs4.o | ||
23 | nfs4-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 | ||
26 | nfs4-$(CONFIG_SYSCTL) += nfs4sysctl.o | ||
27 | nfs4-$(CONFIG_NFS_V4_1) += pnfs.o pnfs_dev.o | ||
27 | 28 | ||
28 | obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o | 29 | obj-$(CONFIG_PNFS_FILE_LAYOUT) += nfs_layout_nfsv41_files.o |
29 | nfs_layout_nfsv41_files-y := nfs4filelayout.o nfs4filelayoutdev.o | 30 | nfs_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 | ||
231 | static bool | ||
232 | bl_check_alignment(u64 offset, u32 len, unsigned long blkmask) | ||
233 | { | ||
234 | if ((offset & blkmask) || (len & blkmask)) | ||
235 | return false; | ||
236 | return true; | ||
237 | } | ||
238 | |||
231 | static enum pnfs_try_status | 239 | static enum pnfs_try_status |
232 | bl_read_pagelist(struct nfs_read_data *rdata) | 240 | bl_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 | ||
1014 | static void | ||
1015 | bl_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 | |||
1023 | static void | ||
1024 | bl_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 | |||
999 | static const struct nfs_pageio_ops bl_pg_read_ops = { | 1032 | static 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 | ||
1005 | static const struct nfs_pageio_ops bl_pg_write_ops = { | 1038 | static 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]; | |||
37 | static DEFINE_MUTEX(nfs_callback_mutex); | 37 | static DEFINE_MUTEX(nfs_callback_mutex); |
38 | static struct svc_program nfs4_callback_program; | 38 | static struct svc_program nfs4_callback_program; |
39 | 39 | ||
40 | unsigned int nfs_callback_set_tcpport; | ||
41 | unsigned short nfs_callback_tcpport; | ||
42 | unsigned short nfs_callback_tcpport6; | 40 | unsigned short nfs_callback_tcpport6; |
43 | #define NFS_CALLBACK_MAXPORTNR (65535U) | ||
44 | |||
45 | static 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 | } | ||
58 | static 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 | |||
64 | module_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); |
193 | extern __be32 nfs4_callback_recall(struct cb_recallargs *args, void *dummy, | 193 | extern __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) |
196 | extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt); | 196 | extern int nfs_callback_up(u32 minorversion, struct rpc_xprt *xprt); |
197 | extern void nfs_callback_down(int minorversion); | 197 | extern void nfs_callback_down(int minorversion); |
198 | extern int nfs4_validate_delegation_stateid(struct nfs_delegation *delegation, | 198 | extern 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 | ||
58 | static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq); | 59 | static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq); |
60 | static DEFINE_SPINLOCK(nfs_version_lock); | ||
61 | static DEFINE_MUTEX(nfs_version_mutex); | ||
62 | static LIST_HEAD(nfs_versions); | ||
59 | 63 | ||
60 | /* | 64 | /* |
61 | * RPC cruft for NFS | 65 | * RPC cruft for NFS |
62 | */ | 66 | */ |
63 | static const struct rpc_version *nfs_version[5] = { | 67 | static 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 | ||
75 | const struct rpc_program nfs_program = { | 73 | const 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 | ||
86 | static 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) { |
90 | static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program }; | 92 | if (nfs->rpc_ops->version == version) { |
91 | static const struct rpc_version *nfsacl_version[] = { | 93 | spin_unlock(&nfs_version_lock); |
92 | [3] = &nfsacl_version3, | 94 | return nfs; |
93 | }; | 95 | } |
96 | }; | ||
94 | 97 | ||
95 | const 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, | 102 | struct 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 | |||
118 | void put_nfs_version(struct nfs_subversion *nfs) | ||
119 | { | ||
120 | module_put(nfs->owner); | ||
121 | } | ||
122 | |||
123 | void 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 | } | ||
132 | EXPORT_SYMBOL_GPL(register_nfs_version); | ||
133 | |||
134 | void 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 | } | ||
143 | EXPORT_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 | ||
147 | error_cleanup: | 191 | error_cleanup: |
192 | put_nfs_version(clp->cl_nfs_mod); | ||
148 | kfree(clp); | 193 | kfree(clp); |
149 | error_0: | 194 | error_0: |
150 | return ERR_PTR(err); | 195 | return ERR_PTR(err); |
151 | } | 196 | } |
197 | EXPORT_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 */ |
155 | void nfs_cleanup_cb_ident_idr(struct net *net) | 201 | void 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 | } |
260 | EXPORT_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 | } |
375 | EXPORT_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 | } |
442 | EXPORT_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 | } |
517 | EXPORT_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 | } |
528 | EXPORT_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 | } |
570 | EXPORT_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 | } |
610 | EXPORT_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 | ||
612 | static 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 | |||
627 | out_noacl: | ||
628 | server->caps &= ~NFS_CAP_ACLS; | ||
629 | } | ||
630 | #else | ||
631 | static 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 | */ |
641 | int nfs_init_server_rpcclient(struct nfs_server *server, | 665 | int 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 | } |
697 | EXPORT_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 | } |
737 | EXPORT_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 | */ |
716 | static int nfs_init_server(struct nfs_server *server, | 742 | static 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 | } |
924 | EXPORT_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 | } |
941 | EXPORT_SYMBOL_GPL(nfs_server_copy_userdata); | ||
930 | 942 | ||
931 | void nfs_server_insert_lists(struct nfs_server *server) | 943 | void 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 | } |
955 | EXPORT_SYMBOL_GPL(nfs_server_insert_lists); | ||
943 | 956 | ||
944 | static void nfs_server_remove_lists(struct nfs_server *server) | 957 | static 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 | } |
1015 | EXPORT_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 | } |
1044 | EXPORT_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 | */ |
1035 | struct nfs_server *nfs_create_server(const struct nfs_parsed_mount_data *data, | 1050 | struct 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 | } |
1112 | EXPORT_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 | } |
1182 | EXPORT_SYMBOL_GPL(nfs_clone_server); | ||
1168 | 1183 | ||
1169 | void nfs_clients_init(struct net *net) | 1184 | void 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 | } |
939 | EXPORT_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 | }; |
1201 | EXPORT_SYMBOL_GPL(nfs_dentry_operations); | ||
1199 | 1202 | ||
1200 | struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, unsigned int flags) | 1203 | struct 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 | } |
1269 | EXPORT_SYMBOL_GPL(nfs_lookup); | ||
1266 | 1270 | ||
1267 | #ifdef CONFIG_NFS_V4 | 1271 | #if IS_ENABLED(CONFIG_NFS_V4) |
1268 | static int nfs4_lookup_revalidate(struct dentry *, unsigned int); | 1272 | static int nfs4_lookup_revalidate(struct dentry *, unsigned int); |
1269 | 1273 | ||
1270 | const struct dentry_operations nfs4_dentry_operations = { | 1274 | const 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 | }; |
1281 | EXPORT_SYMBOL_GPL(nfs4_dentry_operations); | ||
1277 | 1282 | ||
1278 | static fmode_t flags_to_mode(int flags) | 1283 | static 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 | } |
1424 | EXPORT_SYMBOL_GPL(nfs_atomic_open); | ||
1419 | 1425 | ||
1420 | static int nfs4_lookup_revalidate(struct dentry *dentry, unsigned int flags) | 1426 | static 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 | } |
1517 | EXPORT_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 | } |
1546 | EXPORT_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 | } |
1574 | EXPORT_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 | } |
1598 | EXPORT_SYMBOL_GPL(nfs_mkdir); | ||
1589 | 1599 | ||
1590 | static void nfs_dentry_handle_enoent(struct dentry *dentry) | 1600 | static 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 | } |
1622 | EXPORT_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 | } |
1694 | EXPORT_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 | } |
1765 | EXPORT_SYMBOL_GPL(nfs_symlink); | ||
1753 | 1766 | ||
1754 | int | 1767 | int |
1755 | nfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry) | 1768 | nfs_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 | } |
1787 | EXPORT_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 | } |
1886 | EXPORT_SYMBOL_GPL(nfs_rename); | ||
1872 | 1887 | ||
1873 | static DEFINE_SPINLOCK(nfs_access_lru_lock); | 1888 | static DEFINE_SPINLOCK(nfs_access_lru_lock); |
1874 | static LIST_HEAD(nfs_access_lru_list); | 1889 | static 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 | } |
1987 | EXPORT_SYMBOL_GPL(nfs_access_zap_cache); | ||
1972 | 1988 | ||
1973 | static struct nfs_access_entry *nfs_access_search_rbtree(struct inode *inode, struct rpc_cred *cred) | 1989 | static 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 | } |
2148 | EXPORT_SYMBOL_GPL(nfs_may_open); | ||
2132 | 2149 | ||
2133 | int nfs_permission(struct inode *inode, int mask) | 2150 | int 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 | } |
2208 | EXPORT_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) |
464 | static void nfs_direct_write_reschedule(struct nfs_direct_req *dreq) | 464 | static 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 | } |
31 | EXPORT_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 | } |
351 | EXPORT_SYMBOL_GPL(nfs_dns_resolve_name); | ||
348 | 352 | ||
349 | int nfs_dns_resolver_cache_init(struct net *net) | 353 | int 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 | } |
56 | EXPORT_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 | } |
89 | EXPORT_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 | } |
143 | EXPORT_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 | } |
172 | EXPORT_SYMBOL_GPL(nfs_file_flush); | ||
168 | 173 | ||
169 | ssize_t | 174 | ssize_t |
170 | nfs_file_read(struct kiocb *iocb, const struct iovec *iov, | 175 | nfs_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 | } |
197 | EXPORT_SYMBOL_GPL(nfs_file_read); | ||
192 | 198 | ||
193 | ssize_t | 199 | ssize_t |
194 | nfs_file_splice_read(struct file *filp, loff_t *ppos, | 200 | nfs_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 | } |
220 | EXPORT_SYMBOL_GPL(nfs_file_splice_read); | ||
214 | 221 | ||
215 | int | 222 | int |
216 | nfs_file_mmap(struct file * file, struct vm_area_struct * vma) | 223 | nfs_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 | } |
242 | EXPORT_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 | } |
281 | EXPORT_SYMBOL_GPL(nfs_file_fsync_commit); | ||
273 | 282 | ||
274 | static int | 283 | static int |
275 | nfs_file_fsync(struct file *file, loff_t start, loff_t end, int datasync) | 284 | nfs_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 | } |
626 | EXPORT_SYMBOL_GPL(nfs_file_write); | ||
614 | 627 | ||
615 | ssize_t nfs_file_splice_write(struct pipe_inode_info *pipe, | 628 | ssize_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 | } |
658 | EXPORT_SYMBOL_GPL(nfs_file_splice_write); | ||
645 | 659 | ||
646 | static int | 660 | static int |
647 | do_getlk(struct file *filp, int cmd, struct file_lock *fl, int is_local) | 661 | do_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) | |||
802 | out_err: | 816 | out_err: |
803 | return ret; | 817 | return ret; |
804 | } | 818 | } |
819 | EXPORT_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 | } |
858 | EXPORT_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 | } |
871 | EXPORT_SYMBOL_GPL(nfs_setlease); | ||
846 | 872 | ||
847 | const struct file_operations nfs_file_operations = { | 873 | const 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 | }; |
891 | EXPORT_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 */ | ||
56 | unsigned int nfs_idmap_cache_timeout = 600; | ||
57 | static const struct cred *id_resolver_cache; | 55 | static const struct cred *id_resolver_cache; |
58 | static struct key_type key_type_id_resolver_legacy; | 56 | static 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 | ||
216 | failed_reg_legacy: | ||
217 | unregister_key_type(&key_type_id_resolver); | ||
214 | failed_put_key: | 218 | failed_put_key: |
215 | key_put(keyring); | 219 | key_put(keyring); |
216 | failed_put_cred: | 220 | failed_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 */ |
362 | module_param(nfs_idmap_cache_timeout, int, 0644); | ||
363 | 367 | ||
364 | enum { | 368 | enum { |
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 | ||
387 | static struct key_type key_type_id_resolver_legacy = { | 391 | static 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: | |||
687 | out1: | 692 | out1: |
688 | kfree(msg); | 693 | kfree(msg); |
689 | out0: | 694 | out0: |
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 | ||
758 | out: | 769 | out: |
759 | complete_request_key(idmap->idmap_key_cons, ret); | 770 | complete_request_key(cons, ret); |
760 | out_incomplete: | 771 | out_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 | } |
85 | EXPORT_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 | ||
108 | static void nfs_clear_inode(struct inode *inode) | 110 | void 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 | } |
121 | EXPORT_SYMBOL_GPL(nfs_clear_inode); | ||
119 | 122 | ||
120 | void nfs_evict_inode(struct inode *inode) | 123 | void 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 | } |
191 | EXPORT_SYMBOL_GPL(nfs_zap_acl_cache); | ||
188 | 192 | ||
189 | void nfs_invalidate_atime(struct inode *inode) | 193 | void 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 | } |
199 | EXPORT_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 | } |
398 | EXPORT_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) | |||
437 | out: | 443 | out: |
438 | return error; | 444 | return error; |
439 | } | 445 | } |
446 | EXPORT_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 | } |
505 | EXPORT_SYMBOL_GPL(nfs_setattr_update_inode); | ||
498 | 506 | ||
499 | int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | 507 | int 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) | |||
534 | out: | 542 | out: |
535 | return err; | 543 | return err; |
536 | } | 544 | } |
545 | EXPORT_SYMBOL_GPL(nfs_getattr); | ||
537 | 546 | ||
538 | static void nfs_init_lock_context(struct nfs_lock_context *l_ctx) | 547 | static 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 | } |
634 | EXPORT_SYMBOL_GPL(nfs_close_context); | ||
625 | 635 | ||
626 | struct nfs_open_context *alloc_nfs_open_context(struct dentry *dentry, fmode_t f_mode) | 636 | struct 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 | } |
661 | EXPORT_SYMBOL_GPL(alloc_nfs_open_context); | ||
651 | 662 | ||
652 | struct nfs_open_context *get_nfs_open_context(struct nfs_open_context *ctx) | 663 | struct 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 | } |
669 | EXPORT_SYMBOL_GPL(get_nfs_open_context); | ||
658 | 670 | ||
659 | static void __put_nfs_open_context(struct nfs_open_context *ctx, int is_sync) | 671 | static 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 | } |
697 | EXPORT_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 | } |
713 | EXPORT_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 | } |
858 | EXPORT_SYMBOL_GPL(nfs_revalidate_inode); | ||
844 | 859 | ||
845 | static int nfs_invalidate_mapping(struct inode *inode, struct address_space *mapping) | 860 | static 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 | } |
1045 | EXPORT_SYMBOL_GPL(nfs_fattr_init); | ||
1030 | 1046 | ||
1031 | struct nfs_fattr *nfs_alloc_fattr(void) | 1047 | struct 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 | } |
1056 | EXPORT_SYMBOL_GPL(nfs_alloc_fattr); | ||
1040 | 1057 | ||
1041 | struct nfs_fh *nfs_alloc_fhandle(void) | 1058 | struct 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 | } |
1067 | EXPORT_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 | } |
1188 | EXPORT_SYMBOL_GPL(nfs_refresh_inode); | ||
1170 | 1189 | ||
1171 | static int nfs_post_op_update_inode_locked(struct inode *inode, struct nfs_fattr *fattr) | 1190 | static 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 | } |
1225 | EXPORT_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 | } |
1277 | EXPORT_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 | */ | ||
1482 | void 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 | |||
1495 | struct inode *nfs_alloc_inode(struct super_block *sb) | 1495 | struct 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 | } |
1512 | EXPORT_SYMBOL_GPL(nfs_alloc_inode); | ||
1512 | 1513 | ||
1513 | static void nfs_i_callback(struct rcu_head *head) | 1514 | static 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 | } |
1524 | EXPORT_SYMBOL_GPL(nfs_destroy_inode); | ||
1523 | 1525 | ||
1524 | static inline void nfs4_init_once(struct nfs_inode *nfsi) | 1526 | static 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 | ||
1571 | struct workqueue_struct *nfsiod_workqueue; | 1573 | struct workqueue_struct *nfsiod_workqueue; |
1574 | EXPORT_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; |
1684 | out0: | 1680 | out0: |
1685 | #ifdef CONFIG_NFS_V4 | ||
1686 | exit_nfs_v4(); | ||
1687 | out1: | ||
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(); |
1693 | out2: | 1685 | out1: |
1694 | nfs_destroy_writepagecache(); | 1686 | nfs_destroy_writepagecache(); |
1695 | out3: | 1687 | out2: |
1696 | nfs_destroy_readpagecache(); | 1688 | nfs_destroy_readpagecache(); |
1697 | out4: | 1689 | out3: |
1698 | nfs_destroy_inodecache(); | 1690 | nfs_destroy_inodecache(); |
1699 | out5: | 1691 | out4: |
1700 | nfs_destroy_nfspagecache(); | 1692 | nfs_destroy_nfspagecache(); |
1701 | out6: | 1693 | out5: |
1702 | nfs_fs_proc_exit(); | 1694 | nfs_fs_proc_exit(); |
1703 | out7: | 1695 | out6: |
1704 | nfsiod_stop(); | 1696 | nfsiod_stop(); |
1705 | out8: | 1697 | out7: |
1706 | nfs_fscache_unregister(); | 1698 | nfs_fscache_unregister(); |
1707 | out9: | 1699 | out8: |
1708 | unregister_pernet_subsys(&nfs_net_ops); | 1700 | unregister_pernet_subsys(&nfs_net_ops); |
1709 | out10: | 1701 | out9: |
1710 | nfs_dns_resolver_destroy(); | 1702 | nfs_dns_resolver_destroy(); |
1711 | out11: | 1703 | out10: |
1712 | return err; | 1704 | return err; |
1713 | } | 1705 | } |
1714 | 1706 | ||
1715 | static void __exit exit_nfs_fs(void) | 1707 | static 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); | |||
187 | extern struct nfs_client * | 187 | extern struct nfs_client * |
188 | nfs4_find_client_sessionid(struct net *, const struct sockaddr *, | 188 | nfs4_find_client_sessionid(struct net *, const struct sockaddr *, |
189 | struct nfs4_sessionid *); | 189 | struct nfs4_sessionid *); |
190 | extern struct nfs_server *nfs_create_server( | 190 | extern 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 *); | ||
193 | extern struct nfs_server *nfs4_create_server( | 192 | extern 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 *); |
196 | extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *, | 195 | extern struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *, |
197 | struct nfs_fh *); | 196 | struct nfs_fh *); |
198 | extern void nfs_free_server(struct nfs_server *server); | 197 | extern void nfs_free_server(struct nfs_server *server); |
@@ -224,6 +223,13 @@ static inline void nfs_fs_proc_exit(void) | |||
224 | int nfs_sockaddr_match_ipaddr(const struct sockaddr *, const struct sockaddr *); | 223 | int 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) | ||
228 | struct nfs_server *nfs3_create_server(struct nfs_mount_info *, struct nfs_subversion *); | ||
229 | struct 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 */ |
228 | extern struct svc_version nfs4_callback_version1; | 234 | extern struct svc_version nfs4_callback_version1; |
229 | extern struct svc_version nfs4_callback_version4; | 235 | extern 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) |
260 | extern int nfs4_decode_dirent(struct xdr_stream *, | 266 | extern 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) |
270 | extern struct rpc_procinfo nfs4_procedures[]; | 276 | extern struct rpc_procinfo nfs4_procedures[]; |
271 | #endif | 277 | #endif |
272 | 278 | ||
@@ -313,24 +319,26 @@ extern struct workqueue_struct *nfsiod_workqueue; | |||
313 | extern struct inode *nfs_alloc_inode(struct super_block *sb); | 319 | extern struct inode *nfs_alloc_inode(struct super_block *sb); |
314 | extern void nfs_destroy_inode(struct inode *); | 320 | extern void nfs_destroy_inode(struct inode *); |
315 | extern int nfs_write_inode(struct inode *, struct writeback_control *); | 321 | extern int nfs_write_inode(struct inode *, struct writeback_control *); |
322 | extern void nfs_clear_inode(struct inode *); | ||
316 | extern void nfs_evict_inode(struct inode *); | 323 | extern void nfs_evict_inode(struct inode *); |
317 | #ifdef CONFIG_NFS_V4 | ||
318 | extern void nfs4_evict_inode(struct inode *); | ||
319 | #endif | ||
320 | void nfs_zap_acl_cache(struct inode *inode); | 324 | void nfs_zap_acl_cache(struct inode *inode); |
321 | extern int nfs_wait_bit_killable(void *word); | 325 | extern int nfs_wait_bit_killable(void *word); |
322 | 326 | ||
323 | /* super.c */ | 327 | /* super.c */ |
328 | extern const struct super_operations nfs_sops; | ||
329 | extern struct file_system_type nfs_fs_type; | ||
324 | extern struct file_system_type nfs_xdev_fs_type; | 330 | extern struct file_system_type nfs_xdev_fs_type; |
325 | #ifdef CONFIG_NFS_V4 | 331 | #if IS_ENABLED(CONFIG_NFS_V4) |
326 | extern struct file_system_type nfs4_xdev_fs_type; | 332 | extern struct file_system_type nfs4_xdev_fs_type; |
327 | extern struct file_system_type nfs4_referral_fs_type; | 333 | extern struct file_system_type nfs4_referral_fs_type; |
328 | #endif | 334 | #endif |
335 | struct dentry *nfs_try_mount(int, const char *, struct nfs_mount_info *, | ||
336 | struct nfs_subversion *); | ||
329 | void nfs_initialise_sb(struct super_block *); | 337 | void nfs_initialise_sb(struct super_block *); |
330 | int nfs_set_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); | 338 | int nfs_set_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); |
331 | int nfs_clone_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); | 339 | int nfs_clone_sb_security(struct super_block *, struct dentry *, struct nfs_mount_info *); |
332 | struct dentry *nfs_fs_mount_common(struct file_system_type *, struct nfs_server *, | 340 | struct 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 *); |
334 | struct dentry *nfs_fs_mount(struct file_system_type *, int, const char *, void *); | 342 | struct dentry *nfs_fs_mount(struct file_system_type *, int, const char *, void *); |
335 | struct dentry * nfs_xdev_mount_common(struct file_system_type *, int, | 343 | struct 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 */ |
357 | extern struct dentry *nfs_get_root(struct super_block *, struct nfs_fh *, | 365 | extern 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) |
360 | extern struct dentry *nfs4_get_root(struct super_block *, struct nfs_fh *, | 368 | extern 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: | |||
112 | Elong: | 113 | Elong: |
113 | return ERR_PTR(-ENAMETOOLONG); | 114 | return ERR_PTR(-ENAMETOOLONG); |
114 | } | 115 | } |
116 | EXPORT_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 | } |
245 | EXPORT_SYMBOL_GPL(nfs_do_submount); | ||
256 | 246 | ||
257 | struct vfsmount *nfs_submount(struct nfs_server *server, struct dentry *dentry, | 247 | struct 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 | } |
261 | EXPORT_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 | |||
14 | struct 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 | |||
24 | struct nfs_subversion *get_nfs_version(unsigned int); | ||
25 | void put_nfs_version(struct nfs_subversion *); | ||
26 | void register_nfs_version(struct nfs_subversion *); | ||
27 | void 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 | |||
9 | static 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 | |||
17 | static int __init init_nfs_v2(void) | ||
18 | { | ||
19 | register_nfs_version(&nfs_v2); | ||
20 | return 0; | ||
21 | } | ||
22 | |||
23 | static void __exit exit_nfs_v2(void) | ||
24 | { | ||
25 | unregister_nfs_version(&nfs_v2); | ||
26 | } | ||
27 | |||
28 | MODULE_LICENSE("GPL"); | ||
29 | |||
30 | module_init(init_nfs_v2); | ||
31 | module_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 | ||
6 | static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program }; | ||
7 | static const struct rpc_version *nfsacl_version[] = { | ||
8 | [3] = &nfsacl_version3, | ||
9 | }; | ||
10 | |||
11 | const 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 | */ | ||
22 | static 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 | |||
35 | out_noacl: | ||
36 | server->caps &= ~NFS_CAP_ACLS; | ||
37 | } | ||
38 | #else | ||
39 | static 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 | |||
46 | struct 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 | |||
56 | struct 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 | |||
9 | static 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 | |||
17 | static int __init init_nfs_v3(void) | ||
18 | { | ||
19 | register_nfs_version(&nfs_v3); | ||
20 | return 0; | ||
21 | } | ||
22 | |||
23 | static void __exit exit_nfs_v3(void) | ||
24 | { | ||
25 | unregister_nfs_version(&nfs_v3); | ||
26 | } | ||
27 | |||
28 | MODULE_LICENSE("GPL"); | ||
29 | |||
30 | module_init(init_nfs_v3); | ||
31 | module_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 | ||
14 | struct idmap; | 14 | struct idmap; |
15 | 15 | ||
@@ -205,9 +205,6 @@ extern const struct dentry_operations nfs4_dentry_operations; | |||
205 | int nfs_atomic_open(struct inode *, struct dentry *, struct file *, | 205 | int nfs_atomic_open(struct inode *, struct dentry *, struct file *, |
206 | unsigned, umode_t, int *); | 206 | unsigned, umode_t, int *); |
207 | 207 | ||
208 | /* write.c */ | ||
209 | int nfs4_write_inode(struct inode *, struct writeback_control *); | ||
210 | |||
211 | /* nfs4namespace.c */ | 208 | /* nfs4namespace.c */ |
212 | rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *); | 209 | rpc_authflavor_t nfs_find_best_sec(struct nfs4_secinfo_flavors *); |
213 | struct rpc_clnt *nfs4_create_sec_client(struct rpc_clnt *, struct inode *, struct qstr *); | 210 | struct 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 */ |
368 | struct nfs_mount_info; | 365 | struct nfs_mount_info; |
369 | struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *); | 366 | extern struct nfs_subversion nfs_v4; |
370 | int init_nfs_v4(void); | 367 | struct dentry *nfs4_try_mount(int, const char *, struct nfs_mount_info *, struct nfs_subversion *); |
371 | void exit_nfs_v4(void); | 368 | extern bool nfs4_disable_idmapping; |
369 | extern unsigned short max_session_slots; | ||
370 | extern 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 | */ | ||
23 | static 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 | */ |
577 | struct 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)*/ |
574 | struct 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 | |||
661 | module_param(nfs4_disable_idmapping, bool, 0644); | ||
662 | MODULE_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 | ||
75 | static unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE; | ||
76 | |||
77 | struct nfs4_opendata; | 75 | struct nfs4_opendata; |
78 | static int _nfs4_proc_open(struct nfs4_opendata *data); | 76 | static int _nfs4_proc_open(struct nfs4_opendata *data); |
79 | static int _nfs4_recover_proc_open(struct nfs4_opendata *data); | 77 | static 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 | ||
6920 | static const struct xattr_handler nfs4_xattr_nfs4_acl_handler = { | 6921 | static 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 | ||
6932 | module_param(max_session_slots, ushort, 0644); | ||
6933 | MODULE_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 | ||
17 | static int nfs4_write_inode(struct inode *inode, struct writeback_control *wbc); | ||
18 | static void nfs4_evict_inode(struct inode *inode); | ||
14 | static struct dentry *nfs4_remote_mount(struct file_system_type *fs_type, | 19 | static 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); |
16 | static struct dentry *nfs4_xdev_mount(struct file_system_type *fs_type, | ||
17 | int flags, const char *dev_name, void *raw_data); | ||
18 | static struct dentry *nfs4_referral_mount(struct file_system_type *fs_type, | 21 | static 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); |
20 | static struct dentry *nfs4_remote_referral_mount(struct file_system_type *fs_type, | 23 | static 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 | ||
39 | struct 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 | |||
47 | static struct file_system_type nfs4_remote_referral_fs_type = { | 42 | static 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 | ||
73 | struct 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 | |||
82 | static 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 | */ |
81 | static void nfs4_fill_super(struct super_block *sb, | 105 | static 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 | ||
118 | out: | 139 | out: |
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 | ||
230 | struct dentry *nfs4_try_mount(int flags, const char *dev_name, | 251 | struct 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 | */ | ||
259 | static struct dentry * | ||
260 | nfs4_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 | |||
271 | static struct dentry * | 276 | static struct dentry * |
272 | nfs4_remote_referral_mount(struct file_system_type *fs_type, int flags, | 277 | nfs4_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); |
297 | out: | 302 | out: |
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 | ||
330 | int __init init_nfs_v4(void) | 335 | static 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; |
347 | out2: | 353 | out2: |
348 | nfs4_unregister_sysctl(); | 354 | nfs4_unregister_sysctl(); |
@@ -352,9 +358,15 @@ out: | |||
352 | return err; | 358 | return err; |
353 | } | 359 | } |
354 | 360 | ||
355 | void exit_nfs_v4(void) | 361 | static 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 | |||
369 | MODULE_LICENSE("GPL"); | ||
370 | |||
371 | module_init(init_nfs_v4); | ||
372 | module_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 | ||
855 | static unsigned short send_implementation_id = 1; | ||
856 | |||
857 | module_param(send_implementation_id, ushort, 0644); | ||
858 | MODULE_PARM_DESC(send_implementation_id, | ||
859 | "Send implementation ID with NFSv4.1 exchange_id"); | ||
860 | |||
861 | static const umode_t nfs_type2fmt[] = { | 855 | static 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 | } |
57 | EXPORT_SYMBOL_GPL(nfs_pgheader_init); | ||
57 | 58 | ||
58 | void nfs_set_pgio_error(struct nfs_pgio_header *hdr, int error, loff_t pos) | 59 | void 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 | } |
272 | EXPORT_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 | } |
414 | EXPORT_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 | } |
430 | EXPORT_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 | } |
1410 | EXPORT_SYMBOL_GPL(pnfs_writehdr_free); | ||
1410 | 1411 | ||
1411 | int | 1412 | int |
1412 | pnfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc) | 1413 | pnfs_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 | } |
1565 | EXPORT_SYMBOL_GPL(pnfs_readhdr_free); | ||
1564 | 1566 | ||
1565 | int | 1567 | int |
1566 | pnfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc) | 1568 | pnfs_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 | } |
51 | EXPORT_SYMBOL_GPL(nfs_readhdr_alloc); | ||
51 | 52 | ||
52 | static struct nfs_read_data *nfs_readdata_alloc(struct nfs_pgio_header *hdr, | 53 | static 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 | } |
84 | EXPORT_SYMBOL_GPL(nfs_readhdr_free); | ||
83 | 85 | ||
84 | void nfs_readdata_release(struct nfs_read_data *rdata) | 86 | void 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 | } |
101 | EXPORT_SYMBOL_GPL(nfs_readdata_release); | ||
99 | 102 | ||
100 | static | 103 | static |
101 | int nfs_return_empty_page(struct page *page) | 104 | int 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 | } |
119 | EXPORT_SYMBOL_GPL(nfs_pageio_init_read); | ||
116 | 120 | ||
117 | void nfs_pageio_reset_read_mds(struct nfs_pageio_descriptor *pgio) | 121 | void 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 | } |
404 | EXPORT_SYMBOL_GPL(nfs_generic_pagein); | ||
400 | 405 | ||
401 | static int nfs_generic_pg_readpages(struct nfs_pageio_descriptor *desc) | 406 | static 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 = { | |||
281 | static struct dentry *nfs_xdev_mount(struct file_system_type *fs_type, | 282 | static 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 | ||
284 | static struct file_system_type nfs_fs_type = { | 285 | struct 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 | }; |
292 | EXPORT_SYMBOL_GPL(nfs_fs_type); | ||
291 | 293 | ||
292 | struct file_system_type nfs_xdev_fs_type = { | 294 | struct 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 | ||
300 | static const struct super_operations nfs_sops = { | 302 | const 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 | }; |
316 | EXPORT_SYMBOL_GPL(nfs_sops); | ||
314 | 317 | ||
315 | #ifdef CONFIG_NFS_V4 | 318 | #if IS_ENABLED(CONFIG_NFS_V4) |
316 | static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *); | 319 | static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *); |
317 | static int nfs4_validate_mount_data(void *options, | 320 | static 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 | } |
369 | EXPORT_SYMBOL_GPL(nfs_sb_active); | ||
366 | 370 | ||
367 | void nfs_sb_deactive(struct super_block *sb) | 371 | void 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 | } |
378 | EXPORT_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 | } |
444 | EXPORT_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) |
545 | static void nfs_show_nfsv4_options(struct seq_file *m, struct nfs_server *nfss, | 551 | static 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 | } |
681 | EXPORT_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 |
678 | static void show_sessions(struct seq_file *m, struct nfs_server *server) | 685 | static 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) |
710 | static void show_pnfs(struct seq_file *m, struct nfs_server *server) | 717 | static 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 | } |
741 | EXPORT_SYMBOL_GPL(nfs_show_devname); | ||
734 | 742 | ||
735 | int nfs_show_path(struct seq_file *m, struct dentry *dentry) | 743 | int 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 | } |
748 | EXPORT_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 | } |
841 | EXPORT_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 | } |
861 | EXPORT_SYMBOL_GPL(nfs_umount_begin); | ||
851 | 862 | ||
852 | static struct nfs_parsed_mount_data *nfs_alloc_parsed_mount_data(void) | 863 | static 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 | ||
1652 | static struct dentry *nfs_try_mount(int flags, const char *dev_name, | 1663 | struct 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 | } |
1683 | EXPORT_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) |
1895 | out_v3_not_compiled: | 1908 | out_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) |
1914 | static int nfs_validate_mount_data(struct file_system_type *fs_type, | 1927 | static 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) |
1975 | out_v4_not_compiled: | 1988 | out_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 | } |
2086 | EXPORT_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 | } |
2135 | EXPORT_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 | } |
2305 | EXPORT_SYMBOL_GPL(nfs_set_sb_security); | ||
2289 | 2306 | ||
2290 | int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot, | 2307 | int 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 | } |
2316 | EXPORT_SYMBOL_GPL(nfs_clone_sb_security); | ||
2299 | 2317 | ||
2300 | struct dentry *nfs_fs_mount_common(struct file_system_type *fs_type, | 2318 | struct 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 | } |
2390 | EXPORT_SYMBOL_GPL(nfs_fs_mount_common); | ||
2372 | 2391 | ||
2373 | struct dentry *nfs_fs_mount(struct file_system_type *fs_type, | 2392 | struct 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); | ||
2404 | out: | 2426 | out: |
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 | } |
2431 | EXPORT_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 | } |
2443 | EXPORT_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 | } |
2456 | EXPORT_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 | */ |
2436 | struct dentry * | 2461 | struct dentry * |
2437 | nfs_xdev_mount_common(struct file_system_type *fs_type, int flags, | 2462 | nfs_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"); |
2458 | out: | 2489 | out: |
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 | */ | ||
2469 | static struct dentry * | ||
2470 | nfs_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 | ||
2483 | static void nfs4_validate_mount_flags(struct nfs_parsed_mount_data *args) | 2499 | static 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 | */ | ||
2600 | unsigned int nfs_callback_set_tcpport; | ||
2601 | unsigned short nfs_callback_tcpport; | ||
2602 | /* Default cache timeout is 10 minutes */ | ||
2603 | unsigned int nfs_idmap_cache_timeout = 600; | ||
2604 | /* Turn off NFSv4 uid/gid mapping when using AUTH_SYS */ | ||
2605 | bool nfs4_disable_idmapping = true; | ||
2606 | unsigned short max_session_slots = NFS4_DEF_SLOT_TABLE_SIZE; | ||
2607 | unsigned short send_implementation_id = 1; | ||
2608 | |||
2609 | EXPORT_SYMBOL_GPL(nfs_callback_set_tcpport); | ||
2610 | EXPORT_SYMBOL_GPL(nfs_callback_tcpport); | ||
2611 | EXPORT_SYMBOL_GPL(nfs_idmap_cache_timeout); | ||
2612 | EXPORT_SYMBOL_GPL(nfs4_disable_idmapping); | ||
2613 | EXPORT_SYMBOL_GPL(max_session_slots); | ||
2614 | EXPORT_SYMBOL_GPL(send_implementation_id); | ||
2615 | |||
2616 | #define NFS_CALLBACK_MAXPORTNR (65535U) | ||
2617 | |||
2618 | static 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 | } | ||
2631 | static 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 | |||
2637 | module_param_named(callback_tcpport, nfs_callback_set_tcpport, portnr, 0644); | ||
2638 | module_param(nfs_idmap_cache_timeout, int, 0644); | ||
2639 | module_param(nfs4_disable_idmapping, bool, 0644); | ||
2640 | MODULE_PARM_DESC(nfs4_disable_idmapping, | ||
2641 | "Turn off NFSv4 idmapping when using 'sec=sys'"); | ||
2642 | module_param(max_session_slots, ushort, 0644); | ||
2643 | MODULE_PARM_DESC(max_session_slots, "Maximum number of outstanding NFSv4.1 " | ||
2644 | "requests the client will negotiate"); | ||
2645 | module_param(send_implementation_id, ushort, 0644); | ||
2646 | MODULE_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 | } |
87 | EXPORT_SYMBOL_GPL(nfs_writehdr_alloc); | ||
87 | 88 | ||
88 | static struct nfs_write_data *nfs_writedata_alloc(struct nfs_pgio_header *hdr, | 89 | static 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 | } |
119 | EXPORT_SYMBOL_GPL(nfs_writehdr_free); | ||
118 | 120 | ||
119 | void nfs_writedata_release(struct nfs_write_data *wdata) | 121 | void 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 | } |
136 | EXPORT_SYMBOL_GPL(nfs_writedata_release); | ||
134 | 137 | ||
135 | static void nfs_context_set_write_error(struct nfs_open_context *ctx, int error) | 138 | static 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) |
640 | static unsigned long | 643 | static unsigned long |
641 | nfs_reqs_to_commit(struct nfs_commit_info *cinfo) | 644 | nfs_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 | } |
1179 | EXPORT_SYMBOL_GPL(nfs_generic_flush); | ||
1176 | 1180 | ||
1177 | static int nfs_generic_pg_writepages(struct nfs_pageio_descriptor *desc) | 1181 | static 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 | } |
1217 | EXPORT_SYMBOL_GPL(nfs_pageio_init_write); | ||
1213 | 1218 | ||
1214 | void nfs_pageio_reset_write_mds(struct nfs_pageio_descriptor *pgio) | 1219 | void 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) |
1361 | static int nfs_commit_set_lock(struct nfs_inode *nfsi, int may_wait) | 1366 | static 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 | 1681 | EXPORT_SYMBOL_GPL(nfs_write_inode); | |
1677 | #ifdef CONFIG_NFS_V4 | ||
1678 | int 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 | } |
1697 | EXPORT_SYMBOL_GPL(nfs_wb_all); | ||
1711 | 1698 | ||
1712 | int nfs_wb_page_cancel(struct inode *inode, struct page *page) | 1699 | int nfs_wb_page_cancel(struct inode *inode, struct page *page) |
1713 | { | 1700 | { |