aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfsctl.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-02-28 21:02:55 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-02-28 21:02:55 -0500
commitb6669737d3db7df79fad07180837c23dbe581db5 (patch)
tree671a9d13fe5ab00d6a3c7c5c5c466802ca96d38a /fs/nfsd/nfsctl.c
parent1cf0209c431fa7790253c532039d53b0773193aa (diff)
parentdc107402ae06286a9ed33c32daf3f35514a7cb8d (diff)
Merge branch 'for-3.9' of git://linux-nfs.org/~bfields/linux
Pull nfsd changes from J Bruce Fields: "Miscellaneous bugfixes, plus: - An overhaul of the DRC cache by Jeff Layton. The main effect is just to make it larger. This decreases the chances of intermittent errors especially in the UDP case. But we'll need to watch for any reports of performance regressions. - Containerized nfsd: with some limitations, we now support per-container nfs-service, thanks to extensive work from Stanislav Kinsbursky over the last year." Some notes about conflicts, since there were *two* non-data semantic conflicts here: - idr_remove_all() had been added by a memory leak fix, but has since become deprecated since idr_destroy() does it for us now. - xs_local_connect() had been added by this branch to make AF_LOCAL connections be synchronous, but in the meantime Trond had changed the calling convention in order to avoid a RCU dereference. There were a couple of more obvious actual source-level conflicts due to the hlist traversal changes and one just due to code changes next to each other, but those were trivial. * 'for-3.9' of git://linux-nfs.org/~bfields/linux: (49 commits) SUNRPC: make AF_LOCAL connect synchronous nfsd: fix compiler warning about ambiguous types in nfsd_cache_csum svcrpc: fix rpc server shutdown races svcrpc: make svc_age_temp_xprts enqueue under sv_lock lockd: nlmclnt_reclaim(): avoid stack overflow nfsd: enable NFSv4 state in containers nfsd: disable usermode helper client tracker in container nfsd: use proper net while reading "exports" file nfsd: containerize NFSd filesystem nfsd: fix comments on nfsd_cache_lookup SUNRPC: move cache_detail->cache_request callback call to cache_read() SUNRPC: remove "cache_request" argument in sunrpc_cache_pipe_upcall() function SUNRPC: rework cache upcall logic SUNRPC: introduce cache_detail->cache_request callback NFS: simplify and clean cache library NFS: use SUNRPC cache creation and destruction helper for DNS cache nfsd4: free_stid can be static nfsd: keep a checksum of the first 256 bytes of request sunrpc: trim off trailing checksum before returning decrypted or integrity authenticated buffer sunrpc: fix comment in struct xdr_buf definition ...
Diffstat (limited to 'fs/nfsd/nfsctl.c')
-rw-r--r--fs/nfsd/nfsctl.c81
1 files changed, 60 insertions, 21 deletions
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
index 2db7021b01ae..13a21c8fca49 100644
--- a/fs/nfsd/nfsctl.c
+++ b/fs/nfsd/nfsctl.c
@@ -10,7 +10,7 @@
10 10
11#include <linux/sunrpc/svcsock.h> 11#include <linux/sunrpc/svcsock.h>
12#include <linux/lockd/lockd.h> 12#include <linux/lockd/lockd.h>
13#include <linux/sunrpc/clnt.h> 13#include <linux/sunrpc/addr.h>
14#include <linux/sunrpc/gss_api.h> 14#include <linux/sunrpc/gss_api.h>
15#include <linux/sunrpc/gss_krb5_enctypes.h> 15#include <linux/sunrpc/gss_krb5_enctypes.h>
16#include <linux/sunrpc/rpc_pipe_fs.h> 16#include <linux/sunrpc/rpc_pipe_fs.h>
@@ -125,11 +125,11 @@ static const struct file_operations transaction_ops = {
125 .llseek = default_llseek, 125 .llseek = default_llseek,
126}; 126};
127 127
128static int exports_open(struct inode *inode, struct file *file) 128static int exports_net_open(struct net *net, struct file *file)
129{ 129{
130 int err; 130 int err;
131 struct seq_file *seq; 131 struct seq_file *seq;
132 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 132 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
133 133
134 err = seq_open(file, &nfs_exports_op); 134 err = seq_open(file, &nfs_exports_op);
135 if (err) 135 if (err)
@@ -140,8 +140,26 @@ static int exports_open(struct inode *inode, struct file *file)
140 return 0; 140 return 0;
141} 141}
142 142
143static const struct file_operations exports_operations = { 143static int exports_proc_open(struct inode *inode, struct file *file)
144 .open = exports_open, 144{
145 return exports_net_open(current->nsproxy->net_ns, file);
146}
147
148static const struct file_operations exports_proc_operations = {
149 .open = exports_proc_open,
150 .read = seq_read,
151 .llseek = seq_lseek,
152 .release = seq_release,
153 .owner = THIS_MODULE,
154};
155
156static int exports_nfsd_open(struct inode *inode, struct file *file)
157{
158 return exports_net_open(inode->i_sb->s_fs_info, file);
159}
160
161static const struct file_operations exports_nfsd_operations = {
162 .open = exports_nfsd_open,
145 .read = seq_read, 163 .read = seq_read,
146 .llseek = seq_lseek, 164 .llseek = seq_lseek,
147 .release = seq_release, 165 .release = seq_release,
@@ -220,6 +238,7 @@ static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
220 struct sockaddr *sap = (struct sockaddr *)&address; 238 struct sockaddr *sap = (struct sockaddr *)&address;
221 size_t salen = sizeof(address); 239 size_t salen = sizeof(address);
222 char *fo_path; 240 char *fo_path;
241 struct net *net = file->f_dentry->d_sb->s_fs_info;
223 242
224 /* sanity check */ 243 /* sanity check */
225 if (size == 0) 244 if (size == 0)
@@ -232,7 +251,7 @@ static ssize_t write_unlock_ip(struct file *file, char *buf, size_t size)
232 if (qword_get(&buf, fo_path, size) < 0) 251 if (qword_get(&buf, fo_path, size) < 0)
233 return -EINVAL; 252 return -EINVAL;
234 253
235 if (rpc_pton(&init_net, fo_path, size, sap, salen) == 0) 254 if (rpc_pton(net, fo_path, size, sap, salen) == 0)
236 return -EINVAL; 255 return -EINVAL;
237 256
238 return nlmsvc_unlock_all_by_ip(sap); 257 return nlmsvc_unlock_all_by_ip(sap);
@@ -317,6 +336,7 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
317 int len; 336 int len;
318 struct auth_domain *dom; 337 struct auth_domain *dom;
319 struct knfsd_fh fh; 338 struct knfsd_fh fh;
339 struct net *net = file->f_dentry->d_sb->s_fs_info;
320 340
321 if (size == 0) 341 if (size == 0)
322 return -EINVAL; 342 return -EINVAL;
@@ -352,7 +372,7 @@ static ssize_t write_filehandle(struct file *file, char *buf, size_t size)
352 if (!dom) 372 if (!dom)
353 return -ENOMEM; 373 return -ENOMEM;
354 374
355 len = exp_rootfh(&init_net, dom, path, &fh, maxsize); 375 len = exp_rootfh(net, dom, path, &fh, maxsize);
356 auth_domain_put(dom); 376 auth_domain_put(dom);
357 if (len) 377 if (len)
358 return len; 378 return len;
@@ -396,7 +416,7 @@ static ssize_t write_threads(struct file *file, char *buf, size_t size)
396{ 416{
397 char *mesg = buf; 417 char *mesg = buf;
398 int rv; 418 int rv;
399 struct net *net = &init_net; 419 struct net *net = file->f_dentry->d_sb->s_fs_info;
400 420
401 if (size > 0) { 421 if (size > 0) {
402 int newthreads; 422 int newthreads;
@@ -447,7 +467,7 @@ static ssize_t write_pool_threads(struct file *file, char *buf, size_t size)
447 int len; 467 int len;
448 int npools; 468 int npools;
449 int *nthreads; 469 int *nthreads;
450 struct net *net = &init_net; 470 struct net *net = file->f_dentry->d_sb->s_fs_info;
451 471
452 mutex_lock(&nfsd_mutex); 472 mutex_lock(&nfsd_mutex);
453 npools = nfsd_nrpools(net); 473 npools = nfsd_nrpools(net);
@@ -510,7 +530,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
510 unsigned minor; 530 unsigned minor;
511 ssize_t tlen = 0; 531 ssize_t tlen = 0;
512 char *sep; 532 char *sep;
513 struct net *net = &init_net; 533 struct net *net = file->f_dentry->d_sb->s_fs_info;
514 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 534 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
515 535
516 if (size>0) { 536 if (size>0) {
@@ -534,7 +554,7 @@ static ssize_t __write_versions(struct file *file, char *buf, size_t size)
534 else 554 else
535 num = simple_strtol(vers, &minorp, 0); 555 num = simple_strtol(vers, &minorp, 0);
536 if (*minorp == '.') { 556 if (*minorp == '.') {
537 if (num < 4) 557 if (num != 4)
538 return -EINVAL; 558 return -EINVAL;
539 minor = simple_strtoul(minorp+1, NULL, 0); 559 minor = simple_strtoul(minorp+1, NULL, 0);
540 if (minor == 0) 560 if (minor == 0)
@@ -792,7 +812,7 @@ static ssize_t __write_ports(struct file *file, char *buf, size_t size,
792static ssize_t write_ports(struct file *file, char *buf, size_t size) 812static ssize_t write_ports(struct file *file, char *buf, size_t size)
793{ 813{
794 ssize_t rv; 814 ssize_t rv;
795 struct net *net = &init_net; 815 struct net *net = file->f_dentry->d_sb->s_fs_info;
796 816
797 mutex_lock(&nfsd_mutex); 817 mutex_lock(&nfsd_mutex);
798 rv = __write_ports(file, buf, size, net); 818 rv = __write_ports(file, buf, size, net);
@@ -827,7 +847,7 @@ int nfsd_max_blksize;
827static ssize_t write_maxblksize(struct file *file, char *buf, size_t size) 847static ssize_t write_maxblksize(struct file *file, char *buf, size_t size)
828{ 848{
829 char *mesg = buf; 849 char *mesg = buf;
830 struct net *net = &init_net; 850 struct net *net = file->f_dentry->d_sb->s_fs_info;
831 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 851 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
832 852
833 if (size > 0) { 853 if (size > 0) {
@@ -923,7 +943,8 @@ static ssize_t nfsd4_write_time(struct file *file, char *buf, size_t size,
923 */ 943 */
924static ssize_t write_leasetime(struct file *file, char *buf, size_t size) 944static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
925{ 945{
926 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 946 struct net *net = file->f_dentry->d_sb->s_fs_info;
947 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
927 return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn); 948 return nfsd4_write_time(file, buf, size, &nn->nfsd4_lease, nn);
928} 949}
929 950
@@ -939,7 +960,8 @@ static ssize_t write_leasetime(struct file *file, char *buf, size_t size)
939 */ 960 */
940static ssize_t write_gracetime(struct file *file, char *buf, size_t size) 961static ssize_t write_gracetime(struct file *file, char *buf, size_t size)
941{ 962{
942 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 963 struct net *net = file->f_dentry->d_sb->s_fs_info;
964 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
943 return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn); 965 return nfsd4_write_time(file, buf, size, &nn->nfsd4_grace, nn);
944} 966}
945 967
@@ -995,7 +1017,8 @@ static ssize_t __write_recoverydir(struct file *file, char *buf, size_t size,
995static ssize_t write_recoverydir(struct file *file, char *buf, size_t size) 1017static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
996{ 1018{
997 ssize_t rv; 1019 ssize_t rv;
998 struct nfsd_net *nn = net_generic(&init_net, nfsd_net_id); 1020 struct net *net = file->f_dentry->d_sb->s_fs_info;
1021 struct nfsd_net *nn = net_generic(net, nfsd_net_id);
999 1022
1000 mutex_lock(&nfsd_mutex); 1023 mutex_lock(&nfsd_mutex);
1001 rv = __write_recoverydir(file, buf, size, nn); 1024 rv = __write_recoverydir(file, buf, size, nn);
@@ -1013,7 +1036,7 @@ static ssize_t write_recoverydir(struct file *file, char *buf, size_t size)
1013static int nfsd_fill_super(struct super_block * sb, void * data, int silent) 1036static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
1014{ 1037{
1015 static struct tree_descr nfsd_files[] = { 1038 static struct tree_descr nfsd_files[] = {
1016 [NFSD_List] = {"exports", &exports_operations, S_IRUGO}, 1039 [NFSD_List] = {"exports", &exports_nfsd_operations, S_IRUGO},
1017 [NFSD_Export_features] = {"export_features", 1040 [NFSD_Export_features] = {"export_features",
1018 &export_features_operations, S_IRUGO}, 1041 &export_features_operations, S_IRUGO},
1019 [NFSD_FO_UnlockIP] = {"unlock_ip", 1042 [NFSD_FO_UnlockIP] = {"unlock_ip",
@@ -1037,20 +1060,35 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent)
1037#endif 1060#endif
1038 /* last one */ {""} 1061 /* last one */ {""}
1039 }; 1062 };
1040 return simple_fill_super(sb, 0x6e667364, nfsd_files); 1063 struct net *net = data;
1064 int ret;
1065
1066 ret = simple_fill_super(sb, 0x6e667364, nfsd_files);
1067 if (ret)
1068 return ret;
1069 sb->s_fs_info = get_net(net);
1070 return 0;
1041} 1071}
1042 1072
1043static struct dentry *nfsd_mount(struct file_system_type *fs_type, 1073static struct dentry *nfsd_mount(struct file_system_type *fs_type,
1044 int flags, const char *dev_name, void *data) 1074 int flags, const char *dev_name, void *data)
1045{ 1075{
1046 return mount_single(fs_type, flags, data, nfsd_fill_super); 1076 return mount_ns(fs_type, flags, current->nsproxy->net_ns, nfsd_fill_super);
1077}
1078
1079static void nfsd_umount(struct super_block *sb)
1080{
1081 struct net *net = sb->s_fs_info;
1082
1083 kill_litter_super(sb);
1084 put_net(net);
1047} 1085}
1048 1086
1049static struct file_system_type nfsd_fs_type = { 1087static struct file_system_type nfsd_fs_type = {
1050 .owner = THIS_MODULE, 1088 .owner = THIS_MODULE,
1051 .name = "nfsd", 1089 .name = "nfsd",
1052 .mount = nfsd_mount, 1090 .mount = nfsd_mount,
1053 .kill_sb = kill_litter_super, 1091 .kill_sb = nfsd_umount,
1054}; 1092};
1055 1093
1056#ifdef CONFIG_PROC_FS 1094#ifdef CONFIG_PROC_FS
@@ -1061,7 +1099,8 @@ static int create_proc_exports_entry(void)
1061 entry = proc_mkdir("fs/nfs", NULL); 1099 entry = proc_mkdir("fs/nfs", NULL);
1062 if (!entry) 1100 if (!entry)
1063 return -ENOMEM; 1101 return -ENOMEM;
1064 entry = proc_create("exports", 0, entry, &exports_operations); 1102 entry = proc_create("exports", 0, entry,
1103 &exports_proc_operations);
1065 if (!entry) 1104 if (!entry)
1066 return -ENOMEM; 1105 return -ENOMEM;
1067 return 0; 1106 return 0;