aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/inode.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2006-06-09 09:34:33 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2006-06-09 09:34:33 -0400
commitf7b422b17ee5ee4920e8ae24a6ad04bf3481ce72 (patch)
tree4ae8372762efc092ceb4f884b57cad1efe6594de /fs/nfs/inode.c
parent4e5ccf60c5aa79d325c123f47d288a068166f389 (diff)
NFS: Split fs/nfs/inode.c
As fs/nfs/inode.c is rather large, heterogenous and unwieldy, the attached patch splits it up into a number of files: (*) fs/nfs/inode.c Strictly inode specific functions. (*) fs/nfs/super.c Superblock management functions for NFS and NFS4, normal access, clones and referrals. The NFS4 superblock functions _could_ move out into a separate conditionally compiled file, but it's probably not worth it as there're so many common bits. (*) fs/nfs/namespace.c Some namespace-specific functions have been moved here. (*) fs/nfs/nfs4namespace.c NFS4-specific namespace functions (this could be merged into the previous file). This file is conditionally compiled. (*) fs/nfs/internal.h Inter-file declarations, plus a few simple utility functions moved from fs/nfs/inode.c. Additionally, all the in-.c-file externs have been moved here, and those files they were moved from now includes this file. For the most part, the functions have not been changed, only some multiplexor functions have changed significantly. I've also: (*) Added some extra banner comments above some functions. (*) Rearranged the function order within the files to be more logical and better grouped (IMO), though someone may prefer a different order. (*) Reduced the number of #ifdefs in .c files. (*) Added missing __init and __exit directives. Signed-Off-By: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r--fs/nfs/inode.c1793
1 files changed, 19 insertions, 1774 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 7ab2b38a990c..24a7139d3449 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -46,87 +46,17 @@
46#include "callback.h" 46#include "callback.h"
47#include "delegation.h" 47#include "delegation.h"
48#include "iostat.h" 48#include "iostat.h"
49#include "internal.h"
49 50
50#define NFSDBG_FACILITY NFSDBG_VFS 51#define NFSDBG_FACILITY NFSDBG_VFS
51#define NFS_PARANOIA 1 52#define NFS_PARANOIA 1
52 53
53/* Maximum number of readahead requests
54 * FIXME: this should really be a sysctl so that users may tune it to suit
55 * their needs. People that do NFS over a slow network, might for
56 * instance want to reduce it to something closer to 1 for improved
57 * interactive response.
58 */
59#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1)
60
61static void nfs_invalidate_inode(struct inode *); 54static void nfs_invalidate_inode(struct inode *);
62static int nfs_update_inode(struct inode *, struct nfs_fattr *); 55static int nfs_update_inode(struct inode *, struct nfs_fattr *);
63 56
64static struct inode *nfs_alloc_inode(struct super_block *sb);
65static void nfs_destroy_inode(struct inode *);
66static int nfs_write_inode(struct inode *,int);
67static void nfs_clear_inode(struct inode *);
68static void nfs_umount_begin(struct vfsmount *, int);
69static int nfs_statfs(struct super_block *, struct kstatfs *);
70static int nfs_show_options(struct seq_file *, struct vfsmount *);
71static int nfs_show_stats(struct seq_file *, struct vfsmount *);
72static void nfs_zap_acl_cache(struct inode *); 57static void nfs_zap_acl_cache(struct inode *);
73 58
74static struct rpc_program nfs_program; 59static kmem_cache_t * nfs_inode_cachep;
75
76static struct super_operations nfs_sops = {
77 .alloc_inode = nfs_alloc_inode,
78 .destroy_inode = nfs_destroy_inode,
79 .write_inode = nfs_write_inode,
80 .statfs = nfs_statfs,
81 .clear_inode = nfs_clear_inode,
82 .umount_begin = nfs_umount_begin,
83 .show_options = nfs_show_options,
84 .show_stats = nfs_show_stats,
85};
86
87/*
88 * RPC cruft for NFS
89 */
90static struct rpc_stat nfs_rpcstat = {
91 .program = &nfs_program
92};
93static struct rpc_version * nfs_version[] = {
94 NULL,
95 NULL,
96 &nfs_version2,
97#if defined(CONFIG_NFS_V3)
98 &nfs_version3,
99#elif defined(CONFIG_NFS_V4)
100 NULL,
101#endif
102#if defined(CONFIG_NFS_V4)
103 &nfs_version4,
104#endif
105};
106
107static struct rpc_program nfs_program = {
108 .name = "nfs",
109 .number = NFS_PROGRAM,
110 .nrvers = ARRAY_SIZE(nfs_version),
111 .version = nfs_version,
112 .stats = &nfs_rpcstat,
113 .pipe_dir_name = "/nfs",
114};
115
116#ifdef CONFIG_NFS_V3_ACL
117static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
118static struct rpc_version * nfsacl_version[] = {
119 [3] = &nfsacl_version3,
120};
121
122struct rpc_program nfsacl_program = {
123 .name = "nfsacl",
124 .number = NFS_ACL_PROGRAM,
125 .nrvers = ARRAY_SIZE(nfsacl_version),
126 .version = nfsacl_version,
127 .stats = &nfsacl_rpcstat,
128};
129#endif /* CONFIG_NFS_V3_ACL */
130 60
131static inline unsigned long 61static inline unsigned long
132nfs_fattr_to_ino_t(struct nfs_fattr *fattr) 62nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
@@ -134,8 +64,7 @@ nfs_fattr_to_ino_t(struct nfs_fattr *fattr)
134 return nfs_fileid_to_ino_t(fattr->fileid); 64 return nfs_fileid_to_ino_t(fattr->fileid);
135} 65}
136 66
137static int 67int nfs_write_inode(struct inode *inode, int sync)
138nfs_write_inode(struct inode *inode, int sync)
139{ 68{
140 int flags = sync ? FLUSH_SYNC : 0; 69 int flags = sync ? FLUSH_SYNC : 0;
141 int ret; 70 int ret;
@@ -146,8 +75,7 @@ nfs_write_inode(struct inode *inode, int sync)
146 return 0; 75 return 0;
147} 76}
148 77
149static void 78void nfs_clear_inode(struct inode *inode)
150nfs_clear_inode(struct inode *inode)
151{ 79{
152 struct nfs_inode *nfsi = NFS_I(inode); 80 struct nfs_inode *nfsi = NFS_I(inode);
153 struct rpc_cred *cred; 81 struct rpc_cred *cred;
@@ -164,566 +92,6 @@ nfs_clear_inode(struct inode *inode)
164 BUG_ON(atomic_read(&nfsi->data_updates) != 0); 92 BUG_ON(atomic_read(&nfsi->data_updates) != 0);
165} 93}
166 94
167static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags)
168{
169 struct nfs_server *server;
170 struct rpc_clnt *rpc;
171
172 shrink_submounts(vfsmnt, &nfs_automount_list);
173 if (!(flags & MNT_FORCE))
174 return;
175 /* -EIO all pending I/O */
176 server = NFS_SB(vfsmnt->mnt_sb);
177 rpc = server->client;
178 if (!IS_ERR(rpc))
179 rpc_killall_tasks(rpc);
180 rpc = server->client_acl;
181 if (!IS_ERR(rpc))
182 rpc_killall_tasks(rpc);
183}
184
185
186static inline unsigned long
187nfs_block_bits(unsigned long bsize, unsigned char *nrbitsp)
188{
189 /* make sure blocksize is a power of two */
190 if ((bsize & (bsize - 1)) || nrbitsp) {
191 unsigned char nrbits;
192
193 for (nrbits = 31; nrbits && !(bsize & (1 << nrbits)); nrbits--)
194 ;
195 bsize = 1 << nrbits;
196 if (nrbitsp)
197 *nrbitsp = nrbits;
198 }
199
200 return bsize;
201}
202
203/*
204 * Calculate the number of 512byte blocks used.
205 */
206static inline unsigned long
207nfs_calc_block_size(u64 tsize)
208{
209 loff_t used = (tsize + 511) >> 9;
210 return (used > ULONG_MAX) ? ULONG_MAX : used;
211}
212
213/*
214 * Compute and set NFS server blocksize
215 */
216static inline unsigned long
217nfs_block_size(unsigned long bsize, unsigned char *nrbitsp)
218{
219 if (bsize < NFS_MIN_FILE_IO_SIZE)
220 bsize = NFS_DEF_FILE_IO_SIZE;
221 else if (bsize >= NFS_MAX_FILE_IO_SIZE)
222 bsize = NFS_MAX_FILE_IO_SIZE;
223
224 return nfs_block_bits(bsize, nrbitsp);
225}
226
227static inline void
228nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize)
229{
230 sb->s_maxbytes = (loff_t)maxfilesize;
231 if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0)
232 sb->s_maxbytes = MAX_LFS_FILESIZE;
233}
234
235/*
236 * Obtain the root inode of the file system.
237 */
238static struct inode *
239nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh, struct nfs_fsinfo *fsinfo)
240{
241 struct nfs_server *server = NFS_SB(sb);
242 int error;
243
244 error = server->rpc_ops->getroot(server, rootfh, fsinfo);
245 if (error < 0) {
246 dprintk("nfs_get_root: getattr error = %d\n", -error);
247 return ERR_PTR(error);
248 }
249
250 server->fsid = fsinfo->fattr->fsid;
251 return nfs_fhget(sb, rootfh, fsinfo->fattr);
252}
253
254/*
255 * Do NFS version-independent mount processing, and sanity checking
256 */
257static int
258nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor)
259{
260 struct nfs_server *server;
261 struct inode *root_inode;
262 struct nfs_fattr fattr;
263 struct nfs_fsinfo fsinfo = {
264 .fattr = &fattr,
265 };
266 struct nfs_pathconf pathinfo = {
267 .fattr = &fattr,
268 };
269 int no_root_error = 0;
270 unsigned long max_rpc_payload;
271
272 /* We probably want something more informative here */
273 snprintf(sb->s_id, sizeof(sb->s_id), "%x:%x", MAJOR(sb->s_dev), MINOR(sb->s_dev));
274
275 server = NFS_SB(sb);
276
277 sb->s_magic = NFS_SUPER_MAGIC;
278
279 server->io_stats = nfs_alloc_iostats();
280 if (server->io_stats == NULL)
281 return -ENOMEM;
282
283 root_inode = nfs_get_root(sb, &server->fh, &fsinfo);
284 /* Did getting the root inode fail? */
285 if (IS_ERR(root_inode)) {
286 no_root_error = PTR_ERR(root_inode);
287 goto out_no_root;
288 }
289 sb->s_root = d_alloc_root(root_inode);
290 if (!sb->s_root) {
291 no_root_error = -ENOMEM;
292 goto out_no_root;
293 }
294 sb->s_root->d_op = server->rpc_ops->dentry_ops;
295
296 /* mount time stamp, in seconds */
297 server->mount_time = jiffies;
298
299 /* Get some general file system info */
300 if (server->namelen == 0 &&
301 server->rpc_ops->pathconf(server, &server->fh, &pathinfo) >= 0)
302 server->namelen = pathinfo.max_namelen;
303 /* Work out a lot of parameters */
304 if (server->rsize == 0)
305 server->rsize = nfs_block_size(fsinfo.rtpref, NULL);
306 if (server->wsize == 0)
307 server->wsize = nfs_block_size(fsinfo.wtpref, NULL);
308
309 if (fsinfo.rtmax >= 512 && server->rsize > fsinfo.rtmax)
310 server->rsize = nfs_block_size(fsinfo.rtmax, NULL);
311 if (fsinfo.wtmax >= 512 && server->wsize > fsinfo.wtmax)
312 server->wsize = nfs_block_size(fsinfo.wtmax, NULL);
313
314 max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL);
315 if (server->rsize > max_rpc_payload)
316 server->rsize = max_rpc_payload;
317 if (server->rsize > NFS_MAX_FILE_IO_SIZE)
318 server->rsize = NFS_MAX_FILE_IO_SIZE;
319 server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
320
321 if (server->wsize > max_rpc_payload)
322 server->wsize = max_rpc_payload;
323 if (server->wsize > NFS_MAX_FILE_IO_SIZE)
324 server->wsize = NFS_MAX_FILE_IO_SIZE;
325 server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
326
327 if (sb->s_blocksize == 0)
328 sb->s_blocksize = nfs_block_bits(server->wsize,
329 &sb->s_blocksize_bits);
330 server->wtmult = nfs_block_bits(fsinfo.wtmult, NULL);
331
332 server->dtsize = nfs_block_size(fsinfo.dtpref, NULL);
333 if (server->dtsize > PAGE_CACHE_SIZE)
334 server->dtsize = PAGE_CACHE_SIZE;
335 if (server->dtsize > server->rsize)
336 server->dtsize = server->rsize;
337
338 if (server->flags & NFS_MOUNT_NOAC) {
339 server->acregmin = server->acregmax = 0;
340 server->acdirmin = server->acdirmax = 0;
341 sb->s_flags |= MS_SYNCHRONOUS;
342 }
343 server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD;
344
345 nfs_super_set_maxbytes(sb, fsinfo.maxfilesize);
346
347 server->client->cl_intr = (server->flags & NFS_MOUNT_INTR) ? 1 : 0;
348 server->client->cl_softrtry = (server->flags & NFS_MOUNT_SOFT) ? 1 : 0;
349
350 /* We're airborne Set socket buffersize */
351 rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
352 return 0;
353 /* Yargs. It didn't work out. */
354out_no_root:
355 dprintk("nfs_sb_init: get root inode failed: errno %d\n", -no_root_error);
356 if (!IS_ERR(root_inode))
357 iput(root_inode);
358 return no_root_error;
359}
360
361static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, unsigned int timeo, unsigned int retrans)
362{
363 to->to_initval = timeo * HZ / 10;
364 to->to_retries = retrans;
365 if (!to->to_retries)
366 to->to_retries = 2;
367
368 switch (proto) {
369 case IPPROTO_TCP:
370 if (!to->to_initval)
371 to->to_initval = 60 * HZ;
372 if (to->to_initval > NFS_MAX_TCP_TIMEOUT)
373 to->to_initval = NFS_MAX_TCP_TIMEOUT;
374 to->to_increment = to->to_initval;
375 to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
376 to->to_exponential = 0;
377 break;
378 case IPPROTO_UDP:
379 default:
380 if (!to->to_initval)
381 to->to_initval = 11 * HZ / 10;
382 if (to->to_initval > NFS_MAX_UDP_TIMEOUT)
383 to->to_initval = NFS_MAX_UDP_TIMEOUT;
384 to->to_maxval = NFS_MAX_UDP_TIMEOUT;
385 to->to_exponential = 1;
386 break;
387 }
388}
389
390/*
391 * Create an RPC client handle.
392 */
393static struct rpc_clnt *
394nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
395{
396 struct rpc_timeout timeparms;
397 struct rpc_xprt *xprt = NULL;
398 struct rpc_clnt *clnt = NULL;
399 int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
400
401 nfs_init_timeout_values(&timeparms, proto, data->timeo, data->retrans);
402
403 server->retrans_timeo = timeparms.to_initval;
404 server->retrans_count = timeparms.to_retries;
405
406 /* create transport and client */
407 xprt = xprt_create_proto(proto, &server->addr, &timeparms);
408 if (IS_ERR(xprt)) {
409 dprintk("%s: cannot create RPC transport. Error = %ld\n",
410 __FUNCTION__, PTR_ERR(xprt));
411 return (struct rpc_clnt *)xprt;
412 }
413 clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
414 server->rpc_ops->version, data->pseudoflavor);
415 if (IS_ERR(clnt)) {
416 dprintk("%s: cannot create RPC client. Error = %ld\n",
417 __FUNCTION__, PTR_ERR(xprt));
418 goto out_fail;
419 }
420
421 clnt->cl_intr = 1;
422 clnt->cl_softrtry = 1;
423
424 return clnt;
425
426out_fail:
427 return clnt;
428}
429
430/*
431 * The way this works is that the mount process passes a structure
432 * in the data argument which contains the server's IP address
433 * and the root file handle obtained from the server's mount
434 * daemon. We stash these away in the private superblock fields.
435 */
436static int
437nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
438{
439 struct nfs_server *server;
440 rpc_authflavor_t authflavor;
441
442 server = NFS_SB(sb);
443 sb->s_blocksize_bits = 0;
444 sb->s_blocksize = 0;
445 if (data->bsize)
446 sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
447 if (data->rsize)
448 server->rsize = nfs_block_size(data->rsize, NULL);
449 if (data->wsize)
450 server->wsize = nfs_block_size(data->wsize, NULL);
451 server->flags = data->flags & NFS_MOUNT_FLAGMASK;
452
453 server->acregmin = data->acregmin*HZ;
454 server->acregmax = data->acregmax*HZ;
455 server->acdirmin = data->acdirmin*HZ;
456 server->acdirmax = data->acdirmax*HZ;
457
458 /* Start lockd here, before we might error out */
459 if (!(server->flags & NFS_MOUNT_NONLM))
460 lockd_up();
461
462 server->namelen = data->namlen;
463 server->hostname = kmalloc(strlen(data->hostname) + 1, GFP_KERNEL);
464 if (!server->hostname)
465 return -ENOMEM;
466 strcpy(server->hostname, data->hostname);
467
468 /* Check NFS protocol revision and initialize RPC op vector
469 * and file handle pool. */
470#ifdef CONFIG_NFS_V3
471 if (server->flags & NFS_MOUNT_VER3) {
472 server->rpc_ops = &nfs_v3_clientops;
473 server->caps |= NFS_CAP_READDIRPLUS;
474 } else {
475 server->rpc_ops = &nfs_v2_clientops;
476 }
477#else
478 server->rpc_ops = &nfs_v2_clientops;
479#endif
480
481 /* Fill in pseudoflavor for mount version < 5 */
482 if (!(data->flags & NFS_MOUNT_SECFLAVOUR))
483 data->pseudoflavor = RPC_AUTH_UNIX;
484 authflavor = data->pseudoflavor; /* save for sb_init() */
485 /* XXX maybe we want to add a server->pseudoflavor field */
486
487 /* Create RPC client handles */
488 server->client = nfs_create_client(server, data);
489 if (IS_ERR(server->client))
490 return PTR_ERR(server->client);
491 /* RFC 2623, sec 2.3.2 */
492 if (authflavor != RPC_AUTH_UNIX) {
493 struct rpc_auth *auth;
494
495 server->client_sys = rpc_clone_client(server->client);
496 if (IS_ERR(server->client_sys))
497 return PTR_ERR(server->client_sys);
498 auth = rpcauth_create(RPC_AUTH_UNIX, server->client_sys);
499 if (IS_ERR(auth))
500 return PTR_ERR(auth);
501 } else {
502 atomic_inc(&server->client->cl_count);
503 server->client_sys = server->client;
504 }
505 if (server->flags & NFS_MOUNT_VER3) {
506#ifdef CONFIG_NFS_V3_ACL
507 if (!(server->flags & NFS_MOUNT_NOACL)) {
508 server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
509 /* No errors! Assume that Sun nfsacls are supported */
510 if (!IS_ERR(server->client_acl))
511 server->caps |= NFS_CAP_ACLS;
512 }
513#else
514 server->flags &= ~NFS_MOUNT_NOACL;
515#endif /* CONFIG_NFS_V3_ACL */
516 /*
517 * The VFS shouldn't apply the umask to mode bits. We will
518 * do so ourselves when necessary.
519 */
520 sb->s_flags |= MS_POSIXACL;
521 if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
522 server->namelen = NFS3_MAXNAMLEN;
523 sb->s_time_gran = 1;
524 } else {
525 if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
526 server->namelen = NFS2_MAXNAMLEN;
527 }
528
529 sb->s_op = &nfs_sops;
530 return nfs_sb_init(sb, authflavor);
531}
532
533static int
534nfs_statfs(struct super_block *sb, struct kstatfs *buf)
535{
536 struct nfs_server *server = NFS_SB(sb);
537 unsigned char blockbits;
538 unsigned long blockres;
539 struct nfs_fh *rootfh = NFS_FH(sb->s_root->d_inode);
540 struct nfs_fattr fattr;
541 struct nfs_fsstat res = {
542 .fattr = &fattr,
543 };
544 int error;
545
546 lock_kernel();
547
548 error = server->rpc_ops->statfs(server, rootfh, &res);
549 buf->f_type = NFS_SUPER_MAGIC;
550 if (error < 0)
551 goto out_err;
552
553 /*
554 * Current versions of glibc do not correctly handle the
555 * case where f_frsize != f_bsize. Eventually we want to
556 * report the value of wtmult in this field.
557 */
558 buf->f_frsize = sb->s_blocksize;
559
560 /*
561 * On most *nix systems, f_blocks, f_bfree, and f_bavail
562 * are reported in units of f_frsize. Linux hasn't had
563 * an f_frsize field in its statfs struct until recently,
564 * thus historically Linux's sys_statfs reports these
565 * fields in units of f_bsize.
566 */
567 buf->f_bsize = sb->s_blocksize;
568 blockbits = sb->s_blocksize_bits;
569 blockres = (1 << blockbits) - 1;
570 buf->f_blocks = (res.tbytes + blockres) >> blockbits;
571 buf->f_bfree = (res.fbytes + blockres) >> blockbits;
572 buf->f_bavail = (res.abytes + blockres) >> blockbits;
573
574 buf->f_files = res.tfiles;
575 buf->f_ffree = res.afiles;
576
577 buf->f_namelen = server->namelen;
578 out:
579 unlock_kernel();
580 return 0;
581
582 out_err:
583 dprintk("%s: statfs error = %d\n", __FUNCTION__, -error);
584 buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1;
585 goto out;
586
587}
588
589static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, int showdefaults)
590{
591 static struct proc_nfs_info {
592 int flag;
593 char *str;
594 char *nostr;
595 } nfs_info[] = {
596 { NFS_MOUNT_SOFT, ",soft", ",hard" },
597 { NFS_MOUNT_INTR, ",intr", "" },
598 { NFS_MOUNT_NOCTO, ",nocto", "" },
599 { NFS_MOUNT_NOAC, ",noac", "" },
600 { NFS_MOUNT_NONLM, ",nolock", "" },
601 { NFS_MOUNT_NOACL, ",noacl", "" },
602 { 0, NULL, NULL }
603 };
604 struct proc_nfs_info *nfs_infop;
605 char buf[12];
606 char *proto;
607
608 seq_printf(m, ",vers=%d", nfss->rpc_ops->version);
609 seq_printf(m, ",rsize=%d", nfss->rsize);
610 seq_printf(m, ",wsize=%d", nfss->wsize);
611 if (nfss->acregmin != 3*HZ || showdefaults)
612 seq_printf(m, ",acregmin=%d", nfss->acregmin/HZ);
613 if (nfss->acregmax != 60*HZ || showdefaults)
614 seq_printf(m, ",acregmax=%d", nfss->acregmax/HZ);
615 if (nfss->acdirmin != 30*HZ || showdefaults)
616 seq_printf(m, ",acdirmin=%d", nfss->acdirmin/HZ);
617 if (nfss->acdirmax != 60*HZ || showdefaults)
618 seq_printf(m, ",acdirmax=%d", nfss->acdirmax/HZ);
619 for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) {
620 if (nfss->flags & nfs_infop->flag)
621 seq_puts(m, nfs_infop->str);
622 else
623 seq_puts(m, nfs_infop->nostr);
624 }
625 switch (nfss->client->cl_xprt->prot) {
626 case IPPROTO_TCP:
627 proto = "tcp";
628 break;
629 case IPPROTO_UDP:
630 proto = "udp";
631 break;
632 default:
633 snprintf(buf, sizeof(buf), "%u", nfss->client->cl_xprt->prot);
634 proto = buf;
635 }
636 seq_printf(m, ",proto=%s", proto);
637 seq_printf(m, ",timeo=%lu", 10U * nfss->retrans_timeo / HZ);
638 seq_printf(m, ",retrans=%u", nfss->retrans_count);
639}
640
641static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
642{
643 struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
644
645 nfs_show_mount_options(m, nfss, 0);
646
647 seq_puts(m, ",addr=");
648 seq_escape(m, nfss->hostname, " \t\n\\");
649
650 return 0;
651}
652
653static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
654{
655 int i, cpu;
656 struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
657 struct rpc_auth *auth = nfss->client->cl_auth;
658 struct nfs_iostats totals = { };
659
660 seq_printf(m, "statvers=%s", NFS_IOSTAT_VERS);
661
662 /*
663 * Display all mount option settings
664 */
665 seq_printf(m, "\n\topts:\t");
666 seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? "ro" : "rw");
667 seq_puts(m, mnt->mnt_sb->s_flags & MS_SYNCHRONOUS ? ",sync" : "");
668 seq_puts(m, mnt->mnt_sb->s_flags & MS_NOATIME ? ",noatime" : "");
669 seq_puts(m, mnt->mnt_sb->s_flags & MS_NODIRATIME ? ",nodiratime" : "");
670 nfs_show_mount_options(m, nfss, 1);
671
672 seq_printf(m, "\n\tage:\t%lu", (jiffies - nfss->mount_time) / HZ);
673
674 seq_printf(m, "\n\tcaps:\t");
675 seq_printf(m, "caps=0x%x", nfss->caps);
676 seq_printf(m, ",wtmult=%d", nfss->wtmult);
677 seq_printf(m, ",dtsize=%d", nfss->dtsize);
678 seq_printf(m, ",bsize=%d", nfss->bsize);
679 seq_printf(m, ",namelen=%d", nfss->namelen);
680
681#ifdef CONFIG_NFS_V4
682 if (nfss->rpc_ops->version == 4) {
683 seq_printf(m, "\n\tnfsv4:\t");
684 seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]);
685 seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]);
686 seq_printf(m, ",acl=0x%x", nfss->acl_bitmask);
687 }
688#endif
689
690 /*
691 * Display security flavor in effect for this mount
692 */
693 seq_printf(m, "\n\tsec:\tflavor=%d", auth->au_ops->au_flavor);
694 if (auth->au_flavor)
695 seq_printf(m, ",pseudoflavor=%d", auth->au_flavor);
696
697 /*
698 * Display superblock I/O counters
699 */
700 for_each_possible_cpu(cpu) {
701 struct nfs_iostats *stats;
702
703 preempt_disable();
704 stats = per_cpu_ptr(nfss->io_stats, cpu);
705
706 for (i = 0; i < __NFSIOS_COUNTSMAX; i++)
707 totals.events[i] += stats->events[i];
708 for (i = 0; i < __NFSIOS_BYTESMAX; i++)
709 totals.bytes[i] += stats->bytes[i];
710
711 preempt_enable();
712 }
713
714 seq_printf(m, "\n\tevents:\t");
715 for (i = 0; i < __NFSIOS_COUNTSMAX; i++)
716 seq_printf(m, "%lu ", totals.events[i]);
717 seq_printf(m, "\n\tbytes:\t");
718 for (i = 0; i < __NFSIOS_BYTESMAX; i++)
719 seq_printf(m, "%Lu ", totals.bytes[i]);
720 seq_printf(m, "\n");
721
722 rpc_print_iostats(m, nfss->client);
723
724 return 0;
725}
726
727/** 95/**
728 * nfs_sync_mapping - helper to flush all mmapped dirty data to disk 96 * nfs_sync_mapping - helper to flush all mmapped dirty data to disk
729 */ 97 */
@@ -1663,371 +1031,15 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1663 goto out_err; 1031 goto out_err;
1664} 1032}
1665 1033
1666/*
1667 * File system information
1668 */
1669
1670/*
1671 * nfs_path - reconstruct the path given an arbitrary dentry
1672 * @base - arbitrary string to prepend to the path
1673 * @dentry - pointer to dentry
1674 * @buffer - result buffer
1675 * @buflen - length of buffer
1676 *
1677 * Helper function for constructing the path from the
1678 * root dentry to an arbitrary hashed dentry.
1679 *
1680 * This is mainly for use in figuring out the path on the
1681 * server side when automounting on top of an existing partition.
1682 */
1683static char *nfs_path(const char *base, const struct dentry *dentry,
1684 char *buffer, ssize_t buflen)
1685{
1686 char *end = buffer+buflen;
1687 int namelen;
1688
1689 *--end = '\0';
1690 buflen--;
1691 spin_lock(&dcache_lock);
1692 while (!IS_ROOT(dentry)) {
1693 namelen = dentry->d_name.len;
1694 buflen -= namelen + 1;
1695 if (buflen < 0)
1696 goto Elong;
1697 end -= namelen;
1698 memcpy(end, dentry->d_name.name, namelen);
1699 *--end = '/';
1700 dentry = dentry->d_parent;
1701 }
1702 spin_unlock(&dcache_lock);
1703 namelen = strlen(base);
1704 /* Strip off excess slashes in base string */
1705 while (namelen > 0 && base[namelen - 1] == '/')
1706 namelen--;
1707 buflen -= namelen;
1708 if (buflen < 0)
1709 goto Elong;
1710 end -= namelen;
1711 memcpy(end, base, namelen);
1712 return end;
1713Elong:
1714 return ERR_PTR(-ENAMETOOLONG);
1715}
1716
1717struct nfs_clone_mount {
1718 const struct super_block *sb;
1719 const struct dentry *dentry;
1720 struct nfs_fh *fh;
1721 struct nfs_fattr *fattr;
1722 char *hostname;
1723 char *mnt_path;
1724 struct sockaddr_in *addr;
1725 rpc_authflavor_t authflavor;
1726};
1727
1728static struct super_block *nfs_clone_generic_sb(struct nfs_clone_mount *data,
1729 struct super_block *(*fill_sb)(struct nfs_server *, struct nfs_clone_mount *),
1730 struct nfs_server *(*fill_server)(struct super_block *, struct nfs_clone_mount *))
1731{
1732 struct nfs_server *server;
1733 struct nfs_server *parent = NFS_SB(data->sb);
1734 struct super_block *sb = ERR_PTR(-EINVAL);
1735 void *err = ERR_PTR(-ENOMEM);
1736 char *hostname;
1737 int len;
1738
1739 server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL);
1740 if (server == NULL)
1741 goto out_err;
1742 memcpy(server, parent, sizeof(*server));
1743 hostname = (data->hostname != NULL) ? data->hostname : parent->hostname;
1744 len = strlen(hostname) + 1;
1745 server->hostname = kmalloc(len, GFP_KERNEL);
1746 if (server->hostname == NULL)
1747 goto free_server;
1748 memcpy(server->hostname, hostname, len);
1749 if (rpciod_up() != 0)
1750 goto free_hostname;
1751
1752 sb = fill_sb(server, data);
1753 if (IS_ERR((err = sb)) || sb->s_root)
1754 goto kill_rpciod;
1755
1756 server = fill_server(sb, data);
1757 if (IS_ERR((err = server)))
1758 goto out_deactivate;
1759 return sb;
1760out_deactivate:
1761 up_write(&sb->s_umount);
1762 deactivate_super(sb);
1763 return (struct super_block *)err;
1764kill_rpciod:
1765 rpciod_down();
1766free_hostname:
1767 kfree(server->hostname);
1768free_server:
1769 kfree(server);
1770out_err:
1771 return (struct super_block *)err;
1772}
1773
1774static int nfs_set_super(struct super_block *s, void *data)
1775{
1776 s->s_fs_info = data;
1777 return set_anon_super(s, data);
1778}
1779
1780static int nfs_compare_super(struct super_block *sb, void *data)
1781{
1782 struct nfs_server *server = data;
1783 struct nfs_server *old = NFS_SB(sb);
1784
1785 if (old->addr.sin_addr.s_addr != server->addr.sin_addr.s_addr)
1786 return 0;
1787 if (old->addr.sin_port != server->addr.sin_port)
1788 return 0;
1789 return !nfs_compare_fh(&old->fh, &server->fh);
1790}
1791
1792static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
1793 int flags, const char *dev_name, void *raw_data)
1794{
1795 int error;
1796 struct nfs_server *server = NULL;
1797 struct super_block *s;
1798 struct nfs_fh *root;
1799 struct nfs_mount_data *data = raw_data;
1800
1801 s = ERR_PTR(-EINVAL);
1802 if (data == NULL) {
1803 dprintk("%s: missing data argument\n", __FUNCTION__);
1804 goto out_err;
1805 }
1806 if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
1807 dprintk("%s: bad mount version\n", __FUNCTION__);
1808 goto out_err;
1809 }
1810 switch (data->version) {
1811 case 1:
1812 data->namlen = 0;
1813 case 2:
1814 data->bsize = 0;
1815 case 3:
1816 if (data->flags & NFS_MOUNT_VER3) {
1817 dprintk("%s: mount structure version %d does not support NFSv3\n",
1818 __FUNCTION__,
1819 data->version);
1820 goto out_err;
1821 }
1822 data->root.size = NFS2_FHSIZE;
1823 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
1824 case 4:
1825 if (data->flags & NFS_MOUNT_SECFLAVOUR) {
1826 dprintk("%s: mount structure version %d does not support strong security\n",
1827 __FUNCTION__,
1828 data->version);
1829 goto out_err;
1830 }
1831 case 5:
1832 memset(data->context, 0, sizeof(data->context));
1833 }
1834#ifndef CONFIG_NFS_V3
1835 /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */
1836 s = ERR_PTR(-EPROTONOSUPPORT);
1837 if (data->flags & NFS_MOUNT_VER3) {
1838 dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__);
1839 goto out_err;
1840 }
1841#endif /* CONFIG_NFS_V3 */
1842
1843 s = ERR_PTR(-ENOMEM);
1844 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
1845 if (!server)
1846 goto out_err;
1847 /* Zero out the NFS state stuff */
1848 init_nfsv4_state(server);
1849 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
1850
1851 root = &server->fh;
1852 if (data->flags & NFS_MOUNT_VER3)
1853 root->size = data->root.size;
1854 else
1855 root->size = NFS2_FHSIZE;
1856 s = ERR_PTR(-EINVAL);
1857 if (root->size > sizeof(root->data)) {
1858 dprintk("%s: invalid root filehandle\n", __FUNCTION__);
1859 goto out_err;
1860 }
1861 memcpy(root->data, data->root.data, root->size);
1862
1863 /* We now require that the mount process passes the remote address */
1864 memcpy(&server->addr, &data->addr, sizeof(server->addr));
1865 if (server->addr.sin_addr.s_addr == INADDR_ANY) {
1866 dprintk("%s: mount program didn't pass remote address!\n",
1867 __FUNCTION__);
1868 goto out_err;
1869 }
1870
1871 /* Fire up rpciod if not yet running */
1872 s = ERR_PTR(rpciod_up());
1873 if (IS_ERR(s)) {
1874 dprintk("%s: couldn't start rpciod! Error = %ld\n",
1875 __FUNCTION__, PTR_ERR(s));
1876 goto out_err;
1877 }
1878
1879 s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
1880 if (IS_ERR(s) || s->s_root)
1881 goto out_rpciod_down;
1882
1883 s->s_flags = flags;
1884
1885 error = nfs_fill_super(s, data, flags & MS_SILENT ? 1 : 0);
1886 if (error) {
1887 up_write(&s->s_umount);
1888 deactivate_super(s);
1889 return ERR_PTR(error);
1890 }
1891 s->s_flags |= MS_ACTIVE;
1892 return s;
1893out_rpciod_down:
1894 rpciod_down();
1895out_err:
1896 kfree(server);
1897 return s;
1898}
1899
1900static void nfs_kill_super(struct super_block *s)
1901{
1902 struct nfs_server *server = NFS_SB(s);
1903
1904 kill_anon_super(s);
1905
1906 if (!IS_ERR(server->client))
1907 rpc_shutdown_client(server->client);
1908 if (!IS_ERR(server->client_sys))
1909 rpc_shutdown_client(server->client_sys);
1910 if (!IS_ERR(server->client_acl))
1911 rpc_shutdown_client(server->client_acl);
1912
1913 if (!(server->flags & NFS_MOUNT_NONLM))
1914 lockd_down(); /* release rpc.lockd */
1915
1916 rpciod_down(); /* release rpciod */
1917
1918 nfs_free_iostats(server->io_stats);
1919 kfree(server->hostname);
1920 kfree(server);
1921 nfs_release_automount_timer();
1922}
1923
1924static struct file_system_type nfs_fs_type = {
1925 .owner = THIS_MODULE,
1926 .name = "nfs",
1927 .get_sb = nfs_get_sb,
1928 .kill_sb = nfs_kill_super,
1929 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
1930};
1931
1932static struct super_block *nfs_clone_sb(struct nfs_server *server, struct nfs_clone_mount *data)
1933{
1934 struct super_block *sb;
1935
1936 server->fsid = data->fattr->fsid;
1937 nfs_copy_fh(&server->fh, data->fh);
1938 sb = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
1939 if (!IS_ERR(sb) && sb->s_root == NULL && !(server->flags & NFS_MOUNT_NONLM))
1940 lockd_up();
1941 return sb;
1942}
1943
1944static struct nfs_server *nfs_clone_server(struct super_block *sb, struct nfs_clone_mount *data)
1945{
1946 struct nfs_server *server = NFS_SB(sb);
1947 struct nfs_server *parent = NFS_SB(data->sb);
1948 struct inode *root_inode;
1949 struct nfs_fsinfo fsinfo;
1950 void *err = ERR_PTR(-ENOMEM);
1951
1952 sb->s_op = data->sb->s_op;
1953 sb->s_blocksize = data->sb->s_blocksize;
1954 sb->s_blocksize_bits = data->sb->s_blocksize_bits;
1955 sb->s_maxbytes = data->sb->s_maxbytes;
1956
1957 server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
1958 server->io_stats = nfs_alloc_iostats();
1959 if (server->io_stats == NULL)
1960 goto out;
1961
1962 server->client = rpc_clone_client(parent->client);
1963 if (IS_ERR((err = server->client)))
1964 goto out;
1965
1966 if (!IS_ERR(parent->client_sys)) {
1967 server->client_sys = rpc_clone_client(parent->client_sys);
1968 if (IS_ERR((err = server->client_sys)))
1969 goto out;
1970 }
1971 if (!IS_ERR(parent->client_acl)) {
1972 server->client_acl = rpc_clone_client(parent->client_acl);
1973 if (IS_ERR((err = server->client_acl)))
1974 goto out;
1975 }
1976 root_inode = nfs_fhget(sb, data->fh, data->fattr);
1977 if (!root_inode)
1978 goto out;
1979 sb->s_root = d_alloc_root(root_inode);
1980 if (!sb->s_root)
1981 goto out_put_root;
1982 fsinfo.fattr = data->fattr;
1983 if (NFS_PROTO(root_inode)->fsinfo(server, data->fh, &fsinfo) == 0)
1984 nfs_super_set_maxbytes(sb, fsinfo.maxfilesize);
1985 sb->s_root->d_op = server->rpc_ops->dentry_ops;
1986 sb->s_flags |= MS_ACTIVE;
1987 return server;
1988out_put_root:
1989 iput(root_inode);
1990out:
1991 return err;
1992}
1993
1994static struct super_block *nfs_clone_nfs_sb(struct file_system_type *fs_type,
1995 int flags, const char *dev_name, void *raw_data)
1996{
1997 struct nfs_clone_mount *data = raw_data;
1998 return nfs_clone_generic_sb(data, nfs_clone_sb, nfs_clone_server);
1999}
2000
2001static struct file_system_type clone_nfs_fs_type = {
2002 .owner = THIS_MODULE,
2003 .name = "nfs",
2004 .get_sb = nfs_clone_nfs_sb,
2005 .kill_sb = nfs_kill_super,
2006 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
2007};
2008 1034
2009#ifdef CONFIG_NFS_V4 1035#ifdef CONFIG_NFS_V4
2010 1036
2011static void nfs4_clear_inode(struct inode *);
2012
2013
2014static struct super_operations nfs4_sops = {
2015 .alloc_inode = nfs_alloc_inode,
2016 .destroy_inode = nfs_destroy_inode,
2017 .write_inode = nfs_write_inode,
2018 .statfs = nfs_statfs,
2019 .clear_inode = nfs4_clear_inode,
2020 .umount_begin = nfs_umount_begin,
2021 .show_options = nfs_show_options,
2022 .show_stats = nfs_show_stats,
2023};
2024
2025/* 1037/*
2026 * Clean out any remaining NFSv4 state that might be left over due 1038 * Clean out any remaining NFSv4 state that might be left over due
2027 * to open() calls that passed nfs_atomic_lookup, but failed to call 1039 * to open() calls that passed nfs_atomic_lookup, but failed to call
2028 * nfs_open(). 1040 * nfs_open().
2029 */ 1041 */
2030static void nfs4_clear_inode(struct inode *inode) 1042void nfs4_clear_inode(struct inode *inode)
2031{ 1043{
2032 struct nfs_inode *nfsi = NFS_I(inode); 1044 struct nfs_inode *nfsi = NFS_I(inode);
2033 1045
@@ -2051,774 +1063,9 @@ static void nfs4_clear_inode(struct inode *inode)
2051 nfs4_close_state(state, state->state); 1063 nfs4_close_state(state, state->state);
2052 } 1064 }
2053} 1065}
2054
2055
2056static struct rpc_clnt *nfs4_create_client(struct nfs_server *server,
2057 struct rpc_timeout *timeparms, int proto, rpc_authflavor_t flavor)
2058{
2059 struct nfs4_client *clp;
2060 struct rpc_xprt *xprt = NULL;
2061 struct rpc_clnt *clnt = NULL;
2062 int err = -EIO;
2063
2064 clp = nfs4_get_client(&server->addr.sin_addr);
2065 if (!clp) {
2066 dprintk("%s: failed to create NFS4 client.\n", __FUNCTION__);
2067 return ERR_PTR(err);
2068 }
2069
2070 /* Now create transport and client */
2071 down_write(&clp->cl_sem);
2072 if (IS_ERR(clp->cl_rpcclient)) {
2073 xprt = xprt_create_proto(proto, &server->addr, timeparms);
2074 if (IS_ERR(xprt)) {
2075 up_write(&clp->cl_sem);
2076 err = PTR_ERR(xprt);
2077 dprintk("%s: cannot create RPC transport. Error = %d\n",
2078 __FUNCTION__, err);
2079 goto out_fail;
2080 }
2081 /* Bind to a reserved port! */
2082 xprt->resvport = 1;
2083 clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
2084 server->rpc_ops->version, flavor);
2085 if (IS_ERR(clnt)) {
2086 up_write(&clp->cl_sem);
2087 err = PTR_ERR(clnt);
2088 dprintk("%s: cannot create RPC client. Error = %d\n",
2089 __FUNCTION__, err);
2090 goto out_fail;
2091 }
2092 clnt->cl_intr = 1;
2093 clnt->cl_softrtry = 1;
2094 clp->cl_rpcclient = clnt;
2095 memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr));
2096 nfs_idmap_new(clp);
2097 }
2098 list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks);
2099 clnt = rpc_clone_client(clp->cl_rpcclient);
2100 if (!IS_ERR(clnt))
2101 server->nfs4_state = clp;
2102 up_write(&clp->cl_sem);
2103 clp = NULL;
2104
2105 if (IS_ERR(clnt)) {
2106 dprintk("%s: cannot create RPC client. Error = %d\n",
2107 __FUNCTION__, err);
2108 return clnt;
2109 }
2110
2111 if (server->nfs4_state->cl_idmap == NULL) {
2112 dprintk("%s: failed to create idmapper.\n", __FUNCTION__);
2113 return ERR_PTR(-ENOMEM);
2114 }
2115
2116 if (clnt->cl_auth->au_flavor != flavor) {
2117 struct rpc_auth *auth;
2118
2119 auth = rpcauth_create(flavor, clnt);
2120 if (IS_ERR(auth)) {
2121 dprintk("%s: couldn't create credcache!\n", __FUNCTION__);
2122 return (struct rpc_clnt *)auth;
2123 }
2124 }
2125 return clnt;
2126
2127 out_fail:
2128 if (clp)
2129 nfs4_put_client(clp);
2130 return ERR_PTR(err);
2131}
2132
2133static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, int silent)
2134{
2135 struct nfs_server *server;
2136 struct rpc_timeout timeparms;
2137 rpc_authflavor_t authflavour;
2138 int err = -EIO;
2139
2140 sb->s_blocksize_bits = 0;
2141 sb->s_blocksize = 0;
2142 server = NFS_SB(sb);
2143 if (data->rsize != 0)
2144 server->rsize = nfs_block_size(data->rsize, NULL);
2145 if (data->wsize != 0)
2146 server->wsize = nfs_block_size(data->wsize, NULL);
2147 server->flags = data->flags & NFS_MOUNT_FLAGMASK;
2148 server->caps = NFS_CAP_ATOMIC_OPEN;
2149
2150 server->acregmin = data->acregmin*HZ;
2151 server->acregmax = data->acregmax*HZ;
2152 server->acdirmin = data->acdirmin*HZ;
2153 server->acdirmax = data->acdirmax*HZ;
2154
2155 server->rpc_ops = &nfs_v4_clientops;
2156
2157 nfs_init_timeout_values(&timeparms, data->proto, data->timeo, data->retrans);
2158
2159 server->retrans_timeo = timeparms.to_initval;
2160 server->retrans_count = timeparms.to_retries;
2161
2162 /* Now create transport and client */
2163 authflavour = RPC_AUTH_UNIX;
2164 if (data->auth_flavourlen != 0) {
2165 if (data->auth_flavourlen != 1) {
2166 dprintk("%s: Invalid number of RPC auth flavours %d.\n",
2167 __FUNCTION__, data->auth_flavourlen);
2168 err = -EINVAL;
2169 goto out_fail;
2170 }
2171 if (copy_from_user(&authflavour, data->auth_flavours, sizeof(authflavour))) {
2172 err = -EFAULT;
2173 goto out_fail;
2174 }
2175 }
2176
2177 server->client = nfs4_create_client(server, &timeparms, data->proto, authflavour);
2178 if (IS_ERR(server->client)) {
2179 err = PTR_ERR(server->client);
2180 dprintk("%s: cannot create RPC client. Error = %d\n",
2181 __FUNCTION__, err);
2182 goto out_fail;
2183 }
2184
2185 sb->s_time_gran = 1;
2186
2187 sb->s_op = &nfs4_sops;
2188 err = nfs_sb_init(sb, authflavour);
2189
2190 out_fail:
2191 return err;
2192}
2193
2194static int nfs4_compare_super(struct super_block *sb, void *data)
2195{
2196 struct nfs_server *server = data;
2197 struct nfs_server *old = NFS_SB(sb);
2198
2199 if (strcmp(server->hostname, old->hostname) != 0)
2200 return 0;
2201 if (strcmp(server->mnt_path, old->mnt_path) != 0)
2202 return 0;
2203 return 1;
2204}
2205
2206static void *
2207nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen)
2208{
2209 void *p = NULL;
2210
2211 if (!src->len)
2212 return ERR_PTR(-EINVAL);
2213 if (src->len < maxlen)
2214 maxlen = src->len;
2215 if (dst == NULL) {
2216 p = dst = kmalloc(maxlen + 1, GFP_KERNEL);
2217 if (p == NULL)
2218 return ERR_PTR(-ENOMEM);
2219 }
2220 if (copy_from_user(dst, src->data, maxlen)) {
2221 kfree(p);
2222 return ERR_PTR(-EFAULT);
2223 }
2224 dst[maxlen] = '\0';
2225 return dst;
2226}
2227
2228static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
2229 int flags, const char *dev_name, void *raw_data)
2230{
2231 int error;
2232 struct nfs_server *server;
2233 struct super_block *s;
2234 struct nfs4_mount_data *data = raw_data;
2235 void *p;
2236
2237 if (data == NULL) {
2238 dprintk("%s: missing data argument\n", __FUNCTION__);
2239 return ERR_PTR(-EINVAL);
2240 }
2241 if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) {
2242 dprintk("%s: bad mount version\n", __FUNCTION__);
2243 return ERR_PTR(-EINVAL);
2244 }
2245
2246 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
2247 if (!server)
2248 return ERR_PTR(-ENOMEM);
2249 /* Zero out the NFS state stuff */
2250 init_nfsv4_state(server);
2251 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
2252
2253 p = nfs_copy_user_string(NULL, &data->hostname, 256);
2254 if (IS_ERR(p))
2255 goto out_err;
2256 server->hostname = p;
2257
2258 p = nfs_copy_user_string(NULL, &data->mnt_path, 1024);
2259 if (IS_ERR(p))
2260 goto out_err;
2261 server->mnt_path = p;
2262
2263 p = nfs_copy_user_string(server->ip_addr, &data->client_addr,
2264 sizeof(server->ip_addr) - 1);
2265 if (IS_ERR(p))
2266 goto out_err;
2267
2268 /* We now require that the mount process passes the remote address */
2269 if (data->host_addrlen != sizeof(server->addr)) {
2270 s = ERR_PTR(-EINVAL);
2271 goto out_free;
2272 }
2273 if (copy_from_user(&server->addr, data->host_addr, sizeof(server->addr))) {
2274 s = ERR_PTR(-EFAULT);
2275 goto out_free;
2276 }
2277 if (server->addr.sin_family != AF_INET ||
2278 server->addr.sin_addr.s_addr == INADDR_ANY) {
2279 dprintk("%s: mount program didn't pass remote IP address!\n",
2280 __FUNCTION__);
2281 s = ERR_PTR(-EINVAL);
2282 goto out_free;
2283 }
2284
2285 /* Fire up rpciod if not yet running */
2286 s = ERR_PTR(rpciod_up());
2287 if (IS_ERR(s)) {
2288 dprintk("%s: couldn't start rpciod! Error = %ld\n",
2289 __FUNCTION__, PTR_ERR(s));
2290 goto out_free;
2291 }
2292
2293 s = sget(fs_type, nfs4_compare_super, nfs_set_super, server);
2294
2295 if (IS_ERR(s) || s->s_root)
2296 goto out_free;
2297
2298 s->s_flags = flags;
2299
2300 error = nfs4_fill_super(s, data, flags & MS_SILENT ? 1 : 0);
2301 if (error) {
2302 up_write(&s->s_umount);
2303 deactivate_super(s);
2304 return ERR_PTR(error);
2305 }
2306 s->s_flags |= MS_ACTIVE;
2307 return s;
2308out_err:
2309 s = (struct super_block *)p;
2310out_free:
2311 kfree(server->mnt_path);
2312 kfree(server->hostname);
2313 kfree(server);
2314 return s;
2315}
2316
2317static void nfs4_kill_super(struct super_block *sb)
2318{
2319 struct nfs_server *server = NFS_SB(sb);
2320
2321 nfs_return_all_delegations(sb);
2322 kill_anon_super(sb);
2323
2324 nfs4_renewd_prepare_shutdown(server);
2325
2326 if (server->client != NULL && !IS_ERR(server->client))
2327 rpc_shutdown_client(server->client);
2328
2329 destroy_nfsv4_state(server);
2330
2331 rpciod_down();
2332
2333 nfs_free_iostats(server->io_stats);
2334 kfree(server->hostname);
2335 kfree(server);
2336 nfs_release_automount_timer();
2337}
2338
2339static struct file_system_type nfs4_fs_type = {
2340 .owner = THIS_MODULE,
2341 .name = "nfs4",
2342 .get_sb = nfs4_get_sb,
2343 .kill_sb = nfs4_kill_super,
2344 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
2345};
2346
2347static const int nfs_set_port_min = 0;
2348static const int nfs_set_port_max = 65535;
2349static int param_set_port(const char *val, struct kernel_param *kp)
2350{
2351 char *endp;
2352 int num = simple_strtol(val, &endp, 0);
2353 if (endp == val || *endp || num < nfs_set_port_min || num > nfs_set_port_max)
2354 return -EINVAL;
2355 *((int *)kp->arg) = num;
2356 return 0;
2357}
2358
2359module_param_call(callback_tcpport, param_set_port, param_get_int,
2360 &nfs_callback_set_tcpport, 0644);
2361
2362static int param_set_idmap_timeout(const char *val, struct kernel_param *kp)
2363{
2364 char *endp;
2365 int num = simple_strtol(val, &endp, 0);
2366 int jif = num * HZ;
2367 if (endp == val || *endp || num < 0 || jif < num)
2368 return -EINVAL;
2369 *((int *)kp->arg) = jif;
2370 return 0;
2371}
2372
2373module_param_call(idmap_cache_timeout, param_set_idmap_timeout, param_get_int,
2374 &nfs_idmap_cache_timeout, 0644);
2375
2376/* Constructs the SERVER-side path */
2377static inline char *nfs4_path(const struct dentry *dentry, char *buffer, ssize_t buflen)
2378{
2379 return nfs_path(NFS_SB(dentry->d_sb)->mnt_path, dentry, buffer, buflen);
2380}
2381
2382static inline char *nfs4_dup_path(const struct dentry *dentry)
2383{
2384 char *page = (char *) __get_free_page(GFP_USER);
2385 char *path;
2386
2387 path = nfs4_path(dentry, page, PAGE_SIZE);
2388 if (!IS_ERR(path)) {
2389 int len = PAGE_SIZE + page - path;
2390 char *tmp = path;
2391
2392 path = kmalloc(len, GFP_KERNEL);
2393 if (path)
2394 memcpy(path, tmp, len);
2395 else
2396 path = ERR_PTR(-ENOMEM);
2397 }
2398 free_page((unsigned long)page);
2399 return path;
2400}
2401
2402static struct super_block *nfs4_clone_sb(struct nfs_server *server, struct nfs_clone_mount *data)
2403{
2404 const struct dentry *dentry = data->dentry;
2405 struct nfs4_client *clp = server->nfs4_state;
2406 struct super_block *sb;
2407
2408 server->fsid = data->fattr->fsid;
2409 nfs_copy_fh(&server->fh, data->fh);
2410 server->mnt_path = nfs4_dup_path(dentry);
2411 if (IS_ERR(server->mnt_path)) {
2412 sb = (struct super_block *)server->mnt_path;
2413 goto err;
2414 }
2415 sb = sget(&nfs4_fs_type, nfs4_compare_super, nfs_set_super, server);
2416 if (IS_ERR(sb) || sb->s_root)
2417 goto free_path;
2418 nfs4_server_capabilities(server, &server->fh);
2419
2420 down_write(&clp->cl_sem);
2421 atomic_inc(&clp->cl_count);
2422 list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks);
2423 up_write(&clp->cl_sem);
2424 return sb;
2425free_path:
2426 kfree(server->mnt_path);
2427err:
2428 server->mnt_path = NULL;
2429 return sb;
2430}
2431
2432static struct super_block *nfs_clone_nfs4_sb(struct file_system_type *fs_type,
2433 int flags, const char *dev_name, void *raw_data)
2434{
2435 struct nfs_clone_mount *data = raw_data;
2436 return nfs_clone_generic_sb(data, nfs4_clone_sb, nfs_clone_server);
2437}
2438
2439static struct file_system_type clone_nfs4_fs_type = {
2440 .owner = THIS_MODULE,
2441 .name = "nfs4",
2442 .get_sb = nfs_clone_nfs4_sb,
2443 .kill_sb = nfs4_kill_super,
2444 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
2445};
2446
2447static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server, char *devname, struct nfs_clone_mount *mountdata)
2448{
2449 struct vfsmount *mnt = NULL;
2450 switch (server->rpc_ops->version) {
2451 case 2:
2452 case 3:
2453 mnt = vfs_kern_mount(&clone_nfs_fs_type, 0, devname, mountdata);
2454 break;
2455 case 4:
2456 mnt = vfs_kern_mount(&clone_nfs4_fs_type, 0, devname, mountdata);
2457 }
2458 return mnt;
2459}
2460
2461#define nfs4_init_once(nfsi) \
2462 do { \
2463 INIT_LIST_HEAD(&(nfsi)->open_states); \
2464 nfsi->delegation = NULL; \
2465 nfsi->delegation_state = 0; \
2466 init_rwsem(&nfsi->rwsem); \
2467 } while(0)
2468
2469static inline int register_nfs4fs(void)
2470{
2471 int ret;
2472
2473 ret = nfs_register_sysctl();
2474 if (ret != 0)
2475 return ret;
2476 ret = register_filesystem(&nfs4_fs_type);
2477 if (ret != 0)
2478 nfs_unregister_sysctl();
2479 return ret;
2480}
2481
2482static inline void unregister_nfs4fs(void)
2483{
2484 unregister_filesystem(&nfs4_fs_type);
2485 nfs_unregister_sysctl();
2486}
2487#else
2488#define nfs4_fill_sb(a,b) ERR_PTR(-EINVAL)
2489#define nfs4_fill_super(a,b) ERR_PTR(-EINVAL)
2490#define nfs4_init_once(nfsi) \
2491 do { } while (0)
2492#define register_nfs4fs() (0)
2493#define unregister_nfs4fs()
2494static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server, char *devname, struct nfs_clone_mount *mountdata)
2495{
2496 return vfs_kern_mount(&clone_nfs_fs_type, 0, devname, mountdata);
2497}
2498#endif 1066#endif
2499 1067
2500static inline char *nfs_devname(const struct vfsmount *mnt_parent, 1068struct inode *nfs_alloc_inode(struct super_block *sb)
2501 const struct dentry *dentry,
2502 char *buffer, ssize_t buflen)
2503{
2504 return nfs_path(mnt_parent->mnt_devname, dentry, buffer, buflen);
2505}
2506
2507/**
2508 * nfs_do_submount - set up mountpoint when crossing a filesystem boundary
2509 * @mnt_parent - mountpoint of parent directory
2510 * @dentry - parent directory
2511 * @fh - filehandle for new root dentry
2512 * @fattr - attributes for new root inode
2513 *
2514 */
2515struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent,
2516 const struct dentry *dentry, struct nfs_fh *fh,
2517 struct nfs_fattr *fattr)
2518{
2519 struct nfs_clone_mount mountdata = {
2520 .sb = mnt_parent->mnt_sb,
2521 .dentry = dentry,
2522 .fh = fh,
2523 .fattr = fattr,
2524 };
2525 struct vfsmount *mnt = ERR_PTR(-ENOMEM);
2526 char *page = (char *) __get_free_page(GFP_USER);
2527 char *devname;
2528
2529 dprintk("%s: submounting on %s/%s\n", __FUNCTION__,
2530 dentry->d_parent->d_name.name,
2531 dentry->d_name.name);
2532 if (page == NULL)
2533 goto out;
2534 devname = nfs_devname(mnt_parent, dentry, page, PAGE_SIZE);
2535 mnt = (struct vfsmount *)devname;
2536 if (IS_ERR(devname))
2537 goto free_page;
2538 mnt = nfs_do_clone_mount(NFS_SB(mnt_parent->mnt_sb), devname, &mountdata);
2539free_page:
2540 free_page((unsigned long)page);
2541out:
2542 dprintk("%s: done\n", __FUNCTION__);
2543 return mnt;
2544}
2545
2546#ifdef CONFIG_NFS_V4
2547/* Check if fs_root is valid */
2548static inline char *nfs4_pathname_string(struct nfs4_pathname *pathname, char *buffer, ssize_t buflen)
2549{
2550 char *end = buffer + buflen;
2551 int n;
2552
2553 *--end = '\0';
2554 buflen--;
2555
2556 n = pathname->ncomponents;
2557 while (--n >= 0) {
2558 struct nfs4_string *component = &pathname->components[n];
2559 buflen -= component->len + 1;
2560 if (buflen < 0)
2561 goto Elong;
2562 end -= component->len;
2563 memcpy(end, component->data, component->len);
2564 *--end = '/';
2565 }
2566 return end;
2567Elong:
2568 return ERR_PTR(-ENAMETOOLONG);
2569}
2570
2571/* Check if the string represents a "valid" IPv4 address */
2572static inline int valid_ipaddr4(const char *buf)
2573{
2574 int rc, count, in[4];
2575
2576 rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
2577 if (rc != 4)
2578 return -EINVAL;
2579 for (count = 0; count < 4; count++) {
2580 if (in[count] > 255)
2581 return -EINVAL;
2582 }
2583 return 0;
2584}
2585
2586static struct super_block *nfs4_referral_sb(struct nfs_server *server, struct nfs_clone_mount *data)
2587{
2588 struct super_block *sb = ERR_PTR(-ENOMEM);
2589 int len;
2590
2591 len = strlen(data->mnt_path) + 1;
2592 server->mnt_path = kmalloc(len, GFP_KERNEL);
2593 if (server->mnt_path == NULL)
2594 goto err;
2595 memcpy(server->mnt_path, data->mnt_path, len);
2596 memcpy(&server->addr, data->addr, sizeof(struct sockaddr_in));
2597
2598 sb = sget(&nfs4_fs_type, nfs4_compare_super, nfs_set_super, server);
2599 if (IS_ERR(sb) || sb->s_root)
2600 goto free_path;
2601 return sb;
2602free_path:
2603 kfree(server->mnt_path);
2604err:
2605 server->mnt_path = NULL;
2606 return sb;
2607}
2608
2609static struct nfs_server *nfs4_referral_server(struct super_block *sb, struct nfs_clone_mount *data)
2610{
2611 struct nfs_server *server = NFS_SB(sb);
2612 struct rpc_timeout timeparms;
2613 int proto, timeo, retrans;
2614 void *err;
2615
2616 proto = IPPROTO_TCP;
2617 /* Since we are following a referral and there may be alternatives,
2618 set the timeouts and retries to low values */
2619 timeo = 2;
2620 retrans = 1;
2621 nfs_init_timeout_values(&timeparms, proto, timeo, retrans);
2622
2623 server->client = nfs4_create_client(server, &timeparms, proto, data->authflavor);
2624 if (IS_ERR((err = server->client)))
2625 goto out_err;
2626
2627 sb->s_time_gran = 1;
2628 sb->s_op = &nfs4_sops;
2629 err = ERR_PTR(nfs_sb_init(sb, data->authflavor));
2630 if (!IS_ERR(err))
2631 return server;
2632out_err:
2633 return (struct nfs_server *)err;
2634}
2635
2636static struct super_block *nfs_referral_nfs4_sb(struct file_system_type *fs_type,
2637 int flags, const char *dev_name, void *raw_data)
2638{
2639 struct nfs_clone_mount *data = raw_data;
2640 return nfs_clone_generic_sb(data, nfs4_referral_sb, nfs4_referral_server);
2641}
2642
2643static struct file_system_type nfs_referral_nfs4_fs_type = {
2644 .owner = THIS_MODULE,
2645 .name = "nfs4",
2646 .get_sb = nfs_referral_nfs4_sb,
2647 .kill_sb = nfs4_kill_super,
2648 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
2649};
2650
2651/**
2652 * nfs_follow_referral - set up mountpoint when hitting a referral on moved error
2653 * @mnt_parent - mountpoint of parent directory
2654 * @dentry - parent directory
2655 * @fspath - fs path returned in fs_locations
2656 * @mntpath - mount path to new server
2657 * @hostname - hostname of new server
2658 * @addr - host addr of new server
2659 *
2660 */
2661struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
2662 const struct dentry *dentry, struct nfs4_fs_locations *locations)
2663{
2664 struct vfsmount *mnt = ERR_PTR(-ENOENT);
2665 struct nfs_clone_mount mountdata = {
2666 .sb = mnt_parent->mnt_sb,
2667 .dentry = dentry,
2668 .authflavor = NFS_SB(mnt_parent->mnt_sb)->client->cl_auth->au_flavor,
2669 };
2670 char *page, *page2;
2671 char *path, *fs_path;
2672 char *devname;
2673 int loc, s;
2674
2675 if (locations == NULL || locations->nlocations <= 0)
2676 goto out;
2677
2678 dprintk("%s: referral at %s/%s\n", __FUNCTION__,
2679 dentry->d_parent->d_name.name, dentry->d_name.name);
2680
2681 /* Ensure fs path is a prefix of current dentry path */
2682 page = (char *) __get_free_page(GFP_USER);
2683 if (page == NULL)
2684 goto out;
2685 page2 = (char *) __get_free_page(GFP_USER);
2686 if (page2 == NULL)
2687 goto out;
2688
2689 path = nfs4_path(dentry, page, PAGE_SIZE);
2690 if (IS_ERR(path))
2691 goto out_free;
2692
2693 fs_path = nfs4_pathname_string(&locations->fs_path, page2, PAGE_SIZE);
2694 if (IS_ERR(fs_path))
2695 goto out_free;
2696
2697 if (strncmp(path, fs_path, strlen(fs_path)) != 0) {
2698 dprintk("%s: path %s does not begin with fsroot %s\n", __FUNCTION__, path, fs_path);
2699 goto out_free;
2700 }
2701
2702 devname = nfs_devname(mnt_parent, dentry, page, PAGE_SIZE);
2703 if (IS_ERR(devname)) {
2704 mnt = (struct vfsmount *)devname;
2705 goto out_free;
2706 }
2707
2708 loc = 0;
2709 while (loc < locations->nlocations && IS_ERR(mnt)) {
2710 struct nfs4_fs_location *location = &locations->locations[loc];
2711 char *mnt_path;
2712
2713 if (location == NULL || location->nservers <= 0 ||
2714 location->rootpath.ncomponents == 0) {
2715 loc++;
2716 continue;
2717 }
2718
2719 mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE);
2720 if (IS_ERR(mnt_path)) {
2721 loc++;
2722 continue;
2723 }
2724 mountdata.mnt_path = mnt_path;
2725
2726 s = 0;
2727 while (s < location->nservers) {
2728 struct sockaddr_in addr = {};
2729
2730 if (location->servers[s].len <= 0 ||
2731 valid_ipaddr4(location->servers[s].data) < 0) {
2732 s++;
2733 continue;
2734 }
2735
2736 mountdata.hostname = location->servers[s].data;
2737 addr.sin_addr.s_addr = in_aton(mountdata.hostname);
2738 addr.sin_family = AF_INET;
2739 addr.sin_port = htons(NFS_PORT);
2740 mountdata.addr = &addr;
2741
2742 mnt = vfs_kern_mount(&nfs_referral_nfs4_fs_type, 0, devname, &mountdata);
2743 if (!IS_ERR(mnt)) {
2744 break;
2745 }
2746 s++;
2747 }
2748 loc++;
2749 }
2750
2751out_free:
2752 free_page((unsigned long)page);
2753 free_page((unsigned long)page2);
2754out:
2755 dprintk("%s: done\n", __FUNCTION__);
2756 return mnt;
2757}
2758
2759/*
2760 * nfs_do_refmount - handle crossing a referral on server
2761 * @dentry - dentry of referral
2762 * @nd - nameidata info
2763 *
2764 */
2765struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry)
2766{
2767 struct vfsmount *mnt = ERR_PTR(-ENOENT);
2768 struct dentry *parent;
2769 struct nfs4_fs_locations *fs_locations = NULL;
2770 struct page *page;
2771 int err;
2772
2773 /* BUG_ON(IS_ROOT(dentry)); */
2774 dprintk("%s: enter\n", __FUNCTION__);
2775
2776 page = alloc_page(GFP_KERNEL);
2777 if (page == NULL)
2778 goto out;
2779
2780 fs_locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL);
2781 if (fs_locations == NULL)
2782 goto out_free;
2783
2784 /* Get locations */
2785 parent = dget_parent(dentry);
2786 dprintk("%s: getting locations for %s/%s\n", __FUNCTION__, parent->d_name.name, dentry->d_name.name);
2787 err = nfs4_proc_fs_locations(parent->d_inode, dentry, fs_locations, page);
2788 dput(parent);
2789 if (err != 0 || fs_locations->nlocations <= 0 ||
2790 fs_locations->fs_path.ncomponents <= 0)
2791 goto out_free;
2792
2793 mnt = nfs_follow_referral(mnt_parent, dentry, fs_locations);
2794out_free:
2795 __free_page(page);
2796 kfree(fs_locations);
2797out:
2798 dprintk("%s: done\n", __FUNCTION__);
2799 return mnt;
2800}
2801#else
2802struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry)
2803{
2804 return ERR_PTR(-ENOENT);
2805}
2806#endif
2807
2808extern int nfs_init_nfspagecache(void);
2809extern void nfs_destroy_nfspagecache(void);
2810extern int nfs_init_readpagecache(void);
2811extern void nfs_destroy_readpagecache(void);
2812extern int nfs_init_writepagecache(void);
2813extern void nfs_destroy_writepagecache(void);
2814#ifdef CONFIG_NFS_DIRECTIO
2815extern int nfs_init_directcache(void);
2816extern void nfs_destroy_directcache(void);
2817#endif
2818
2819static kmem_cache_t * nfs_inode_cachep;
2820
2821static struct inode *nfs_alloc_inode(struct super_block *sb)
2822{ 1069{
2823 struct nfs_inode *nfsi; 1070 struct nfs_inode *nfsi;
2824 nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, SLAB_KERNEL); 1071 nfsi = (struct nfs_inode *)kmem_cache_alloc(nfs_inode_cachep, SLAB_KERNEL);
@@ -2837,11 +1084,19 @@ static struct inode *nfs_alloc_inode(struct super_block *sb)
2837 return &nfsi->vfs_inode; 1084 return &nfsi->vfs_inode;
2838} 1085}
2839 1086
2840static void nfs_destroy_inode(struct inode *inode) 1087void nfs_destroy_inode(struct inode *inode)
2841{ 1088{
2842 kmem_cache_free(nfs_inode_cachep, NFS_I(inode)); 1089 kmem_cache_free(nfs_inode_cachep, NFS_I(inode));
2843} 1090}
2844 1091
1092#define nfs4_init_once(nfsi) \
1093 do { \
1094 INIT_LIST_HEAD(&(nfsi)->open_states); \
1095 nfsi->delegation = NULL; \
1096 nfsi->delegation_state = 0; \
1097 init_rwsem(&nfsi->rwsem); \
1098 } while(0)
1099
2845static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags) 1100static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
2846{ 1101{
2847 struct nfs_inode *nfsi = (struct nfs_inode *) foo; 1102 struct nfs_inode *nfsi = (struct nfs_inode *) foo;
@@ -2862,7 +1117,7 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
2862 } 1117 }
2863} 1118}
2864 1119
2865static int nfs_init_inodecache(void) 1120static int __init nfs_init_inodecache(void)
2866{ 1121{
2867 nfs_inode_cachep = kmem_cache_create("nfs_inode_cache", 1122 nfs_inode_cachep = kmem_cache_create("nfs_inode_cache",
2868 sizeof(struct nfs_inode), 1123 sizeof(struct nfs_inode),
@@ -2875,7 +1130,7 @@ static int nfs_init_inodecache(void)
2875 return 0; 1130 return 0;
2876} 1131}
2877 1132
2878static void nfs_destroy_inodecache(void) 1133static void __exit nfs_destroy_inodecache(void)
2879{ 1134{
2880 if (kmem_cache_destroy(nfs_inode_cachep)) 1135 if (kmem_cache_destroy(nfs_inode_cachep))
2881 printk(KERN_INFO "nfs_inode_cache: not all structures were freed\n"); 1136 printk(KERN_INFO "nfs_inode_cache: not all structures were freed\n");
@@ -2904,29 +1159,22 @@ static int __init init_nfs_fs(void)
2904 if (err) 1159 if (err)
2905 goto out1; 1160 goto out1;
2906 1161
2907#ifdef CONFIG_NFS_DIRECTIO
2908 err = nfs_init_directcache(); 1162 err = nfs_init_directcache();
2909 if (err) 1163 if (err)
2910 goto out0; 1164 goto out0;
2911#endif
2912 1165
2913#ifdef CONFIG_PROC_FS 1166#ifdef CONFIG_PROC_FS
2914 rpc_proc_register(&nfs_rpcstat); 1167 rpc_proc_register(&nfs_rpcstat);
2915#endif 1168#endif
2916 err = register_filesystem(&nfs_fs_type); 1169 if ((err = register_nfs_fs()) != 0)
2917 if (err)
2918 goto out;
2919 if ((err = register_nfs4fs()) != 0)
2920 goto out; 1170 goto out;
2921 return 0; 1171 return 0;
2922out: 1172out:
2923#ifdef CONFIG_PROC_FS 1173#ifdef CONFIG_PROC_FS
2924 rpc_proc_unregister("nfs"); 1174 rpc_proc_unregister("nfs");
2925#endif 1175#endif
2926#ifdef CONFIG_NFS_DIRECTIO
2927 nfs_destroy_directcache(); 1176 nfs_destroy_directcache();
2928out0: 1177out0:
2929#endif
2930 nfs_destroy_writepagecache(); 1178 nfs_destroy_writepagecache();
2931out1: 1179out1:
2932 nfs_destroy_readpagecache(); 1180 nfs_destroy_readpagecache();
@@ -2940,9 +1188,7 @@ out4:
2940 1188
2941static void __exit exit_nfs_fs(void) 1189static void __exit exit_nfs_fs(void)
2942{ 1190{
2943#ifdef CONFIG_NFS_DIRECTIO
2944 nfs_destroy_directcache(); 1191 nfs_destroy_directcache();
2945#endif
2946 nfs_destroy_writepagecache(); 1192 nfs_destroy_writepagecache();
2947 nfs_destroy_readpagecache(); 1193 nfs_destroy_readpagecache();
2948 nfs_destroy_inodecache(); 1194 nfs_destroy_inodecache();
@@ -2950,8 +1196,7 @@ static void __exit exit_nfs_fs(void)
2950#ifdef CONFIG_PROC_FS 1196#ifdef CONFIG_PROC_FS
2951 rpc_proc_unregister("nfs"); 1197 rpc_proc_unregister("nfs");
2952#endif 1198#endif
2953 unregister_filesystem(&nfs_fs_type); 1199 unregister_nfs_fs();
2954 unregister_nfs4fs();
2955} 1200}
2956 1201
2957/* Not quite true; I just maintain it */ 1202/* Not quite true; I just maintain it */