diff options
Diffstat (limited to 'fs/nfsd/nfssvc.c')
-rw-r--r-- | fs/nfsd/nfssvc.c | 79 |
1 files changed, 51 insertions, 28 deletions
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 1697539a7171..0568ff8565b1 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/nfsd/nfsd.h> | 30 | #include <linux/nfsd/nfsd.h> |
31 | #include <linux/nfsd/stats.h> | 31 | #include <linux/nfsd/stats.h> |
32 | #include <linux/nfsd/cache.h> | 32 | #include <linux/nfsd/cache.h> |
33 | #include <linux/nfsd/syscall.h> | ||
33 | #include <linux/lockd/bind.h> | 34 | #include <linux/lockd/bind.h> |
34 | #include <linux/nfsacl.h> | 35 | #include <linux/nfsacl.h> |
35 | 36 | ||
@@ -52,7 +53,7 @@ | |||
52 | extern struct svc_program nfsd_program; | 53 | extern struct svc_program nfsd_program; |
53 | static void nfsd(struct svc_rqst *rqstp); | 54 | static void nfsd(struct svc_rqst *rqstp); |
54 | struct timeval nfssvc_boot; | 55 | struct timeval nfssvc_boot; |
55 | static struct svc_serv *nfsd_serv; | 56 | struct svc_serv *nfsd_serv; |
56 | static atomic_t nfsd_busy; | 57 | static atomic_t nfsd_busy; |
57 | static unsigned long nfsd_last_call; | 58 | static unsigned long nfsd_last_call; |
58 | static DEFINE_SPINLOCK(nfsd_call_lock); | 59 | static DEFINE_SPINLOCK(nfsd_call_lock); |
@@ -63,6 +64,31 @@ struct nfsd_list { | |||
63 | }; | 64 | }; |
64 | static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list); | 65 | static struct list_head nfsd_list = LIST_HEAD_INIT(nfsd_list); |
65 | 66 | ||
67 | static struct svc_version * nfsd_version[] = { | ||
68 | [2] = &nfsd_version2, | ||
69 | #if defined(CONFIG_NFSD_V3) | ||
70 | [3] = &nfsd_version3, | ||
71 | #endif | ||
72 | #if defined(CONFIG_NFSD_V4) | ||
73 | [4] = &nfsd_version4, | ||
74 | #endif | ||
75 | }; | ||
76 | |||
77 | #define NFSD_MINVERS 2 | ||
78 | #define NFSD_NRVERS (sizeof(nfsd_version)/sizeof(nfsd_version[0])) | ||
79 | static struct svc_version *nfsd_versions[NFSD_NRVERS]; | ||
80 | |||
81 | struct svc_program nfsd_program = { | ||
82 | .pg_prog = NFS_PROGRAM, /* program number */ | ||
83 | .pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */ | ||
84 | .pg_vers = nfsd_versions, /* version table */ | ||
85 | .pg_name = "nfsd", /* program name */ | ||
86 | .pg_class = "nfsd", /* authentication class */ | ||
87 | .pg_stats = &nfsd_svcstats, /* version table */ | ||
88 | .pg_authenticate = &svc_set_client, /* export authentication */ | ||
89 | |||
90 | }; | ||
91 | |||
66 | /* | 92 | /* |
67 | * Maximum number of nfsd processes | 93 | * Maximum number of nfsd processes |
68 | */ | 94 | */ |
@@ -80,11 +106,12 @@ int | |||
80 | nfsd_svc(unsigned short port, int nrservs) | 106 | nfsd_svc(unsigned short port, int nrservs) |
81 | { | 107 | { |
82 | int error; | 108 | int error; |
83 | int none_left; | 109 | int none_left, found_one, i; |
84 | struct list_head *victim; | 110 | struct list_head *victim; |
85 | 111 | ||
86 | lock_kernel(); | 112 | lock_kernel(); |
87 | dprintk("nfsd: creating service\n"); | 113 | dprintk("nfsd: creating service: vers 0x%x\n", |
114 | nfsd_versbits); | ||
88 | error = -EINVAL; | 115 | error = -EINVAL; |
89 | if (nrservs <= 0) | 116 | if (nrservs <= 0) |
90 | nrservs = 0; | 117 | nrservs = 0; |
@@ -99,6 +126,27 @@ nfsd_svc(unsigned short port, int nrservs) | |||
99 | if (error<0) | 126 | if (error<0) |
100 | goto out; | 127 | goto out; |
101 | if (!nfsd_serv) { | 128 | if (!nfsd_serv) { |
129 | /* | ||
130 | * Use the nfsd_ctlbits to define which | ||
131 | * versions that will be advertised. | ||
132 | * If nfsd_ctlbits doesn't list any version, | ||
133 | * export them all. | ||
134 | */ | ||
135 | found_one = 0; | ||
136 | |||
137 | for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) { | ||
138 | if (NFSCTL_VERISSET(nfsd_versbits, i)) { | ||
139 | nfsd_program.pg_vers[i] = nfsd_version[i]; | ||
140 | found_one = 1; | ||
141 | } else | ||
142 | nfsd_program.pg_vers[i] = NULL; | ||
143 | } | ||
144 | |||
145 | if (!found_one) { | ||
146 | for (i = NFSD_MINVERS; i < NFSD_NRVERS; i++) | ||
147 | nfsd_program.pg_vers[i] = nfsd_version[i]; | ||
148 | } | ||
149 | |||
102 | atomic_set(&nfsd_busy, 0); | 150 | atomic_set(&nfsd_busy, 0); |
103 | error = -ENOMEM; | 151 | error = -ENOMEM; |
104 | nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE); | 152 | nfsd_serv = svc_create(&nfsd_program, NFSD_BUFSIZE); |
@@ -389,28 +437,3 @@ static struct svc_stat nfsd_acl_svcstats = { | |||
389 | #else | 437 | #else |
390 | #define nfsd_acl_program_p NULL | 438 | #define nfsd_acl_program_p NULL |
391 | #endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */ | 439 | #endif /* defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) */ |
392 | |||
393 | extern struct svc_version nfsd_version2, nfsd_version3, nfsd_version4; | ||
394 | |||
395 | static struct svc_version * nfsd_version[] = { | ||
396 | [2] = &nfsd_version2, | ||
397 | #if defined(CONFIG_NFSD_V3) | ||
398 | [3] = &nfsd_version3, | ||
399 | #endif | ||
400 | #if defined(CONFIG_NFSD_V4) | ||
401 | [4] = &nfsd_version4, | ||
402 | #endif | ||
403 | }; | ||
404 | |||
405 | #define NFSD_NRVERS (sizeof(nfsd_version)/sizeof(nfsd_version[0])) | ||
406 | struct svc_program nfsd_program = { | ||
407 | .pg_next = nfsd_acl_program_p, | ||
408 | .pg_prog = NFS_PROGRAM, /* program number */ | ||
409 | .pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */ | ||
410 | .pg_vers = nfsd_version, /* version table */ | ||
411 | .pg_name = "nfsd", /* program name */ | ||
412 | .pg_class = "nfsd", /* authentication class */ | ||
413 | .pg_stats = &nfsd_svcstats, /* version table */ | ||
414 | .pg_authenticate = &svc_set_client, /* export authentication */ | ||
415 | |||
416 | }; | ||