1/*
2 *  linux/fs/nfs/super.c
3 *
4 *  Copyright (C) 1992  Rick Sladkey
5 *
6 *  nfs superblock handling functions
7 *
8 *  Modularised by Alan Cox <Alan.Cox@linux.org>, while hacking some
9 *  experimental NFS changes. Modularisation taken straight from SYS5 fs.
10 *
11 *  Change to nfs_read_super() to permit NFS mounts to multi-homed hosts.
12 *  J.S.Peatfield@damtp.cam.ac.uk
13 *
14 *  Split from inode.c by David Howells <dhowells@redhat.com>
15 *
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())
21 */
22
23#include <linux/module.h>
24#include <linux/init.h>
25
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/nfs_fs.h>
37#include <linux/nfs_mount.h>
38#include <linux/nfs4_mount.h>
39#include <linux/lockd/bind.h>
40#include <linux/smp_lock.h>
41#include <linux/seq_file.h>
42#include <linux/mount.h>
43#include <linux/nfs_idmap.h>
44#include <linux/vfs.h>
45#include <linux/inet.h>
46#include <linux/nfs_xdr.h>
47#include <linux/magic.h>
48
49#include <asm/system.h>
50#include <asm/uaccess.h>
51
52#include "nfs4_fs.h"
53#include "callback.h"
54#include "delegation.h"
55#include "iostat.h"
56#include "internal.h"
57
58#define NFSDBG_FACILITY		NFSDBG_VFS
59
60static void nfs_umount_begin(struct vfsmount *, int);
61static int  nfs_statfs(struct dentry *, struct kstatfs *);
62static int  nfs_show_options(struct seq_file *, struct vfsmount *);
63static int  nfs_show_stats(struct seq_file *, struct vfsmount *);
64static int nfs_get_sb(struct file_system_type *, int, const char *, void *, struct vfsmount *);
65static int nfs_xdev_get_sb(struct file_system_type *fs_type,
66		int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
67static void nfs_kill_super(struct super_block *);
68
69static struct file_system_type nfs_fs_type = {
70	.owner		= THIS_MODULE,
71	.name		= "nfs",
72	.get_sb		= nfs_get_sb,
73	.kill_sb	= nfs_kill_super,
74	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
75};
76
77struct file_system_type nfs_xdev_fs_type = {
78	.owner		= THIS_MODULE,
79	.name		= "nfs",
80	.get_sb		= nfs_xdev_get_sb,
81	.kill_sb	= nfs_kill_super,
82	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
83};
84
85static const struct super_operations nfs_sops = {
86	.alloc_inode	= nfs_alloc_inode,
87	.destroy_inode	= nfs_destroy_inode,
88	.write_inode	= nfs_write_inode,
89	.statfs		= nfs_statfs,
90	.clear_inode	= nfs_clear_inode,
91	.umount_begin	= nfs_umount_begin,
92	.show_options	= nfs_show_options,
93	.show_stats	= nfs_show_stats,
94};
95
96#ifdef CONFIG_NFS_V4
97static int nfs4_get_sb(struct file_system_type *fs_type,
98	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
99static int nfs4_xdev_get_sb(struct file_system_type *fs_type,
100	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
101static int nfs4_referral_get_sb(struct file_system_type *fs_type,
102	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt);
103static void nfs4_kill_super(struct super_block *sb);
104
105static struct file_system_type nfs4_fs_type = {
106	.owner		= THIS_MODULE,
107	.name		= "nfs4",
108	.get_sb		= nfs4_get_sb,
109	.kill_sb	= nfs4_kill_super,
110	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
111};
112
113struct file_system_type nfs4_xdev_fs_type = {
114	.owner		= THIS_MODULE,
115	.name		= "nfs4",
116	.get_sb		= nfs4_xdev_get_sb,
117	.kill_sb	= nfs4_kill_super,
118	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
119};
120
121struct file_system_type nfs4_referral_fs_type = {
122	.owner		= THIS_MODULE,
123	.name		= "nfs4",
124	.get_sb		= nfs4_referral_get_sb,
125	.kill_sb	= nfs4_kill_super,
126	.fs_flags	= FS_RENAME_DOES_D_MOVE|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
127};
128
129static const struct super_operations nfs4_sops = {
130	.alloc_inode	= nfs_alloc_inode,
131	.destroy_inode	= nfs_destroy_inode,
132	.write_inode	= nfs_write_inode,
133	.statfs		= nfs_statfs,
134	.clear_inode	= nfs4_clear_inode,
135	.umount_begin	= nfs_umount_begin,
136	.show_options	= nfs_show_options,
137	.show_stats	= nfs_show_stats,
138};
139#endif
140
141static struct shrinker *acl_shrinker;
142
143/*
144 * Register the NFS filesystems
145 */
146int __init register_nfs_fs(void)
147{
148	int ret;
149
150        ret = register_filesystem(&nfs_fs_type);
151	if (ret < 0)
152		goto error_0;
153
154	ret = nfs_register_sysctl();
155	if (ret < 0)
156		goto error_1;
157#ifdef CONFIG_NFS_V4
158	ret = register_filesystem(&nfs4_fs_type);
159	if (ret < 0)
160		goto error_2;
161#endif
162	acl_shrinker = set_shrinker(DEFAULT_SEEKS, nfs_access_cache_shrinker);
163	return 0;
164
165#ifdef CONFIG_NFS_V4
166error_2:
167	nfs_unregister_sysctl();
168#endif
169error_1:
170	unregister_filesystem(&nfs_fs_type);
171error_0:
172	return ret;
173}
174
175/*
176 * Unregister the NFS filesystems
177 */
178void __exit unregister_nfs_fs(void)
179{
180	if (acl_shrinker != NULL)
181		remove_shrinker(acl_shrinker);
182#ifdef CONFIG_NFS_V4
183	unregister_filesystem(&nfs4_fs_type);
184	nfs_unregister_sysctl();
185#endif
186	unregister_filesystem(&nfs_fs_type);
187}
188
189/*
190 * Deliver file system statistics to userspace
191 */
192static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf)
193{
194	struct nfs_server *server = NFS_SB(dentry->d_sb);
195	unsigned char blockbits;
196	unsigned long blockres;
197	struct nfs_fh *fh = NFS_FH(dentry->d_inode);
198	struct nfs_fattr fattr;
199	struct nfs_fsstat res = {
200			.fattr = &fattr,
201	};
202	int error;
203
204	lock_kernel();
205
206	error = server->nfs_client->rpc_ops->statfs(server, fh, &res);
207	if (error < 0)
208		goto out_err;
209	buf->f_type = NFS_SUPER_MAGIC;
210
211	/*
212	 * Current versions of glibc do not correctly handle the
213	 * case where f_frsize != f_bsize.  Eventually we want to
214	 * report the value of wtmult in this field.
215	 */
216	buf->f_frsize = dentry->d_sb->s_blocksize;
217
218	/*
219	 * On most *nix systems, f_blocks, f_bfree, and f_bavail
220	 * are reported in units of f_frsize.  Linux hasn't had
221	 * an f_frsize field in its statfs struct until recently,
222	 * thus historically Linux's sys_statfs reports these
223	 * fields in units of f_bsize.
224	 */
225	buf->f_bsize = dentry->d_sb->s_blocksize;
226	blockbits = dentry->d_sb->s_blocksize_bits;
227	blockres = (1 << blockbits) - 1;
228	buf->f_blocks = (res.tbytes + blockres) >> blockbits;
229	buf->f_bfree = (res.fbytes + blockres) >> blockbits;
230	buf->f_bavail = (res.abytes + blockres) >> blockbits;
231
232	buf->f_files = res.tfiles;
233	buf->f_ffree = res.afiles;
234
235	buf->f_namelen = server->namelen;
236
237	unlock_kernel();
238	return 0;
239
240 out_err:
241	dprintk("%s: statfs error = %d\n", __FUNCTION__, -error);
242	unlock_kernel();
243	return error;
244}
245
246/*
247 * Map the security flavour number to a name
248 */
249static const char *nfs_pseudoflavour_to_name(rpc_authflavor_t flavour)
250{
251	static const struct {
252		rpc_authflavor_t flavour;
253		const char *str;
254	} sec_flavours[] = {
255		{ RPC_AUTH_NULL, "null" },
256		{ RPC_AUTH_UNIX, "sys" },
257		{ RPC_AUTH_GSS_KRB5, "krb5" },
258		{ RPC_AUTH_GSS_KRB5I, "krb5i" },
259		{ RPC_AUTH_GSS_KRB5P, "krb5p" },
260		{ RPC_AUTH_GSS_LKEY, "lkey" },
261		{ RPC_AUTH_GSS_LKEYI, "lkeyi" },
262		{ RPC_AUTH_GSS_LKEYP, "lkeyp" },
263		{ RPC_AUTH_GSS_SPKM, "spkm" },
264		{ RPC_AUTH_GSS_SPKMI, "spkmi" },
265		{ RPC_AUTH_GSS_SPKMP, "spkmp" },
266		{ -1, "unknown" }
267	};
268	int i;
269
270	for (i=0; sec_flavours[i].flavour != -1; i++) {
271		if (sec_flavours[i].flavour == flavour)
272			break;
273	}
274	return sec_flavours[i].str;
275}
276
277/*
278 * Describe the mount options in force on this server representation
279 */
280static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, int showdefaults)
281{
282	static const struct proc_nfs_info {
283		int flag;
284		const char *str;
285		const char *nostr;
286	} nfs_info[] = {
287		{ NFS_MOUNT_SOFT, ",soft", ",hard" },
288		{ NFS_MOUNT_INTR, ",intr", "" },
289		{ NFS_MOUNT_NOCTO, ",nocto", "" },
290		{ NFS_MOUNT_NOAC, ",noac", "" },
291		{ NFS_MOUNT_NONLM, ",nolock", "" },
292		{ NFS_MOUNT_NOACL, ",noacl", "" },
293		{ NFS_MOUNT_NORDIRPLUS, ",nordirplus", "" },
294		{ 0, NULL, NULL }
295	};
296	const struct proc_nfs_info *nfs_infop;
297	struct nfs_client *clp = nfss->nfs_client;
298	char buf[12];
299	const char *proto;
300
301	seq_printf(m, ",vers=%d", clp->rpc_ops->version);
302	seq_printf(m, ",rsize=%d", nfss->rsize);
303	seq_printf(m, ",wsize=%d", nfss->wsize);
304	if (nfss->acregmin != 3*HZ || showdefaults)
305		seq_printf(m, ",acregmin=%d", nfss->acregmin/HZ);
306	if (nfss->acregmax != 60*HZ || showdefaults)
307		seq_printf(m, ",acregmax=%d", nfss->acregmax/HZ);
308	if (nfss->acdirmin != 30*HZ || showdefaults)
309		seq_printf(m, ",acdirmin=%d", nfss->acdirmin/HZ);
310	if (nfss->acdirmax != 60*HZ || showdefaults)
311		seq_printf(m, ",acdirmax=%d", nfss->acdirmax/HZ);
312	for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) {
313		if (nfss->flags & nfs_infop->flag)
314			seq_puts(m, nfs_infop->str);
315		else
316			seq_puts(m, nfs_infop->nostr);
317	}
318	switch (nfss->client->cl_xprt->prot) {
319		case IPPROTO_TCP:
320			proto = "tcp";
321			break;
322		case IPPROTO_UDP:
323			proto = "udp";
324			break;
325		default:
326			snprintf(buf, sizeof(buf), "%u", nfss->client->cl_xprt->prot);
327			proto = buf;
328	}
329	seq_printf(m, ",proto=%s", proto);
330	seq_printf(m, ",timeo=%lu", 10U * clp->retrans_timeo / HZ);
331	seq_printf(m, ",retrans=%u", clp->retrans_count);
332	seq_printf(m, ",sec=%s", nfs_pseudoflavour_to_name(nfss->client->cl_auth->au_flavor));
333}
334
335/*
336 * Describe the mount options on this VFS mountpoint
337 */
338static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
339{
340	struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
341
342	nfs_show_mount_options(m, nfss, 0);
343
344	seq_puts(m, ",addr=");
345	seq_escape(m, nfss->nfs_client->cl_hostname, " \t\n\\");
346
347	return 0;
348}
349
350/*
351 * Present statistical information for this VFS mountpoint
352 */
353static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
354{
355	int i, cpu;
356	struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
357	struct rpc_auth *auth = nfss->client->cl_auth;
358	struct nfs_iostats totals = { };
359
360	seq_printf(m, "statvers=%s", NFS_IOSTAT_VERS);
361
362	/*
363	 * Display all mount option settings
364	 */
365	seq_printf(m, "\n\topts:\t");
366	seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? "ro" : "rw");
367	seq_puts(m, mnt->mnt_sb->s_flags & MS_SYNCHRONOUS ? ",sync" : "");
368	seq_puts(m, mnt->mnt_sb->s_flags & MS_NOATIME ? ",noatime" : "");
369	seq_puts(m, mnt->mnt_sb->s_flags & MS_NODIRATIME ? ",nodiratime" : "");
370	nfs_show_mount_options(m, nfss, 1);
371
372	seq_printf(m, "\n\tage:\t%lu", (jiffies - nfss->mount_time) / HZ);
373
374	seq_printf(m, "\n\tcaps:\t");
375	seq_printf(m, "caps=0x%x", nfss->caps);
376	seq_printf(m, ",wtmult=%d", nfss->wtmult);
377	seq_printf(m, ",dtsize=%d", nfss->dtsize);
378	seq_printf(m, ",bsize=%d", nfss->bsize);
379	seq_printf(m, ",namelen=%d", nfss->namelen);
380
381#ifdef CONFIG_NFS_V4
382	if (nfss->nfs_client->cl_nfsversion == 4) {
383		seq_printf(m, "\n\tnfsv4:\t");
384		seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]);
385		seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]);
386		seq_printf(m, ",acl=0x%x", nfss->acl_bitmask);
387	}
388#endif
389
390	/*
391	 * Display security flavor in effect for this mount
392	 */
393	seq_printf(m, "\n\tsec:\tflavor=%d", auth->au_ops->au_flavor);
394	if (auth->au_flavor)
395		seq_printf(m, ",pseudoflavor=%d", auth->au_flavor);
396
397	/*
398	 * Display superblock I/O counters
399	 */
400	for_each_possible_cpu(cpu) {
401		struct nfs_iostats *stats;
402
403		preempt_disable();
404		stats = per_cpu_ptr(nfss->io_stats, cpu);
405
406		for (i = 0; i < __NFSIOS_COUNTSMAX; i++)
407			totals.events[i] += stats->events[i];
408		for (i = 0; i < __NFSIOS_BYTESMAX; i++)
409			totals.bytes[i] += stats->bytes[i];
410
411		preempt_enable();
412	}
413
414	seq_printf(m, "\n\tevents:\t");
415	for (i = 0; i < __NFSIOS_COUNTSMAX; i++)
416		seq_printf(m, "%lu ", totals.events[i]);
417	seq_printf(m, "\n\tbytes:\t");
418	for (i = 0; i < __NFSIOS_BYTESMAX; i++)
419		seq_printf(m, "%Lu ", totals.bytes[i]);
420	seq_printf(m, "\n");
421
422	rpc_print_iostats(m, nfss->client);
423
424	return 0;
425}
426
427/*
428 * Begin unmount by attempting to remove all automounted mountpoints we added
429 * in response to xdev traversals and referrals
430 */
431static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags)
432{
433	shrink_submounts(vfsmnt, &nfs_automount_list);
434}
435
436/*
437 * Validate the NFS2/NFS3 mount data
438 * - fills in the mount root filehandle
439 */
440static int nfs_validate_mount_data(struct nfs_mount_data *data,
441				   struct nfs_fh *mntfh)
442{
443	if (data == NULL) {
444		dprintk("%s: missing data argument\n", __FUNCTION__);
445		return -EINVAL;
446	}
447
448	if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
449		dprintk("%s: bad mount version\n", __FUNCTION__);
450		return -EINVAL;
451	}
452
453	switch (data->version) {
454		case 1:
455			data->namlen = 0;
456		case 2:
457			data->bsize  = 0;
458		case 3:
459			if (data->flags & NFS_MOUNT_VER3) {
460				dprintk("%s: mount structure version %d does not support NFSv3\n",
461						__FUNCTION__,
462						data->version);
463				return -EINVAL;
464			}
465			data->root.size = NFS2_FHSIZE;
466			memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
467		case 4:
468			if (data->flags & NFS_MOUNT_SECFLAVOUR) {
469				dprintk("%s: mount structure version %d does not support strong security\n",
470						__FUNCTION__,
471						data->version);
472				return -EINVAL;
473			}
474		case 5:
475			memset(data->context, 0, sizeof(data->context));
476	}
477
478	/* Set the pseudoflavor */
479	if (!(data->flags & NFS_MOUNT_SECFLAVOUR))
480		data->pseudoflavor = RPC_AUTH_UNIX;
481
482#ifndef CONFIG_NFS_V3
483	/* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */
484	if (data->flags & NFS_MOUNT_VER3) {
485		dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__);
486		return -EPROTONOSUPPORT;
487	}
488#endif /* CONFIG_NFS_V3 */
489
490	/* We now require that the mount process passes the remote address */
491	if (data->addr.sin_addr.s_addr == INADDR_ANY) {
492		dprintk("%s: mount program didn't pass remote address!\n",
493			__FUNCTION__);
494		return -EINVAL;
495	}
496
497	/* Prepare the root filehandle */
498	if (data->flags & NFS_MOUNT_VER3)
499		mntfh->size = data->root.size;
500	else
501		mntfh->size = NFS2_FHSIZE;
502
503	if (mntfh->size > sizeof(mntfh->data)) {
504		dprintk("%s: invalid root filehandle\n", __FUNCTION__);
505		return -EINVAL;
506	}
507
508	memcpy(mntfh->data, data->root.data, mntfh->size);
509	if (mntfh->size < sizeof(mntfh->data))
510		memset(mntfh->data + mntfh->size, 0,
511		       sizeof(mntfh->data) - mntfh->size);
512
513	return 0;
514}
515
516/*
517 * Initialise the common bits of the superblock
518 */
519static inline void nfs_initialise_sb(struct super_block *sb)
520{
521	struct nfs_server *server = NFS_SB(sb);
522
523	sb->s_magic = NFS_SUPER_MAGIC;
524
525	/* We probably want something more informative here */
526	snprintf(sb->s_id, sizeof(sb->s_id),
527		 "%x:%x", MAJOR(sb->s_dev), MINOR(sb->s_dev));
528
529	if (sb->s_blocksize == 0)
530		sb->s_blocksize = nfs_block_bits(server->wsize,
531						 &sb->s_blocksize_bits);
532
533	if (server->flags & NFS_MOUNT_NOAC)
534		sb->s_flags |= MS_SYNCHRONOUS;
535
536	nfs_super_set_maxbytes(sb, server->maxfilesize);
537}
538
539/*
540 * Finish setting up an NFS2/3 superblock
541 */
542static void nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data)
543{
544	struct nfs_server *server = NFS_SB(sb);
545
546	sb->s_blocksize_bits = 0;
547	sb->s_blocksize = 0;
548	if (data->bsize)
549		sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
550
551	if (server->flags & NFS_MOUNT_VER3) {
552		/* The VFS shouldn't apply the umask to mode bits. We will do
553		 * so ourselves when necessary.
554		 */
555		sb->s_flags |= MS_POSIXACL;
556		sb->s_time_gran = 1;
557	}
558
559	sb->s_op = &nfs_sops;
560 	nfs_initialise_sb(sb);
561}
562
563/*
564 * Finish setting up a cloned NFS2/3 superblock
565 */
566static void nfs_clone_super(struct super_block *sb,
567			    const struct super_block *old_sb)
568{
569	struct nfs_server *server = NFS_SB(sb);
570
571	sb->s_blocksize_bits = old_sb->s_blocksize_bits;
572	sb->s_blocksize = old_sb->s_blocksize;
573	sb->s_maxbytes = old_sb->s_maxbytes;
574
575	if (server->flags & NFS_MOUNT_VER3) {
576		/* The VFS shouldn't apply the umask to mode bits. We will do
577		 * so ourselves when necessary.
578		 */
579		sb->s_flags |= MS_POSIXACL;
580		sb->s_time_gran = 1;
581	}
582
583	sb->s_op = old_sb->s_op;
584 	nfs_initialise_sb(sb);
585}
586
587static int nfs_set_super(struct super_block *s, void *_server)
588{
589	struct nfs_server *server = _server;
590	int ret;
591
592	s->s_fs_info = server;
593	ret = set_anon_super(s, server);
594	if (ret == 0)
595		server->s_dev = s->s_dev;
596	return ret;
597}
598
599static int nfs_compare_super(struct super_block *sb, void *data)
600{
601	struct nfs_server *server = data, *old = NFS_SB(sb);
602
603	if (old->nfs_client != server->nfs_client)
604		return 0;
605	if (memcmp(&old->fsid, &server->fsid, sizeof(old->fsid)) != 0)
606		return 0;
607	return 1;
608}
609
610static int nfs_get_sb(struct file_system_type *fs_type,
611	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
612{
613	struct nfs_server *server = NULL;
614	struct super_block *s;
615	struct nfs_fh mntfh;
616	struct nfs_mount_data *data = raw_data;
617	struct dentry *mntroot;
618	int error;
619
620	/* Validate the mount data */
621	error = nfs_validate_mount_data(data, &mntfh);
622	if (error < 0)
623		return error;
624
625	/* Get a volume representation */
626	server = nfs_create_server(data, &mntfh);
627	if (IS_ERR(server)) {
628		error = PTR_ERR(server);
629		goto out_err_noserver;
630	}
631
632	/* Get a superblock - note that we may end up sharing one that already exists */
633	s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
634	if (IS_ERR(s)) {
635		error = PTR_ERR(s);
636		goto out_err_nosb;
637	}
638
639	if (s->s_fs_info != server) {
640		nfs_free_server(server);
641		server = NULL;
642	}
643
644	if (!s->s_root) {
645		/* initial superblock/root creation */
646		s->s_flags = flags;
647		nfs_fill_super(s, data);
648	}
649
650	mntroot = nfs_get_root(s, &mntfh);
651	if (IS_ERR(mntroot)) {
652		error = PTR_ERR(mntroot);
653		goto error_splat_super;
654	}
655
656	s->s_flags |= MS_ACTIVE;
657	mnt->mnt_sb = s;
658	mnt->mnt_root = mntroot;
659	return 0;
660
661out_err_nosb:
662	nfs_free_server(server);
663out_err_noserver:
664	return error;
665
666error_splat_super:
667	up_write(&s->s_umount);
668	deactivate_super(s);
669	return error;
670}
671
672/*
673 * Destroy an NFS2/3 superblock
674 */
675static void nfs_kill_super(struct super_block *s)
676{
677	struct nfs_server *server = NFS_SB(s);
678
679	kill_anon_super(s);
680	nfs_free_server(server);
681}
682
683/*
684 * Clone an NFS2/3 server record on xdev traversal (FSID-change)
685 */
686static int nfs_xdev_get_sb(struct file_system_type *fs_type, int flags,
687			   const char *dev_name, void *raw_data,
688			   struct vfsmount *mnt)
689{
690	struct nfs_clone_mount *data = raw_data;
691	struct super_block *s;
692	struct nfs_server *server;
693	struct dentry *mntroot;
694	int error;
695
696	dprintk("--> nfs_xdev_get_sb()\n");
697
698	/* create a new volume representation */
699	server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
700	if (IS_ERR(server)) {
701		error = PTR_ERR(server);
702		goto out_err_noserver;
703	}
704
705	/* Get a superblock - note that we may end up sharing one that already exists */
706	s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
707	if (IS_ERR(s)) {
708		error = PTR_ERR(s);
709		goto out_err_nosb;
710	}
711
712	if (s->s_fs_info != server) {
713		nfs_free_server(server);
714		server = NULL;
715	}
716
717	if (!s->s_root) {
718		/* initial superblock/root creation */
719		s->s_flags = flags;
720		nfs_clone_super(s, data->sb);
721	}
722
723	mntroot = nfs_get_root(s, data->fh);
724	if (IS_ERR(mntroot)) {
725		error = PTR_ERR(mntroot);
726		goto error_splat_super;
727	}
728
729	s->s_flags |= MS_ACTIVE;
730	mnt->mnt_sb = s;
731	mnt->mnt_root = mntroot;
732
733	dprintk("<-- nfs_xdev_get_sb() = 0\n");
734	return 0;
735
736out_err_nosb:
737	nfs_free_server(server);
738out_err_noserver:
739	dprintk("<-- nfs_xdev_get_sb() = %d [error]\n", error);
740	return error;
741
742error_splat_super:
743	up_write(&s->s_umount);
744	deactivate_super(s);
745	dprintk("<-- nfs_xdev_get_sb() = %d [splat]\n", error);
746	return error;
747}
748
749#ifdef CONFIG_NFS_V4
750
751/*
752 * Finish setting up a cloned NFS4 superblock
753 */
754static void nfs4_clone_super(struct super_block *sb,
755			    const struct super_block *old_sb)
756{
757	sb->s_blocksize_bits = old_sb->s_blocksize_bits;
758	sb->s_blocksize = old_sb->s_blocksize;
759	sb->s_maxbytes = old_sb->s_maxbytes;
760	sb->s_time_gran = 1;
761	sb->s_op = old_sb->s_op;
762 	nfs_initialise_sb(sb);
763}
764
765/*
766 * Set up an NFS4 superblock
767 */
768static void nfs4_fill_super(struct super_block *sb)
769{
770	sb->s_time_gran = 1;
771	sb->s_op = &nfs4_sops;
772	nfs_initialise_sb(sb);
773}
774
775static void *nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen)
776{
777	void *p = NULL;
778
779	if (!src->len)
780		return ERR_PTR(-EINVAL);
781	if (src->len < maxlen)
782		maxlen = src->len;
783	if (dst == NULL) {
784		p = dst = kmalloc(maxlen + 1, GFP_KERNEL);
785		if (p == NULL)
786			return ERR_PTR(-ENOMEM);
787	}
788	if (copy_from_user(dst, src->data, maxlen)) {
789		kfree(p);
790		return ERR_PTR(-EFAULT);
791	}
792	dst[maxlen] = '\0';
793	return dst;
794}
795
796/*
797 * Get the superblock for an NFS4 mountpoint
798 */
799static int nfs4_get_sb(struct file_system_type *fs_type,
800	int flags, const char *dev_name, void *raw_data, struct vfsmount *mnt)
801{
802	struct nfs4_mount_data *data = raw_data;
803	struct super_block *s;
804	struct nfs_server *server;
805	struct sockaddr_in addr;
806	rpc_authflavor_t authflavour;
807	struct nfs_fh mntfh;
808	struct dentry *mntroot;
809	char *mntpath = NULL, *hostname = NULL, ip_addr[16];
810	void *p;
811	int error;
812
813	if (data == NULL) {
814		dprintk("%s: missing data argument\n", __FUNCTION__);
815		return -EINVAL;
816	}
817	if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) {
818		dprintk("%s: bad mount version\n", __FUNCTION__);
819		return -EINVAL;
820	}
821
822	/* We now require that the mount process passes the remote address */
823	if (data->host_addrlen != sizeof(addr))
824		return -EINVAL;
825
826	if (copy_from_user(&addr, data->host_addr, sizeof(addr)))
827		return -EFAULT;
828
829	if (addr.sin_family != AF_INET ||
830	    addr.sin_addr.s_addr == INADDR_ANY
831	    ) {
832		dprintk("%s: mount program didn't pass remote IP address!\n",
833				__FUNCTION__);
834		return -EINVAL;
835	}
836	/* RFC3530: The default port for NFS is 2049 */
837	if (addr.sin_port == 0)
838		addr.sin_port = htons(NFS_PORT);
839
840	/* Grab the authentication type */
841	authflavour = RPC_AUTH_UNIX;
842	if (data->auth_flavourlen != 0) {
843		if (data->auth_flavourlen != 1) {
844			dprintk("%s: Invalid number of RPC auth flavours %d.\n",
845					__FUNCTION__, data->auth_flavourlen);
846			error = -EINVAL;
847			goto out_err_noserver;
848		}
849
850		if (copy_from_user(&authflavour, data->auth_flavours,
851				   sizeof(authflavour))) {
852			error = -EFAULT;
853			goto out_err_noserver;
854		}
855	}
856
857	p = nfs_copy_user_string(NULL, &data->hostname, 256);
858	if (IS_ERR(p))
859		goto out_err;
860	hostname = p;
861
862	p = nfs_copy_user_string(NULL, &data->mnt_path, 1024);
863	if (IS_ERR(p))
864		goto out_err;
865	mntpath = p;
866
867	dprintk("MNTPATH: %s\n", mntpath);
868
869	p = nfs_copy_user_string(ip_addr, &data->client_addr,
870				 sizeof(ip_addr) - 1);
871	if (IS_ERR(p))
872		goto out_err;
873
874	/* Get a volume representation */
875	server = nfs4_create_server(data, hostname, &addr, mntpath, ip_addr,
876				    authflavour, &mntfh);
877	if (IS_ERR(server)) {
878		error = PTR_ERR(server);
879		goto out_err_noserver;
880	}
881
882	/* Get a superblock - note that we may end up sharing one that already exists */
883	s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
884	if (IS_ERR(s)) {
885		error = PTR_ERR(s);
886		goto out_free;
887	}
888
889	if (s->s_fs_info != server) {
890		nfs_free_server(server);
891		server = NULL;
892	}
893
894	if (!s->s_root) {
895		/* initial superblock/root creation */
896		s->s_flags = flags;
897		nfs4_fill_super(s);
898	}
899
900	mntroot = nfs4_get_root(s, &mntfh);
901	if (IS_ERR(mntroot)) {
902		error = PTR_ERR(mntroot);
903		goto error_splat_super;
904	}
905
906	s->s_flags |= MS_ACTIVE;
907	mnt->mnt_sb = s;
908	mnt->mnt_root = mntroot;
909	kfree(mntpath);
910	kfree(hostname);
911	return 0;
912
913out_err:
914	error = PTR_ERR(p);
915	goto out_err_noserver;
916
917out_free:
918	nfs_free_server(server);
919out_err_noserver:
920	kfree(mntpath);
921	kfree(hostname);
922	return error;
923
924error_splat_super:
925	up_write(&s->s_umount);
926	deactivate_super(s);
927	goto out_err_noserver;
928}
929
930static void nfs4_kill_super(struct super_block *sb)
931{
932	struct nfs_server *server = NFS_SB(sb);
933
934	nfs_return_all_delegations(sb);
935	kill_anon_super(sb);
936
937	nfs4_renewd_prepare_shutdown(server);
938	nfs_free_server(server);
939}
940
941/*
942 * Clone an NFS4 server record on xdev traversal (FSID-change)
943 */
944static int nfs4_xdev_get_sb(struct file_system_type *fs_type, int flags,
945			    const char *dev_name, void *raw_data,
946			    struct vfsmount *mnt)
947{
948	struct nfs_clone_mount *data = raw_data;
949	struct super_block *s;
950	struct nfs_server *server;
951	struct dentry *mntroot;
952	int error;
953
954	dprintk("--> nfs4_xdev_get_sb()\n");
955
956	/* create a new volume representation */
957	server = nfs_clone_server(NFS_SB(data->sb), data->fh, data->fattr);
958	if (IS_ERR(server)) {
959		error = PTR_ERR(server);
960		goto out_err_noserver;
961	}
962
963	/* Get a superblock - note that we may end up sharing one that already exists */
964	s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
965	if (IS_ERR(s)) {
966		error = PTR_ERR(s);
967		goto out_err_nosb;
968	}
969
970	if (s->s_fs_info != server) {
971		nfs_free_server(server);
972		server = NULL;
973	}
974
975	if (!s->s_root) {
976		/* initial superblock/root creation */
977		s->s_flags = flags;
978		nfs4_clone_super(s, data->sb);
979	}
980
981	mntroot = nfs4_get_root(s, data->fh);
982	if (IS_ERR(mntroot)) {
983		error = PTR_ERR(mntroot);
984		goto error_splat_super;
985	}
986
987	s->s_flags |= MS_ACTIVE;
988	mnt->mnt_sb = s;
989	mnt->mnt_root = mntroot;
990
991	dprintk("<-- nfs4_xdev_get_sb() = 0\n");
992	return 0;
993
994out_err_nosb:
995	nfs_free_server(server);
996out_err_noserver:
997	dprintk("<-- nfs4_xdev_get_sb() = %d [error]\n", error);
998	return error;
999
1000error_splat_super:
1001	up_write(&s->s_umount);
1002	deactivate_super(s);
1003	dprintk("<-- nfs4_xdev_get_sb() = %d [splat]\n", error);
1004	return error;
1005}
1006
1007/*
1008 * Create an NFS4 server record on referral traversal
1009 */
1010static int nfs4_referral_get_sb(struct file_system_type *fs_type, int flags,
1011				const char *dev_name, void *raw_data,
1012				struct vfsmount *mnt)
1013{
1014	struct nfs_clone_mount *data = raw_data;
1015	struct super_block *s;
1016	struct nfs_server *server;
1017	struct dentry *mntroot;
1018	struct nfs_fh mntfh;
1019	int error;
1020
1021	dprintk("--> nfs4_referral_get_sb()\n");
1022
1023	/* create a new volume representation */
1024	server = nfs4_create_referral_server(data, &mntfh);
1025	if (IS_ERR(server)) {
1026		error = PTR_ERR(server);
1027		goto out_err_noserver;
1028	}
1029
1030	/* Get a superblock - note that we may end up sharing one that already exists */
1031	s = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
1032	if (IS_ERR(s)) {
1033		error = PTR_ERR(s);
1034		goto out_err_nosb;
1035	}
1036
1037	if (s->s_fs_info != server) {
1038		nfs_free_server(server);
1039		server = NULL;
1040	}
1041
1042	if (!s->s_root) {
1043		/* initial superblock/root creation */
1044		s->s_flags = flags;
1045		nfs4_fill_super(s);
1046	}
1047
1048	mntroot = nfs4_get_root(s, &mntfh);
1049	if (IS_ERR(mntroot)) {
1050		error = PTR_ERR(mntroot);
1051		goto error_splat_super;
1052	}
1053
1054	s->s_flags |= MS_ACTIVE;
1055	mnt->mnt_sb = s;
1056	mnt->mnt_root = mntroot;
1057
1058	dprintk("<-- nfs4_referral_get_sb() = 0\n");
1059	return 0;
1060
1061out_err_nosb:
1062	nfs_free_server(server);
1063out_err_noserver:
1064	dprintk("<-- nfs4_referral_get_sb() = %d [error]\n", error);
1065	return error;
1066
1067error_splat_super:
1068	up_write(&s->s_umount);
1069	deactivate_super(s);
1070	dprintk("<-- nfs4_referral_get_sb() = %d [splat]\n", error);
1071	return error;
1072}
1073
1074#endif /* CONFIG_NFS_V4 */
1075