aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--fs/nfs/Makefile5
-rw-r--r--fs/nfs/callback.c2
-rw-r--r--fs/nfs/direct.c6
-rw-r--r--fs/nfs/inode.c1793
-rw-r--r--fs/nfs/internal.h179
-rw-r--r--fs/nfs/namespace.c112
-rw-r--r--fs/nfs/nfs2xdr.c2
-rw-r--r--fs/nfs/nfs3proc.c5
-rw-r--r--fs/nfs/nfs3xdr.c3
-rw-r--r--fs/nfs/nfs4namespace.c201
-rw-r--r--fs/nfs/nfs4proc.c2
-rw-r--r--fs/nfs/pagelist.c4
-rw-r--r--fs/nfs/proc.c5
-rw-r--r--fs/nfs/read.c4
-rw-r--r--fs/nfs/super.c1468
-rw-r--r--fs/nfs/write.c4
16 files changed, 1993 insertions, 1802 deletions
diff --git a/fs/nfs/Makefile b/fs/nfs/Makefile
index d9d494cee38..0b572a0c196 100644
--- a/fs/nfs/Makefile
+++ b/fs/nfs/Makefile
@@ -4,7 +4,7 @@
4 4
5obj-$(CONFIG_NFS_FS) += nfs.o 5obj-$(CONFIG_NFS_FS) += nfs.o
6 6
7nfs-y := dir.o file.o inode.o nfs2xdr.o pagelist.o \ 7nfs-y := dir.o file.o inode.o super.o nfs2xdr.o pagelist.o \
8 proc.o read.o symlink.o unlink.o write.o \ 8 proc.o read.o symlink.o unlink.o write.o \
9 namespace.o 9 namespace.o
10nfs-$(CONFIG_ROOT_NFS) += nfsroot.o mount_clnt.o 10nfs-$(CONFIG_ROOT_NFS) += nfsroot.o mount_clnt.o
@@ -12,7 +12,8 @@ nfs-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o
12nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o 12nfs-$(CONFIG_NFS_V3_ACL) += nfs3acl.o
13nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \ 13nfs-$(CONFIG_NFS_V4) += nfs4proc.o nfs4xdr.o nfs4state.o nfs4renewd.o \
14 delegation.o idmap.o \ 14 delegation.o idmap.o \
15 callback.o callback_xdr.o callback_proc.o 15 callback.o callback_xdr.o callback_proc.o \
16 nfs4namespace.o
16nfs-$(CONFIG_NFS_DIRECTIO) += direct.o 17nfs-$(CONFIG_NFS_DIRECTIO) += direct.o
17nfs-$(CONFIG_SYSCTL) += sysctl.o 18nfs-$(CONFIG_SYSCTL) += sysctl.o
18nfs-objs := $(nfs-y) 19nfs-objs := $(nfs-y)
diff --git a/fs/nfs/callback.c b/fs/nfs/callback.c
index 90c95adc8c1..d53f8c6a9ec 100644
--- a/fs/nfs/callback.c
+++ b/fs/nfs/callback.c
@@ -182,8 +182,6 @@ static int nfs_callback_authenticate(struct svc_rqst *rqstp)
182/* 182/*
183 * Define NFS4 callback program 183 * Define NFS4 callback program
184 */ 184 */
185extern struct svc_version nfs4_callback_version1;
186
187static struct svc_version *nfs4_callback_version[] = { 185static struct svc_version *nfs4_callback_version[] = {
188 [1] = &nfs4_callback_version1, 186 [1] = &nfs4_callback_version1,
189}; 187};
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c
index 3c72b0c0728..402005c35ab 100644
--- a/fs/nfs/direct.c
+++ b/fs/nfs/direct.c
@@ -892,7 +892,7 @@ out:
892 * nfs_init_directcache - create a slab cache for nfs_direct_req structures 892 * nfs_init_directcache - create a slab cache for nfs_direct_req structures
893 * 893 *
894 */ 894 */
895int nfs_init_directcache(void) 895int __init nfs_init_directcache(void)
896{ 896{
897 nfs_direct_cachep = kmem_cache_create("nfs_direct_cache", 897 nfs_direct_cachep = kmem_cache_create("nfs_direct_cache",
898 sizeof(struct nfs_direct_req), 898 sizeof(struct nfs_direct_req),
@@ -906,10 +906,10 @@ int nfs_init_directcache(void)
906} 906}
907 907
908/** 908/**
909 * nfs_init_directcache - destroy the slab cache for nfs_direct_req structures 909 * nfs_destroy_directcache - destroy the slab cache for nfs_direct_req structures
910 * 910 *
911 */ 911 */
912void nfs_destroy_directcache(void) 912void __exit nfs_destroy_directcache(void)
913{ 913{
914 if (kmem_cache_destroy(nfs_direct_cachep)) 914 if (kmem_cache_destroy(nfs_direct_cachep))
915 printk(KERN_INFO "nfs_direct_cache: not all structures were freed\n"); 915 printk(KERN_INFO "nfs_direct_cache: not all structures were freed\n");
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 7ab2b38a990..24a7139d344 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 */
diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h
new file mode 100644
index 00000000000..5e51c4535b6
--- /dev/null
+++ b/fs/nfs/internal.h
@@ -0,0 +1,179 @@
1/*
2 * NFS internal definitions
3 */
4
5#include <linux/mount.h>
6
7struct nfs_clone_mount {
8 const struct super_block *sb;
9 const struct dentry *dentry;
10 struct nfs_fh *fh;
11 struct nfs_fattr *fattr;
12 char *hostname;
13 char *mnt_path;
14 struct sockaddr_in *addr;
15 rpc_authflavor_t authflavor;
16};
17
18/* namespace-nfs4.c */
19#ifdef CONFIG_NFS_V4
20extern struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry);
21#else
22static inline
23struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry)
24{
25 return ERR_PTR(-ENOENT);
26}
27#endif
28
29/* callback_xdr.c */
30extern struct svc_version nfs4_callback_version1;
31
32/* pagelist.c */
33extern int __init nfs_init_nfspagecache(void);
34extern void __exit nfs_destroy_nfspagecache(void);
35extern int __init nfs_init_readpagecache(void);
36extern void __exit nfs_destroy_readpagecache(void);
37extern int __init nfs_init_writepagecache(void);
38extern void __exit nfs_destroy_writepagecache(void);
39
40#ifdef CONFIG_NFS_DIRECTIO
41extern int __init nfs_init_directcache(void);
42extern void __exit nfs_destroy_directcache(void);
43#else
44#define nfs_init_directcache() (0)
45#define nfs_destroy_directcache() do {} while(0)
46#endif
47
48/* nfs2xdr.c */
49extern struct rpc_procinfo nfs_procedures[];
50extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int);
51
52/* nfs3xdr.c */
53extern struct rpc_procinfo nfs3_procedures[];
54extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int);
55
56/* nfs4xdr.c */
57extern int nfs_stat_to_errno(int);
58extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus);
59
60/* nfs4proc.c */
61extern struct rpc_procinfo nfs4_procedures[];
62
63extern int nfs4_proc_fs_locations(struct inode *dir, struct dentry *dentry,
64 struct nfs4_fs_locations *fs_locations,
65 struct page *page);
66
67/* inode.c */
68extern struct inode *nfs_alloc_inode(struct super_block *sb);
69extern void nfs_destroy_inode(struct inode *);
70extern int nfs_write_inode(struct inode *,int);
71extern void nfs_clear_inode(struct inode *);
72#ifdef CONFIG_NFS_V4
73extern void nfs4_clear_inode(struct inode *);
74#endif
75
76/* super.c */
77extern struct file_system_type nfs_referral_nfs4_fs_type;
78extern struct file_system_type clone_nfs_fs_type;
79#ifdef CONFIG_NFS_V4
80extern struct file_system_type clone_nfs4_fs_type;
81#endif
82#ifdef CONFIG_PROC_FS
83extern struct rpc_stat nfs_rpcstat;
84#endif
85extern int __init register_nfs_fs(void);
86extern void __exit unregister_nfs_fs(void);
87
88/* namespace.c */
89extern char *nfs_path(const char *base, const struct dentry *dentry,
90 char *buffer, ssize_t buflen);
91
92/*
93 * Determine the mount path as a string
94 */
95static inline char *nfs4_path(const struct dentry *dentry, char *buffer, ssize_t buflen)
96{
97 return nfs_path(NFS_SB(dentry->d_sb)->mnt_path, dentry, buffer, buflen);
98}
99
100/*
101 * Determine the device name as a string
102 */
103static inline char *nfs_devname(const struct vfsmount *mnt_parent,
104 const struct dentry *dentry,
105 char *buffer, ssize_t buflen)
106{
107 return nfs_path(mnt_parent->mnt_devname, dentry, buffer, buflen);
108}
109
110/*
111 * Determine the actual block size (and log2 thereof)
112 */
113static inline
114unsigned long nfs_block_bits(unsigned long bsize, unsigned char *nrbitsp)
115{
116 /* make sure blocksize is a power of two */
117 if ((bsize & (bsize - 1)) || nrbitsp) {
118 unsigned char nrbits;
119
120 for (nrbits = 31; nrbits && !(bsize & (1 << nrbits)); nrbits--)
121 ;
122 bsize = 1 << nrbits;
123 if (nrbitsp)
124 *nrbitsp = nrbits;
125 }
126
127 return bsize;
128}
129
130/*
131 * Calculate the number of 512byte blocks used.
132 */
133static inline unsigned long nfs_calc_block_size(u64 tsize)
134{
135 loff_t used = (tsize + 511) >> 9;
136 return (used > ULONG_MAX) ? ULONG_MAX : used;
137}
138
139/*
140 * Compute and set NFS server blocksize
141 */
142static inline
143unsigned long nfs_block_size(unsigned long bsize, unsigned char *nrbitsp)
144{
145 if (bsize < NFS_MIN_FILE_IO_SIZE)
146 bsize = NFS_DEF_FILE_IO_SIZE;
147 else if (bsize >= NFS_MAX_FILE_IO_SIZE)
148 bsize = NFS_MAX_FILE_IO_SIZE;
149
150 return nfs_block_bits(bsize, nrbitsp);
151}
152
153/*
154 * Determine the maximum file size for a superblock
155 */
156static inline
157void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize)
158{
159 sb->s_maxbytes = (loff_t)maxfilesize;
160 if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0)
161 sb->s_maxbytes = MAX_LFS_FILESIZE;
162}
163
164/*
165 * Check if the string represents a "valid" IPv4 address
166 */
167static inline int valid_ipaddr4(const char *buf)
168{
169 int rc, count, in[4];
170
171 rc = sscanf(buf, "%d.%d.%d.%d", &in[0], &in[1], &in[2], &in[3]);
172 if (rc != 4)
173 return -EINVAL;
174 for (count = 0; count < 4; count++) {
175 if (in[count] > 255)
176 return -EINVAL;
177 }
178 return 0;
179}
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 8ca44b7b25c..19b98ca468e 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -15,15 +15,64 @@
15#include <linux/string.h> 15#include <linux/string.h>
16#include <linux/sunrpc/clnt.h> 16#include <linux/sunrpc/clnt.h>
17#include <linux/vfs.h> 17#include <linux/vfs.h>
18#include "internal.h"
18 19
19#define NFSDBG_FACILITY NFSDBG_VFS 20#define NFSDBG_FACILITY NFSDBG_VFS
20 21
21LIST_HEAD(nfs_automount_list);
22static void nfs_expire_automounts(void *list); 22static void nfs_expire_automounts(void *list);
23
24LIST_HEAD(nfs_automount_list);
23static DECLARE_WORK(nfs_automount_task, nfs_expire_automounts, &nfs_automount_list); 25static DECLARE_WORK(nfs_automount_task, nfs_expire_automounts, &nfs_automount_list);
24int nfs_mountpoint_expiry_timeout = 500 * HZ; 26int nfs_mountpoint_expiry_timeout = 500 * HZ;
25 27
26/* 28/*
29 * nfs_path - reconstruct the path given an arbitrary dentry
30 * @base - arbitrary string to prepend to the path
31 * @dentry - pointer to dentry
32 * @buffer - result buffer
33 * @buflen - length of buffer
34 *
35 * Helper function for constructing the path from the
36 * root dentry to an arbitrary hashed dentry.
37 *
38 * This is mainly for use in figuring out the path on the
39 * server side when automounting on top of an existing partition.
40 */
41char *nfs_path(const char *base, const struct dentry *dentry,
42 char *buffer, ssize_t buflen)
43{
44 char *end = buffer+buflen;
45 int namelen;
46
47 *--end = '\0';
48 buflen--;
49 spin_lock(&dcache_lock);
50 while (!IS_ROOT(dentry)) {
51 namelen = dentry->d_name.len;
52 buflen -= namelen + 1;
53 if (buflen < 0)
54 goto Elong;
55 end -= namelen;
56 memcpy(end, dentry->d_name.name, namelen);
57 *--end = '/';
58 dentry = dentry->d_parent;
59 }
60 spin_unlock(&dcache_lock);
61 namelen = strlen(base);
62 /* Strip off excess slashes in base string */
63 while (namelen > 0 && base[namelen - 1] == '/')
64 namelen--;
65 buflen -= namelen;
66 if (buflen < 0)
67 goto Elong;
68 end -= namelen;
69 memcpy(end, base, namelen);
70 return end;
71Elong:
72 return ERR_PTR(-ENAMETOOLONG);
73}
74
75/*
27 * nfs_follow_mountpoint - handle crossing a mountpoint on the server 76 * nfs_follow_mountpoint - handle crossing a mountpoint on the server
28 * @dentry - dentry of mountpoint 77 * @dentry - dentry of mountpoint
29 * @nd - nameidata info 78 * @nd - nameidata info
@@ -117,3 +166,64 @@ void nfs_release_automount_timer(void)
117 flush_scheduled_work(); 166 flush_scheduled_work();
118 } 167 }
119} 168}
169
170/*
171 * Clone a mountpoint of the appropriate type
172 */
173static struct vfsmount *nfs_do_clone_mount(struct nfs_server *server, char *devname,
174 struct nfs_clone_mount *mountdata)
175{
176#ifdef CONFIG_NFS_V4
177 struct vfsmount *mnt = NULL;
178 switch (server->rpc_ops->version) {
179 case 2:
180 case 3:
181 mnt = vfs_kern_mount(&clone_nfs_fs_type, 0, devname, mountdata);
182 break;
183 case 4:
184 mnt = vfs_kern_mount(&clone_nfs4_fs_type, 0, devname, mountdata);
185 }
186 return mnt;
187#else
188 return vfs_kern_mount(&clone_nfs_fs_type, 0, devname, mountdata);
189#endif
190}
191
192/**
193 * nfs_do_submount - set up mountpoint when crossing a filesystem boundary
194 * @mnt_parent - mountpoint of parent directory
195 * @dentry - parent directory
196 * @fh - filehandle for new root dentry
197 * @fattr - attributes for new root inode
198 *
199 */
200struct vfsmount *nfs_do_submount(const struct vfsmount *mnt_parent,
201 const struct dentry *dentry, struct nfs_fh *fh,
202 struct nfs_fattr *fattr)
203{
204 struct nfs_clone_mount mountdata = {
205 .sb = mnt_parent->mnt_sb,
206 .dentry = dentry,
207 .fh = fh,
208 .fattr = fattr,
209 };
210 struct vfsmount *mnt = ERR_PTR(-ENOMEM);
211 char *page = (char *) __get_free_page(GFP_USER);
212 char *devname;
213
214 dprintk("%s: submounting on %s/%s\n", __FUNCTION__,
215 dentry->d_parent->d_name.name,
216 dentry->d_name.name);
217 if (page == NULL)
218 goto out;
219 devname = nfs_devname(mnt_parent, dentry, page, PAGE_SIZE);
220 mnt = (struct vfsmount *)devname;
221 if (IS_ERR(devname))
222 goto free_page;
223 mnt = nfs_do_clone_mount(NFS_SB(mnt_parent->mnt_sb), devname, &mountdata);
224free_page:
225 free_page((unsigned long)page);
226out:
227 dprintk("%s: done\n", __FUNCTION__);
228 return mnt;
229}
diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c
index a7ed88f97a1..4a006f81666 100644
--- a/fs/nfs/nfs2xdr.c
+++ b/fs/nfs/nfs2xdr.c
@@ -27,8 +27,6 @@
27#define NFSDBG_FACILITY NFSDBG_XDR 27#define NFSDBG_FACILITY NFSDBG_XDR
28/* #define NFS_PARANOIA 1 */ 28/* #define NFS_PARANOIA 1 */
29 29
30extern int nfs_stat_to_errno(int stat);
31
32/* Mapping from NFS error code to "errno" error code. */ 30/* Mapping from NFS error code to "errno" error code. */
33#define errno_NFSERR_IO EIO 31#define errno_NFSERR_IO EIO
34 32
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index cf186f0d2b3..7143b1f82ce 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -20,11 +20,10 @@
20#include <linux/nfs_mount.h> 20#include <linux/nfs_mount.h>
21 21
22#include "iostat.h" 22#include "iostat.h"
23#include "internal.h"
23 24
24#define NFSDBG_FACILITY NFSDBG_PROC 25#define NFSDBG_FACILITY NFSDBG_PROC
25 26
26extern struct rpc_procinfo nfs3_procedures[];
27
28/* A wrapper to handle the EJUKEBOX error message */ 27/* A wrapper to handle the EJUKEBOX error message */
29static int 28static int
30nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags) 29nfs3_rpc_wrapper(struct rpc_clnt *clnt, struct rpc_message *msg, int flags)
@@ -809,8 +808,6 @@ nfs3_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
809 return status; 808 return status;
810} 809}
811 810
812extern u32 *nfs3_decode_dirent(u32 *, struct nfs_entry *, int);
813
814static int nfs3_read_done(struct rpc_task *task, struct nfs_read_data *data) 811static int nfs3_read_done(struct rpc_task *task, struct nfs_read_data *data)
815{ 812{
816 if (nfs3_async_handle_jukebox(task, data->inode)) 813 if (nfs3_async_handle_jukebox(task, data->inode))
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c
index f70eee2cac0..0250269e975 100644
--- a/fs/nfs/nfs3xdr.c
+++ b/fs/nfs/nfs3xdr.c
@@ -22,14 +22,13 @@
22#include <linux/nfs3.h> 22#include <linux/nfs3.h>
23#include <linux/nfs_fs.h> 23#include <linux/nfs_fs.h>
24#include <linux/nfsacl.h> 24#include <linux/nfsacl.h>
25#include "internal.h"
25 26
26#define NFSDBG_FACILITY NFSDBG_XDR 27#define NFSDBG_FACILITY NFSDBG_XDR
27 28
28/* Mapping from NFS error code to "errno" error code. */ 29/* Mapping from NFS error code to "errno" error code. */
29#define errno_NFSERR_IO EIO 30#define errno_NFSERR_IO EIO
30 31
31extern int nfs_stat_to_errno(int);
32
33/* 32/*
34 * Declare the space requirements for NFS arguments and replies as 33 * Declare the space requirements for NFS arguments and replies as
35 * number of 32bit-words 34 * number of 32bit-words
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c
new file mode 100644
index 00000000000..ea38d27b74e
--- /dev/null
+++ b/fs/nfs/nfs4namespace.c
@@ -0,0 +1,201 @@
1/*
2 * linux/fs/nfs/nfs4namespace.c
3 *
4 * Copyright (C) 2005 Trond Myklebust <Trond.Myklebust@netapp.com>
5 *
6 * NFSv4 namespace
7 */
8
9#include <linux/config.h>
10
11#include <linux/dcache.h>
12#include <linux/mount.h>
13#include <linux/namei.h>
14#include <linux/nfs_fs.h>
15#include <linux/string.h>
16#include <linux/sunrpc/clnt.h>
17#include <linux/vfs.h>
18#include <linux/inet.h>
19#include "internal.h"
20
21#define NFSDBG_FACILITY NFSDBG_VFS
22
23/*
24 * Check if fs_root is valid
25 */
26static inline char *nfs4_pathname_string(struct nfs4_pathname *pathname,
27 char *buffer, ssize_t buflen)
28{
29 char *end = buffer + buflen;
30 int n;
31
32 *--end = '\0';
33 buflen--;
34
35 n = pathname->ncomponents;
36 while (--n >= 0) {
37 struct nfs4_string *component = &pathname->components[n];
38 buflen -= component->len + 1;
39 if (buflen < 0)
40 goto Elong;
41 end -= component->len;
42 memcpy(end, component->data, component->len);
43 *--end = '/';
44 }
45 return end;
46Elong:
47 return ERR_PTR(-ENAMETOOLONG);
48}
49
50
51/**
52 * nfs_follow_referral - set up mountpoint when hitting a referral on moved error
53 * @mnt_parent - mountpoint of parent directory
54 * @dentry - parent directory
55 * @fspath - fs path returned in fs_locations
56 * @mntpath - mount path to new server
57 * @hostname - hostname of new server
58 * @addr - host addr of new server
59 *
60 */
61static struct vfsmount *nfs_follow_referral(const struct vfsmount *mnt_parent,
62 const struct dentry *dentry,
63 struct nfs4_fs_locations *locations)
64{
65 struct vfsmount *mnt = ERR_PTR(-ENOENT);
66 struct nfs_clone_mount mountdata = {
67 .sb = mnt_parent->mnt_sb,
68 .dentry = dentry,
69 .authflavor = NFS_SB(mnt_parent->mnt_sb)->client->cl_auth->au_flavor,
70 };
71 char *page, *page2;
72 char *path, *fs_path;
73 char *devname;
74 int loc, s;
75
76 if (locations == NULL || locations->nlocations <= 0)
77 goto out;
78
79 dprintk("%s: referral at %s/%s\n", __FUNCTION__,
80 dentry->d_parent->d_name.name, dentry->d_name.name);
81
82 /* Ensure fs path is a prefix of current dentry path */
83 page = (char *) __get_free_page(GFP_USER);
84 if (page == NULL)
85 goto out;
86 page2 = (char *) __get_free_page(GFP_USER);
87 if (page2 == NULL)
88 goto out;
89
90 path = nfs4_path(dentry, page, PAGE_SIZE);
91 if (IS_ERR(path))
92 goto out_free;
93
94 fs_path = nfs4_pathname_string(&locations->fs_path, page2, PAGE_SIZE);
95 if (IS_ERR(fs_path))
96 goto out_free;
97
98 if (strncmp(path, fs_path, strlen(fs_path)) != 0) {
99 dprintk("%s: path %s does not begin with fsroot %s\n", __FUNCTION__, path, fs_path);
100 goto out_free;
101 }
102
103 devname = nfs_devname(mnt_parent, dentry, page, PAGE_SIZE);
104 if (IS_ERR(devname)) {
105 mnt = (struct vfsmount *)devname;
106 goto out_free;
107 }
108
109 loc = 0;
110 while (loc < locations->nlocations && IS_ERR(mnt)) {
111 struct nfs4_fs_location *location = &locations->locations[loc];
112 char *mnt_path;
113
114 if (location == NULL || location->nservers <= 0 ||
115 location->rootpath.ncomponents == 0) {
116 loc++;
117 continue;
118 }
119
120 mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE);
121 if (IS_ERR(mnt_path)) {
122 loc++;
123 continue;
124 }
125 mountdata.mnt_path = mnt_path;
126
127 s = 0;
128 while (s < location->nservers) {
129 struct sockaddr_in addr = {};
130
131 if (location->servers[s].len <= 0 ||
132 valid_ipaddr4(location->servers[s].data) < 0) {
133 s++;
134 continue;
135 }
136
137 mountdata.hostname = location->servers[s].data;
138 addr.sin_addr.s_addr = in_aton(mountdata.hostname);
139 addr.sin_family = AF_INET;
140 addr.sin_port = htons(NFS_PORT);
141 mountdata.addr = &addr;
142
143 mnt = vfs_kern_mount(&nfs_referral_nfs4_fs_type, 0, devname, &mountdata);
144 if (!IS_ERR(mnt)) {
145 break;
146 }
147 s++;
148 }
149 loc++;
150 }
151
152out_free:
153 free_page((unsigned long)page);
154 free_page((unsigned long)page2);
155out:
156 dprintk("%s: done\n", __FUNCTION__);
157 return mnt;
158}
159
160/*
161 * nfs_do_refmount - handle crossing a referral on server
162 * @dentry - dentry of referral
163 * @nd - nameidata info
164 *
165 */
166struct vfsmount *nfs_do_refmount(const struct vfsmount *mnt_parent, struct dentry *dentry)
167{
168 struct vfsmount *mnt = ERR_PTR(-ENOENT);
169 struct dentry *parent;
170 struct nfs4_fs_locations *fs_locations = NULL;
171 struct page *page;
172 int err;
173
174 /* BUG_ON(IS_ROOT(dentry)); */
175 dprintk("%s: enter\n", __FUNCTION__);
176
177 page = alloc_page(GFP_KERNEL);
178 if (page == NULL)
179 goto out;
180
181 fs_locations = kmalloc(sizeof(struct nfs4_fs_locations), GFP_KERNEL);
182 if (fs_locations == NULL)
183 goto out_free;
184
185 /* Get locations */
186 parent = dget_parent(dentry);
187 dprintk("%s: getting locations for %s/%s\n", __FUNCTION__, parent->d_name.name, dentry->d_name.name);
188 err = nfs4_proc_fs_locations(parent->d_inode, dentry, fs_locations, page);
189 dput(parent);
190 if (err != 0 || fs_locations->nlocations <= 0 ||
191 fs_locations->fs_path.ncomponents <= 0)
192 goto out_free;
193
194 mnt = nfs_follow_referral(mnt_parent, dentry, fs_locations);
195out_free:
196 __free_page(page);
197 kfree(fs_locations);
198out:
199 dprintk("%s: done\n", __FUNCTION__);
200 return mnt;
201}
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index 3300e35d74a..b4916b09219 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -65,8 +65,6 @@ static int nfs4_async_handle_error(struct rpc_task *, const struct nfs_server *)
65static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry); 65static int _nfs4_proc_access(struct inode *inode, struct nfs_access_entry *entry);
66static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception); 66static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception);
67static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp); 67static int nfs4_wait_clnt_recover(struct rpc_clnt *clnt, struct nfs4_client *clp);
68extern u32 *nfs4_decode_dirent(u32 *p, struct nfs_entry *entry, int plus);
69extern struct rpc_procinfo nfs4_procedures[];
70 68
71/* Prevent leaks of NFSv4 errors into userland */ 69/* Prevent leaks of NFSv4 errors into userland */
72int nfs4_map_errors(int err) 70int nfs4_map_errors(int err)
diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c
index 656481c0daa..ef9429643eb 100644
--- a/fs/nfs/pagelist.c
+++ b/fs/nfs/pagelist.c
@@ -378,7 +378,7 @@ out:
378 return res; 378 return res;
379} 379}
380 380
381int nfs_init_nfspagecache(void) 381int __init nfs_init_nfspagecache(void)
382{ 382{
383 nfs_page_cachep = kmem_cache_create("nfs_page", 383 nfs_page_cachep = kmem_cache_create("nfs_page",
384 sizeof(struct nfs_page), 384 sizeof(struct nfs_page),
@@ -390,7 +390,7 @@ int nfs_init_nfspagecache(void)
390 return 0; 390 return 0;
391} 391}
392 392
393void nfs_destroy_nfspagecache(void) 393void __exit nfs_destroy_nfspagecache(void)
394{ 394{
395 if (kmem_cache_destroy(nfs_page_cachep)) 395 if (kmem_cache_destroy(nfs_page_cachep))
396 printk(KERN_INFO "nfs_page: not all structures were freed\n"); 396 printk(KERN_INFO "nfs_page: not all structures were freed\n");
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index 9dd85cac2df..b3899ea3229 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -44,11 +44,10 @@
44#include <linux/nfs_page.h> 44#include <linux/nfs_page.h>
45#include <linux/lockd/bind.h> 45#include <linux/lockd/bind.h>
46#include <linux/smp_lock.h> 46#include <linux/smp_lock.h>
47#include "internal.h"
47 48
48#define NFSDBG_FACILITY NFSDBG_PROC 49#define NFSDBG_FACILITY NFSDBG_PROC
49 50
50extern struct rpc_procinfo nfs_procedures[];
51
52/* 51/*
53 * Bare-bones access to getattr: this is for nfs_read_super. 52 * Bare-bones access to getattr: this is for nfs_read_super.
54 */ 53 */
@@ -611,8 +610,6 @@ nfs_proc_pathconf(struct nfs_server *server, struct nfs_fh *fhandle,
611 return 0; 610 return 0;
612} 611}
613 612
614extern u32 * nfs_decode_dirent(u32 *, struct nfs_entry *, int);
615
616static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data) 613static int nfs_read_done(struct rpc_task *task, struct nfs_read_data *data)
617{ 614{
618 if (task->tk_status >= 0) { 615 if (task->tk_status >= 0) {
diff --git a/fs/nfs/read.c b/fs/nfs/read.c
index fd9018c692b..41c2ffee24f 100644
--- a/fs/nfs/read.c
+++ b/fs/nfs/read.c
@@ -694,7 +694,7 @@ int nfs_readpages(struct file *filp, struct address_space *mapping,
694 return ret; 694 return ret;
695} 695}
696 696
697int nfs_init_readpagecache(void) 697int __init nfs_init_readpagecache(void)
698{ 698{
699 nfs_rdata_cachep = kmem_cache_create("nfs_read_data", 699 nfs_rdata_cachep = kmem_cache_create("nfs_read_data",
700 sizeof(struct nfs_read_data), 700 sizeof(struct nfs_read_data),
@@ -711,7 +711,7 @@ int nfs_init_readpagecache(void)
711 return 0; 711 return 0;
712} 712}
713 713
714void nfs_destroy_readpagecache(void) 714void __exit nfs_destroy_readpagecache(void)
715{ 715{
716 mempool_destroy(nfs_rdata_mempool); 716 mempool_destroy(nfs_rdata_mempool);
717 if (kmem_cache_destroy(nfs_rdata_cachep)) 717 if (kmem_cache_destroy(nfs_rdata_cachep))
diff --git a/fs/nfs/super.c b/fs/nfs/super.c
new file mode 100644
index 00000000000..4acd3ee9642
--- /dev/null
+++ b/fs/nfs/super.c
@@ -0,0 +1,1468 @@
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 */
17
18#include <linux/config.h>
19#include <linux/module.h>
20#include <linux/init.h>
21
22#include <linux/time.h>
23#include <linux/kernel.h>
24#include <linux/mm.h>
25#include <linux/string.h>
26#include <linux/stat.h>
27#include <linux/errno.h>
28#include <linux/unistd.h>
29#include <linux/sunrpc/clnt.h>
30#include <linux/sunrpc/stats.h>
31#include <linux/sunrpc/metrics.h>
32#include <linux/nfs_fs.h>
33#include <linux/nfs_mount.h>
34#include <linux/nfs4_mount.h>
35#include <linux/lockd/bind.h>
36#include <linux/smp_lock.h>
37#include <linux/seq_file.h>
38#include <linux/mount.h>
39#include <linux/nfs_idmap.h>
40#include <linux/vfs.h>
41#include <linux/inet.h>
42#include <linux/nfs_xdr.h>
43
44#include <asm/system.h>
45#include <asm/uaccess.h>
46
47#include "nfs4_fs.h"
48#include "callback.h"
49#include "delegation.h"
50#include "iostat.h"
51#include "internal.h"
52
53#define NFSDBG_FACILITY NFSDBG_VFS
54
55/* Maximum number of readahead requests
56 * FIXME: this should really be a sysctl so that users may tune it to suit
57 * their needs. People that do NFS over a slow network, might for
58 * instance want to reduce it to something closer to 1 for improved
59 * interactive response.
60 */
61#define NFS_MAX_READAHEAD (RPC_DEF_SLOT_TABLE - 1)
62
63/*
64 * RPC cruft for NFS
65 */
66static struct rpc_version * nfs_version[] = {
67 NULL,
68 NULL,
69 &nfs_version2,
70#if defined(CONFIG_NFS_V3)
71 &nfs_version3,
72#elif defined(CONFIG_NFS_V4)
73 NULL,
74#endif
75#if defined(CONFIG_NFS_V4)
76 &nfs_version4,
77#endif
78};
79
80static struct rpc_program nfs_program = {
81 .name = "nfs",
82 .number = NFS_PROGRAM,
83 .nrvers = ARRAY_SIZE(nfs_version),
84 .version = nfs_version,
85 .stats = &nfs_rpcstat,
86 .pipe_dir_name = "/nfs",
87};
88
89struct rpc_stat nfs_rpcstat = {
90 .program = &nfs_program
91};
92
93
94#ifdef CONFIG_NFS_V3_ACL
95static struct rpc_stat nfsacl_rpcstat = { &nfsacl_program };
96static struct rpc_version * nfsacl_version[] = {
97 [3] = &nfsacl_version3,
98};
99
100struct rpc_program nfsacl_program = {
101 .name = "nfsacl",
102 .number = NFS_ACL_PROGRAM,
103 .nrvers = ARRAY_SIZE(nfsacl_version),
104 .version = nfsacl_version,
105 .stats = &nfsacl_rpcstat,
106};
107#endif /* CONFIG_NFS_V3_ACL */
108
109static void nfs_umount_begin(struct vfsmount *, int);
110static int nfs_statfs(struct super_block *, struct kstatfs *);
111static int nfs_show_options(struct seq_file *, struct vfsmount *);
112static int nfs_show_stats(struct seq_file *, struct vfsmount *);
113static struct super_block *nfs_get_sb(struct file_system_type *, int, const char *, void *);
114static struct super_block *nfs_clone_nfs_sb(struct file_system_type *fs_type,
115 int flags, const char *dev_name, void *raw_data);
116static void nfs_kill_super(struct super_block *);
117
118static struct file_system_type nfs_fs_type = {
119 .owner = THIS_MODULE,
120 .name = "nfs",
121 .get_sb = nfs_get_sb,
122 .kill_sb = nfs_kill_super,
123 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
124};
125
126struct file_system_type clone_nfs_fs_type = {
127 .owner = THIS_MODULE,
128 .name = "nfs",
129 .get_sb = nfs_clone_nfs_sb,
130 .kill_sb = nfs_kill_super,
131 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
132};
133
134static struct super_operations nfs_sops = {
135 .alloc_inode = nfs_alloc_inode,
136 .destroy_inode = nfs_destroy_inode,
137 .write_inode = nfs_write_inode,
138 .statfs = nfs_statfs,
139 .clear_inode = nfs_clear_inode,
140 .umount_begin = nfs_umount_begin,
141 .show_options = nfs_show_options,
142 .show_stats = nfs_show_stats,
143};
144
145#ifdef CONFIG_NFS_V4
146static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
147 int flags, const char *dev_name, void *raw_data);
148static struct super_block *nfs_clone_nfs4_sb(struct file_system_type *fs_type,
149 int flags, const char *dev_name, void *raw_data);
150static struct super_block *nfs_referral_nfs4_sb(struct file_system_type *fs_type,
151 int flags, const char *dev_name, void *raw_data);
152static void nfs4_kill_super(struct super_block *sb);
153
154static struct file_system_type nfs4_fs_type = {
155 .owner = THIS_MODULE,
156 .name = "nfs4",
157 .get_sb = nfs4_get_sb,
158 .kill_sb = nfs4_kill_super,
159 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
160};
161
162struct file_system_type clone_nfs4_fs_type = {
163 .owner = THIS_MODULE,
164 .name = "nfs4",
165 .get_sb = nfs_clone_nfs4_sb,
166 .kill_sb = nfs4_kill_super,
167 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
168};
169
170struct file_system_type nfs_referral_nfs4_fs_type = {
171 .owner = THIS_MODULE,
172 .name = "nfs4",
173 .get_sb = nfs_referral_nfs4_sb,
174 .kill_sb = nfs4_kill_super,
175 .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT|FS_BINARY_MOUNTDATA,
176};
177
178static struct super_operations nfs4_sops = {
179 .alloc_inode = nfs_alloc_inode,
180 .destroy_inode = nfs_destroy_inode,
181 .write_inode = nfs_write_inode,
182 .statfs = nfs_statfs,
183 .clear_inode = nfs4_clear_inode,
184 .umount_begin = nfs_umount_begin,
185 .show_options = nfs_show_options,
186 .show_stats = nfs_show_stats,
187};
188#endif
189
190static const int nfs_set_port_min = 0;
191static const int nfs_set_port_max = 65535;
192
193static int param_set_port(const char *val, struct kernel_param *kp)
194{
195 char *endp;
196 int num = simple_strtol(val, &endp, 0);
197 if (endp == val || *endp || num < nfs_set_port_min || num > nfs_set_port_max)
198 return -EINVAL;
199 *((int *)kp->arg) = num;
200 return 0;
201}
202
203module_param_call(callback_tcpport, param_set_port, param_get_int,
204 &nfs_callback_set_tcpport, 0644);
205
206static int param_set_idmap_timeout(const char *val, struct kernel_param *kp)
207{
208 char *endp;
209 int num = simple_strtol(val, &endp, 0);
210 int jif = num * HZ;
211 if (endp == val || *endp || num < 0 || jif < num)
212 return -EINVAL;
213 *((int *)kp->arg) = jif;
214 return 0;
215}
216
217module_param_call(idmap_cache_timeout, param_set_idmap_timeout, param_get_int,
218 &nfs_idmap_cache_timeout, 0644);
219
220/*
221 * Register the NFS filesystems
222 */
223int __init register_nfs_fs(void)
224{
225 int ret;
226
227 ret = register_filesystem(&nfs_fs_type);
228 if (ret < 0)
229 goto error_0;
230
231#ifdef CONFIG_NFS_V4
232 ret = nfs_register_sysctl();
233 if (ret < 0)
234 goto error_1;
235 ret = register_filesystem(&nfs4_fs_type);
236 if (ret < 0)
237 goto error_2;
238#endif
239 return 0;
240
241#ifdef CONFIG_NFS_V4
242error_2:
243 nfs_unregister_sysctl();
244error_1:
245 unregister_filesystem(&nfs_fs_type);
246#endif
247error_0:
248 return ret;
249}
250
251/*
252 * Unregister the NFS filesystems
253 */
254void __exit unregister_nfs_fs(void)
255{
256#ifdef CONFIG_NFS_V4
257 unregister_filesystem(&nfs4_fs_type);
258 nfs_unregister_sysctl();
259#endif
260 unregister_filesystem(&nfs_fs_type);
261}
262
263/*
264 * Deliver file system statistics to userspace
265 */
266static int nfs_statfs(struct super_block *sb, struct kstatfs *buf)
267{
268 struct nfs_server *server = NFS_SB(sb);
269 unsigned char blockbits;
270 unsigned long blockres;
271 struct nfs_fh *rootfh = NFS_FH(sb->s_root->d_inode);
272 struct nfs_fattr fattr;
273 struct nfs_fsstat res = {
274 .fattr = &fattr,
275 };
276 int error;
277
278 lock_kernel();
279
280 error = server->rpc_ops->statfs(server, rootfh, &res);
281 buf->f_type = NFS_SUPER_MAGIC;
282 if (error < 0)
283 goto out_err;
284
285 /*
286 * Current versions of glibc do not correctly handle the
287 * case where f_frsize != f_bsize. Eventually we want to
288 * report the value of wtmult in this field.
289 */
290 buf->f_frsize = sb->s_blocksize;
291
292 /*
293 * On most *nix systems, f_blocks, f_bfree, and f_bavail
294 * are reported in units of f_frsize. Linux hasn't had
295 * an f_frsize field in its statfs struct until recently,
296 * thus historically Linux's sys_statfs reports these
297 * fields in units of f_bsize.
298 */
299 buf->f_bsize = sb->s_blocksize;
300 blockbits = sb->s_blocksize_bits;
301 blockres = (1 << blockbits) - 1;
302 buf->f_blocks = (res.tbytes + blockres) >> blockbits;
303 buf->f_bfree = (res.fbytes + blockres) >> blockbits;
304 buf->f_bavail = (res.abytes + blockres) >> blockbits;
305
306 buf->f_files = res.tfiles;
307 buf->f_ffree = res.afiles;
308
309 buf->f_namelen = server->namelen;
310 out:
311 unlock_kernel();
312 return 0;
313
314 out_err:
315 dprintk("%s: statfs error = %d\n", __FUNCTION__, -error);
316 buf->f_bsize = buf->f_blocks = buf->f_bfree = buf->f_bavail = -1;
317 goto out;
318
319}
320
321/*
322 * Describe the mount options in force on this server representation
323 */
324static void nfs_show_mount_options(struct seq_file *m, struct nfs_server *nfss, int showdefaults)
325{
326 static struct proc_nfs_info {
327 int flag;
328 char *str;
329 char *nostr;
330 } nfs_info[] = {
331 { NFS_MOUNT_SOFT, ",soft", ",hard" },
332 { NFS_MOUNT_INTR, ",intr", "" },
333 { NFS_MOUNT_NOCTO, ",nocto", "" },
334 { NFS_MOUNT_NOAC, ",noac", "" },
335 { NFS_MOUNT_NONLM, ",nolock", "" },
336 { NFS_MOUNT_NOACL, ",noacl", "" },
337 { 0, NULL, NULL }
338 };
339 struct proc_nfs_info *nfs_infop;
340 char buf[12];
341 char *proto;
342
343 seq_printf(m, ",vers=%d", nfss->rpc_ops->version);
344 seq_printf(m, ",rsize=%d", nfss->rsize);
345 seq_printf(m, ",wsize=%d", nfss->wsize);
346 if (nfss->acregmin != 3*HZ || showdefaults)
347 seq_printf(m, ",acregmin=%d", nfss->acregmin/HZ);
348 if (nfss->acregmax != 60*HZ || showdefaults)
349 seq_printf(m, ",acregmax=%d", nfss->acregmax/HZ);
350 if (nfss->acdirmin != 30*HZ || showdefaults)
351 seq_printf(m, ",acdirmin=%d", nfss->acdirmin/HZ);
352 if (nfss->acdirmax != 60*HZ || showdefaults)
353 seq_printf(m, ",acdirmax=%d", nfss->acdirmax/HZ);
354 for (nfs_infop = nfs_info; nfs_infop->flag; nfs_infop++) {
355 if (nfss->flags & nfs_infop->flag)
356 seq_puts(m, nfs_infop->str);
357 else
358 seq_puts(m, nfs_infop->nostr);
359 }
360 switch (nfss->client->cl_xprt->prot) {
361 case IPPROTO_TCP:
362 proto = "tcp";
363 break;
364 case IPPROTO_UDP:
365 proto = "udp";
366 break;
367 default:
368 snprintf(buf, sizeof(buf), "%u", nfss->client->cl_xprt->prot);
369 proto = buf;
370 }
371 seq_printf(m, ",proto=%s", proto);
372 seq_printf(m, ",timeo=%lu", 10U * nfss->retrans_timeo / HZ);
373 seq_printf(m, ",retrans=%u", nfss->retrans_count);
374}
375
376/*
377 * Describe the mount options on this VFS mountpoint
378 */
379static int nfs_show_options(struct seq_file *m, struct vfsmount *mnt)
380{
381 struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
382
383 nfs_show_mount_options(m, nfss, 0);
384
385 seq_puts(m, ",addr=");
386 seq_escape(m, nfss->hostname, " \t\n\\");
387
388 return 0;
389}
390
391/*
392 * Present statistical information for this VFS mountpoint
393 */
394static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
395{
396 int i, cpu;
397 struct nfs_server *nfss = NFS_SB(mnt->mnt_sb);
398 struct rpc_auth *auth = nfss->client->cl_auth;
399 struct nfs_iostats totals = { };
400
401 seq_printf(m, "statvers=%s", NFS_IOSTAT_VERS);
402
403 /*
404 * Display all mount option settings
405 */
406 seq_printf(m, "\n\topts:\t");
407 seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? "ro" : "rw");
408 seq_puts(m, mnt->mnt_sb->s_flags & MS_SYNCHRONOUS ? ",sync" : "");
409 seq_puts(m, mnt->mnt_sb->s_flags & MS_NOATIME ? ",noatime" : "");
410 seq_puts(m, mnt->mnt_sb->s_flags & MS_NODIRATIME ? ",nodiratime" : "");
411 nfs_show_mount_options(m, nfss, 1);
412
413 seq_printf(m, "\n\tage:\t%lu", (jiffies - nfss->mount_time) / HZ);
414
415 seq_printf(m, "\n\tcaps:\t");
416 seq_printf(m, "caps=0x%x", nfss->caps);
417 seq_printf(m, ",wtmult=%d", nfss->wtmult);
418 seq_printf(m, ",dtsize=%d", nfss->dtsize);
419 seq_printf(m, ",bsize=%d", nfss->bsize);
420 seq_printf(m, ",namelen=%d", nfss->namelen);
421
422#ifdef CONFIG_NFS_V4
423 if (nfss->rpc_ops->version == 4) {
424 seq_printf(m, "\n\tnfsv4:\t");
425 seq_printf(m, "bm0=0x%x", nfss->attr_bitmask[0]);
426 seq_printf(m, ",bm1=0x%x", nfss->attr_bitmask[1]);
427 seq_printf(m, ",acl=0x%x", nfss->acl_bitmask);
428 }
429#endif
430
431 /*
432 * Display security flavor in effect for this mount
433 */
434 seq_printf(m, "\n\tsec:\tflavor=%d", auth->au_ops->au_flavor);
435 if (auth->au_flavor)
436 seq_printf(m, ",pseudoflavor=%d", auth->au_flavor);
437
438 /*
439 * Display superblock I/O counters
440 */
441 for_each_possible_cpu(cpu) {
442 struct nfs_iostats *stats;
443
444 preempt_disable();
445 stats = per_cpu_ptr(nfss->io_stats, cpu);
446
447 for (i = 0; i < __NFSIOS_COUNTSMAX; i++)
448 totals.events[i] += stats->events[i];
449 for (i = 0; i < __NFSIOS_BYTESMAX; i++)
450 totals.bytes[i] += stats->bytes[i];
451
452 preempt_enable();
453 }
454
455 seq_printf(m, "\n\tevents:\t");
456 for (i = 0; i < __NFSIOS_COUNTSMAX; i++)
457 seq_printf(m, "%lu ", totals.events[i]);
458 seq_printf(m, "\n\tbytes:\t");
459 for (i = 0; i < __NFSIOS_BYTESMAX; i++)
460 seq_printf(m, "%Lu ", totals.bytes[i]);
461 seq_printf(m, "\n");
462
463 rpc_print_iostats(m, nfss->client);
464
465 return 0;
466}
467
468/*
469 * Begin unmount by attempting to remove all automounted mountpoints we added
470 * in response to traversals
471 */
472static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags)
473{
474 struct nfs_server *server;
475 struct rpc_clnt *rpc;
476
477 shrink_submounts(vfsmnt, &nfs_automount_list);
478 if (!(flags & MNT_FORCE))
479 return;
480 /* -EIO all pending I/O */
481 server = NFS_SB(vfsmnt->mnt_sb);
482 rpc = server->client;
483 if (!IS_ERR(rpc))
484 rpc_killall_tasks(rpc);
485 rpc = server->client_acl;
486 if (!IS_ERR(rpc))
487 rpc_killall_tasks(rpc);
488}
489
490/*
491 * Obtain the root inode of the file system.
492 */
493static struct inode *
494nfs_get_root(struct super_block *sb, struct nfs_fh *rootfh, struct nfs_fsinfo *fsinfo)
495{
496 struct nfs_server *server = NFS_SB(sb);
497 int error;
498
499 error = server->rpc_ops->getroot(server, rootfh, fsinfo);
500 if (error < 0) {
501 dprintk("nfs_get_root: getattr error = %d\n", -error);
502 return ERR_PTR(error);
503 }
504
505 server->fsid = fsinfo->fattr->fsid;
506 return nfs_fhget(sb, rootfh, fsinfo->fattr);
507}
508
509/*
510 * Do NFS version-independent mount processing, and sanity checking
511 */
512static int
513nfs_sb_init(struct super_block *sb, rpc_authflavor_t authflavor)
514{
515 struct nfs_server *server;
516 struct inode *root_inode;
517 struct nfs_fattr fattr;
518 struct nfs_fsinfo fsinfo = {
519 .fattr = &fattr,
520 };
521 struct nfs_pathconf pathinfo = {
522 .fattr = &fattr,
523 };
524 int no_root_error = 0;
525 unsigned long max_rpc_payload;
526
527 /* We probably want something more informative here */
528 snprintf(sb->s_id, sizeof(sb->s_id), "%x:%x", MAJOR(sb->s_dev), MINOR(sb->s_dev));
529
530 server = NFS_SB(sb);
531
532 sb->s_magic = NFS_SUPER_MAGIC;
533
534 server->io_stats = nfs_alloc_iostats();
535 if (server->io_stats == NULL)
536 return -ENOMEM;
537
538 root_inode = nfs_get_root(sb, &server->fh, &fsinfo);
539 /* Did getting the root inode fail? */
540 if (IS_ERR(root_inode)) {
541 no_root_error = PTR_ERR(root_inode);
542 goto out_no_root;
543 }
544 sb->s_root = d_alloc_root(root_inode);
545 if (!sb->s_root) {
546 no_root_error = -ENOMEM;
547 goto out_no_root;
548 }
549 sb->s_root->d_op = server->rpc_ops->dentry_ops;
550
551 /* mount time stamp, in seconds */
552 server->mount_time = jiffies;
553
554 /* Get some general file system info */
555 if (server->namelen == 0 &&
556 server->rpc_ops->pathconf(server, &server->fh, &pathinfo) >= 0)
557 server->namelen = pathinfo.max_namelen;
558 /* Work out a lot of parameters */
559 if (server->rsize == 0)
560 server->rsize = nfs_block_size(fsinfo.rtpref, NULL);
561 if (server->wsize == 0)
562 server->wsize = nfs_block_size(fsinfo.wtpref, NULL);
563
564 if (fsinfo.rtmax >= 512 && server->rsize > fsinfo.rtmax)
565 server->rsize = nfs_block_size(fsinfo.rtmax, NULL);
566 if (fsinfo.wtmax >= 512 && server->wsize > fsinfo.wtmax)
567 server->wsize = nfs_block_size(fsinfo.wtmax, NULL);
568
569 max_rpc_payload = nfs_block_size(rpc_max_payload(server->client), NULL);
570 if (server->rsize > max_rpc_payload)
571 server->rsize = max_rpc_payload;
572 if (server->rsize > NFS_MAX_FILE_IO_SIZE)
573 server->rsize = NFS_MAX_FILE_IO_SIZE;
574 server->rpages = (server->rsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
575
576 if (server->wsize > max_rpc_payload)
577 server->wsize = max_rpc_payload;
578 if (server->wsize > NFS_MAX_FILE_IO_SIZE)
579 server->wsize = NFS_MAX_FILE_IO_SIZE;
580 server->wpages = (server->wsize + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
581
582 if (sb->s_blocksize == 0)
583 sb->s_blocksize = nfs_block_bits(server->wsize,
584 &sb->s_blocksize_bits);
585 server->wtmult = nfs_block_bits(fsinfo.wtmult, NULL);
586
587 server->dtsize = nfs_block_size(fsinfo.dtpref, NULL);
588 if (server->dtsize > PAGE_CACHE_SIZE)
589 server->dtsize = PAGE_CACHE_SIZE;
590 if (server->dtsize > server->rsize)
591 server->dtsize = server->rsize;
592
593 if (server->flags & NFS_MOUNT_NOAC) {
594 server->acregmin = server->acregmax = 0;
595 server->acdirmin = server->acdirmax = 0;
596 sb->s_flags |= MS_SYNCHRONOUS;
597 }
598 server->backing_dev_info.ra_pages = server->rpages * NFS_MAX_READAHEAD;
599
600 nfs_super_set_maxbytes(sb, fsinfo.maxfilesize);
601
602 server->client->cl_intr = (server->flags & NFS_MOUNT_INTR) ? 1 : 0;
603 server->client->cl_softrtry = (server->flags & NFS_MOUNT_SOFT) ? 1 : 0;
604
605 /* We're airborne Set socket buffersize */
606 rpc_setbufsize(server->client, server->wsize + 100, server->rsize + 100);
607 return 0;
608 /* Yargs. It didn't work out. */
609out_no_root:
610 dprintk("nfs_sb_init: get root inode failed: errno %d\n", -no_root_error);
611 if (!IS_ERR(root_inode))
612 iput(root_inode);
613 return no_root_error;
614}
615
616/*
617 * Initialise the timeout values for a connection
618 */
619static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, unsigned int timeo, unsigned int retrans)
620{
621 to->to_initval = timeo * HZ / 10;
622 to->to_retries = retrans;
623 if (!to->to_retries)
624 to->to_retries = 2;
625
626 switch (proto) {
627 case IPPROTO_TCP:
628 if (!to->to_initval)
629 to->to_initval = 60 * HZ;
630 if (to->to_initval > NFS_MAX_TCP_TIMEOUT)
631 to->to_initval = NFS_MAX_TCP_TIMEOUT;
632 to->to_increment = to->to_initval;
633 to->to_maxval = to->to_initval + (to->to_increment * to->to_retries);
634 to->to_exponential = 0;
635 break;
636 case IPPROTO_UDP:
637 default:
638 if (!to->to_initval)
639 to->to_initval = 11 * HZ / 10;
640 if (to->to_initval > NFS_MAX_UDP_TIMEOUT)
641 to->to_initval = NFS_MAX_UDP_TIMEOUT;
642 to->to_maxval = NFS_MAX_UDP_TIMEOUT;
643 to->to_exponential = 1;
644 break;
645 }
646}
647
648/*
649 * Create an RPC client handle.
650 */
651static struct rpc_clnt *
652nfs_create_client(struct nfs_server *server, const struct nfs_mount_data *data)
653{
654 struct rpc_timeout timeparms;
655 struct rpc_xprt *xprt = NULL;
656 struct rpc_clnt *clnt = NULL;
657 int proto = (data->flags & NFS_MOUNT_TCP) ? IPPROTO_TCP : IPPROTO_UDP;
658
659 nfs_init_timeout_values(&timeparms, proto, data->timeo, data->retrans);
660
661 server->retrans_timeo = timeparms.to_initval;
662 server->retrans_count = timeparms.to_retries;
663
664 /* create transport and client */
665 xprt = xprt_create_proto(proto, &server->addr, &timeparms);
666 if (IS_ERR(xprt)) {
667 dprintk("%s: cannot create RPC transport. Error = %ld\n",
668 __FUNCTION__, PTR_ERR(xprt));
669 return (struct rpc_clnt *)xprt;
670 }
671 clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
672 server->rpc_ops->version, data->pseudoflavor);
673 if (IS_ERR(clnt)) {
674 dprintk("%s: cannot create RPC client. Error = %ld\n",
675 __FUNCTION__, PTR_ERR(xprt));
676 goto out_fail;
677 }
678
679 clnt->cl_intr = 1;
680 clnt->cl_softrtry = 1;
681
682 return clnt;
683
684out_fail:
685 return clnt;
686}
687
688/*
689 * Clone a server record
690 */
691static struct nfs_server *nfs_clone_server(struct super_block *sb, struct nfs_clone_mount *data)
692{
693 struct nfs_server *server = NFS_SB(sb);
694 struct nfs_server *parent = NFS_SB(data->sb);
695 struct inode *root_inode;
696 struct nfs_fsinfo fsinfo;
697 void *err = ERR_PTR(-ENOMEM);
698
699 sb->s_op = data->sb->s_op;
700 sb->s_blocksize = data->sb->s_blocksize;
701 sb->s_blocksize_bits = data->sb->s_blocksize_bits;
702 sb->s_maxbytes = data->sb->s_maxbytes;
703
704 server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
705 server->io_stats = nfs_alloc_iostats();
706 if (server->io_stats == NULL)
707 goto out;
708
709 server->client = rpc_clone_client(parent->client);
710 if (IS_ERR((err = server->client)))
711 goto out;
712
713 if (!IS_ERR(parent->client_sys)) {
714 server->client_sys = rpc_clone_client(parent->client_sys);
715 if (IS_ERR((err = server->client_sys)))
716 goto out;
717 }
718 if (!IS_ERR(parent->client_acl)) {
719 server->client_acl = rpc_clone_client(parent->client_acl);
720 if (IS_ERR((err = server->client_acl)))
721 goto out;
722 }
723 root_inode = nfs_fhget(sb, data->fh, data->fattr);
724 if (!root_inode)
725 goto out;
726 sb->s_root = d_alloc_root(root_inode);
727 if (!sb->s_root)
728 goto out_put_root;
729 fsinfo.fattr = data->fattr;
730 if (NFS_PROTO(root_inode)->fsinfo(server, data->fh, &fsinfo) == 0)
731 nfs_super_set_maxbytes(sb, fsinfo.maxfilesize);
732 sb->s_root->d_op = server->rpc_ops->dentry_ops;
733 sb->s_flags |= MS_ACTIVE;
734 return server;
735out_put_root:
736 iput(root_inode);
737out:
738 return err;
739}
740
741/*
742 * Copy an existing superblock and attach revised data
743 */
744static struct super_block *nfs_clone_generic_sb(struct nfs_clone_mount *data,
745 struct super_block *(*fill_sb)(struct nfs_server *, struct nfs_clone_mount *),
746 struct nfs_server *(*fill_server)(struct super_block *, struct nfs_clone_mount *))
747{
748 struct nfs_server *server;
749 struct nfs_server *parent = NFS_SB(data->sb);
750 struct super_block *sb = ERR_PTR(-EINVAL);
751 void *err = ERR_PTR(-ENOMEM);
752 char *hostname;
753 int len;
754
755 server = kmalloc(sizeof(struct nfs_server), GFP_KERNEL);
756 if (server == NULL)
757 goto out_err;
758 memcpy(server, parent, sizeof(*server));
759 hostname = (data->hostname != NULL) ? data->hostname : parent->hostname;
760 len = strlen(hostname) + 1;
761 server->hostname = kmalloc(len, GFP_KERNEL);
762 if (server->hostname == NULL)
763 goto free_server;
764 memcpy(server->hostname, hostname, len);
765 if (rpciod_up() != 0)
766 goto free_hostname;
767
768 sb = fill_sb(server, data);
769 if (IS_ERR((err = sb)) || sb->s_root)
770 goto kill_rpciod;
771
772 server = fill_server(sb, data);
773 if (IS_ERR((err = server)))
774 goto out_deactivate;
775 return sb;
776out_deactivate:
777 up_write(&sb->s_umount);
778 deactivate_super(sb);
779 return (struct super_block *)err;
780kill_rpciod:
781 rpciod_down();
782free_hostname:
783 kfree(server->hostname);
784free_server:
785 kfree(server);
786out_err:
787 return (struct super_block *)err;
788}
789
790/*
791 * Set up an NFS2/3 superblock
792 *
793 * The way this works is that the mount process passes a structure
794 * in the data argument which contains the server's IP address
795 * and the root file handle obtained from the server's mount
796 * daemon. We stash these away in the private superblock fields.
797 */
798static int
799nfs_fill_super(struct super_block *sb, struct nfs_mount_data *data, int silent)
800{
801 struct nfs_server *server;
802 rpc_authflavor_t authflavor;
803
804 server = NFS_SB(sb);
805 sb->s_blocksize_bits = 0;
806 sb->s_blocksize = 0;
807 if (data->bsize)
808 sb->s_blocksize = nfs_block_size(data->bsize, &sb->s_blocksize_bits);
809 if (data->rsize)
810 server->rsize = nfs_block_size(data->rsize, NULL);
811 if (data->wsize)
812 server->wsize = nfs_block_size(data->wsize, NULL);
813 server->flags = data->flags & NFS_MOUNT_FLAGMASK;
814
815 server->acregmin = data->acregmin*HZ;
816 server->acregmax = data->acregmax*HZ;
817 server->acdirmin = data->acdirmin*HZ;
818 server->acdirmax = data->acdirmax*HZ;
819
820 /* Start lockd here, before we might error out */
821 if (!(server->flags & NFS_MOUNT_NONLM))
822 lockd_up();
823
824 server->namelen = data->namlen;
825 server->hostname = kmalloc(strlen(data->hostname) + 1, GFP_KERNEL);
826 if (!server->hostname)
827 return -ENOMEM;
828 strcpy(server->hostname, data->hostname);
829
830 /* Check NFS protocol revision and initialize RPC op vector
831 * and file handle pool. */
832#ifdef CONFIG_NFS_V3
833 if (server->flags & NFS_MOUNT_VER3) {
834 server->rpc_ops = &nfs_v3_clientops;
835 server->caps |= NFS_CAP_READDIRPLUS;
836 } else {
837 server->rpc_ops = &nfs_v2_clientops;
838 }
839#else
840 server->rpc_ops = &nfs_v2_clientops;
841#endif
842
843 /* Fill in pseudoflavor for mount version < 5 */
844 if (!(data->flags & NFS_MOUNT_SECFLAVOUR))
845 data->pseudoflavor = RPC_AUTH_UNIX;
846 authflavor = data->pseudoflavor; /* save for sb_init() */
847 /* XXX maybe we want to add a server->pseudoflavor field */
848
849 /* Create RPC client handles */
850 server->client = nfs_create_client(server, data);
851 if (IS_ERR(server->client))
852 return PTR_ERR(server->client);
853 /* RFC 2623, sec 2.3.2 */
854 if (authflavor != RPC_AUTH_UNIX) {
855 struct rpc_auth *auth;
856
857 server->client_sys = rpc_clone_client(server->client);
858 if (IS_ERR(server->client_sys))
859 return PTR_ERR(server->client_sys);
860 auth = rpcauth_create(RPC_AUTH_UNIX, server->client_sys);
861 if (IS_ERR(auth))
862 return PTR_ERR(auth);
863 } else {
864 atomic_inc(&server->client->cl_count);
865 server->client_sys = server->client;
866 }
867 if (server->flags & NFS_MOUNT_VER3) {
868#ifdef CONFIG_NFS_V3_ACL
869 if (!(server->flags & NFS_MOUNT_NOACL)) {
870 server->client_acl = rpc_bind_new_program(server->client, &nfsacl_program, 3);
871 /* No errors! Assume that Sun nfsacls are supported */
872 if (!IS_ERR(server->client_acl))
873 server->caps |= NFS_CAP_ACLS;
874 }
875#else
876 server->flags &= ~NFS_MOUNT_NOACL;
877#endif /* CONFIG_NFS_V3_ACL */
878 /*
879 * The VFS shouldn't apply the umask to mode bits. We will
880 * do so ourselves when necessary.
881 */
882 sb->s_flags |= MS_POSIXACL;
883 if (server->namelen == 0 || server->namelen > NFS3_MAXNAMLEN)
884 server->namelen = NFS3_MAXNAMLEN;
885 sb->s_time_gran = 1;
886 } else {
887 if (server->namelen == 0 || server->namelen > NFS2_MAXNAMLEN)
888 server->namelen = NFS2_MAXNAMLEN;
889 }
890
891 sb->s_op = &nfs_sops;
892 return nfs_sb_init(sb, authflavor);
893}
894
895static int nfs_set_super(struct super_block *s, void *data)
896{
897 s->s_fs_info = data;
898 return set_anon_super(s, data);
899}
900
901static int nfs_compare_super(struct super_block *sb, void *data)
902{
903 struct nfs_server *server = data;
904 struct nfs_server *old = NFS_SB(sb);
905
906 if (old->addr.sin_addr.s_addr != server->addr.sin_addr.s_addr)
907 return 0;
908 if (old->addr.sin_port != server->addr.sin_port)
909 return 0;
910 return !nfs_compare_fh(&old->fh, &server->fh);
911}
912
913static struct super_block *nfs_get_sb(struct file_system_type *fs_type,
914 int flags, const char *dev_name, void *raw_data)
915{
916 int error;
917 struct nfs_server *server = NULL;
918 struct super_block *s;
919 struct nfs_fh *root;
920 struct nfs_mount_data *data = raw_data;
921
922 s = ERR_PTR(-EINVAL);
923 if (data == NULL) {
924 dprintk("%s: missing data argument\n", __FUNCTION__);
925 goto out_err;
926 }
927 if (data->version <= 0 || data->version > NFS_MOUNT_VERSION) {
928 dprintk("%s: bad mount version\n", __FUNCTION__);
929 goto out_err;
930 }
931 switch (data->version) {
932 case 1:
933 data->namlen = 0;
934 case 2:
935 data->bsize = 0;
936 case 3:
937 if (data->flags & NFS_MOUNT_VER3) {
938 dprintk("%s: mount structure version %d does not support NFSv3\n",
939 __FUNCTION__,
940 data->version);
941 goto out_err;
942 }
943 data->root.size = NFS2_FHSIZE;
944 memcpy(data->root.data, data->old_root.data, NFS2_FHSIZE);
945 case 4:
946 if (data->flags & NFS_MOUNT_SECFLAVOUR) {
947 dprintk("%s: mount structure version %d does not support strong security\n",
948 __FUNCTION__,
949 data->version);
950 goto out_err;
951 }
952 case 5:
953 memset(data->context, 0, sizeof(data->context));
954 }
955#ifndef CONFIG_NFS_V3
956 /* If NFSv3 is not compiled in, return -EPROTONOSUPPORT */
957 s = ERR_PTR(-EPROTONOSUPPORT);
958 if (data->flags & NFS_MOUNT_VER3) {
959 dprintk("%s: NFSv3 not compiled into kernel\n", __FUNCTION__);
960 goto out_err;
961 }
962#endif /* CONFIG_NFS_V3 */
963
964 s = ERR_PTR(-ENOMEM);
965 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
966 if (!server)
967 goto out_err;
968 /* Zero out the NFS state stuff */
969 init_nfsv4_state(server);
970 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
971
972 root = &server->fh;
973 if (data->flags & NFS_MOUNT_VER3)
974 root->size = data->root.size;
975 else
976 root->size = NFS2_FHSIZE;
977 s = ERR_PTR(-EINVAL);
978 if (root->size > sizeof(root->data)) {
979 dprintk("%s: invalid root filehandle\n", __FUNCTION__);
980 goto out_err;
981 }
982 memcpy(root->data, data->root.data, root->size);
983
984 /* We now require that the mount process passes the remote address */
985 memcpy(&server->addr, &data->addr, sizeof(server->addr));
986 if (server->addr.sin_addr.s_addr == INADDR_ANY) {
987 dprintk("%s: mount program didn't pass remote address!\n",
988 __FUNCTION__);
989 goto out_err;
990 }
991
992 /* Fire up rpciod if not yet running */
993 s = ERR_PTR(rpciod_up());
994 if (IS_ERR(s)) {
995 dprintk("%s: couldn't start rpciod! Error = %ld\n",
996 __FUNCTION__, PTR_ERR(s));
997 goto out_err;
998 }
999
1000 s = sget(fs_type, nfs_compare_super, nfs_set_super, server);
1001 if (IS_ERR(s) || s->s_root)
1002 goto out_rpciod_down;
1003
1004 s->s_flags = flags;
1005
1006 error = nfs_fill_super(s, data, flags & MS_SILENT ? 1 : 0);
1007 if (error) {
1008 up_write(&s->s_umount);
1009 deactivate_super(s);
1010 return ERR_PTR(error);
1011 }
1012 s->s_flags |= MS_ACTIVE;
1013 return s;
1014out_rpciod_down:
1015 rpciod_down();
1016out_err:
1017 kfree(server);
1018 return s;
1019}
1020
1021static void nfs_kill_super(struct super_block *s)
1022{
1023 struct nfs_server *server = NFS_SB(s);
1024
1025 kill_anon_super(s);
1026
1027 if (!IS_ERR(server->client))
1028 rpc_shutdown_client(server->client);
1029 if (!IS_ERR(server->client_sys))
1030 rpc_shutdown_client(server->client_sys);
1031 if (!IS_ERR(server->client_acl))
1032 rpc_shutdown_client(server->client_acl);
1033
1034 if (!(server->flags & NFS_MOUNT_NONLM))
1035 lockd_down(); /* release rpc.lockd */
1036
1037 rpciod_down(); /* release rpciod */
1038
1039 nfs_free_iostats(server->io_stats);
1040 kfree(server->hostname);
1041 kfree(server);
1042 nfs_release_automount_timer();
1043}
1044
1045static struct super_block *nfs_clone_sb(struct nfs_server *server, struct nfs_clone_mount *data)
1046{
1047 struct super_block *sb;
1048
1049 server->fsid = data->fattr->fsid;
1050 nfs_copy_fh(&server->fh, data->fh);
1051 sb = sget(&nfs_fs_type, nfs_compare_super, nfs_set_super, server);
1052 if (!IS_ERR(sb) && sb->s_root == NULL && !(server->flags & NFS_MOUNT_NONLM))
1053 lockd_up();
1054 return sb;
1055}
1056
1057static struct super_block *nfs_clone_nfs_sb(struct file_system_type *fs_type,
1058 int flags, const char *dev_name, void *raw_data)
1059{
1060 struct nfs_clone_mount *data = raw_data;
1061 return nfs_clone_generic_sb(data, nfs_clone_sb, nfs_clone_server);
1062}
1063
1064#ifdef CONFIG_NFS_V4
1065static struct rpc_clnt *nfs4_create_client(struct nfs_server *server,
1066 struct rpc_timeout *timeparms, int proto, rpc_authflavor_t flavor)
1067{
1068 struct nfs4_client *clp;
1069 struct rpc_xprt *xprt = NULL;
1070 struct rpc_clnt *clnt = NULL;
1071 int err = -EIO;
1072
1073 clp = nfs4_get_client(&server->addr.sin_addr);
1074 if (!clp) {
1075 dprintk("%s: failed to create NFS4 client.\n", __FUNCTION__);
1076 return ERR_PTR(err);
1077 }
1078
1079 /* Now create transport and client */
1080 down_write(&clp->cl_sem);
1081 if (IS_ERR(clp->cl_rpcclient)) {
1082 xprt = xprt_create_proto(proto, &server->addr, timeparms);
1083 if (IS_ERR(xprt)) {
1084 up_write(&clp->cl_sem);
1085 err = PTR_ERR(xprt);
1086 dprintk("%s: cannot create RPC transport. Error = %d\n",
1087 __FUNCTION__, err);
1088 goto out_fail;
1089 }
1090 /* Bind to a reserved port! */
1091 xprt->resvport = 1;
1092 clnt = rpc_create_client(xprt, server->hostname, &nfs_program,
1093 server->rpc_ops->version, flavor);
1094 if (IS_ERR(clnt)) {
1095 up_write(&clp->cl_sem);
1096 err = PTR_ERR(clnt);
1097 dprintk("%s: cannot create RPC client. Error = %d\n",
1098 __FUNCTION__, err);
1099 goto out_fail;
1100 }
1101 clnt->cl_intr = 1;
1102 clnt->cl_softrtry = 1;
1103 clp->cl_rpcclient = clnt;
1104 memcpy(clp->cl_ipaddr, server->ip_addr, sizeof(clp->cl_ipaddr));
1105 nfs_idmap_new(clp);
1106 }
1107 list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks);
1108 clnt = rpc_clone_client(clp->cl_rpcclient);
1109 if (!IS_ERR(clnt))
1110 server->nfs4_state = clp;
1111 up_write(&clp->cl_sem);
1112 clp = NULL;
1113
1114 if (IS_ERR(clnt)) {
1115 dprintk("%s: cannot create RPC client. Error = %d\n",
1116 __FUNCTION__, err);
1117 return clnt;
1118 }
1119
1120 if (server->nfs4_state->cl_idmap == NULL) {
1121 dprintk("%s: failed to create idmapper.\n", __FUNCTION__);
1122 return ERR_PTR(-ENOMEM);
1123 }
1124
1125 if (clnt->cl_auth->au_flavor != flavor) {
1126 struct rpc_auth *auth;
1127
1128 auth = rpcauth_create(flavor, clnt);
1129 if (IS_ERR(auth)) {
1130 dprintk("%s: couldn't create credcache!\n", __FUNCTION__);
1131 return (struct rpc_clnt *)auth;
1132 }
1133 }
1134 return clnt;
1135
1136 out_fail:
1137 if (clp)
1138 nfs4_put_client(clp);
1139 return ERR_PTR(err);
1140}
1141
1142/*
1143 * Set up an NFS4 superblock
1144 */
1145static int nfs4_fill_super(struct super_block *sb, struct nfs4_mount_data *data, int silent)
1146{
1147 struct nfs_server *server;
1148 struct rpc_timeout timeparms;
1149 rpc_authflavor_t authflavour;
1150 int err = -EIO;
1151
1152 sb->s_blocksize_bits = 0;
1153 sb->s_blocksize = 0;
1154 server = NFS_SB(sb);
1155 if (data->rsize != 0)
1156 server->rsize = nfs_block_size(data->rsize, NULL);
1157 if (data->wsize != 0)
1158 server->wsize = nfs_block_size(data->wsize, NULL);
1159 server->flags = data->flags & NFS_MOUNT_FLAGMASK;
1160 server->caps = NFS_CAP_ATOMIC_OPEN;
1161
1162 server->acregmin = data->acregmin*HZ;
1163 server->acregmax = data->acregmax*HZ;
1164 server->acdirmin = data->acdirmin*HZ;
1165 server->acdirmax = data->acdirmax*HZ;
1166
1167 server->rpc_ops = &nfs_v4_clientops;
1168
1169 nfs_init_timeout_values(&timeparms, data->proto, data->timeo, data->retrans);
1170
1171 server->retrans_timeo = timeparms.to_initval;
1172 server->retrans_count = timeparms.to_retries;
1173
1174 /* Now create transport and client */
1175 authflavour = RPC_AUTH_UNIX;
1176 if (data->auth_flavourlen != 0) {
1177 if (data->auth_flavourlen != 1) {
1178 dprintk("%s: Invalid number of RPC auth flavours %d.\n",
1179 __FUNCTION__, data->auth_flavourlen);
1180 err = -EINVAL;
1181 goto out_fail;
1182 }
1183 if (copy_from_user(&authflavour, data->auth_flavours, sizeof(authflavour))) {
1184 err = -EFAULT;
1185 goto out_fail;
1186 }
1187 }
1188
1189 server->client = nfs4_create_client(server, &timeparms, data->proto, authflavour);
1190 if (IS_ERR(server->client)) {
1191 err = PTR_ERR(server->client);
1192 dprintk("%s: cannot create RPC client. Error = %d\n",
1193 __FUNCTION__, err);
1194 goto out_fail;
1195 }
1196
1197 sb->s_time_gran = 1;
1198
1199 sb->s_op = &nfs4_sops;
1200 err = nfs_sb_init(sb, authflavour);
1201
1202 out_fail:
1203 return err;
1204}
1205
1206static int nfs4_compare_super(struct super_block *sb, void *data)
1207{
1208 struct nfs_server *server = data;
1209 struct nfs_server *old = NFS_SB(sb);
1210
1211 if (strcmp(server->hostname, old->hostname) != 0)
1212 return 0;
1213 if (strcmp(server->mnt_path, old->mnt_path) != 0)
1214 return 0;
1215 return 1;
1216}
1217
1218static void *
1219nfs_copy_user_string(char *dst, struct nfs_string *src, int maxlen)
1220{
1221 void *p = NULL;
1222
1223 if (!src->len)
1224 return ERR_PTR(-EINVAL);
1225 if (src->len < maxlen)
1226 maxlen = src->len;
1227 if (dst == NULL) {
1228 p = dst = kmalloc(maxlen + 1, GFP_KERNEL);
1229 if (p == NULL)
1230 return ERR_PTR(-ENOMEM);
1231 }
1232 if (copy_from_user(dst, src->data, maxlen)) {
1233 kfree(p);
1234 return ERR_PTR(-EFAULT);
1235 }
1236 dst[maxlen] = '\0';
1237 return dst;
1238}
1239
1240static struct super_block *nfs4_get_sb(struct file_system_type *fs_type,
1241 int flags, const char *dev_name, void *raw_data)
1242{
1243 int error;
1244 struct nfs_server *server;
1245 struct super_block *s;
1246 struct nfs4_mount_data *data = raw_data;
1247 void *p;
1248
1249 if (data == NULL) {
1250 dprintk("%s: missing data argument\n", __FUNCTION__);
1251 return ERR_PTR(-EINVAL);
1252 }
1253 if (data->version <= 0 || data->version > NFS4_MOUNT_VERSION) {
1254 dprintk("%s: bad mount version\n", __FUNCTION__);
1255 return ERR_PTR(-EINVAL);
1256 }
1257
1258 server = kzalloc(sizeof(struct nfs_server), GFP_KERNEL);
1259 if (!server)
1260 return ERR_PTR(-ENOMEM);
1261 /* Zero out the NFS state stuff */
1262 init_nfsv4_state(server);
1263 server->client = server->client_sys = server->client_acl = ERR_PTR(-EINVAL);
1264
1265 p = nfs_copy_user_string(NULL, &data->hostname, 256);
1266 if (IS_ERR(p))
1267 goto out_err;
1268 server->hostname = p;
1269
1270 p = nfs_copy_user_string(NULL, &data->mnt_path, 1024);
1271 if (IS_ERR(p))
1272 goto out_err;
1273 server->mnt_path = p;
1274
1275 p = nfs_copy_user_string(server->ip_addr, &data->client_addr,
1276 sizeof(server->ip_addr) - 1);
1277 if (IS_ERR(p))
1278 goto out_err;
1279
1280 /* We now require that the mount process passes the remote address */
1281 if (data->host_addrlen != sizeof(server->addr)) {
1282 s = ERR_PTR(-EINVAL);
1283 goto out_free;
1284 }
1285 if (copy_from_user(&server->addr, data->host_addr, sizeof(server->addr))) {
1286 s = ERR_PTR(-EFAULT);
1287 goto out_free;
1288 }
1289 if (server->addr.sin_family != AF_INET ||
1290 server->addr.sin_addr.s_addr == INADDR_ANY) {
1291 dprintk("%s: mount program didn't pass remote IP address!\n",
1292 __FUNCTION__);
1293 s = ERR_PTR(-EINVAL);
1294 goto out_free;
1295 }
1296
1297 /* Fire up rpciod if not yet running */
1298 s = ERR_PTR(rpciod_up());
1299 if (IS_ERR(s)) {
1300 dprintk("%s: couldn't start rpciod! Error = %ld\n",
1301 __FUNCTION__, PTR_ERR(s));
1302 goto out_free;
1303 }
1304
1305 s = sget(fs_type, nfs4_compare_super, nfs_set_super, server);
1306
1307 if (IS_ERR(s) || s->s_root)
1308 goto out_free;
1309
1310 s->s_flags = flags;
1311
1312 error = nfs4_fill_super(s, data, flags & MS_SILENT ? 1 : 0);
1313 if (error) {
1314 up_write(&s->s_umount);
1315 deactivate_super(s);
1316 return ERR_PTR(error);
1317 }
1318 s->s_flags |= MS_ACTIVE;
1319 return s;
1320out_err:
1321 s = (struct super_block *)p;
1322out_free:
1323 kfree(server->mnt_path);
1324 kfree(server->hostname);
1325 kfree(server);
1326 return s;
1327}
1328
1329static void nfs4_kill_super(struct super_block *sb)
1330{
1331 struct nfs_server *server = NFS_SB(sb);
1332
1333 nfs_return_all_delegations(sb);
1334 kill_anon_super(sb);
1335
1336 nfs4_renewd_prepare_shutdown(server);
1337
1338 if (server->client != NULL && !IS_ERR(server->client))
1339 rpc_shutdown_client(server->client);
1340
1341 destroy_nfsv4_state(server);
1342
1343 rpciod_down();
1344
1345 nfs_free_iostats(server->io_stats);
1346 kfree(server->hostname);
1347 kfree(server);
1348 nfs_release_automount_timer();
1349}
1350
1351/*
1352 * Constructs the SERVER-side path
1353 */
1354static inline char *nfs4_dup_path(const struct dentry *dentry)
1355{
1356 char *page = (char *) __get_free_page(GFP_USER);
1357 char *path;
1358
1359 path = nfs4_path(dentry, page, PAGE_SIZE);
1360 if (!IS_ERR(path)) {
1361 int len = PAGE_SIZE + page - path;
1362 char *tmp = path;
1363
1364 path = kmalloc(len, GFP_KERNEL);
1365 if (path)
1366 memcpy(path, tmp, len);
1367 else
1368 path = ERR_PTR(-ENOMEM);
1369 }
1370 free_page((unsigned long)page);
1371 return path;
1372}
1373
1374static struct super_block *nfs4_clone_sb(struct nfs_server *server, struct nfs_clone_mount *data)
1375{
1376 const struct dentry *dentry = data->dentry;
1377 struct nfs4_client *clp = server->nfs4_state;
1378 struct super_block *sb;
1379
1380 server->fsid = data->fattr->fsid;
1381 nfs_copy_fh(&server->fh, data->fh);
1382 server->mnt_path = nfs4_dup_path(dentry);
1383 if (IS_ERR(server->mnt_path)) {
1384 sb = (struct super_block *)server->mnt_path;
1385 goto err;
1386 }
1387 sb = sget(&nfs4_fs_type, nfs4_compare_super, nfs_set_super, server);
1388 if (IS_ERR(sb) || sb->s_root)
1389 goto free_path;
1390 nfs4_server_capabilities(server, &server->fh);
1391
1392 down_write(&clp->cl_sem);
1393 atomic_inc(&clp->cl_count);
1394 list_add_tail(&server->nfs4_siblings, &clp->cl_superblocks);
1395 up_write(&clp->cl_sem);
1396 return sb;
1397free_path:
1398 kfree(server->mnt_path);
1399err:
1400 server->mnt_path = NULL;
1401 return sb;
1402}
1403
1404static struct super_block *nfs_clone_nfs4_sb(struct file_system_type *fs_type,
1405 int flags, const char *dev_name, void *raw_data)
1406{
1407 struct nfs_clone_mount *data = raw_data;
1408 return nfs_clone_generic_sb(data, nfs4_clone_sb, nfs_clone_server);
1409}
1410
1411static struct super_block *nfs4_referral_sb(struct nfs_server *server, struct nfs_clone_mount *data)
1412{
1413 struct super_block *sb = ERR_PTR(-ENOMEM);
1414 int len;
1415
1416 len = strlen(data->mnt_path) + 1;
1417 server->mnt_path = kmalloc(len, GFP_KERNEL);
1418 if (server->mnt_path == NULL)
1419 goto err;
1420 memcpy(server->mnt_path, data->mnt_path, len);
1421 memcpy(&server->addr, data->addr, sizeof(struct sockaddr_in));
1422
1423 sb = sget(&nfs4_fs_type, nfs4_compare_super, nfs_set_super, server);
1424 if (IS_ERR(sb) || sb->s_root)
1425 goto free_path;
1426 return sb;
1427free_path:
1428 kfree(server->mnt_path);
1429err:
1430 server->mnt_path = NULL;
1431 return sb;
1432}
1433
1434static struct nfs_server *nfs4_referral_server(struct super_block *sb, struct nfs_clone_mount *data)
1435{
1436 struct nfs_server *server = NFS_SB(sb);
1437 struct rpc_timeout timeparms;
1438 int proto, timeo, retrans;
1439 void *err;
1440
1441 proto = IPPROTO_TCP;
1442 /* Since we are following a referral and there may be alternatives,
1443 set the timeouts and retries to low values */
1444 timeo = 2;
1445 retrans = 1;
1446 nfs_init_timeout_values(&timeparms, proto, timeo, retrans);
1447
1448 server->client = nfs4_create_client(server, &timeparms, proto, data->authflavor);
1449 if (IS_ERR((err = server->client)))
1450 goto out_err;
1451
1452 sb->s_time_gran = 1;
1453 sb->s_op = &nfs4_sops;
1454 err = ERR_PTR(nfs_sb_init(sb, data->authflavor));
1455 if (!IS_ERR(err))
1456 return server;
1457out_err:
1458 return (struct nfs_server *)err;
1459}
1460
1461static struct super_block *nfs_referral_nfs4_sb(struct file_system_type *fs_type,
1462 int flags, const char *dev_name, void *raw_data)
1463{
1464 struct nfs_clone_mount *data = raw_data;
1465 return nfs_clone_generic_sb(data, nfs4_referral_sb, nfs4_referral_server);
1466}
1467
1468#endif
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index e03abbd8302..b383fdd3a15 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -1529,7 +1529,7 @@ int nfs_sync_inode_wait(struct inode *inode, unsigned long idx_start,
1529 return ret; 1529 return ret;
1530} 1530}
1531 1531
1532int nfs_init_writepagecache(void) 1532int __init nfs_init_writepagecache(void)
1533{ 1533{
1534 nfs_wdata_cachep = kmem_cache_create("nfs_write_data", 1534 nfs_wdata_cachep = kmem_cache_create("nfs_write_data",
1535 sizeof(struct nfs_write_data), 1535 sizeof(struct nfs_write_data),
@@ -1551,7 +1551,7 @@ int nfs_init_writepagecache(void)
1551 return 0; 1551 return 0;
1552} 1552}
1553 1553
1554void nfs_destroy_writepagecache(void) 1554void __exit nfs_destroy_writepagecache(void)
1555{ 1555{
1556 mempool_destroy(nfs_commit_mempool); 1556 mempool_destroy(nfs_commit_mempool);
1557 mempool_destroy(nfs_wdata_mempool); 1557 mempool_destroy(nfs_wdata_mempool);