diff options
Diffstat (limited to 'fs/nfsd/export.c')
-rw-r--r-- | fs/nfsd/export.c | 57 |
1 files changed, 29 insertions, 28 deletions
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index c1c9e035d4a4..a0c4016413f1 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
@@ -1,7 +1,5 @@ | |||
1 | #define MSNFS /* HACK HACK */ | 1 | #define MSNFS /* HACK HACK */ |
2 | /* | 2 | /* |
3 | * linux/fs/nfsd/export.c | ||
4 | * | ||
5 | * NFS exporting and validation. | 3 | * NFS exporting and validation. |
6 | * | 4 | * |
7 | * We maintain a list of clients, each of which has a list of | 5 | * We maintain a list of clients, each of which has a list of |
@@ -14,29 +12,16 @@ | |||
14 | * Copyright (C) 1995, 1996 Olaf Kirch, <okir@monad.swb.de> | 12 | * Copyright (C) 1995, 1996 Olaf Kirch, <okir@monad.swb.de> |
15 | */ | 13 | */ |
16 | 14 | ||
17 | #include <linux/unistd.h> | ||
18 | #include <linux/slab.h> | ||
19 | #include <linux/stat.h> | ||
20 | #include <linux/in.h> | ||
21 | #include <linux/seq_file.h> | ||
22 | #include <linux/syscalls.h> | ||
23 | #include <linux/rwsem.h> | ||
24 | #include <linux/dcache.h> | ||
25 | #include <linux/namei.h> | 15 | #include <linux/namei.h> |
26 | #include <linux/mount.h> | ||
27 | #include <linux/hash.h> | ||
28 | #include <linux/module.h> | 16 | #include <linux/module.h> |
29 | #include <linux/exportfs.h> | 17 | #include <linux/exportfs.h> |
30 | 18 | ||
31 | #include <linux/sunrpc/svc.h> | ||
32 | #include <linux/nfsd/nfsd.h> | ||
33 | #include <linux/nfsd/nfsfh.h> | ||
34 | #include <linux/nfsd/syscall.h> | 19 | #include <linux/nfsd/syscall.h> |
35 | #include <linux/lockd/bind.h> | ||
36 | #include <linux/sunrpc/msg_prot.h> | ||
37 | #include <linux/sunrpc/gss_api.h> | ||
38 | #include <net/ipv6.h> | 20 | #include <net/ipv6.h> |
39 | 21 | ||
22 | #include "nfsd.h" | ||
23 | #include "nfsfh.h" | ||
24 | |||
40 | #define NFSDDBG_FACILITY NFSDDBG_EXPORT | 25 | #define NFSDDBG_FACILITY NFSDDBG_EXPORT |
41 | 26 | ||
42 | typedef struct auth_domain svc_client; | 27 | typedef struct auth_domain svc_client; |
@@ -369,16 +354,25 @@ static struct svc_export *svc_export_update(struct svc_export *new, | |||
369 | struct svc_export *old); | 354 | struct svc_export *old); |
370 | static struct svc_export *svc_export_lookup(struct svc_export *); | 355 | static struct svc_export *svc_export_lookup(struct svc_export *); |
371 | 356 | ||
372 | static int check_export(struct inode *inode, int flags, unsigned char *uuid) | 357 | static int check_export(struct inode *inode, int *flags, unsigned char *uuid) |
373 | { | 358 | { |
374 | 359 | ||
375 | /* We currently export only dirs and regular files. | 360 | /* |
376 | * This is what umountd does. | 361 | * We currently export only dirs, regular files, and (for v4 |
362 | * pseudoroot) symlinks. | ||
377 | */ | 363 | */ |
378 | if (!S_ISDIR(inode->i_mode) && | 364 | if (!S_ISDIR(inode->i_mode) && |
365 | !S_ISLNK(inode->i_mode) && | ||
379 | !S_ISREG(inode->i_mode)) | 366 | !S_ISREG(inode->i_mode)) |
380 | return -ENOTDIR; | 367 | return -ENOTDIR; |
381 | 368 | ||
369 | /* | ||
370 | * Mountd should never pass down a writeable V4ROOT export, but, | ||
371 | * just to make sure: | ||
372 | */ | ||
373 | if (*flags & NFSEXP_V4ROOT) | ||
374 | *flags |= NFSEXP_READONLY; | ||
375 | |||
382 | /* There are two requirements on a filesystem to be exportable. | 376 | /* There are two requirements on a filesystem to be exportable. |
383 | * 1: We must be able to identify the filesystem from a number. | 377 | * 1: We must be able to identify the filesystem from a number. |
384 | * either a device number (so FS_REQUIRES_DEV needed) | 378 | * either a device number (so FS_REQUIRES_DEV needed) |
@@ -387,7 +381,7 @@ static int check_export(struct inode *inode, int flags, unsigned char *uuid) | |||
387 | * This means that s_export_op must be set. | 381 | * This means that s_export_op must be set. |
388 | */ | 382 | */ |
389 | if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) && | 383 | if (!(inode->i_sb->s_type->fs_flags & FS_REQUIRES_DEV) && |
390 | !(flags & NFSEXP_FSID) && | 384 | !(*flags & NFSEXP_FSID) && |
391 | uuid == NULL) { | 385 | uuid == NULL) { |
392 | dprintk("exp_export: export of non-dev fs without fsid\n"); | 386 | dprintk("exp_export: export of non-dev fs without fsid\n"); |
393 | return -EINVAL; | 387 | return -EINVAL; |
@@ -602,7 +596,7 @@ static int svc_export_parse(struct cache_detail *cd, char *mesg, int mlen) | |||
602 | goto out4; | 596 | goto out4; |
603 | } | 597 | } |
604 | 598 | ||
605 | err = check_export(exp.ex_path.dentry->d_inode, exp.ex_flags, | 599 | err = check_export(exp.ex_path.dentry->d_inode, &exp.ex_flags, |
606 | exp.ex_uuid); | 600 | exp.ex_uuid); |
607 | if (err) | 601 | if (err) |
608 | goto out4; | 602 | goto out4; |
@@ -1041,7 +1035,7 @@ exp_export(struct nfsctl_export *nxp) | |||
1041 | goto finish; | 1035 | goto finish; |
1042 | } | 1036 | } |
1043 | 1037 | ||
1044 | err = check_export(path.dentry->d_inode, nxp->ex_flags, NULL); | 1038 | err = check_export(path.dentry->d_inode, &nxp->ex_flags, NULL); |
1045 | if (err) goto finish; | 1039 | if (err) goto finish; |
1046 | 1040 | ||
1047 | err = -ENOMEM; | 1041 | err = -ENOMEM; |
@@ -1320,6 +1314,15 @@ rqst_exp_parent(struct svc_rqst *rqstp, struct path *path) | |||
1320 | return exp; | 1314 | return exp; |
1321 | } | 1315 | } |
1322 | 1316 | ||
1317 | static struct svc_export *find_fsidzero_export(struct svc_rqst *rqstp) | ||
1318 | { | ||
1319 | u32 fsidv[2]; | ||
1320 | |||
1321 | mk_fsid(FSID_NUM, fsidv, 0, 0, 0, NULL); | ||
1322 | |||
1323 | return rqst_exp_find(rqstp, FSID_NUM, fsidv); | ||
1324 | } | ||
1325 | |||
1323 | /* | 1326 | /* |
1324 | * Called when we need the filehandle for the root of the pseudofs, | 1327 | * Called when we need the filehandle for the root of the pseudofs, |
1325 | * for a given NFSv4 client. The root is defined to be the | 1328 | * for a given NFSv4 client. The root is defined to be the |
@@ -1330,11 +1333,8 @@ exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp) | |||
1330 | { | 1333 | { |
1331 | struct svc_export *exp; | 1334 | struct svc_export *exp; |
1332 | __be32 rv; | 1335 | __be32 rv; |
1333 | u32 fsidv[2]; | ||
1334 | |||
1335 | mk_fsid(FSID_NUM, fsidv, 0, 0, 0, NULL); | ||
1336 | 1336 | ||
1337 | exp = rqst_exp_find(rqstp, FSID_NUM, fsidv); | 1337 | exp = find_fsidzero_export(rqstp); |
1338 | if (IS_ERR(exp)) | 1338 | if (IS_ERR(exp)) |
1339 | return nfserrno(PTR_ERR(exp)); | 1339 | return nfserrno(PTR_ERR(exp)); |
1340 | rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL); | 1340 | rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL); |
@@ -1425,6 +1425,7 @@ static struct flags { | |||
1425 | { NFSEXP_CROSSMOUNT, {"crossmnt", ""}}, | 1425 | { NFSEXP_CROSSMOUNT, {"crossmnt", ""}}, |
1426 | { NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}}, | 1426 | { NFSEXP_NOSUBTREECHECK, {"no_subtree_check", ""}}, |
1427 | { NFSEXP_NOAUTHNLM, {"insecure_locks", ""}}, | 1427 | { NFSEXP_NOAUTHNLM, {"insecure_locks", ""}}, |
1428 | { NFSEXP_V4ROOT, {"v4root", ""}}, | ||
1428 | #ifdef MSNFS | 1429 | #ifdef MSNFS |
1429 | { NFSEXP_MSNFS, {"msnfs", ""}}, | 1430 | { NFSEXP_MSNFS, {"msnfs", ""}}, |
1430 | #endif | 1431 | #endif |