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 | |
| 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
40 files changed, 725 insertions, 403 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 | { |
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 4b6043c20f77..2889877318bc 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h | |||
| @@ -191,7 +191,7 @@ struct nfs_inode { | |||
| 191 | struct hlist_head silly_list; | 191 | struct hlist_head silly_list; |
| 192 | wait_queue_head_t waitqueue; | 192 | wait_queue_head_t waitqueue; |
| 193 | 193 | ||
| 194 | #ifdef CONFIG_NFS_V4 | 194 | #if IS_ENABLED(CONFIG_NFS_V4) |
| 195 | struct nfs4_cached_acl *nfs4_acl; | 195 | struct nfs4_cached_acl *nfs4_acl; |
| 196 | /* NFSv4 state */ | 196 | /* NFSv4 state */ |
| 197 | struct list_head open_states; | 197 | struct list_head open_states; |
| @@ -428,7 +428,7 @@ extern __be32 root_nfs_parse_addr(char *name); /*__init*/ | |||
| 428 | * linux/fs/nfs/file.c | 428 | * linux/fs/nfs/file.c |
| 429 | */ | 429 | */ |
| 430 | extern const struct file_operations nfs_file_operations; | 430 | extern const struct file_operations nfs_file_operations; |
| 431 | #ifdef CONFIG_NFS_V4 | 431 | #if IS_ENABLED(CONFIG_NFS_V4) |
| 432 | extern const struct file_operations nfs4_file_operations; | 432 | extern const struct file_operations nfs4_file_operations; |
| 433 | #endif /* CONFIG_NFS_V4 */ | 433 | #endif /* CONFIG_NFS_V4 */ |
| 434 | extern const struct address_space_operations nfs_file_aops; | 434 | extern const struct address_space_operations nfs_file_aops; |
| @@ -538,7 +538,7 @@ extern void nfs_writeback_done(struct rpc_task *, struct nfs_write_data *); | |||
| 538 | extern int nfs_wb_all(struct inode *inode); | 538 | extern int nfs_wb_all(struct inode *inode); |
| 539 | extern int nfs_wb_page(struct inode *inode, struct page* page); | 539 | extern int nfs_wb_page(struct inode *inode, struct page* page); |
| 540 | extern int nfs_wb_page_cancel(struct inode *inode, struct page* page); | 540 | extern int nfs_wb_page_cancel(struct inode *inode, struct page* page); |
| 541 | #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4) | 541 | #if IS_ENABLED(CONFIG_NFS_V3) || IS_ENABLED(CONFIG_NFS_V4) |
| 542 | extern int nfs_commit_inode(struct inode *, int); | 542 | extern int nfs_commit_inode(struct inode *, int); |
| 543 | extern struct nfs_commit_data *nfs_commitdata_alloc(void); | 543 | extern struct nfs_commit_data *nfs_commitdata_alloc(void); |
| 544 | extern void nfs_commit_free(struct nfs_commit_data *data); | 544 | extern void nfs_commit_free(struct nfs_commit_data *data); |
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 65327652c61a..310c63c8ab2c 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h | |||
| @@ -48,11 +48,12 @@ struct nfs_client { | |||
| 48 | struct rpc_clnt * cl_rpcclient; | 48 | struct rpc_clnt * cl_rpcclient; |
| 49 | const struct nfs_rpc_ops *rpc_ops; /* NFS protocol vector */ | 49 | const struct nfs_rpc_ops *rpc_ops; /* NFS protocol vector */ |
| 50 | int cl_proto; /* Network transport protocol */ | 50 | int cl_proto; /* Network transport protocol */ |
| 51 | struct nfs_subversion * cl_nfs_mod; /* pointer to nfs version module */ | ||
| 51 | 52 | ||
| 52 | u32 cl_minorversion;/* NFSv4 minorversion */ | 53 | u32 cl_minorversion;/* NFSv4 minorversion */ |
| 53 | struct rpc_cred *cl_machine_cred; | 54 | struct rpc_cred *cl_machine_cred; |
| 54 | 55 | ||
| 55 | #ifdef CONFIG_NFS_V4 | 56 | #if IS_ENABLED(CONFIG_NFS_V4) |
| 56 | u64 cl_clientid; /* constant */ | 57 | u64 cl_clientid; /* constant */ |
| 57 | nfs4_verifier cl_confirm; /* Clientid verifier */ | 58 | nfs4_verifier cl_confirm; /* Clientid verifier */ |
| 58 | unsigned long cl_state; | 59 | unsigned long cl_state; |
| @@ -137,7 +138,7 @@ struct nfs_server { | |||
| 137 | #endif | 138 | #endif |
| 138 | 139 | ||
| 139 | u32 pnfs_blksize; /* layout_blksize attr */ | 140 | u32 pnfs_blksize; /* layout_blksize attr */ |
| 140 | #ifdef CONFIG_NFS_V4 | 141 | #if IS_ENABLED(CONFIG_NFS_V4) |
| 141 | u32 attr_bitmask[3];/* V4 bitmask representing the set | 142 | u32 attr_bitmask[3];/* V4 bitmask representing the set |
| 142 | of attributes supported on this | 143 | of attributes supported on this |
| 143 | filesystem */ | 144 | filesystem */ |
| @@ -200,7 +201,7 @@ struct nfs_server { | |||
| 200 | #define NFS4_MAX_SLOT_TABLE (256U) | 201 | #define NFS4_MAX_SLOT_TABLE (256U) |
| 201 | #define NFS4_NO_SLOT ((u32)-1) | 202 | #define NFS4_NO_SLOT ((u32)-1) |
| 202 | 203 | ||
| 203 | #if defined(CONFIG_NFS_V4) | 204 | #if IS_ENABLED(CONFIG_NFS_V4) |
| 204 | 205 | ||
| 205 | /* Sessions */ | 206 | /* Sessions */ |
| 206 | #define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long)) | 207 | #define SLOT_TABLE_SZ DIV_ROUND_UP(NFS4_MAX_SLOT_TABLE, 8*sizeof(long)) |
diff --git a/include/linux/nfs_idmap.h b/include/linux/nfs_idmap.h index 7eed2012d288..ece91c57ad79 100644 --- a/include/linux/nfs_idmap.h +++ b/include/linux/nfs_idmap.h | |||
| @@ -69,7 +69,7 @@ struct nfs_server; | |||
| 69 | struct nfs_fattr; | 69 | struct nfs_fattr; |
| 70 | struct nfs4_string; | 70 | struct nfs4_string; |
| 71 | 71 | ||
| 72 | #ifdef CONFIG_NFS_V4 | 72 | #if IS_ENABLED(CONFIG_NFS_V4) |
| 73 | int nfs_idmap_init(void); | 73 | int nfs_idmap_init(void); |
| 74 | void nfs_idmap_quit(void); | 74 | void nfs_idmap_quit(void); |
| 75 | #else | 75 | #else |
diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 0e181c2320b7..00485e084394 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h | |||
| @@ -824,7 +824,7 @@ struct nfs3_getaclres { | |||
| 824 | struct posix_acl * acl_default; | 824 | struct posix_acl * acl_default; |
| 825 | }; | 825 | }; |
| 826 | 826 | ||
| 827 | #ifdef CONFIG_NFS_V4 | 827 | #if IS_ENABLED(CONFIG_NFS_V4) |
| 828 | 828 | ||
| 829 | typedef u64 clientid4; | 829 | typedef u64 clientid4; |
| 830 | 830 | ||
| @@ -1353,6 +1353,8 @@ struct nfs_renamedata { | |||
| 1353 | struct nfs_access_entry; | 1353 | struct nfs_access_entry; |
| 1354 | struct nfs_client; | 1354 | struct nfs_client; |
| 1355 | struct rpc_timeout; | 1355 | struct rpc_timeout; |
| 1356 | struct nfs_subversion; | ||
| 1357 | struct nfs_mount_info; | ||
| 1356 | struct nfs_client_initdata; | 1358 | struct nfs_client_initdata; |
| 1357 | struct nfs_pageio_descriptor; | 1359 | struct nfs_pageio_descriptor; |
| 1358 | 1360 | ||
| @@ -1370,6 +1372,8 @@ struct nfs_rpc_ops { | |||
| 1370 | struct nfs_fsinfo *); | 1372 | struct nfs_fsinfo *); |
| 1371 | struct vfsmount *(*submount) (struct nfs_server *, struct dentry *, | 1373 | struct vfsmount *(*submount) (struct nfs_server *, struct dentry *, |
| 1372 | struct nfs_fh *, struct nfs_fattr *); | 1374 | struct nfs_fh *, struct nfs_fattr *); |
| 1375 | struct dentry *(*try_mount) (int, const char *, struct nfs_mount_info *, | ||
| 1376 | struct nfs_subversion *); | ||
| 1373 | int (*getattr) (struct nfs_server *, struct nfs_fh *, | 1377 | int (*getattr) (struct nfs_server *, struct nfs_fh *, |
| 1374 | struct nfs_fattr *); | 1378 | struct nfs_fattr *); |
| 1375 | int (*setattr) (struct dentry *, struct nfs_fattr *, | 1379 | int (*setattr) (struct dentry *, struct nfs_fattr *, |
| @@ -1435,6 +1439,9 @@ struct nfs_rpc_ops { | |||
| 1435 | (*init_client) (struct nfs_client *, const struct rpc_timeout *, | 1439 | (*init_client) (struct nfs_client *, const struct rpc_timeout *, |
| 1436 | const char *, rpc_authflavor_t); | 1440 | const char *, rpc_authflavor_t); |
| 1437 | void (*free_client) (struct nfs_client *); | 1441 | void (*free_client) (struct nfs_client *); |
| 1442 | struct nfs_server *(*create_server)(struct nfs_mount_info *, struct nfs_subversion *); | ||
| 1443 | struct nfs_server *(*clone_server)(struct nfs_server *, struct nfs_fh *, | ||
| 1444 | struct nfs_fattr *, rpc_authflavor_t); | ||
| 1438 | }; | 1445 | }; |
| 1439 | 1446 | ||
| 1440 | /* | 1447 | /* |
diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 92509ffe15fc..a70acae496e4 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c | |||
| @@ -251,7 +251,7 @@ static int rpcb_create_local_unix(struct net *net) | |||
| 251 | if (IS_ERR(clnt)) { | 251 | if (IS_ERR(clnt)) { |
| 252 | dprintk("RPC: failed to create AF_LOCAL rpcbind " | 252 | dprintk("RPC: failed to create AF_LOCAL rpcbind " |
| 253 | "client (errno %ld).\n", PTR_ERR(clnt)); | 253 | "client (errno %ld).\n", PTR_ERR(clnt)); |
| 254 | result = -PTR_ERR(clnt); | 254 | result = PTR_ERR(clnt); |
| 255 | goto out; | 255 | goto out; |
| 256 | } | 256 | } |
| 257 | 257 | ||
| @@ -298,7 +298,7 @@ static int rpcb_create_local_net(struct net *net) | |||
| 298 | if (IS_ERR(clnt)) { | 298 | if (IS_ERR(clnt)) { |
| 299 | dprintk("RPC: failed to create local rpcbind " | 299 | dprintk("RPC: failed to create local rpcbind " |
| 300 | "client (errno %ld).\n", PTR_ERR(clnt)); | 300 | "client (errno %ld).\n", PTR_ERR(clnt)); |
| 301 | result = -PTR_ERR(clnt); | 301 | result = PTR_ERR(clnt); |
| 302 | goto out; | 302 | goto out; |
| 303 | } | 303 | } |
| 304 | 304 | ||
diff --git a/net/sunrpc/sched.c b/net/sunrpc/sched.c index 994cfea2bad6..1f19aa15f89b 100644 --- a/net/sunrpc/sched.c +++ b/net/sunrpc/sched.c | |||
| @@ -300,8 +300,9 @@ EXPORT_SYMBOL_GPL(__rpc_wait_for_completion_task); | |||
| 300 | /* | 300 | /* |
| 301 | * Make an RPC task runnable. | 301 | * Make an RPC task runnable. |
| 302 | * | 302 | * |
| 303 | * Note: If the task is ASYNC, this must be called with | 303 | * Note: If the task is ASYNC, and is being made runnable after sitting on an |
| 304 | * the spinlock held to protect the wait queue operation. | 304 | * rpc_wait_queue, this must be called with the queue spinlock held to protect |
| 305 | * the wait queue operation. | ||
| 305 | */ | 306 | */ |
| 306 | static void rpc_make_runnable(struct rpc_task *task) | 307 | static void rpc_make_runnable(struct rpc_task *task) |
| 307 | { | 308 | { |
| @@ -790,7 +791,9 @@ void rpc_execute(struct rpc_task *task) | |||
| 790 | 791 | ||
| 791 | static void rpc_async_schedule(struct work_struct *work) | 792 | static void rpc_async_schedule(struct work_struct *work) |
| 792 | { | 793 | { |
| 794 | current->flags |= PF_FSTRANS; | ||
| 793 | __rpc_execute(container_of(work, struct rpc_task, u.tk_work)); | 795 | __rpc_execute(container_of(work, struct rpc_task, u.tk_work)); |
| 796 | current->flags &= ~PF_FSTRANS; | ||
| 794 | } | 797 | } |
| 795 | 798 | ||
| 796 | /** | 799 | /** |
diff --git a/net/sunrpc/xprtrdma/transport.c b/net/sunrpc/xprtrdma/transport.c index b446e100286f..06cdbff79e4a 100644 --- a/net/sunrpc/xprtrdma/transport.c +++ b/net/sunrpc/xprtrdma/transport.c | |||
| @@ -200,6 +200,7 @@ xprt_rdma_connect_worker(struct work_struct *work) | |||
| 200 | int rc = 0; | 200 | int rc = 0; |
| 201 | 201 | ||
| 202 | if (!xprt->shutdown) { | 202 | if (!xprt->shutdown) { |
| 203 | current->flags |= PF_FSTRANS; | ||
| 203 | xprt_clear_connected(xprt); | 204 | xprt_clear_connected(xprt); |
| 204 | 205 | ||
| 205 | dprintk("RPC: %s: %sconnect\n", __func__, | 206 | dprintk("RPC: %s: %sconnect\n", __func__, |
| @@ -212,10 +213,10 @@ xprt_rdma_connect_worker(struct work_struct *work) | |||
| 212 | 213 | ||
| 213 | out: | 214 | out: |
| 214 | xprt_wake_pending_tasks(xprt, rc); | 215 | xprt_wake_pending_tasks(xprt, rc); |
| 215 | |||
| 216 | out_clear: | 216 | out_clear: |
| 217 | dprintk("RPC: %s: exit\n", __func__); | 217 | dprintk("RPC: %s: exit\n", __func__); |
| 218 | xprt_clear_connecting(xprt); | 218 | xprt_clear_connecting(xprt); |
| 219 | current->flags &= ~PF_FSTRANS; | ||
| 219 | } | 220 | } |
| 220 | 221 | ||
| 221 | /* | 222 | /* |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 62d0dac8f780..926679459e71 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
| @@ -1892,6 +1892,8 @@ static void xs_local_setup_socket(struct work_struct *work) | |||
| 1892 | if (xprt->shutdown) | 1892 | if (xprt->shutdown) |
| 1893 | goto out; | 1893 | goto out; |
| 1894 | 1894 | ||
| 1895 | current->flags |= PF_FSTRANS; | ||
| 1896 | |||
| 1895 | clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); | 1897 | clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); |
| 1896 | status = __sock_create(xprt->xprt_net, AF_LOCAL, | 1898 | status = __sock_create(xprt->xprt_net, AF_LOCAL, |
| 1897 | SOCK_STREAM, 0, &sock, 1); | 1899 | SOCK_STREAM, 0, &sock, 1); |
| @@ -1925,6 +1927,7 @@ static void xs_local_setup_socket(struct work_struct *work) | |||
| 1925 | out: | 1927 | out: |
| 1926 | xprt_clear_connecting(xprt); | 1928 | xprt_clear_connecting(xprt); |
| 1927 | xprt_wake_pending_tasks(xprt, status); | 1929 | xprt_wake_pending_tasks(xprt, status); |
| 1930 | current->flags &= ~PF_FSTRANS; | ||
| 1928 | } | 1931 | } |
| 1929 | 1932 | ||
| 1930 | static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) | 1933 | static void xs_udp_finish_connecting(struct rpc_xprt *xprt, struct socket *sock) |
| @@ -1967,6 +1970,8 @@ static void xs_udp_setup_socket(struct work_struct *work) | |||
| 1967 | if (xprt->shutdown) | 1970 | if (xprt->shutdown) |
| 1968 | goto out; | 1971 | goto out; |
| 1969 | 1972 | ||
| 1973 | current->flags |= PF_FSTRANS; | ||
| 1974 | |||
| 1970 | /* Start by resetting any existing state */ | 1975 | /* Start by resetting any existing state */ |
| 1971 | xs_reset_transport(transport); | 1976 | xs_reset_transport(transport); |
| 1972 | sock = xs_create_sock(xprt, transport, | 1977 | sock = xs_create_sock(xprt, transport, |
| @@ -1985,6 +1990,7 @@ static void xs_udp_setup_socket(struct work_struct *work) | |||
| 1985 | out: | 1990 | out: |
| 1986 | xprt_clear_connecting(xprt); | 1991 | xprt_clear_connecting(xprt); |
| 1987 | xprt_wake_pending_tasks(xprt, status); | 1992 | xprt_wake_pending_tasks(xprt, status); |
| 1993 | current->flags &= ~PF_FSTRANS; | ||
| 1988 | } | 1994 | } |
| 1989 | 1995 | ||
| 1990 | /* | 1996 | /* |
| @@ -2110,6 +2116,8 @@ static void xs_tcp_setup_socket(struct work_struct *work) | |||
| 2110 | if (xprt->shutdown) | 2116 | if (xprt->shutdown) |
| 2111 | goto out; | 2117 | goto out; |
| 2112 | 2118 | ||
| 2119 | current->flags |= PF_FSTRANS; | ||
| 2120 | |||
| 2113 | if (!sock) { | 2121 | if (!sock) { |
| 2114 | clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); | 2122 | clear_bit(XPRT_CONNECTION_ABORT, &xprt->state); |
| 2115 | sock = xs_create_sock(xprt, transport, | 2123 | sock = xs_create_sock(xprt, transport, |
| @@ -2159,6 +2167,7 @@ static void xs_tcp_setup_socket(struct work_struct *work) | |||
| 2159 | case -EINPROGRESS: | 2167 | case -EINPROGRESS: |
| 2160 | case -EALREADY: | 2168 | case -EALREADY: |
| 2161 | xprt_clear_connecting(xprt); | 2169 | xprt_clear_connecting(xprt); |
| 2170 | current->flags &= ~PF_FSTRANS; | ||
| 2162 | return; | 2171 | return; |
| 2163 | case -EINVAL: | 2172 | case -EINVAL: |
| 2164 | /* Happens, for instance, if the user specified a link | 2173 | /* Happens, for instance, if the user specified a link |
| @@ -2171,6 +2180,7 @@ out_eagain: | |||
| 2171 | out: | 2180 | out: |
| 2172 | xprt_clear_connecting(xprt); | 2181 | xprt_clear_connecting(xprt); |
| 2173 | xprt_wake_pending_tasks(xprt, status); | 2182 | xprt_wake_pending_tasks(xprt, status); |
| 2183 | current->flags &= ~PF_FSTRANS; | ||
| 2174 | } | 2184 | } |
| 2175 | 2185 | ||
| 2176 | /** | 2186 | /** |
