NFS: Switch from intr mount option to TASK_KILLABLE
[linux-2.6/mini2440.git] / fs / nfs / super.c
blob5b6339f70a4cfb65f9b6d17850392b20a93f2706
1 /*
2 * linux/fs/nfs/super.c
4 * Copyright (C) 1992 Rick Sladkey
6 * nfs superblock handling functions
8 * Modularised by Alan Cox <Alan.Cox@linux.org>, while hacking some
9 * experimental NFS changes. Modularisation taken straight from SYS5 fs.
11 * Change to nfs_read_super() to permit NFS mounts to multi-homed hosts.
12 * J.S.Peatfield@damtp.cam.ac.uk
14 * Split from inode.c by David Howells <dhowells@redhat.com>
16 * - superblocks are indexed on server only - all inodes, dentries, etc. associated with a
17 * particular server are held in the same superblock
18 * - NFS superblocks can have several effective roots to the dentry tree
19 * - directory type roots are spliced into the tree when a path from one root reaches the root
20 * of another (see nfs_lookup())
23 #include <linux/module.h>
24 #include <linux/init.h>
26 #include <linux/time.h>
27 #include <linux/kernel.h>
28 #include <linux/mm.h>
29 #include <linux/string.h>
30 #include <linux/stat.h>
31 #include <linux/errno.h>
32 #include <linux/unistd.h>
33 #include <linux/sunrpc/clnt.h>
34 #include <linux/sunrpc/stats.h>
35 #include <linux/sunrpc/metrics.h>
36 #include <linux/sunrpc/xprtsock.h>
37 #include <linux/sunrpc/xprtrdma.h>
38 #include <linux/nfs_fs.h>
39 #include <linux/nfs_mount.h>
40 #include <linux/nfs4_mount.h>
41 #include <linux/lockd/bind.h>
42 #include <linux/smp_lock.h>
43 #include <linux/seq_file.h>
44 #include <linux/mount.h>
45 #include <linux/nfs_idmap.h>
46 #include <linux/vfs.h>
47 #include <linux/inet.h>
48 #include <linux/nfs_xdr.h>
49 #include <linux/magic.h>
50 #include <linux/parser.h>
52 #include <asm/system.h>
53 #include <asm/uaccess.h>
55 #include "nfs4_fs.h"
56 #include "callback.h"
57 #include "delegation.h"
58 #include "iostat.h"
59 #include "internal.h"
61 #define NFSDBG_FACILITY NFSDBG_VFS
63 enum {
64 /* Mount options that take no arguments */
65 Opt_soft, Opt_hard,
66 Opt_intr, Opt_nointr,
67 Opt_posix, Opt_noposix,
68 Opt_cto, Opt_nocto,
69 Opt_ac, Opt_noac,
70 Opt_lock, Opt_nolock,
71 Opt_v2, Opt_v3,
72 Opt_udp, Opt_tcp, Opt_rdma,
73 Opt_acl, Opt_noacl,
74 Opt_rdirplus, Opt_nordirplus,
75 Opt_sharecache, Opt_nosharecache,
77 /* Mount options that take integer arguments */
78 Opt_port,
79 Opt_rsize, Opt_wsize, Opt_bsize,
80 Opt_timeo, Opt_retrans,
81 Opt_acregmin, Opt_acregmax,
82 Opt_acdirmin, Opt_acdirmax,
83 Opt_actimeo,
84 Opt_namelen,
85 Opt_mountport,
86 Opt_mountprog, Opt_mountvers,
87 Opt_nfsprog, Opt_nfsvers,
89 /* Mount options that take string arguments */
90 Opt_sec, Opt_proto, Opt_mountproto,
91 Opt_addr, Opt_mountaddr, Opt_clientaddr,
93 /* Mount options that are ignored */
94 Opt_userspace, Opt_deprecated,
96 Opt_err
99 static match_table_t nfs_mount_option_tokens = {
100 { Opt_userspace, "bg" },
101 { Opt_userspace, "fg" },
102 { Opt_soft, "soft" },
103 { Opt_hard, "hard" },
104 { Opt_intr, "intr" },
105 { Opt_nointr, "nointr" },
106 { Opt_posix, "posix" },
107 { Opt_noposix, "noposix" },
108 { Opt_cto, "cto" },
109 { Opt_nocto, "nocto" },
110 { Opt_ac, "ac" },
111 { Opt_noac, "noac" },
112 { Opt_lock, "lock" },
113 { Opt_nolock, "nolock" },
114 { Opt_v2, "v2" },
115 { Opt_v3, "v3" },
116 { Opt_udp, "udp" },
117 { Opt_tcp, "tcp" },
118 { Opt_rdma, "rdma" },
119 { Opt_acl, "acl" },
120 { Opt_noacl, "noacl" },
121 { Opt_rdirplus, "rdirplus" },
122 { Opt_nordirplus, "nordirplus" },
123 { Opt_sharecache, "sharecache" },
124 { Opt_nosharecache, "nosharecache" },
126 { Opt_port, "port=%u" },
127 { Opt_rsize, "rsize=%u" },
128 { Opt_wsize, "wsize=%u" },
129 { Opt_bsize, "bsize=%u" },
130 { Opt_timeo, "timeo=%u" },
131 { Opt_retrans, "retrans=%u" },
132 { Opt_acregmin, "acregmin=%u" },
133 { Opt_acregmax, "acregmax=%u" },
134 { Opt_acdirmin, "acdirmin=%u" },
135 { Opt_acdirmax, "acdirmax=%u" },
136 { Opt_actimeo, "actimeo=%u" },
137 { Opt_userspace, "retry=%u" },
138 { Opt_namelen, "namlen=%u" },
139 { Opt_mountport, "mountport=%u" },
140 { Opt_mountprog, "mountprog=%u" },
141 { Opt_mountvers, "mountvers=%u" },
142 { Opt_nfsprog, "nfsprog=%u" },
143 { Opt_nfsvers, "nfsvers=%u" },
144 { Opt_nfsvers, "vers=%u" },
146 { Opt_sec, "sec=%s" },
147 { Opt_proto, "proto=%s" },
148 { Opt_mountproto, "mountproto=%s" },
149 { Opt_addr, "addr=%s" },
150 { Opt_clientaddr, "clientaddr=%s" },
151 { Opt_userspace, "mounthost=%s" },
152 { Opt_mountaddr, "mountaddr=%s" },
154 { Opt_err, NULL }
157 enum {
158 Opt_xprt_udp, Opt_xprt_tcp, Opt_xprt_rdma,
160 Opt_xprt_err
163 static match_table_t nfs_xprt_protocol_tokens = {
164 { Opt_xprt_udp, "udp" },
165 { Opt_xprt_tcp, "tcp" },
166 { Opt_xprt_rdma, "rdma" },
168 { Opt_xprt_err, NULL }
171 enum {
172 Opt_sec_none, Opt_sec_sys,
173 Opt_sec_krb5, Opt_sec_krb5i, Opt_sec_krb5p,
174 Opt_sec_lkey, Opt_sec_lkeyi, Opt_sec_lkeyp,
175 Opt_sec_spkm, Opt_sec_spkmi, Opt_sec_spkmp,
177 Opt_sec_err
180 static match_table_t nfs_secflavor_tokens = {
181 { Opt_sec_none, "none" },
182 { Opt_sec_none, "null" },
183 { Opt_sec_sys, "sys" },
185 { Opt_sec_krb5, "krb5" },
186 { Opt_sec_krb5i, "krb5i" },
187 { Opt_sec_krb5p, "krb5p" },
189 { Opt_sec_lkey, "lkey" },
190 { Opt_sec_lkeyi, "lkeyi" },
191 { Opt_sec_lkeyp, "lkeyp" },
193 { Opt_sec_err, NULL }
197 static void nfs_umount_begin(struct vfsmount *, int);
198 static int nfs_statfs(struct dentry *, struct kstatfs *);
199 static int nfs_show_options(struct seq_file *, struct vfsmount *);
200 static int nfs_show_stats(struct seq_file *, struct vfsmount *);
201 static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *);
202 static int nfs_xdev_get_sb(struct file_system_type *fs_type,
203 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
204 static void nfs_kill_super(struct super_block *);
206 static struct file_system_type nfs_fs_type = {
207 .owner = THIS_MODULE,
208 .name = "nfs",
209 .get_sb = nfs_get_sb,
210 .kill_sb = nfs_kill_super,
211 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
214 struct file_system_type nfs_xdev_fs_type = {
215 .owner = THIS_MODULE,
216 .name = "nfs",
217 .get_sb = nfs_xdev_get_sb,
218 .kill_sb = nfs_kill_super,
219 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
222 static const struct super_operations nfs_sops = {
223 .alloc_inode = nfs_alloc_inode,
224 .destroy_inode = nfs_destroy_inode,
225 .write_inode = nfs_write_inode,
226 .statfs = nfs_statfs,
227 .clear_inode = nfs_clear_inode,
228 .umount_begin = nfs_umount_begin,
229 .show_options = nfs_show_options,
230 .show_stats = nfs_show_stats,
233 #ifdef CONFIG_NFS_V4
234 static int nfs4_get_sb(struct file_system_type *fs_type,
235 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
236 static int nfs4_xdev_get_sb(struct file_system_type *fs_type,
237 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
238 static int nfs4_referral_get_sb(struct file_system_type *fs_type,
239 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
240 static void nfs4_kill_super(struct super_block *sb);
242 static struct file_system_type nfs4_fs_type = {
243 .owner = THIS_MODULE,
244 .name = "nfs4",
245 .get_sb = nfs4_get_sb,
246 .kill_sb = nfs4_kill_super,
247 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
250 struct file_system_type nfs4_xdev_fs_type = {
251 .owner = THIS_MODULE,
252 .name = "nfs4",
253 .get_sb = nfs4_xdev_get_sb,
254 .kill_sb = nfs4_kill_super,
255 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
258 struct file_system_type nfs4_referral_fs_type = {
259 .owner = THIS_MODULE,
260 .name = "nfs4",
261 .get_sb = nfs4_referral_get_sb,
262 .kill_sb = nfs4_kill_super,
263 .fs_flags = FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
266 static const struct super_operations nfs4_sops = {
267 .alloc_inode = nfs_alloc_inode,
268 .destroy_inode = nfs_destroy_inode,
269 .write_inode = nfs_write_inode,
270 .statfs = nfs_statfs,
271 .clear_inode = nfs4_clear_inode,
272 .umount_begin = nfs_umount_begin,
273 .show_options = nfs_show_options,
274 .show_stats = nfs_show_stats,
276 #endif
278 static struct shrinker acl_shrinker = {
279 .shrink = nfs_access_cache_shrinker,
280 .seeks = DEFAULT_SEEKS,
284 * Register the NFS filesystems
286 int __init register_nfs_fs(void)
288 int ret;
290 ret = register_filesystem(&nfs_fs_type);
291 if (ret < 0)
292 goto error_0;
294 ret = nfs_register_sysctl();
295 if (ret < 0)
296 goto error_1;
297 #ifdef CONFIG_NFS_V4
298 ret = register_filesystem(&nfs4_fs_type);
299 if (ret < 0)
300 goto error_2;
301 #endif
302 register_shrinker(&acl_shrinker);
303 return 0;
305 #ifdef CONFIG_NFS_V4
306 error_2:
307 nfs_unregister_sysctl();
308 #endif
309 error_1:
310 unregister_filesystem(&nfs_fs_type);
311 error_0:
312 return ret;
316 * Unregister the NFS filesystems
318 void __exit unregister_nfs_fs(void)
320 unregister_shrinker(&acl_shrinker);
321 #ifdef CONFIG_NFS_V4
322 unregister_filesystem(&nfs4_fs_type);
323 #endif
324 nfs_unregister_sysctl();
325 unregister_filesystem(&nfs_fs_type);
329 * Deliver file system statistics to userspace
331 static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
333 struct nfs_server *server = NFS_SB(dentry->d_sb);
334 unsigned char blockbits;
335 unsigned long blockres;
336 struct nfs_fh *fh = NFS_FH(dentry->d_inode);
337 struct nfs_fattr fattr;
338 struct nfs_fsstat res = {
339 .fattr = &fattr,
341 int error;
343 lock_kernel();
345 error = server->nfs_client->rpc_ops->statfs(server, fh, &res);
346 if (error < 0)
347 goto out_err;
348 buf->f_type = NFS_SUPER_MAGIC;
351 * Current versions of glibc do not correctly handle the
352 * case where f_frsize != f_bsize. Eventually we want to
353 * report the value of wtmult in this field.
355 buf->f_frsize = dentry->d_sb->s_blocksize;
358 * On most *nix systems, f_blocks, f_bfree, and f_bavail
359 * are reported in units of f_frsize. Linux hasn't had
360 * an f_frsize field in its statfs struct until recently,
361 * thus historically Linux's sys_statfs reports these
362 * fields in units of f_bsize.
364 buf->f_bsize = dentry->d_sb->s_blocksize;
365 blockbits = dentry->d_sb->s_blocksize_bits;
366 blockres = (1 << blockbits) - 1;
367 buf->f_blocks = (res.tbytes + blockres) >> blockbits;
368 buf->f_bfree = (res.fbytes + blockres) >> blockbits;
369 buf->f_bavail = (res.abytes + blockres) >> blockbits;
371 buf->f_files = res.tfiles;
372 buf->f_ffree = res.afiles;
374 buf->f_namelen = server->namelen;
376 unlock_kernel();
377 return 0;
379 out_err:
380 dprintk("%s: statfs error = %d\n", __FUNCTION__, -error);
381 unlock_kernel();
382 return error;
386 * Map the security flavour number to a name
388 static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour)
390 static const struct {
391 rpc_authflavor_t flavour;
392 const char *str;
393 } sec_flavours[] = {
394 { RPC_AUTH_NULL, "null" },
395 { RPC_AUTH_UNIX, "sys" },
396 { RPC_AUTH_GSS_KRB5, "krb5" },
397 { RPC_AUTH_GSS_KRB5I, "krb5i" },
398 { RPC_AUTH_GSS_KRB5P, "krb5p" },
399 { RPC_AUTH_GSS_LKEY, "lkey" },
400 { RPC_AUTH_GSS_LKEYI, "lkeyi" },
401 { RPC_AUTH_GSS_LKEYP, "lkeyp" },
402 { RPC_AUTH_GSS_SPKM, "spkm" },
403 { RPC_AUTH_GSS_SPKMI, "spkmi" },
404 { RPC_AUTH_GSS_SPKMP, "spkmp" },
405 { UINT_MAX, "unknown" }
407 int i;
409 for (i = 0; sec_flavours[i].flavour != UINT_MAX; i++) {
410 if (sec_flavours[i].flavour == flavour)
411 break;
413 return sec_flavours[i].str;
417 * Describe the mount options in force on this server representation
419 static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, int showdefaults)
421 static const struct proc_nfs_info {
422 int flag;
423 const char *str;
424 const char *nostr;
425 } nfs_info[] = {
426 { NFS_MOUNT_SOFT, ",soft", ",hard" },
427 { NFS_MOUNT_NOCTO, ",nocto", "" },
428 { NFS_MOUNT_NOAC, ",noac", "" },
429 { NFS_MOUNT_NONLM, ",nolock", "" },
430 { NFS_MOUNT_NOACL, ",noacl", "" },
431 { NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
432 { NFS_MOUNT_UNSHARED, ",nosharecache", ""},
433 { 0, NULL, NULL }
435 const struct proc_nfs_info *nfs_infop;
436 struct nfs_client *clp = nfss->nfs_client;
438 seq_printf(m, ",vers=%d", clp->rpc_ops->version);
439 seq_printf(m, ",rsize=%d", nfss->rsize);
440 seq_printf(m, ",wsize=%d", nfss->wsize);
441 if (nfss->acregmin != 3*HZ || showdefaults)
442 seq_printf(m, ",acregmin=%d", nfss->acregmin/HZ);
443 if (nfss->acregmax != 60*HZ || showdefaults)
444 seq_printf(m, ",acregmax=%d", nfss->acregmax/HZ);
445 if (nfss->acdirmin != 30*HZ || showdefaults)
446 seq_printf(m, ",acdirmin=%d", nfss->acdirmin/HZ);
447 if (nfss->acdirmax != 60*HZ || showdefaults)
448 seq_printf(m, ",acdirmax=%d", nfss->acdirmax/HZ);
449 for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) {
450 if (nfss->flags & nfs_infop->flag)
451 seq_puts(m, nfs_infop->str);
452 else
453 seq_puts(m, nfs_infop->nostr);
455 seq_printf(m, ",proto=%s",
456 rpc_peeraddr2str(nfss->client, RPC_DISPLAY_PROTO));
457 seq_printf(m, ",timeo=%lu", 10U * clp->retrans_timeo / HZ);
458 seq_printf(m, ",retrans=%u", clp->retrans_count);
459 seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor));
463 * Describe the mount options on this VFS mountpoint
465 static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
467 struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
469 nfs_show_mount_options(m, nfss, 0);
471 seq_printf(m, ",addr="NIPQUAD_FMT,
472 NIPQUAD(nfss->nfs_client->cl_addr.sin_addr));
474 return 0;
478 * Present statistical information for this VFS mountpoint
480 static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
482 int i, cpu;
483 struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
484 struct rpc_auth *auth = nfss->client->cl_auth;
485 struct nfs_iostats totals = { };
487 seq_printf(m, "statvers=%s", NFS_IOSTAT_VERS);
490 * Display all mount option settings
492 seq_printf(m, "\n\topts:\t");
493 seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? "ro" : "rw");
494 seq_puts(m, mnt->mnt_sb->s_flags & MS_SYNCHRONOUS ? ",sync" : "");
495 seq_puts(m, mnt->mnt_sb->s_flags & MS_NOATIME ? ",noatime" : "");
496 seq_puts(m, mnt->mnt_sb->s_flags & MS_NODIRATIME ? ",nodiratime" : "");
497 nfs_show_mount_options(m, nfss, 1);
499 seq_printf(m, "\n\tage:\t%lu", (jiffies - nfss->mount_time) / HZ);
501 seq_printf(m, "\n\tcaps:\t");
502 seq_printf(m, "caps=0x%x", nfss->caps);
503 seq_printf(m, ",wtmult=%d", nfss->wtmult);
504 seq_printf(m, ",dtsize=%d", nfss->dtsize);
505 seq_printf(m, ",bsize=%d", nfss->bsize);
506 seq_printf(m, ",namelen=%d", nfss->namelen);
508 #ifdef CONFIG_NFS_V4
509 if (nfss->nfs_client->cl_nfsversion == 4) {
510 seq_printf(m, "\n\tnfsv4:\t");
511 seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]);
512 seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]);
513 seq_printf(m, ",acl=0x%x", nfss->acl_bitmask);
515 #endif
518 * Display security flavor in effect for this mount
520 seq_printf(m, "\n\tsec:\tflavor=%d", auth->au_ops->au_flavor);
521 if (auth->au_flavor)
522 seq_printf(m, ",pseudoflavor=%d", auth->au_flavor);
525 * Display superblock I/O counters
527 for_each_possible_cpu(cpu) {
528 struct nfs_iostats *stats;
530 preempt_disable();
531 stats = per_cpu_ptr(nfss->io_stats, cpu);
533 for (i = 0; i < __NFSIOS_COUNTSMAX; i++)
534 totals.events[i] += stats->events[i];
535 for (i = 0; i < __NFSIOS_BYTESMAX; i++)
536 totals.bytes[i] += stats->bytes[i];
538 preempt_enable();
541 seq_printf(m, "\n\tevents:\t");
542 for (i = 0; i < __NFSIOS_COUNTSMAX; i++)
543 seq_printf(m, "%lu ", totals.events[i]);
544 seq_printf(m, "\n\tbytes:\t");
545 for (i = 0; i < __NFSIOS_BYTESMAX; i++)
546 seq_printf(m, "%Lu ", totals.bytes[i]);
547 seq_printf(m, "\n");
549 rpc_print_iostats(m, nfss->client);
551 return 0;
555 * Begin unmount by attempting to remove all automounted mountpoints we added
556 * in response to xdev traversals and referrals
558 static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags)
560 struct nfs_server *server = NFS_SB(vfsmnt->mnt_sb);
561 struct rpc_clnt *rpc;
563 shrink_submounts(vfsmnt, &nfs_automount_list);
565 if (!(flags & MNT_FORCE))
566 return;
567 /* -EIO all pending I/O */
568 rpc = server->client_acl;
569 if (!IS_ERR(rpc))
570 rpc_killall_tasks(rpc);
571 rpc = server->client;
572 if (!IS_ERR(rpc))
573 rpc_killall_tasks(rpc);
577 * Sanity-check a server address provided by the mount command
579 static int nfs_verify_server_address(struct sockaddr *addr)
581 switch (addr->sa_family) {
582 case AF_INET: {
583 struct sockaddr_in *sa = (struct sockaddr_in *) addr;
584 if (sa->sin_addr.s_addr != INADDR_ANY)
585 return 1;
586 break;
590 return 0;
594 * Error-check and convert a string of mount options from user space into
595 * a data structure
597 static int nfs_parse_mount_options(char *raw,
598 struct nfs_parsed_mount_data *mnt)
600 char *p, *string;
602 if (!raw) {
603 dfprintk(MOUNT, "NFS: mount options string was NULL.\n");
604 return 1;
606 dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw);
608 while ((p = strsep(&raw, ",")) != NULL) {
609 substring_t args[MAX_OPT_ARGS];
610 int option, token;
612 if (!*p)
613 continue;
615 dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", p);
617 token = match_token(p, nfs_mount_option_tokens, args);
618 switch (token) {
619 case Opt_soft:
620 mnt->flags |= NFS_MOUNT_SOFT;
621 break;
622 case Opt_hard:
623 mnt->flags &= ~NFS_MOUNT_SOFT;
624 break;
625 case Opt_intr:
626 case Opt_nointr:
627 break;
628 case Opt_posix:
629 mnt->flags |= NFS_MOUNT_POSIX;
630 break;
631 case Opt_noposix:
632 mnt->flags &= ~NFS_MOUNT_POSIX;
633 break;
634 case Opt_cto:
635 mnt->flags &= ~NFS_MOUNT_NOCTO;
636 break;
637 case Opt_nocto:
638 mnt->flags |= NFS_MOUNT_NOCTO;
639 break;
640 case Opt_ac:
641 mnt->flags &= ~NFS_MOUNT_NOAC;
642 break;
643 case Opt_noac:
644 mnt->flags |= NFS_MOUNT_NOAC;
645 break;
646 case Opt_lock:
647 mnt->flags &= ~NFS_MOUNT_NONLM;
648 break;
649 case Opt_nolock:
650 mnt->flags |= NFS_MOUNT_NONLM;
651 break;
652 case Opt_v2:
653 mnt->flags &= ~NFS_MOUNT_VER3;
654 break;
655 case Opt_v3:
656 mnt->flags |= NFS_MOUNT_VER3;
657 break;
658 case Opt_udp:
659 mnt->flags &= ~NFS_MOUNT_TCP;
660 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
661 mnt->timeo = 7;
662 mnt->retrans = 5;
663 break;
664 case Opt_tcp:
665 mnt->flags |= NFS_MOUNT_TCP;
666 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
667 mnt->timeo = 600;
668 mnt->retrans = 2;
669 break;
670 case Opt_rdma:
671 mnt->flags |= NFS_MOUNT_TCP; /* for side protocols */
672 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
673 mnt->timeo = 600;
674 mnt->retrans = 2;
675 break;
676 case Opt_acl:
677 mnt->flags &= ~NFS_MOUNT_NOACL;
678 break;
679 case Opt_noacl:
680 mnt->flags |= NFS_MOUNT_NOACL;
681 break;
682 case Opt_rdirplus:
683 mnt->flags &= ~NFS_MOUNT_NORDIRPLUS;
684 break;
685 case Opt_nordirplus:
686 mnt->flags |= NFS_MOUNT_NORDIRPLUS;
687 break;
688 case Opt_sharecache:
689 mnt->flags &= ~NFS_MOUNT_UNSHARED;
690 break;
691 case Opt_nosharecache:
692 mnt->flags |= NFS_MOUNT_UNSHARED;
693 break;
695 case Opt_port:
696 if (match_int(args, &option))
697 return 0;
698 if (option < 0 || option > 65535)
699 return 0;
700 mnt->nfs_server.address.sin_port = htons(option);
701 break;
702 case Opt_rsize:
703 if (match_int(args, &mnt->rsize))
704 return 0;
705 break;
706 case Opt_wsize:
707 if (match_int(args, &mnt->wsize))
708 return 0;
709 break;
710 case Opt_bsize:
711 if (match_int(args, &option))
712 return 0;
713 if (option < 0)
714 return 0;
715 mnt->bsize = option;
716 break;
717 case Opt_timeo:
718 if (match_int(args, &mnt->timeo))
719 return 0;
720 break;
721 case Opt_retrans:
722 if (match_int(args, &mnt->retrans))
723 return 0;
724 break;
725 case Opt_acregmin:
726 if (match_int(args, &mnt->acregmin))
727 return 0;
728 break;
729 case Opt_acregmax:
730 if (match_int(args, &mnt->acregmax))
731 return 0;
732 break;
733 case Opt_acdirmin:
734 if (match_int(args, &mnt->acdirmin))
735 return 0;
736 break;
737 case Opt_acdirmax:
738 if (match_int(args, &mnt->acdirmax))
739 return 0;
740 break;
741 case Opt_actimeo:
742 if (match_int(args, &option))
743 return 0;
744 if (option < 0)
745 return 0;
746 mnt->acregmin =
747 mnt->acregmax =
748 mnt->acdirmin =
749 mnt->acdirmax = option;
750 break;
751 case Opt_namelen:
752 if (match_int(args, &mnt->namlen))
753 return 0;
754 break;
755 case Opt_mountport:
756 if (match_int(args, &option))
757 return 0;
758 if (option < 0 || option > 65535)
759 return 0;
760 mnt->mount_server.port = option;
761 break;
762 case Opt_mountprog:
763 if (match_int(args, &option))
764 return 0;
765 if (option < 0)
766 return 0;
767 mnt->mount_server.program = option;
768 break;
769 case Opt_mountvers:
770 if (match_int(args, &option))
771 return 0;
772 if (option < 0)
773 return 0;
774 mnt->mount_server.version = option;
775 break;
776 case Opt_nfsprog:
777 if (match_int(args, &option))
778 return 0;
779 if (option < 0)
780 return 0;
781 mnt->nfs_server.program = option;
782 break;
783 case Opt_nfsvers:
784 if (match_int(args, &option))
785 return 0;
786 switch (option) {
787 case 2:
788 mnt->flags &= ~NFS_MOUNT_VER3;
789 break;
790 case 3:
791 mnt->flags |= NFS_MOUNT_VER3;
792 break;
793 default:
794 goto out_unrec_vers;
796 break;
798 case Opt_sec:
799 string = match_strdup(args);
800 if (string == NULL)
801 goto out_nomem;
802 token = match_token(string, nfs_secflavor_tokens, args);
803 kfree(string);
806 * The flags setting is for v2/v3. The flavor_len
807 * setting is for v4. v2/v3 also need to know the
808 * difference between NULL and UNIX.
810 switch (token) {
811 case Opt_sec_none:
812 mnt->flags &= ~NFS_MOUNT_SECFLAVOUR;
813 mnt->auth_flavor_len = 0;
814 mnt->auth_flavors[0] = RPC_AUTH_NULL;
815 break;
816 case Opt_sec_sys:
817 mnt->flags &= ~NFS_MOUNT_SECFLAVOUR;
818 mnt->auth_flavor_len = 0;
819 mnt->auth_flavors[0] = RPC_AUTH_UNIX;
820 break;
821 case Opt_sec_krb5:
822 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
823 mnt->auth_flavor_len = 1;
824 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5;
825 break;
826 case Opt_sec_krb5i:
827 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
828 mnt->auth_flavor_len = 1;
829 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5I;
830 break;
831 case Opt_sec_krb5p:
832 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
833 mnt->auth_flavor_len = 1;
834 mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5P;
835 break;
836 case Opt_sec_lkey:
837 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
838 mnt->auth_flavor_len = 1;
839 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEY;
840 break;
841 case Opt_sec_lkeyi:
842 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
843 mnt->auth_flavor_len = 1;
844 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYI;
845 break;
846 case Opt_sec_lkeyp:
847 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
848 mnt->auth_flavor_len = 1;
849 mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYP;
850 break;
851 case Opt_sec_spkm:
852 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
853 mnt->auth_flavor_len = 1;
854 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKM;
855 break;
856 case Opt_sec_spkmi:
857 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
858 mnt->auth_flavor_len = 1;
859 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMI;
860 break;
861 case Opt_sec_spkmp:
862 mnt->flags |= NFS_MOUNT_SECFLAVOUR;
863 mnt->auth_flavor_len = 1;
864 mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMP;
865 break;
866 default:
867 goto out_unrec_sec;
869 break;
870 case Opt_proto:
871 string = match_strdup(args);
872 if (string == NULL)
873 goto out_nomem;
874 token = match_token(string,
875 nfs_xprt_protocol_tokens, args);
876 kfree(string);
878 switch (token) {
879 case Opt_xprt_udp:
880 mnt->flags &= ~NFS_MOUNT_TCP;
881 mnt->nfs_server.protocol = XPRT_TRANSPORT_UDP;
882 mnt->timeo = 7;
883 mnt->retrans = 5;
884 break;
885 case Opt_xprt_tcp:
886 mnt->flags |= NFS_MOUNT_TCP;
887 mnt->nfs_server.protocol = XPRT_TRANSPORT_TCP;
888 mnt->timeo = 600;
889 mnt->retrans = 2;
890 break;
891 case Opt_xprt_rdma:
892 /* vector side protocols to TCP */
893 mnt->flags |= NFS_MOUNT_TCP;
894 mnt->nfs_server.protocol = XPRT_TRANSPORT_RDMA;
895 mnt->timeo = 600;
896 mnt->retrans = 2;
897 break;
898 default:
899 goto out_unrec_xprt;
901 break;
902 case Opt_mountproto:
903 string = match_strdup(args);
904 if (string == NULL)
905 goto out_nomem;
906 token = match_token(string,
907 nfs_xprt_protocol_tokens, args);
908 kfree(string);
910 switch (token) {
911 case Opt_xprt_udp:
912 mnt->mount_server.protocol = XPRT_TRANSPORT_UDP;
913 break;
914 case Opt_xprt_tcp:
915 mnt->mount_server.protocol = XPRT_TRANSPORT_TCP;
916 break;
917 case Opt_xprt_rdma: /* not used for side protocols */
918 default:
919 goto out_unrec_xprt;
921 break;
922 case Opt_addr:
923 string = match_strdup(args);
924 if (string == NULL)
925 goto out_nomem;
926 mnt->nfs_server.address.sin_family = AF_INET;
927 mnt->nfs_server.address.sin_addr.s_addr =
928 in_aton(string);
929 kfree(string);
930 break;
931 case Opt_clientaddr:
932 string = match_strdup(args);
933 if (string == NULL)
934 goto out_nomem;
935 mnt->client_address = string;
936 break;
937 case Opt_mountaddr:
938 string = match_strdup(args);
939 if (string == NULL)
940 goto out_nomem;
941 mnt->mount_server.address.sin_family = AF_INET;
942 mnt->mount_server.address.sin_addr.s_addr =
943 in_aton(string);
944 kfree(string);
945 break;
947 case Opt_userspace:
948 case Opt_deprecated:
949 break;
951 default:
952 goto out_unknown;
956 return 1;
958 out_nomem:
959 printk(KERN_INFO "NFS: not enough memory to parse option\n");
960 return 0;
962 out_unrec_vers:
963 printk(KERN_INFO "NFS: unrecognized NFS version number\n");
964 return 0;
966 out_unrec_xprt:
967 printk(KERN_INFO "NFS: unrecognized transport protocol\n");
968 return 0;
970 out_unrec_sec:
971 printk(KERN_INFO "NFS: unrecognized security flavor\n");
972 return 0;
974 out_unknown:
975 printk(KERN_INFO "NFS: unknown mount option: %s\n", p);
976 return 0;
980 * Use the remote server's MOUNT service to request the NFS file handle
981 * corresponding to the provided path.
983 static int nfs_try_mount(struct nfs_parsed_mount_data *args,
984 struct nfs_fh *root_fh)
986 struct sockaddr_in sin;
987 int status;
989 if (args->mount_server.version == 0) {
990 if (args->flags & NFS_MOUNT_VER3)
991 args->mount_server.version = NFS_MNT3_VERSION;
992 else
993 args->mount_server.version = NFS_MNT_VERSION;
997 * Construct the mount server's address.
999 if (args->mount_server.address.sin_addr.s_addr != INADDR_ANY)
1000 sin = args->mount_server.address;
1001 else
1002 sin = args->nfs_server.address;
1004 * autobind will be used if mount_server.port == 0
1006 sin.sin_port = htons(args->mount_server.port);
1009 * Now ask the mount server to map our export path
1010 * to a file handle.
1012 status = nfs_mount((struct sockaddr *) &sin,
1013 sizeof(sin),
1014 args->nfs_server.hostname,
1015 args->nfs_server.export_path,
1016 args->mount_server.version,
1017 args->mount_server.protocol,
1018 root_fh);
1019 if (status == 0)
1020 return 0;
1022 dfprintk(MOUNT, "NFS: unable to mount server " NIPQUAD_FMT
1023 ", error %d\n", NIPQUAD(sin.sin_addr.s_addr), status);
1024 return status;
1028 * Validate the NFS2/NFS3 mount data
1029 * - fills in the mount root filehandle
1031 * For option strings, user space handles the following behaviors:
1033 * + DNS: mapping server host name to IP address ("addr=" option)
1035 * + failure mode: how to behave if a mount request can't be handled
1036 * immediately ("fg/bg" option)
1038 * + retry: how often to retry a mount request ("retry=" option)
1040 * + breaking back: trying proto=udp after proto=tcp, v2 after v3,
1041 * mountproto=tcp after mountproto=udp, and so on
1043 * XXX: as far as I can tell, changing the NFS program number is not
1044 * supported in the NFS client.
1046 static int nfs_validate_mount_data(void *options,
1047 struct nfs_parsed_mount_data *args,
1048 struct nfs_fh *mntfh,
1049 const char *dev_name)
1051 struct nfs_mount_data *data = (struct nfs_mount_data *)options;
1053 memset(args, 0, sizeof(*args));
1055 if (data == NULL)
1056 goto out_no_data;
1058 args->flags = (NFS_MOUNT_VER3 | NFS_MOUNT_TCP);
1059 args->rsize = NFS_MAX_FILE_IO_SIZE;
1060 args->wsize = NFS_MAX_FILE_IO_SIZE;
1061 args->timeo = 600;
1062 args->retrans = 2;
1063 args->acregmin = 3;
1064 args->acregmax = 60;
1065 args->acdirmin = 30;
1066 args->acdirmax = 60;
1067 args->mount_server.protocol = XPRT_TRANSPORT_UDP;
1068 args->mount_server.program = NFS_MNT_PROGRAM;
1069 args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
1070 args->nfs_server.program = NFS_PROGRAM;
1072 switch (data->version) {
1073 case 1:
1074 data->namlen = 0;
1075 case 2:
1076 data->bsize = 0;
1077 case 3:
1078 if (data->flags & NFS_MOUNT_VER3)
1079 goto out_no_v3;
1080 data->root.size = NFS2_FHSIZE;
1081 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
1082 case 4:
1083 if (data->flags & NFS_MOUNT_SECFLAVOUR)
1084 goto out_no_sec;
1085 case 5:
1086 memset(data->context, 0, sizeof(data->context));
1087 case 6:
1088 if (data->flags & NFS_MOUNT_VER3)
1089 mntfh->size = data->root.size;
1090 else
1091 mntfh->size = NFS2_FHSIZE;
1093 if (mntfh->size > sizeof(mntfh->data))
1094 goto out_invalid_fh;
1096 memcpy(mntfh->data, data->root.data, mntfh->size);
1097 if (mntfh->size < sizeof(mntfh->data))
1098 memset(mntfh->data + mntfh->size, 0,
1099 sizeof(mntfh->data) - mntfh->size);
1101 if (!nfs_verify_server_address((struct sockaddr *) &data->addr))
1102 goto out_no_address;
1105 * Translate to nfs_parsed_mount_data, which nfs_fill_super
1106 * can deal with.
1108 args->flags = data->flags;
1109 args->rsize = data->rsize;
1110 args->wsize = data->wsize;
1111 args->flags = data->flags;
1112 args->timeo = data->timeo;
1113 args->retrans = data->retrans;
1114 args->acregmin = data->acregmin;
1115 args->acregmax = data->acregmax;
1116 args->acdirmin = data->acdirmin;
1117 args->acdirmax = data->acdirmax;
1118 args->nfs_server.address = data->addr;
1119 if (!(data->flags & NFS_MOUNT_TCP))
1120 args->nfs_server.protocol = XPRT_TRANSPORT_UDP;
1121 /* N.B. caller will free nfs_server.hostname in all cases */
1122 args->nfs_server.hostname = kstrdup(data->hostname, GFP_KERNEL);
1123 args->namlen = data->namlen;
1124 args->bsize = data->bsize;
1125 args->auth_flavors[0] = data->pseudoflavor;
1126 break;
1127 default: {
1128 unsigned int len;
1129 char *c;
1130 int status;
1132 if (nfs_parse_mount_options((char *)options, args) == 0)
1133 return -EINVAL;
1135 if (!nfs_verify_server_address((struct sockaddr *)
1136 &args->nfs_server.address))
1137 goto out_no_address;
1139 c = strchr(dev_name, ':');
1140 if (c == NULL)
1141 return -EINVAL;
1142 len = c - dev_name;
1143 /* N.B. caller will free nfs_server.hostname in all cases */
1144 args->nfs_server.hostname = kstrndup(dev_name, len, GFP_KERNEL);
1146 c++;
1147 if (strlen(c) > NFS_MAXPATHLEN)
1148 return -ENAMETOOLONG;
1149 args->nfs_server.export_path = c;
1151 status = nfs_try_mount(args, mntfh);
1152 if (status)
1153 return status;
1155 break;
1159 if (!(args->flags & NFS_MOUNT_SECFLAVOUR))
1160 args->auth_flavors[0] = RPC_AUTH_UNIX;
1162 #ifndef CONFIG_NFS_V3
1163 if (args->flags & NFS_MOUNT_VER3)
1164 goto out_v3_not_compiled;
1165 #endif /* !CONFIG_NFS_V3 */
1167 return 0;
1169 out_no_data:
1170 dfprintk(MOUNT, "NFS: mount program didn't pass any mount data\n");
1171 return -EINVAL;
1173 out_no_v3:
1174 dfprintk(MOUNT, "NFS: nfs_mount_data version %d does not support v3\n",
1175 data->version);
1176 return -EINVAL;
1178 out_no_sec:
1179 dfprintk(MOUNT, "NFS: nfs_mount_data version supports only AUTH_SYS\n");
1180 return -EINVAL;
1182 #ifndef CONFIG_NFS_V3
1183 out_v3_not_compiled:
1184 dfprintk(MOUNT, "NFS: NFSv3 is not compiled into kernel\n");
1185 return -EPROTONOSUPPORT;
1186 #endif /* !CONFIG_NFS_V3 */
1188 out_no_address:
1189 dfprintk(MOUNT, "NFS: mount program didn't pass remote address\n");
1190 return -EINVAL;
1192 out_invalid_fh:
1193 dfprintk(MOUNT, "NFS: invalid root filehandle\n");
1194 return -EINVAL;
1198 * Initialise the common bits of the superblock
1200 static inline void nfs_initialise_sb(struct super_block *sb)
1202 struct nfs_server *server = NFS_SB(sb);
1204 sb->s_magic = NFS_SUPER_MAGIC;
1206 /* We probably want something more informative here */
1207 snprintf(sb->s_id, sizeof(sb->s_id),
1208 "%x:%x", MAJOR(sb->s_dev), MINOR(sb->s_dev));
1210 if (sb->s_blocksize == 0)
1211 sb->s_blocksize = nfs_block_bits(server->wsize,
1212 &sb->s_blocksize_bits);
1214 if (server->flags & NFS_MOUNT_NOAC)
1215 sb->s_flags |= MS_SYNCHRONOUS;
1217 nfs_super_set_maxbytes(sb, server->maxfilesize);
1221 * Finish setting up an NFS2/3 superblock
1223 static void nfs_fill_super(struct super_block *sb,
1224 struct nfs_parsed_mount_data *data)
1226 struct nfs_server *server = NFS_SB(sb);
1228 sb->s_blocksize_bits = 0;
1229 sb->s_blocksize = 0;
1230 if (data->bsize)
1231 sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
1233 if (server->flags & NFS_MOUNT_VER3) {
1234 /* The VFS shouldn't apply the umask to mode bits. We will do
1235 * so ourselves when necessary.
1237 sb->s_flags |= MS_POSIXACL;
1238 sb->s_time_gran = 1;
1241 sb->s_op = &nfs_sops;
1242 nfs_initialise_sb(sb);
1246 * Finish setting up a cloned NFS2/3 superblock
1248 static void nfs_clone_super(struct super_block *sb,
1249 const struct super_block *old_sb)
1251 struct nfs_server *server = NFS_SB(sb);
1253 sb->s_blocksize_bits = old_sb->s_blocksize_bits;
1254 sb->s_blocksize = old_sb->s_blocksize;
1255 sb->s_maxbytes = old_sb->s_maxbytes;
1257 if (server->flags & NFS_MOUNT_VER3) {
1258 /* The VFS shouldn't apply the umask to mode bits. We will do
1259 * so ourselves when necessary.
1261 sb->s_flags |= MS_POSIXACL;
1262 sb->s_time_gran = 1;
1265 sb->s_op = old_sb->s_op;
1266 nfs_initialise_sb(sb);
1269 #define NFS_MS_MASK (MS_RDONLY|MS_NOSUID|MS_NODEV|MS_NOEXEC|MS_SYNCHRONOUS)
1271 static int nfs_compare_mount_options(const struct super_block *s, const struct nfs_server *b, int flags)
1273 const struct nfs_server *a = s->s_fs_info;
1274 const struct rpc_clnt *clnt_a = a->client;
1275 const struct rpc_clnt *clnt_b = b->client;
1277 if ((s->s_flags & NFS_MS_MASK) != (flags & NFS_MS_MASK))
1278 goto Ebusy;
1279 if (a->nfs_client != b->nfs_client)
1280 goto Ebusy;
1281 if (a->flags != b->flags)
1282 goto Ebusy;
1283 if (a->wsize != b->wsize)
1284 goto Ebusy;
1285 if (a->rsize != b->rsize)
1286 goto Ebusy;
1287 if (a->acregmin != b->acregmin)
1288 goto Ebusy;
1289 if (a->acregmax != b->acregmax)
1290 goto Ebusy;
1291 if (a->acdirmin != b->acdirmin)
1292 goto Ebusy;
1293 if (a->acdirmax != b->acdirmax)
1294 goto Ebusy;
1295 if (clnt_a->cl_auth->au_flavor != clnt_b->cl_auth->au_flavor)
1296 goto Ebusy;
1297 return 1;
1298 Ebusy:
1299 return 0;
1302 struct nfs_sb_mountdata {
1303 struct nfs_server *server;
1304 int mntflags;
1307 static int nfs_set_super(struct super_block *s, void *data)
1309 struct nfs_sb_mountdata *sb_mntdata = data;
1310 struct nfs_server *server = sb_mntdata->server;
1311 int ret;
1313 s->s_flags = sb_mntdata->mntflags;
1314 s->s_fs_info = server;
1315 ret = set_anon_super(s, server);
1316 if (ret == 0)
1317 server->s_dev = s->s_dev;
1318 return ret;
1321 static int nfs_compare_super(struct super_block *sb, void *data)
1323 struct nfs_sb_mountdata *sb_mntdata = data;
1324 struct nfs_server *server = sb_mntdata->server, *old = NFS_SB(sb);
1325 int mntflags = sb_mntdata->mntflags;
1327 if (memcmp(&old->nfs_client->cl_addr,
1328 &server->nfs_client->cl_addr,
1329 sizeof(old->nfs_client->cl_addr)) != 0)
1330 return 0;
1331 /* Note: NFS_MOUNT_UNSHARED == NFS4_MOUNT_UNSHARED */
1332 if (old->flags & NFS_MOUNT_UNSHARED)
1333 return 0;
1334 if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0)
1335 return 0;
1336 return nfs_compare_mount_options(sb, server, mntflags);
1339 static int nfs_get_sb(struct file_system_type *fs_type,
1340 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
1342 struct nfs_server *server = NULL;
1343 struct super_block *s;
1344 struct nfs_fh mntfh;
1345 struct nfs_parsed_mount_data data;
1346 struct dentry *mntroot;
1347 int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
1348 struct nfs_sb_mountdata sb_mntdata = {
1349 .mntflags = flags,
1351 int error;
1353 /* Validate the mount data */
1354 error = nfs_validate_mount_data(raw_data, &data, &mntfh, dev_name);
1355 if (error < 0)
1356 goto out;
1358 /* Get a volume representation */
1359 server = nfs_create_server(&data, &mntfh);
1360 if (IS_ERR(server)) {
1361 error = PTR_ERR(server);
1362 goto out;
1364 sb_mntdata.server = server;
1366 if (server->flags & NFS_MOUNT_UNSHARED)
1367 compare_super = NULL;
1369 /* Get a superblock - note that we may end up sharing one that already exists */
1370 s = sget(fs_type, compare_super, nfs_set_super, &sb_mntdata);
1371 if (IS_ERR(s)) {
1372 error = PTR_ERR(s);
1373 goto out_err_nosb;
1376 if (s->s_fs_info != server) {
1377 nfs_free_server(server);
1378 server = NULL;
1381 if (!s->s_root) {
1382 /* initial superblock/root creation */
1383 nfs_fill_super(s, &data);
1386 mntroot = nfs_get_root(s, &mntfh);
1387 if (IS_ERR(mntroot)) {
1388 error = PTR_ERR(mntroot);
1389 goto error_splat_super;
1392 s->s_flags |= MS_ACTIVE;
1393 mnt->mnt_sb = s;
1394 mnt->mnt_root = mntroot;
1395 error = 0;
1397 out:
1398 kfree(data.nfs_server.hostname);
1399 return error;
1401 out_err_nosb:
1402 nfs_free_server(server);
1403 goto out;
1405 error_splat_super:
1406 up_write(&s->s_umount);
1407 deactivate_super(s);
1408 goto out;
1412 * Destroy an NFS2/3 superblock
1414 static void nfs_kill_super(struct super_block *s)
1416 struct nfs_server *server = NFS_SB(s);
1418 kill_anon_super(s);
1419 nfs_free_server(server);
1423 * Clone an NFS2/3 server record on xdev traversal (FSID-change)
1425 static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
1426 const char *dev_name, void *raw_data,
1427 struct vfsmount *mnt)
1429 struct nfs_clone_mount *data = raw_data;
1430 struct super_block *s;
1431 struct nfs_server *server;
1432 struct dentry *mntroot;
1433 int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
1434 struct nfs_sb_mountdata sb_mntdata = {
1435 .mntflags = flags,
1437 int error;
1439 dprintk("--> nfs_xdev_get_sb()\n");
1441 /* create a new volume representation */
1442 server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
1443 if (IS_ERR(server)) {
1444 error = PTR_ERR(server);
1445 goto out_err_noserver;
1447 sb_mntdata.server = server;
1449 if (server->flags & NFS_MOUNT_UNSHARED)
1450 compare_super = NULL;
1452 /* Get a superblock - note that we may end up sharing one that already exists */
1453 s = sget(&nfs_fs_type, compare_super, nfs_set_super, &sb_mntdata);
1454 if (IS_ERR(s)) {
1455 error = PTR_ERR(s);
1456 goto out_err_nosb;
1459 if (s->s_fs_info != server) {
1460 nfs_free_server(server);
1461 server = NULL;
1464 if (!s->s_root) {
1465 /* initial superblock/root creation */
1466 nfs_clone_super(s, data->sb);
1469 mntroot = nfs_get_root(s, data->fh);
1470 if (IS_ERR(mntroot)) {
1471 error = PTR_ERR(mntroot);
1472 goto error_splat_super;
1474 if (mntroot->d_inode->i_op != &nfs_dir_inode_operations) {
1475 dput(mntroot);
1476 error = -ESTALE;
1477 goto error_splat_super;
1480 s->s_flags |= MS_ACTIVE;
1481 mnt->mnt_sb = s;
1482 mnt->mnt_root = mntroot;
1484 dprintk("<-- nfs_xdev_get_sb() = 0\n");
1485 return 0;
1487 out_err_nosb:
1488 nfs_free_server(server);
1489 out_err_noserver:
1490 dprintk("<-- nfs_xdev_get_sb() = %d [error]\n", error);
1491 return error;
1493 error_splat_super:
1494 up_write(&s->s_umount);
1495 deactivate_super(s);
1496 dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error);
1497 return error;
1500 #ifdef CONFIG_NFS_V4
1503 * Finish setting up a cloned NFS4 superblock
1505 static void nfs4_clone_super(struct super_block *sb,
1506 const struct super_block *old_sb)
1508 sb->s_blocksize_bits = old_sb->s_blocksize_bits;
1509 sb->s_blocksize = old_sb->s_blocksize;
1510 sb->s_maxbytes = old_sb->s_maxbytes;
1511 sb->s_time_gran = 1;
1512 sb->s_op = old_sb->s_op;
1513 nfs_initialise_sb(sb);
1517 * Set up an NFS4 superblock
1519 static void nfs4_fill_super(struct super_block *sb)
1521 sb->s_time_gran = 1;
1522 sb->s_op = &nfs4_sops;
1523 nfs_initialise_sb(sb);
1527 * Validate NFSv4 mount options
1529 static int nfs4_validate_mount_data(void *options,
1530 struct nfs_parsed_mount_data *args,
1531 const char *dev_name)
1533 struct nfs4_mount_data *data = (struct nfs4_mount_data *)options;
1534 char *c;
1536 memset(args, 0, sizeof(*args));
1538 if (data == NULL)
1539 goto out_no_data;
1541 args->rsize = NFS_MAX_FILE_IO_SIZE;
1542 args->wsize = NFS_MAX_FILE_IO_SIZE;
1543 args->timeo = 600;
1544 args->retrans = 2;
1545 args->acregmin = 3;
1546 args->acregmax = 60;
1547 args->acdirmin = 30;
1548 args->acdirmax = 60;
1549 args->nfs_server.protocol = XPRT_TRANSPORT_TCP;
1551 switch (data->version) {
1552 case 1:
1553 if (data->host_addrlen != sizeof(args->nfs_server.address))
1554 goto out_no_address;
1555 if (copy_from_user(&args->nfs_server.address,
1556 data->host_addr,
1557 sizeof(args->nfs_server.address)))
1558 return -EFAULT;
1559 if (args->nfs_server.address.sin_port == 0)
1560 args->nfs_server.address.sin_port = htons(NFS_PORT);
1561 if (!nfs_verify_server_address((struct sockaddr *)
1562 &args->nfs_server.address))
1563 goto out_no_address;
1565 switch (data->auth_flavourlen) {
1566 case 0:
1567 args->auth_flavors[0] = RPC_AUTH_UNIX;
1568 break;
1569 case 1:
1570 if (copy_from_user(&args->auth_flavors[0],
1571 data->auth_flavours,
1572 sizeof(args->auth_flavors[0])))
1573 return -EFAULT;
1574 break;
1575 default:
1576 goto out_inval_auth;
1579 c = strndup_user(data->hostname.data, NFS4_MAXNAMLEN);
1580 if (IS_ERR(c))
1581 return PTR_ERR(c);
1582 args->nfs_server.hostname = c;
1584 c = strndup_user(data->mnt_path.data, NFS4_MAXPATHLEN);
1585 if (IS_ERR(c))
1586 return PTR_ERR(c);
1587 args->nfs_server.export_path = c;
1588 dfprintk(MOUNT, "NFS: MNTPATH: '%s'\n", c);
1590 c = strndup_user(data->client_addr.data, 16);
1591 if (IS_ERR(c))
1592 return PTR_ERR(c);
1593 args->client_address = c;
1596 * Translate to nfs_parsed_mount_data, which nfs4_fill_super
1597 * can deal with.
1600 args->flags = data->flags & NFS4_MOUNT_FLAGMASK;
1601 args->rsize = data->rsize;
1602 args->wsize = data->wsize;
1603 args->timeo = data->timeo;
1604 args->retrans = data->retrans;
1605 args->acregmin = data->acregmin;
1606 args->acregmax = data->acregmax;
1607 args->acdirmin = data->acdirmin;
1608 args->acdirmax = data->acdirmax;
1609 args->nfs_server.protocol = data->proto;
1611 break;
1612 default: {
1613 unsigned int len;
1615 if (nfs_parse_mount_options((char *)options, args) == 0)
1616 return -EINVAL;
1618 if (!nfs_verify_server_address((struct sockaddr *)
1619 &args->nfs_server.address))
1620 return -EINVAL;
1622 switch (args->auth_flavor_len) {
1623 case 0:
1624 args->auth_flavors[0] = RPC_AUTH_UNIX;
1625 break;
1626 case 1:
1627 break;
1628 default:
1629 goto out_inval_auth;
1633 * Split "dev_name" into "hostname:mntpath".
1635 c = strchr(dev_name, ':');
1636 if (c == NULL)
1637 return -EINVAL;
1638 /* while calculating len, pretend ':' is '\0' */
1639 len = c - dev_name;
1640 if (len > NFS4_MAXNAMLEN)
1641 return -ENAMETOOLONG;
1642 args->nfs_server.hostname = kzalloc(len, GFP_KERNEL);
1643 if (args->nfs_server.hostname == NULL)
1644 return -ENOMEM;
1645 strncpy(args->nfs_server.hostname, dev_name, len - 1);
1647 c++; /* step over the ':' */
1648 len = strlen(c);
1649 if (len > NFS4_MAXPATHLEN)
1650 return -ENAMETOOLONG;
1651 args->nfs_server.export_path = kzalloc(len + 1, GFP_KERNEL);
1652 if (args->nfs_server.export_path == NULL)
1653 return -ENOMEM;
1654 strncpy(args->nfs_server.export_path, c, len);
1656 dprintk("MNTPATH: %s\n", args->nfs_server.export_path);
1658 if (args->client_address == NULL)
1659 goto out_no_client_address;
1661 break;
1665 return 0;
1667 out_no_data:
1668 dfprintk(MOUNT, "NFS4: mount program didn't pass any mount data\n");
1669 return -EINVAL;
1671 out_inval_auth:
1672 dfprintk(MOUNT, "NFS4: Invalid number of RPC auth flavours %d\n",
1673 data->auth_flavourlen);
1674 return -EINVAL;
1676 out_no_address:
1677 dfprintk(MOUNT, "NFS4: mount program didn't pass remote address\n");
1678 return -EINVAL;
1680 out_no_client_address:
1681 dfprintk(MOUNT, "NFS4: mount program didn't pass callback address\n");
1682 return -EINVAL;
1686 * Get the superblock for an NFS4 mountpoint
1688 static int nfs4_get_sb(struct file_system_type *fs_type,
1689 int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
1691 struct nfs_parsed_mount_data data;
1692 struct super_block *s;
1693 struct nfs_server *server;
1694 struct nfs_fh mntfh;
1695 struct dentry *mntroot;
1696 int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
1697 struct nfs_sb_mountdata sb_mntdata = {
1698 .mntflags = flags,
1700 int error;
1702 /* Validate the mount data */
1703 error = nfs4_validate_mount_data(raw_data, &data, dev_name);
1704 if (error < 0)
1705 goto out;
1707 /* Get a volume representation */
1708 server = nfs4_create_server(&data, &mntfh);
1709 if (IS_ERR(server)) {
1710 error = PTR_ERR(server);
1711 goto out;
1713 sb_mntdata.server = server;
1715 if (server->flags & NFS4_MOUNT_UNSHARED)
1716 compare_super = NULL;
1718 /* Get a superblock - note that we may end up sharing one that already exists */
1719 s = sget(fs_type, compare_super, nfs_set_super, &sb_mntdata);
1720 if (IS_ERR(s)) {
1721 error = PTR_ERR(s);
1722 goto out_free;
1725 if (s->s_fs_info != server) {
1726 nfs_free_server(server);
1727 server = NULL;
1730 if (!s->s_root) {
1731 /* initial superblock/root creation */
1732 nfs4_fill_super(s);
1735 mntroot = nfs4_get_root(s, &mntfh);
1736 if (IS_ERR(mntroot)) {
1737 error = PTR_ERR(mntroot);
1738 goto error_splat_super;
1741 s->s_flags |= MS_ACTIVE;
1742 mnt->mnt_sb = s;
1743 mnt->mnt_root = mntroot;
1744 error = 0;
1746 out:
1747 kfree(data.client_address);
1748 kfree(data.nfs_server.export_path);
1749 kfree(data.nfs_server.hostname);
1750 return error;
1752 out_free:
1753 nfs_free_server(server);
1754 goto out;
1756 error_splat_super:
1757 up_write(&s->s_umount);
1758 deactivate_super(s);
1759 goto out;
1762 static void nfs4_kill_super(struct super_block *sb)
1764 struct nfs_server *server = NFS_SB(sb);
1766 nfs_return_all_delegations(sb);
1767 kill_anon_super(sb);
1769 nfs4_renewd_prepare_shutdown(server);
1770 nfs_free_server(server);
1774 * Clone an NFS4 server record on xdev traversal (FSID-change)
1776 static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
1777 const char *dev_name, void *raw_data,
1778 struct vfsmount *mnt)
1780 struct nfs_clone_mount *data = raw_data;
1781 struct super_block *s;
1782 struct nfs_server *server;
1783 struct dentry *mntroot;
1784 int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
1785 struct nfs_sb_mountdata sb_mntdata = {
1786 .mntflags = flags,
1788 int error;
1790 dprintk("--> nfs4_xdev_get_sb()\n");
1792 /* create a new volume representation */
1793 server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
1794 if (IS_ERR(server)) {
1795 error = PTR_ERR(server);
1796 goto out_err_noserver;
1798 sb_mntdata.server = server;
1800 if (server->flags & NFS4_MOUNT_UNSHARED)
1801 compare_super = NULL;
1803 /* Get a superblock - note that we may end up sharing one that already exists */
1804 s = sget(&nfs_fs_type, compare_super, nfs_set_super, &sb_mntdata);
1805 if (IS_ERR(s)) {
1806 error = PTR_ERR(s);
1807 goto out_err_nosb;
1810 if (s->s_fs_info != server) {
1811 nfs_free_server(server);
1812 server = NULL;
1815 if (!s->s_root) {
1816 /* initial superblock/root creation */
1817 nfs4_clone_super(s, data->sb);
1820 mntroot = nfs4_get_root(s, data->fh);
1821 if (IS_ERR(mntroot)) {
1822 error = PTR_ERR(mntroot);
1823 goto error_splat_super;
1826 s->s_flags |= MS_ACTIVE;
1827 mnt->mnt_sb = s;
1828 mnt->mnt_root = mntroot;
1830 dprintk("<-- nfs4_xdev_get_sb() = 0\n");
1831 return 0;
1833 out_err_nosb:
1834 nfs_free_server(server);
1835 out_err_noserver:
1836 dprintk("<-- nfs4_xdev_get_sb() = %d [error]\n", error);
1837 return error;
1839 error_splat_super:
1840 up_write(&s->s_umount);
1841 deactivate_super(s);
1842 dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error);
1843 return error;
1847 * Create an NFS4 server record on referral traversal
1849 static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags,
1850 const char *dev_name, void *raw_data,
1851 struct vfsmount *mnt)
1853 struct nfs_clone_mount *data = raw_data;
1854 struct super_block *s;
1855 struct nfs_server *server;
1856 struct dentry *mntroot;
1857 struct nfs_fh mntfh;
1858 int (*compare_super)(struct super_block *, void *) = nfs_compare_super;
1859 struct nfs_sb_mountdata sb_mntdata = {
1860 .mntflags = flags,
1862 int error;
1864 dprintk("--> nfs4_referral_get_sb()\n");
1866 /* create a new volume representation */
1867 server = nfs4_create_referral_server(data, &mntfh);
1868 if (IS_ERR(server)) {
1869 error = PTR_ERR(server);
1870 goto out_err_noserver;
1872 sb_mntdata.server = server;
1874 if (server->flags & NFS4_MOUNT_UNSHARED)
1875 compare_super = NULL;
1877 /* Get a superblock - note that we may end up sharing one that already exists */
1878 s = sget(&nfs_fs_type, compare_super, nfs_set_super, &sb_mntdata);
1879 if (IS_ERR(s)) {
1880 error = PTR_ERR(s);
1881 goto out_err_nosb;
1884 if (s->s_fs_info != server) {
1885 nfs_free_server(server);
1886 server = NULL;
1889 if (!s->s_root) {
1890 /* initial superblock/root creation */
1891 nfs4_fill_super(s);
1894 mntroot = nfs4_get_root(s, &mntfh);
1895 if (IS_ERR(mntroot)) {
1896 error = PTR_ERR(mntroot);
1897 goto error_splat_super;
1900 s->s_flags |= MS_ACTIVE;
1901 mnt->mnt_sb = s;
1902 mnt->mnt_root = mntroot;
1904 dprintk("<-- nfs4_referral_get_sb() = 0\n");
1905 return 0;
1907 out_err_nosb:
1908 nfs_free_server(server);
1909 out_err_noserver:
1910 dprintk("<-- nfs4_referral_get_sb() = %d [error]\n", error);
1911 return error;
1913 error_splat_super:
1914 up_write(&s->s_umount);
1915 deactivate_super(s);
1916 dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
1917 return error;
1920 #endif /* CONFIG_NFS_V4 */