diff options
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/auth.c | 12 | ||||
-rw-r--r-- | fs/nfsd/cache.h | 83 | ||||
-rw-r--r-- | fs/nfsd/export.c | 57 | ||||
-rw-r--r-- | fs/nfsd/lockd.c | 10 | ||||
-rw-r--r-- | fs/nfsd/nfs2acl.c | 27 | ||||
-rw-r--r-- | fs/nfsd/nfs3acl.c | 15 | ||||
-rw-r--r-- | fs/nfsd/nfs3proc.c | 20 | ||||
-rw-r--r-- | fs/nfsd/nfs3xdr.c | 15 | ||||
-rw-r--r-- | fs/nfsd/nfs4acl.c | 12 | ||||
-rw-r--r-- | fs/nfsd/nfs4callback.c | 19 | ||||
-rw-r--r-- | fs/nfsd/nfs4idmap.c | 17 | ||||
-rw-r--r-- | fs/nfsd/nfs4proc.c | 19 | ||||
-rw-r--r-- | fs/nfsd/nfs4recover.c | 16 | ||||
-rw-r--r-- | fs/nfsd/nfs4state.c | 84 | ||||
-rw-r--r-- | fs/nfsd/nfs4xdr.c | 26 | ||||
-rw-r--r-- | fs/nfsd/nfscache.c | 14 | ||||
-rw-r--r-- | fs/nfsd/nfsctl.c | 51 | ||||
-rw-r--r-- | fs/nfsd/nfsd.h | 338 | ||||
-rw-r--r-- | fs/nfsd/nfsfh.c | 102 | ||||
-rw-r--r-- | fs/nfsd/nfsfh.h | 208 | ||||
-rw-r--r-- | fs/nfsd/nfsproc.c | 22 | ||||
-rw-r--r-- | fs/nfsd/nfssvc.c | 22 | ||||
-rw-r--r-- | fs/nfsd/nfsxdr.c | 12 | ||||
-rw-r--r-- | fs/nfsd/state.h | 408 | ||||
-rw-r--r-- | fs/nfsd/stats.c | 11 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 143 | ||||
-rw-r--r-- | fs/nfsd/vfs.h | 101 | ||||
-rw-r--r-- | fs/nfsd/xdr.h | 173 | ||||
-rw-r--r-- | fs/nfsd/xdr3.h | 344 | ||||
-rw-r--r-- | fs/nfsd/xdr4.h | 562 |
30 files changed, 2500 insertions, 443 deletions
diff --git a/fs/nfsd/auth.c b/fs/nfsd/auth.c index 36fcabbf5186..79717a40daba 100644 --- a/fs/nfsd/auth.c +++ b/fs/nfsd/auth.c | |||
@@ -1,15 +1,7 @@ | |||
1 | /* | 1 | /* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */ |
2 | * linux/fs/nfsd/auth.c | ||
3 | * | ||
4 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> | ||
5 | */ | ||
6 | 2 | ||
7 | #include <linux/types.h> | ||
8 | #include <linux/sched.h> | 3 | #include <linux/sched.h> |
9 | #include <linux/sunrpc/svc.h> | 4 | #include "nfsd.h" |
10 | #include <linux/sunrpc/svcauth.h> | ||
11 | #include <linux/nfsd/nfsd.h> | ||
12 | #include <linux/nfsd/export.h> | ||
13 | #include "auth.h" | 5 | #include "auth.h" |
14 | 6 | ||
15 | int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp) | 7 | int nfsexp_flags(struct svc_rqst *rqstp, struct svc_export *exp) |
diff --git a/fs/nfsd/cache.h b/fs/nfsd/cache.h new file mode 100644 index 000000000000..d892be61016c --- /dev/null +++ b/fs/nfsd/cache.h | |||
@@ -0,0 +1,83 @@ | |||
1 | /* | ||
2 | * Request reply cache. This was heavily inspired by the | ||
3 | * implementation in 4.3BSD/4.4BSD. | ||
4 | * | ||
5 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> | ||
6 | */ | ||
7 | |||
8 | #ifndef NFSCACHE_H | ||
9 | #define NFSCACHE_H | ||
10 | |||
11 | #include <linux/sunrpc/svc.h> | ||
12 | |||
13 | /* | ||
14 | * Representation of a reply cache entry. | ||
15 | */ | ||
16 | struct svc_cacherep { | ||
17 | struct hlist_node c_hash; | ||
18 | struct list_head c_lru; | ||
19 | |||
20 | unsigned char c_state, /* unused, inprog, done */ | ||
21 | c_type, /* status, buffer */ | ||
22 | c_secure : 1; /* req came from port < 1024 */ | ||
23 | struct sockaddr_in c_addr; | ||
24 | __be32 c_xid; | ||
25 | u32 c_prot; | ||
26 | u32 c_proc; | ||
27 | u32 c_vers; | ||
28 | unsigned long c_timestamp; | ||
29 | union { | ||
30 | struct kvec u_vec; | ||
31 | __be32 u_status; | ||
32 | } c_u; | ||
33 | }; | ||
34 | |||
35 | #define c_replvec c_u.u_vec | ||
36 | #define c_replstat c_u.u_status | ||
37 | |||
38 | /* cache entry states */ | ||
39 | enum { | ||
40 | RC_UNUSED, | ||
41 | RC_INPROG, | ||
42 | RC_DONE | ||
43 | }; | ||
44 | |||
45 | /* return values */ | ||
46 | enum { | ||
47 | RC_DROPIT, | ||
48 | RC_REPLY, | ||
49 | RC_DOIT, | ||
50 | RC_INTR | ||
51 | }; | ||
52 | |||
53 | /* | ||
54 | * Cache types. | ||
55 | * We may want to add more types one day, e.g. for diropres and | ||
56 | * attrstat replies. Using cache entries with fixed length instead | ||
57 | * of buffer pointers may be more efficient. | ||
58 | */ | ||
59 | enum { | ||
60 | RC_NOCACHE, | ||
61 | RC_REPLSTAT, | ||
62 | RC_REPLBUFF, | ||
63 | }; | ||
64 | |||
65 | /* | ||
66 | * If requests are retransmitted within this interval, they're dropped. | ||
67 | */ | ||
68 | #define RC_DELAY (HZ/5) | ||
69 | |||
70 | int nfsd_reply_cache_init(void); | ||
71 | void nfsd_reply_cache_shutdown(void); | ||
72 | int nfsd_cache_lookup(struct svc_rqst *, int); | ||
73 | void nfsd_cache_update(struct svc_rqst *, int, __be32 *); | ||
74 | |||
75 | #ifdef CONFIG_NFSD_V4 | ||
76 | void nfsd4_set_statp(struct svc_rqst *rqstp, __be32 *statp); | ||
77 | #else /* CONFIG_NFSD_V4 */ | ||
78 | static inline void nfsd4_set_statp(struct svc_rqst *rqstp, __be32 *statp) | ||
79 | { | ||
80 | } | ||
81 | #endif /* CONFIG_NFSD_V4 */ | ||
82 | |||
83 | #endif /* NFSCACHE_H */ | ||
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 |
diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c index b2786a5f9afe..0c6d81670137 100644 --- a/fs/nfsd/lockd.c +++ b/fs/nfsd/lockd.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/nfsd/lockd.c | ||
3 | * | ||
4 | * This file contains all the stubs needed when communicating with lockd. | 2 | * This file contains all the stubs needed when communicating with lockd. |
5 | * This level of indirection is necessary so we can run nfsd+lockd without | 3 | * This level of indirection is necessary so we can run nfsd+lockd without |
6 | * requiring the nfs client to be compiled in/loaded, and vice versa. | 4 | * requiring the nfs client to be compiled in/loaded, and vice versa. |
@@ -8,14 +6,10 @@ | |||
8 | * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> | 6 | * Copyright (C) 1996, Olaf Kirch <okir@monad.swb.de> |
9 | */ | 7 | */ |
10 | 8 | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/fs.h> | ||
13 | #include <linux/file.h> | 9 | #include <linux/file.h> |
14 | #include <linux/mount.h> | ||
15 | #include <linux/sunrpc/clnt.h> | ||
16 | #include <linux/sunrpc/svc.h> | ||
17 | #include <linux/nfsd/nfsd.h> | ||
18 | #include <linux/lockd/bind.h> | 10 | #include <linux/lockd/bind.h> |
11 | #include "nfsd.h" | ||
12 | #include "vfs.h" | ||
19 | 13 | ||
20 | #define NFSDDBG_FACILITY NFSDDBG_LOCKD | 14 | #define NFSDDBG_FACILITY NFSDDBG_LOCKD |
21 | 15 | ||
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c index 4e3219e84116..f20589d2ae27 100644 --- a/fs/nfsd/nfs2acl.c +++ b/fs/nfsd/nfs2acl.c | |||
@@ -1,19 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/nfsd/nfs2acl.c | ||
3 | * | ||
4 | * Process version 2 NFSACL requests. | 2 | * Process version 2 NFSACL requests. |
5 | * | 3 | * |
6 | * Copyright (C) 2002-2003 Andreas Gruenbacher <agruen@suse.de> | 4 | * Copyright (C) 2002-2003 Andreas Gruenbacher <agruen@suse.de> |
7 | */ | 5 | */ |
8 | 6 | ||
9 | #include <linux/sunrpc/svc.h> | 7 | #include "nfsd.h" |
10 | #include <linux/nfs.h> | 8 | /* FIXME: nfsacl.h is a broken header */ |
11 | #include <linux/nfsd/nfsd.h> | ||
12 | #include <linux/nfsd/cache.h> | ||
13 | #include <linux/nfsd/xdr.h> | ||
14 | #include <linux/nfsd/xdr3.h> | ||
15 | #include <linux/posix_acl.h> | ||
16 | #include <linux/nfsacl.h> | 9 | #include <linux/nfsacl.h> |
10 | #include "cache.h" | ||
11 | #include "xdr3.h" | ||
12 | #include "vfs.h" | ||
17 | 13 | ||
18 | #define NFSDDBG_FACILITY NFSDDBG_PROC | 14 | #define NFSDDBG_FACILITY NFSDDBG_PROC |
19 | #define RETURN_STATUS(st) { resp->status = (st); return (st); } | 15 | #define RETURN_STATUS(st) { resp->status = (st); return (st); } |
@@ -217,6 +213,16 @@ static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p, | |||
217 | * XDR encode functions | 213 | * XDR encode functions |
218 | */ | 214 | */ |
219 | 215 | ||
216 | /* | ||
217 | * There must be an encoding function for void results so svc_process | ||
218 | * will work properly. | ||
219 | */ | ||
220 | int | ||
221 | nfsaclsvc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy) | ||
222 | { | ||
223 | return xdr_ressize_check(rqstp, p); | ||
224 | } | ||
225 | |||
220 | /* GETACL */ | 226 | /* GETACL */ |
221 | static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, | 227 | static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, |
222 | struct nfsd3_getaclres *resp) | 228 | struct nfsd3_getaclres *resp) |
@@ -308,7 +314,6 @@ static int nfsaclsvc_release_access(struct svc_rqst *rqstp, __be32 *p, | |||
308 | } | 314 | } |
309 | 315 | ||
310 | #define nfsaclsvc_decode_voidargs NULL | 316 | #define nfsaclsvc_decode_voidargs NULL |
311 | #define nfsaclsvc_encode_voidres NULL | ||
312 | #define nfsaclsvc_release_void NULL | 317 | #define nfsaclsvc_release_void NULL |
313 | #define nfsd3_fhandleargs nfsd_fhandle | 318 | #define nfsd3_fhandleargs nfsd_fhandle |
314 | #define nfsd3_attrstatres nfsd_attrstat | 319 | #define nfsd3_attrstatres nfsd_attrstat |
@@ -346,5 +351,5 @@ struct svc_version nfsd_acl_version2 = { | |||
346 | .vs_proc = nfsd_acl_procedures2, | 351 | .vs_proc = nfsd_acl_procedures2, |
347 | .vs_dispatch = nfsd_dispatch, | 352 | .vs_dispatch = nfsd_dispatch, |
348 | .vs_xdrsize = NFS3_SVC_XDRSIZE, | 353 | .vs_xdrsize = NFS3_SVC_XDRSIZE, |
349 | .vs_hidden = 1, | 354 | .vs_hidden = 0, |
350 | }; | 355 | }; |
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c index 9981dbb377a3..e0c4846bad92 100644 --- a/fs/nfsd/nfs3acl.c +++ b/fs/nfsd/nfs3acl.c | |||
@@ -1,18 +1,15 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/nfsd/nfs3acl.c | ||
3 | * | ||
4 | * Process version 3 NFSACL requests. | 2 | * Process version 3 NFSACL requests. |
5 | * | 3 | * |
6 | * Copyright (C) 2002-2003 Andreas Gruenbacher <agruen@suse.de> | 4 | * Copyright (C) 2002-2003 Andreas Gruenbacher <agruen@suse.de> |
7 | */ | 5 | */ |
8 | 6 | ||
9 | #include <linux/sunrpc/svc.h> | 7 | #include "nfsd.h" |
10 | #include <linux/nfs3.h> | 8 | /* FIXME: nfsacl.h is a broken header */ |
11 | #include <linux/nfsd/nfsd.h> | ||
12 | #include <linux/nfsd/cache.h> | ||
13 | #include <linux/nfsd/xdr3.h> | ||
14 | #include <linux/posix_acl.h> | ||
15 | #include <linux/nfsacl.h> | 9 | #include <linux/nfsacl.h> |
10 | #include "cache.h" | ||
11 | #include "xdr3.h" | ||
12 | #include "vfs.h" | ||
16 | 13 | ||
17 | #define RETURN_STATUS(st) { resp->status = (st); return (st); } | 14 | #define RETURN_STATUS(st) { resp->status = (st); return (st); } |
18 | 15 | ||
@@ -264,6 +261,6 @@ struct svc_version nfsd_acl_version3 = { | |||
264 | .vs_proc = nfsd_acl_procedures3, | 261 | .vs_proc = nfsd_acl_procedures3, |
265 | .vs_dispatch = nfsd_dispatch, | 262 | .vs_dispatch = nfsd_dispatch, |
266 | .vs_xdrsize = NFS3_SVC_XDRSIZE, | 263 | .vs_xdrsize = NFS3_SVC_XDRSIZE, |
267 | .vs_hidden = 1, | 264 | .vs_hidden = 0, |
268 | }; | 265 | }; |
269 | 266 | ||
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index a713c418a922..3d68f45a37b9 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c | |||
@@ -1,30 +1,16 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/nfsd/nfs3proc.c | ||
3 | * | ||
4 | * Process version 3 NFS requests. | 2 | * Process version 3 NFS requests. |
5 | * | 3 | * |
6 | * Copyright (C) 1996, 1997, 1998 Olaf Kirch <okir@monad.swb.de> | 4 | * Copyright (C) 1996, 1997, 1998 Olaf Kirch <okir@monad.swb.de> |
7 | */ | 5 | */ |
8 | 6 | ||
9 | #include <linux/linkage.h> | ||
10 | #include <linux/time.h> | ||
11 | #include <linux/errno.h> | ||
12 | #include <linux/fs.h> | 7 | #include <linux/fs.h> |
13 | #include <linux/ext2_fs.h> | 8 | #include <linux/ext2_fs.h> |
14 | #include <linux/stat.h> | ||
15 | #include <linux/fcntl.h> | ||
16 | #include <linux/net.h> | ||
17 | #include <linux/in.h> | ||
18 | #include <linux/unistd.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/major.h> | ||
21 | #include <linux/magic.h> | 9 | #include <linux/magic.h> |
22 | 10 | ||
23 | #include <linux/sunrpc/svc.h> | 11 | #include "cache.h" |
24 | #include <linux/nfsd/nfsd.h> | 12 | #include "xdr3.h" |
25 | #include <linux/nfsd/cache.h> | 13 | #include "vfs.h" |
26 | #include <linux/nfsd/xdr3.h> | ||
27 | #include <linux/nfs3.h> | ||
28 | 14 | ||
29 | #define NFSDDBG_FACILITY NFSDDBG_PROC | 15 | #define NFSDDBG_FACILITY NFSDDBG_PROC |
30 | 16 | ||
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index d0a2ce1b4324..2a533a0af2a9 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/nfsd/nfs3xdr.c | ||
3 | * | ||
4 | * XDR support for nfsd/protocol version 3. | 2 | * XDR support for nfsd/protocol version 3. |
5 | * | 3 | * |
6 | * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> | 4 | * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> |
@@ -8,19 +6,8 @@ | |||
8 | * 2003-08-09 Jamie Lokier: Use htonl() for nanoseconds, not htons()! | 6 | * 2003-08-09 Jamie Lokier: Use htonl() for nanoseconds, not htons()! |
9 | */ | 7 | */ |
10 | 8 | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/time.h> | ||
13 | #include <linux/nfs3.h> | ||
14 | #include <linux/list.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | #include <linux/dcache.h> | ||
17 | #include <linux/namei.h> | 9 | #include <linux/namei.h> |
18 | #include <linux/mm.h> | 10 | #include "xdr3.h" |
19 | #include <linux/vfs.h> | ||
20 | #include <linux/sunrpc/xdr.h> | ||
21 | #include <linux/sunrpc/svc.h> | ||
22 | #include <linux/nfsd/nfsd.h> | ||
23 | #include <linux/nfsd/xdr3.h> | ||
24 | #include "auth.h" | 11 | #include "auth.h" |
25 | 12 | ||
26 | #define NFSDDBG_FACILITY NFSDDBG_XDR | 13 | #define NFSDDBG_FACILITY NFSDDBG_XDR |
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 725d02f210e2..88150685df34 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * fs/nfs4acl/acl.c | ||
3 | * | ||
4 | * Common NFSv4 ACL handling code. | 2 | * Common NFSv4 ACL handling code. |
5 | * | 3 | * |
6 | * Copyright (c) 2002, 2003 The Regents of the University of Michigan. | 4 | * Copyright (c) 2002, 2003 The Regents of the University of Michigan. |
@@ -36,15 +34,7 @@ | |||
36 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
37 | */ | 35 | */ |
38 | 36 | ||
39 | #include <linux/string.h> | ||
40 | #include <linux/slab.h> | ||
41 | #include <linux/list.h> | ||
42 | #include <linux/types.h> | ||
43 | #include <linux/fs.h> | ||
44 | #include <linux/module.h> | ||
45 | #include <linux/nfs_fs.h> | 37 | #include <linux/nfs_fs.h> |
46 | #include <linux/posix_acl.h> | ||
47 | #include <linux/nfs4.h> | ||
48 | #include <linux/nfs4_acl.h> | 38 | #include <linux/nfs4_acl.h> |
49 | 39 | ||
50 | 40 | ||
@@ -389,7 +379,7 @@ sort_pacl(struct posix_acl *pacl) | |||
389 | sort_pacl_range(pacl, 1, i-1); | 379 | sort_pacl_range(pacl, 1, i-1); |
390 | 380 | ||
391 | BUG_ON(pacl->a_entries[i].e_tag != ACL_GROUP_OBJ); | 381 | BUG_ON(pacl->a_entries[i].e_tag != ACL_GROUP_OBJ); |
392 | j = i++; | 382 | j = ++i; |
393 | while (pacl->a_entries[j].e_tag == ACL_GROUP) | 383 | while (pacl->a_entries[j].e_tag == ACL_GROUP) |
394 | j++; | 384 | j++; |
395 | sort_pacl_range(pacl, i, j-1); | 385 | sort_pacl_range(pacl, i, j-1); |
diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 24e8d78f8dde..c6eed2a3b093 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/nfsd/nfs4callback.c | ||
3 | * | ||
4 | * Copyright (c) 2001 The Regents of the University of Michigan. | 2 | * Copyright (c) 2001 The Regents of the University of Michigan. |
5 | * All rights reserved. | 3 | * All rights reserved. |
6 | * | 4 | * |
@@ -33,22 +31,9 @@ | |||
33 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
34 | */ | 32 | */ |
35 | 33 | ||
36 | #include <linux/module.h> | ||
37 | #include <linux/list.h> | ||
38 | #include <linux/inet.h> | ||
39 | #include <linux/errno.h> | ||
40 | #include <linux/delay.h> | ||
41 | #include <linux/sched.h> | ||
42 | #include <linux/kthread.h> | ||
43 | #include <linux/sunrpc/xdr.h> | ||
44 | #include <linux/sunrpc/svc.h> | ||
45 | #include <linux/sunrpc/clnt.h> | 34 | #include <linux/sunrpc/clnt.h> |
46 | #include <linux/sunrpc/svcsock.h> | 35 | #include "nfsd.h" |
47 | #include <linux/nfsd/nfsd.h> | 36 | #include "state.h" |
48 | #include <linux/nfsd/state.h> | ||
49 | #include <linux/sunrpc/sched.h> | ||
50 | #include <linux/nfs4.h> | ||
51 | #include <linux/sunrpc/xprtsock.h> | ||
52 | 37 | ||
53 | #define NFSDDBG_FACILITY NFSDDBG_PROC | 38 | #define NFSDDBG_FACILITY NFSDDBG_PROC |
54 | 39 | ||
diff --git a/fs/nfsd/nfs4idmap.c b/fs/nfsd/nfs4idmap.c index ba2c199592fd..6e2983b27f3c 100644 --- a/fs/nfsd/nfs4idmap.c +++ b/fs/nfsd/nfs4idmap.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * fs/nfsd/nfs4idmap.c | ||
3 | * | ||
4 | * Mapping of UID/GIDs to name and vice versa. | 2 | * Mapping of UID/GIDs to name and vice versa. |
5 | * | 3 | * |
6 | * Copyright (c) 2002, 2003 The Regents of the University of | 4 | * Copyright (c) 2002, 2003 The Regents of the University of |
@@ -35,22 +33,9 @@ | |||
35 | */ | 33 | */ |
36 | 34 | ||
37 | #include <linux/module.h> | 35 | #include <linux/module.h> |
38 | #include <linux/init.h> | ||
39 | |||
40 | #include <linux/mm.h> | ||
41 | #include <linux/errno.h> | ||
42 | #include <linux/string.h> | ||
43 | #include <linux/sunrpc/clnt.h> | ||
44 | #include <linux/nfs.h> | ||
45 | #include <linux/nfs4.h> | ||
46 | #include <linux/nfs_fs.h> | ||
47 | #include <linux/nfs_page.h> | ||
48 | #include <linux/sunrpc/cache.h> | ||
49 | #include <linux/nfsd_idmap.h> | 36 | #include <linux/nfsd_idmap.h> |
50 | #include <linux/list.h> | ||
51 | #include <linux/time.h> | ||
52 | #include <linux/seq_file.h> | 37 | #include <linux/seq_file.h> |
53 | #include <linux/sunrpc/svcauth.h> | 38 | #include <linux/sched.h> |
54 | 39 | ||
55 | /* | 40 | /* |
56 | * Cache entry | 41 | * Cache entry |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index bebc0c2e1b0a..37514c469846 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * fs/nfsd/nfs4proc.c | ||
3 | * | ||
4 | * Server-side procedures for NFSv4. | 2 | * Server-side procedures for NFSv4. |
5 | * | 3 | * |
6 | * Copyright (c) 2002 The Regents of the University of Michigan. | 4 | * Copyright (c) 2002 The Regents of the University of Michigan. |
@@ -34,20 +32,11 @@ | |||
34 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | 32 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
35 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 33 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
36 | */ | 34 | */ |
37 | |||
38 | #include <linux/param.h> | ||
39 | #include <linux/major.h> | ||
40 | #include <linux/slab.h> | ||
41 | #include <linux/file.h> | 35 | #include <linux/file.h> |
42 | 36 | ||
43 | #include <linux/sunrpc/svc.h> | 37 | #include "cache.h" |
44 | #include <linux/nfsd/nfsd.h> | 38 | #include "xdr4.h" |
45 | #include <linux/nfsd/cache.h> | 39 | #include "vfs.h" |
46 | #include <linux/nfs4.h> | ||
47 | #include <linux/nfsd/state.h> | ||
48 | #include <linux/nfsd/xdr4.h> | ||
49 | #include <linux/nfs4_acl.h> | ||
50 | #include <linux/sunrpc/gss_api.h> | ||
51 | 40 | ||
52 | #define NFSDDBG_FACILITY NFSDDBG_PROC | 41 | #define NFSDDBG_FACILITY NFSDDBG_PROC |
53 | 42 | ||
@@ -170,7 +159,7 @@ do_open_permission(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nfs | |||
170 | accmode |= NFSD_MAY_READ; | 159 | accmode |= NFSD_MAY_READ; |
171 | if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) | 160 | if (open->op_share_access & NFS4_SHARE_ACCESS_WRITE) |
172 | accmode |= (NFSD_MAY_WRITE | NFSD_MAY_TRUNC); | 161 | accmode |= (NFSD_MAY_WRITE | NFSD_MAY_TRUNC); |
173 | if (open->op_share_deny & NFS4_SHARE_DENY_WRITE) | 162 | if (open->op_share_deny & NFS4_SHARE_DENY_READ) |
174 | accmode |= NFSD_MAY_WRITE; | 163 | accmode |= NFSD_MAY_WRITE; |
175 | 164 | ||
176 | status = fh_verify(rqstp, current_fh, S_IFREG, accmode); | 165 | status = fh_verify(rqstp, current_fh, S_IFREG, accmode); |
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index b5348405046b..5a754f7b71ed 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/nfsd/nfs4recover.c | ||
3 | * | ||
4 | * Copyright (c) 2004 The Regents of the University of Michigan. | 2 | * Copyright (c) 2004 The Regents of the University of Michigan. |
5 | * All rights reserved. | 3 | * All rights reserved. |
6 | * | 4 | * |
@@ -33,20 +31,14 @@ | |||
33 | * | 31 | * |
34 | */ | 32 | */ |
35 | 33 | ||
36 | #include <linux/err.h> | ||
37 | #include <linux/sunrpc/svc.h> | ||
38 | #include <linux/nfsd/nfsd.h> | ||
39 | #include <linux/nfs4.h> | ||
40 | #include <linux/nfsd/state.h> | ||
41 | #include <linux/nfsd/xdr4.h> | ||
42 | #include <linux/param.h> | ||
43 | #include <linux/file.h> | 34 | #include <linux/file.h> |
44 | #include <linux/namei.h> | 35 | #include <linux/namei.h> |
45 | #include <asm/uaccess.h> | ||
46 | #include <linux/scatterlist.h> | ||
47 | #include <linux/crypto.h> | 36 | #include <linux/crypto.h> |
48 | #include <linux/sched.h> | 37 | #include <linux/sched.h> |
49 | #include <linux/mount.h> | 38 | |
39 | #include "nfsd.h" | ||
40 | #include "state.h" | ||
41 | #include "vfs.h" | ||
50 | 42 | ||
51 | #define NFSDDBG_FACILITY NFSDDBG_PROC | 43 | #define NFSDDBG_FACILITY NFSDDBG_PROC |
52 | 44 | ||
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2153f9bdbebd..f19ed866c95f 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/nfsd/nfs4state.c | ||
3 | * | ||
4 | * Copyright (c) 2001 The Regents of the University of Michigan. | 2 | * Copyright (c) 2001 The Regents of the University of Michigan. |
5 | * All rights reserved. | 3 | * All rights reserved. |
6 | * | 4 | * |
@@ -34,28 +32,14 @@ | |||
34 | * | 32 | * |
35 | */ | 33 | */ |
36 | 34 | ||
37 | #include <linux/param.h> | ||
38 | #include <linux/major.h> | ||
39 | #include <linux/slab.h> | ||
40 | |||
41 | #include <linux/sunrpc/svc.h> | ||
42 | #include <linux/nfsd/nfsd.h> | ||
43 | #include <linux/nfsd/cache.h> | ||
44 | #include <linux/file.h> | 35 | #include <linux/file.h> |
45 | #include <linux/mount.h> | ||
46 | #include <linux/workqueue.h> | ||
47 | #include <linux/smp_lock.h> | 36 | #include <linux/smp_lock.h> |
48 | #include <linux/kthread.h> | ||
49 | #include <linux/nfs4.h> | ||
50 | #include <linux/nfsd/state.h> | ||
51 | #include <linux/nfsd/xdr4.h> | ||
52 | #include <linux/namei.h> | 37 | #include <linux/namei.h> |
53 | #include <linux/swap.h> | 38 | #include <linux/swap.h> |
54 | #include <linux/mutex.h> | ||
55 | #include <linux/lockd/bind.h> | ||
56 | #include <linux/module.h> | ||
57 | #include <linux/sunrpc/svcauth_gss.h> | 39 | #include <linux/sunrpc/svcauth_gss.h> |
58 | #include <linux/sunrpc/clnt.h> | 40 | #include <linux/sunrpc/clnt.h> |
41 | #include "xdr4.h" | ||
42 | #include "vfs.h" | ||
59 | 43 | ||
60 | #define NFSDDBG_FACILITY NFSDDBG_PROC | 44 | #define NFSDDBG_FACILITY NFSDDBG_PROC |
61 | 45 | ||
@@ -477,13 +461,14 @@ static int set_forechannel_drc_size(struct nfsd4_channel_attrs *fchan) | |||
477 | 461 | ||
478 | /* | 462 | /* |
479 | * fchan holds the client values on input, and the server values on output | 463 | * fchan holds the client values on input, and the server values on output |
464 | * sv_max_mesg is the maximum payload plus one page for overhead. | ||
480 | */ | 465 | */ |
481 | static int init_forechannel_attrs(struct svc_rqst *rqstp, | 466 | static int init_forechannel_attrs(struct svc_rqst *rqstp, |
482 | struct nfsd4_channel_attrs *session_fchan, | 467 | struct nfsd4_channel_attrs *session_fchan, |
483 | struct nfsd4_channel_attrs *fchan) | 468 | struct nfsd4_channel_attrs *fchan) |
484 | { | 469 | { |
485 | int status = 0; | 470 | int status = 0; |
486 | __u32 maxcount = svc_max_payload(rqstp); | 471 | __u32 maxcount = nfsd_serv->sv_max_mesg; |
487 | 472 | ||
488 | /* headerpadsz set to zero in encode routine */ | 473 | /* headerpadsz set to zero in encode routine */ |
489 | 474 | ||
@@ -523,6 +508,15 @@ free_session_slots(struct nfsd4_session *ses) | |||
523 | kfree(ses->se_slots[i]); | 508 | kfree(ses->se_slots[i]); |
524 | } | 509 | } |
525 | 510 | ||
511 | /* | ||
512 | * We don't actually need to cache the rpc and session headers, so we | ||
513 | * can allocate a little less for each slot: | ||
514 | */ | ||
515 | static inline int slot_bytes(struct nfsd4_channel_attrs *ca) | ||
516 | { | ||
517 | return ca->maxresp_cached - NFSD_MIN_HDR_SEQ_SZ; | ||
518 | } | ||
519 | |||
526 | static int | 520 | static int |
527 | alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp, | 521 | alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp, |
528 | struct nfsd4_create_session *cses) | 522 | struct nfsd4_create_session *cses) |
@@ -554,7 +548,7 @@ alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp, | |||
554 | memcpy(new, &tmp, sizeof(*new)); | 548 | memcpy(new, &tmp, sizeof(*new)); |
555 | 549 | ||
556 | /* allocate each struct nfsd4_slot and data cache in one piece */ | 550 | /* allocate each struct nfsd4_slot and data cache in one piece */ |
557 | cachesize = new->se_fchannel.maxresp_cached - NFSD_MIN_HDR_SEQ_SZ; | 551 | cachesize = slot_bytes(&new->se_fchannel); |
558 | for (i = 0; i < new->se_fchannel.maxreqs; i++) { | 552 | for (i = 0; i < new->se_fchannel.maxreqs; i++) { |
559 | sp = kzalloc(sizeof(*sp) + cachesize, GFP_KERNEL); | 553 | sp = kzalloc(sizeof(*sp) + cachesize, GFP_KERNEL); |
560 | if (!sp) | 554 | if (!sp) |
@@ -628,10 +622,12 @@ void | |||
628 | free_session(struct kref *kref) | 622 | free_session(struct kref *kref) |
629 | { | 623 | { |
630 | struct nfsd4_session *ses; | 624 | struct nfsd4_session *ses; |
625 | int mem; | ||
631 | 626 | ||
632 | ses = container_of(kref, struct nfsd4_session, se_ref); | 627 | ses = container_of(kref, struct nfsd4_session, se_ref); |
633 | spin_lock(&nfsd_drc_lock); | 628 | spin_lock(&nfsd_drc_lock); |
634 | nfsd_drc_mem_used -= ses->se_fchannel.maxreqs * NFSD_SLOT_CACHE_SIZE; | 629 | mem = ses->se_fchannel.maxreqs * slot_bytes(&ses->se_fchannel); |
630 | nfsd_drc_mem_used -= mem; | ||
635 | spin_unlock(&nfsd_drc_lock); | 631 | spin_unlock(&nfsd_drc_lock); |
636 | free_session_slots(ses); | 632 | free_session_slots(ses); |
637 | kfree(ses); | 633 | kfree(ses); |
@@ -2404,11 +2400,8 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta | |||
2404 | 2400 | ||
2405 | memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid)); | 2401 | memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid)); |
2406 | 2402 | ||
2407 | dprintk("NFSD: delegation stateid=(%08x/%08x/%08x/%08x)\n\n", | 2403 | dprintk("NFSD: delegation stateid=" STATEID_FMT "\n", |
2408 | dp->dl_stateid.si_boot, | 2404 | STATEID_VAL(&dp->dl_stateid)); |
2409 | dp->dl_stateid.si_stateownerid, | ||
2410 | dp->dl_stateid.si_fileid, | ||
2411 | dp->dl_stateid.si_generation); | ||
2412 | out: | 2405 | out: |
2413 | if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS | 2406 | if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS |
2414 | && flag == NFS4_OPEN_DELEGATE_NONE | 2407 | && flag == NFS4_OPEN_DELEGATE_NONE |
@@ -2498,9 +2491,8 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf | |||
2498 | 2491 | ||
2499 | status = nfs_ok; | 2492 | status = nfs_ok; |
2500 | 2493 | ||
2501 | dprintk("nfs4_process_open2: stateid=(%08x/%08x/%08x/%08x)\n", | 2494 | dprintk("%s: stateid=" STATEID_FMT "\n", __func__, |
2502 | stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid, | 2495 | STATEID_VAL(&stp->st_stateid)); |
2503 | stp->st_stateid.si_fileid, stp->st_stateid.si_generation); | ||
2504 | out: | 2496 | out: |
2505 | if (fp) | 2497 | if (fp) |
2506 | put_nfs4_file(fp); | 2498 | put_nfs4_file(fp); |
@@ -2666,9 +2658,8 @@ STALE_STATEID(stateid_t *stateid) | |||
2666 | { | 2658 | { |
2667 | if (time_after((unsigned long)boot_time, | 2659 | if (time_after((unsigned long)boot_time, |
2668 | (unsigned long)stateid->si_boot)) { | 2660 | (unsigned long)stateid->si_boot)) { |
2669 | dprintk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n", | 2661 | dprintk("NFSD: stale stateid " STATEID_FMT "!\n", |
2670 | stateid->si_boot, stateid->si_stateownerid, | 2662 | STATEID_VAL(stateid)); |
2671 | stateid->si_fileid, stateid->si_generation); | ||
2672 | return 1; | 2663 | return 1; |
2673 | } | 2664 | } |
2674 | return 0; | 2665 | return 0; |
@@ -2680,9 +2671,8 @@ EXPIRED_STATEID(stateid_t *stateid) | |||
2680 | if (time_before((unsigned long)boot_time, | 2671 | if (time_before((unsigned long)boot_time, |
2681 | ((unsigned long)stateid->si_boot)) && | 2672 | ((unsigned long)stateid->si_boot)) && |
2682 | time_before((unsigned long)(stateid->si_boot + lease_time), get_seconds())) { | 2673 | time_before((unsigned long)(stateid->si_boot + lease_time), get_seconds())) { |
2683 | dprintk("NFSD: expired stateid (%08x/%08x/%08x/%08x)!\n", | 2674 | dprintk("NFSD: expired stateid " STATEID_FMT "!\n", |
2684 | stateid->si_boot, stateid->si_stateownerid, | 2675 | STATEID_VAL(stateid)); |
2685 | stateid->si_fileid, stateid->si_generation); | ||
2686 | return 1; | 2676 | return 1; |
2687 | } | 2677 | } |
2688 | return 0; | 2678 | return 0; |
@@ -2696,9 +2686,8 @@ stateid_error_map(stateid_t *stateid) | |||
2696 | if (EXPIRED_STATEID(stateid)) | 2686 | if (EXPIRED_STATEID(stateid)) |
2697 | return nfserr_expired; | 2687 | return nfserr_expired; |
2698 | 2688 | ||
2699 | dprintk("NFSD: bad stateid (%08x/%08x/%08x/%08x)!\n", | 2689 | dprintk("NFSD: bad stateid " STATEID_FMT "!\n", |
2700 | stateid->si_boot, stateid->si_stateownerid, | 2690 | STATEID_VAL(stateid)); |
2701 | stateid->si_fileid, stateid->si_generation); | ||
2702 | return nfserr_bad_stateid; | 2691 | return nfserr_bad_stateid; |
2703 | } | 2692 | } |
2704 | 2693 | ||
@@ -2884,10 +2873,8 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, | |||
2884 | struct svc_fh *current_fh = &cstate->current_fh; | 2873 | struct svc_fh *current_fh = &cstate->current_fh; |
2885 | __be32 status; | 2874 | __be32 status; |
2886 | 2875 | ||
2887 | dprintk("NFSD: preprocess_seqid_op: seqid=%d " | 2876 | dprintk("NFSD: %s: seqid=%d stateid = " STATEID_FMT "\n", __func__, |
2888 | "stateid = (%08x/%08x/%08x/%08x)\n", seqid, | 2877 | seqid, STATEID_VAL(stateid)); |
2889 | stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid, | ||
2890 | stateid->si_generation); | ||
2891 | 2878 | ||
2892 | *stpp = NULL; | 2879 | *stpp = NULL; |
2893 | *sopp = NULL; | 2880 | *sopp = NULL; |
@@ -3019,12 +3006,8 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3019 | sop->so_confirmed = 1; | 3006 | sop->so_confirmed = 1; |
3020 | update_stateid(&stp->st_stateid); | 3007 | update_stateid(&stp->st_stateid); |
3021 | memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t)); | 3008 | memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t)); |
3022 | dprintk("NFSD: nfsd4_open_confirm: success, seqid=%d " | 3009 | dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n", |
3023 | "stateid=(%08x/%08x/%08x/%08x)\n", oc->oc_seqid, | 3010 | __func__, oc->oc_seqid, STATEID_VAL(&stp->st_stateid)); |
3024 | stp->st_stateid.si_boot, | ||
3025 | stp->st_stateid.si_stateownerid, | ||
3026 | stp->st_stateid.si_fileid, | ||
3027 | stp->st_stateid.si_generation); | ||
3028 | 3011 | ||
3029 | nfsd4_create_clid_dir(sop->so_client); | 3012 | nfsd4_create_clid_dir(sop->so_client); |
3030 | out: | 3013 | out: |
@@ -3283,9 +3266,8 @@ find_delegation_stateid(struct inode *ino, stateid_t *stid) | |||
3283 | struct nfs4_file *fp; | 3266 | struct nfs4_file *fp; |
3284 | struct nfs4_delegation *dl; | 3267 | struct nfs4_delegation *dl; |
3285 | 3268 | ||
3286 | dprintk("NFSD:find_delegation_stateid stateid=(%08x/%08x/%08x/%08x)\n", | 3269 | dprintk("NFSD: %s: stateid=" STATEID_FMT "\n", __func__, |
3287 | stid->si_boot, stid->si_stateownerid, | 3270 | STATEID_VAL(stid)); |
3288 | stid->si_fileid, stid->si_generation); | ||
3289 | 3271 | ||
3290 | fp = find_file(ino); | 3272 | fp = find_file(ino); |
3291 | if (!fp) | 3273 | if (!fp) |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 0fbd50cee1f6..a8587e90fd5a 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -40,24 +40,16 @@ | |||
40 | * at the end of nfs4svc_decode_compoundargs. | 40 | * at the end of nfs4svc_decode_compoundargs. |
41 | */ | 41 | */ |
42 | 42 | ||
43 | #include <linux/param.h> | ||
44 | #include <linux/smp.h> | ||
45 | #include <linux/fs.h> | ||
46 | #include <linux/namei.h> | 43 | #include <linux/namei.h> |
47 | #include <linux/vfs.h> | 44 | #include <linux/statfs.h> |
48 | #include <linux/utsname.h> | 45 | #include <linux/utsname.h> |
49 | #include <linux/sunrpc/xdr.h> | ||
50 | #include <linux/sunrpc/svc.h> | ||
51 | #include <linux/sunrpc/clnt.h> | ||
52 | #include <linux/nfsd/nfsd.h> | ||
53 | #include <linux/nfsd/state.h> | ||
54 | #include <linux/nfsd/xdr4.h> | ||
55 | #include <linux/nfsd_idmap.h> | 46 | #include <linux/nfsd_idmap.h> |
56 | #include <linux/nfs4.h> | ||
57 | #include <linux/nfs4_acl.h> | 47 | #include <linux/nfs4_acl.h> |
58 | #include <linux/sunrpc/gss_api.h> | ||
59 | #include <linux/sunrpc/svcauth_gss.h> | 48 | #include <linux/sunrpc/svcauth_gss.h> |
60 | 49 | ||
50 | #include "xdr4.h" | ||
51 | #include "vfs.h" | ||
52 | |||
61 | #define NFSDDBG_FACILITY NFSDDBG_XDR | 53 | #define NFSDDBG_FACILITY NFSDDBG_XDR |
62 | 54 | ||
63 | /* | 55 | /* |
@@ -2204,11 +2196,14 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, | |||
2204 | * we will not follow the cross mount and will fill the attribtutes | 2196 | * we will not follow the cross mount and will fill the attribtutes |
2205 | * directly from the mountpoint dentry. | 2197 | * directly from the mountpoint dentry. |
2206 | */ | 2198 | */ |
2207 | if (d_mountpoint(dentry) && !attributes_need_mount(cd->rd_bmval)) | 2199 | if (nfsd_mountpoint(dentry, exp)) { |
2208 | ignore_crossmnt = 1; | ||
2209 | else if (d_mountpoint(dentry)) { | ||
2210 | int err; | 2200 | int err; |
2211 | 2201 | ||
2202 | if (!(exp->ex_flags & NFSEXP_V4ROOT) | ||
2203 | && !attributes_need_mount(cd->rd_bmval)) { | ||
2204 | ignore_crossmnt = 1; | ||
2205 | goto out_encode; | ||
2206 | } | ||
2212 | /* | 2207 | /* |
2213 | * Why the heck aren't we just using nfsd_lookup?? | 2208 | * Why the heck aren't we just using nfsd_lookup?? |
2214 | * Different "."/".." handling? Something else? | 2209 | * Different "."/".." handling? Something else? |
@@ -2224,6 +2219,7 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd, | |||
2224 | goto out_put; | 2219 | goto out_put; |
2225 | 2220 | ||
2226 | } | 2221 | } |
2222 | out_encode: | ||
2227 | nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval, | 2223 | nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval, |
2228 | cd->rd_rqstp, ignore_crossmnt); | 2224 | cd->rd_rqstp, ignore_crossmnt); |
2229 | out_put: | 2225 | out_put: |
diff --git a/fs/nfsd/nfscache.c b/fs/nfsd/nfscache.c index 4638635c5d87..da08560c4818 100644 --- a/fs/nfsd/nfscache.c +++ b/fs/nfsd/nfscache.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/nfsd/nfscache.c | ||
3 | * | ||
4 | * Request reply cache. This is currently a global cache, but this may | 2 | * Request reply cache. This is currently a global cache, but this may |
5 | * change in the future and be a per-client cache. | 3 | * change in the future and be a per-client cache. |
6 | * | 4 | * |
@@ -10,16 +8,8 @@ | |||
10 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> | 8 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> |
11 | */ | 9 | */ |
12 | 10 | ||
13 | #include <linux/kernel.h> | 11 | #include "nfsd.h" |
14 | #include <linux/time.h> | 12 | #include "cache.h" |
15 | #include <linux/slab.h> | ||
16 | #include <linux/string.h> | ||
17 | #include <linux/spinlock.h> | ||
18 | #include <linux/list.h> | ||
19 | |||
20 | #include <linux/sunrpc/svc.h> | ||
21 | #include <linux/nfsd/nfsd.h> | ||
22 | #include <linux/nfsd/cache.h> | ||
23 | 13 | ||
24 | /* Size of reply cache. Common values are: | 14 | /* Size of reply cache. Common values are: |
25 | * 4.3BSD: 128 | 15 | * 4.3BSD: 128 |
diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 5c01fc148ce8..2604c3e70ea5 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c | |||
@@ -1,46 +1,20 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/nfsd/nfsctl.c | ||
3 | * | ||
4 | * Syscall interface to knfsd. | 2 | * Syscall interface to knfsd. |
5 | * | 3 | * |
6 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> | 4 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> |
7 | */ | 5 | */ |
8 | 6 | ||
9 | #include <linux/module.h> | ||
10 | |||
11 | #include <linux/linkage.h> | ||
12 | #include <linux/time.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/fs.h> | ||
15 | #include <linux/namei.h> | 7 | #include <linux/namei.h> |
16 | #include <linux/fcntl.h> | ||
17 | #include <linux/net.h> | ||
18 | #include <linux/in.h> | ||
19 | #include <linux/syscalls.h> | ||
20 | #include <linux/unistd.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/proc_fs.h> | ||
23 | #include <linux/seq_file.h> | ||
24 | #include <linux/pagemap.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/inet.h> | ||
27 | #include <linux/string.h> | ||
28 | #include <linux/ctype.h> | 8 | #include <linux/ctype.h> |
29 | 9 | ||
30 | #include <linux/nfs.h> | ||
31 | #include <linux/nfsd_idmap.h> | 10 | #include <linux/nfsd_idmap.h> |
32 | #include <linux/lockd/bind.h> | ||
33 | #include <linux/sunrpc/svc.h> | ||
34 | #include <linux/sunrpc/svcsock.h> | 11 | #include <linux/sunrpc/svcsock.h> |
35 | #include <linux/nfsd/nfsd.h> | ||
36 | #include <linux/nfsd/cache.h> | ||
37 | #include <linux/nfsd/xdr.h> | ||
38 | #include <linux/nfsd/syscall.h> | 12 | #include <linux/nfsd/syscall.h> |
39 | #include <linux/lockd/lockd.h> | 13 | #include <linux/lockd/lockd.h> |
40 | #include <linux/sunrpc/clnt.h> | 14 | #include <linux/sunrpc/clnt.h> |
41 | 15 | ||
42 | #include <asm/uaccess.h> | 16 | #include "nfsd.h" |
43 | #include <net/ipv6.h> | 17 | #include "cache.h" |
44 | 18 | ||
45 | /* | 19 | /* |
46 | * We have a single directory with 9 nodes in it. | 20 | * We have a single directory with 9 nodes in it. |
@@ -55,6 +29,7 @@ enum { | |||
55 | NFSD_Getfd, | 29 | NFSD_Getfd, |
56 | NFSD_Getfs, | 30 | NFSD_Getfs, |
57 | NFSD_List, | 31 | NFSD_List, |
32 | NFSD_Export_features, | ||
58 | NFSD_Fh, | 33 | NFSD_Fh, |
59 | NFSD_FO_UnlockIP, | 34 | NFSD_FO_UnlockIP, |
60 | NFSD_FO_UnlockFS, | 35 | NFSD_FO_UnlockFS, |
@@ -173,6 +148,24 @@ static const struct file_operations exports_operations = { | |||
173 | .owner = THIS_MODULE, | 148 | .owner = THIS_MODULE, |
174 | }; | 149 | }; |
175 | 150 | ||
151 | static int export_features_show(struct seq_file *m, void *v) | ||
152 | { | ||
153 | seq_printf(m, "0x%x 0x%x\n", NFSEXP_ALLFLAGS, NFSEXP_SECINFO_FLAGS); | ||
154 | return 0; | ||
155 | } | ||
156 | |||
157 | static int export_features_open(struct inode *inode, struct file *file) | ||
158 | { | ||
159 | return single_open(file, export_features_show, NULL); | ||
160 | } | ||
161 | |||
162 | static struct file_operations export_features_operations = { | ||
163 | .open = export_features_open, | ||
164 | .read = seq_read, | ||
165 | .llseek = seq_lseek, | ||
166 | .release = single_release, | ||
167 | }; | ||
168 | |||
176 | extern int nfsd_pool_stats_open(struct inode *inode, struct file *file); | 169 | extern int nfsd_pool_stats_open(struct inode *inode, struct file *file); |
177 | extern int nfsd_pool_stats_release(struct inode *inode, struct file *file); | 170 | extern int nfsd_pool_stats_release(struct inode *inode, struct file *file); |
178 | 171 | ||
@@ -1330,6 +1323,8 @@ static int nfsd_fill_super(struct super_block * sb, void * data, int silent) | |||
1330 | [NFSD_Getfd] = {".getfd", &transaction_ops, S_IWUSR|S_IRUSR}, | 1323 | [NFSD_Getfd] = {".getfd", &transaction_ops, S_IWUSR|S_IRUSR}, |
1331 | [NFSD_Getfs] = {".getfs", &transaction_ops, S_IWUSR|S_IRUSR}, | 1324 | [NFSD_Getfs] = {".getfs", &transaction_ops, S_IWUSR|S_IRUSR}, |
1332 | [NFSD_List] = {"exports", &exports_operations, S_IRUGO}, | 1325 | [NFSD_List] = {"exports", &exports_operations, S_IRUGO}, |
1326 | [NFSD_Export_features] = {"export_features", | ||
1327 | &export_features_operations, S_IRUGO}, | ||
1333 | [NFSD_FO_UnlockIP] = {"unlock_ip", | 1328 | [NFSD_FO_UnlockIP] = {"unlock_ip", |
1334 | &transaction_ops, S_IWUSR|S_IRUSR}, | 1329 | &transaction_ops, S_IWUSR|S_IRUSR}, |
1335 | [NFSD_FO_UnlockFS] = {"unlock_filesystem", | 1330 | [NFSD_FO_UnlockFS] = {"unlock_filesystem", |
diff --git a/fs/nfsd/nfsd.h b/fs/nfsd/nfsd.h new file mode 100644 index 000000000000..e942a1aaac92 --- /dev/null +++ b/fs/nfsd/nfsd.h | |||
@@ -0,0 +1,338 @@ | |||
1 | /* | ||
2 | * Hodge-podge collection of knfsd-related stuff. | ||
3 | * I will sort this out later. | ||
4 | * | ||
5 | * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de> | ||
6 | */ | ||
7 | |||
8 | #ifndef LINUX_NFSD_NFSD_H | ||
9 | #define LINUX_NFSD_NFSD_H | ||
10 | |||
11 | #include <linux/types.h> | ||
12 | #include <linux/mount.h> | ||
13 | |||
14 | #include <linux/nfsd/debug.h> | ||
15 | #include <linux/nfsd/export.h> | ||
16 | #include <linux/nfsd/stats.h> | ||
17 | /* | ||
18 | * nfsd version | ||
19 | */ | ||
20 | #define NFSD_SUPPORTED_MINOR_VERSION 1 | ||
21 | |||
22 | struct readdir_cd { | ||
23 | __be32 err; /* 0, nfserr, or nfserr_eof */ | ||
24 | }; | ||
25 | |||
26 | |||
27 | extern struct svc_program nfsd_program; | ||
28 | extern struct svc_version nfsd_version2, nfsd_version3, | ||
29 | nfsd_version4; | ||
30 | extern u32 nfsd_supported_minorversion; | ||
31 | extern struct mutex nfsd_mutex; | ||
32 | extern struct svc_serv *nfsd_serv; | ||
33 | extern spinlock_t nfsd_drc_lock; | ||
34 | extern unsigned int nfsd_drc_max_mem; | ||
35 | extern unsigned int nfsd_drc_mem_used; | ||
36 | |||
37 | extern const struct seq_operations nfs_exports_op; | ||
38 | |||
39 | /* | ||
40 | * Function prototypes. | ||
41 | */ | ||
42 | int nfsd_svc(unsigned short port, int nrservs); | ||
43 | int nfsd_dispatch(struct svc_rqst *rqstp, __be32 *statp); | ||
44 | |||
45 | int nfsd_nrthreads(void); | ||
46 | int nfsd_nrpools(void); | ||
47 | int nfsd_get_nrthreads(int n, int *); | ||
48 | int nfsd_set_nrthreads(int n, int *); | ||
49 | |||
50 | #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) | ||
51 | #ifdef CONFIG_NFSD_V2_ACL | ||
52 | extern struct svc_version nfsd_acl_version2; | ||
53 | #else | ||
54 | #define nfsd_acl_version2 NULL | ||
55 | #endif | ||
56 | #ifdef CONFIG_NFSD_V3_ACL | ||
57 | extern struct svc_version nfsd_acl_version3; | ||
58 | #else | ||
59 | #define nfsd_acl_version3 NULL | ||
60 | #endif | ||
61 | #endif | ||
62 | |||
63 | enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL }; | ||
64 | int nfsd_vers(int vers, enum vers_op change); | ||
65 | int nfsd_minorversion(u32 minorversion, enum vers_op change); | ||
66 | void nfsd_reset_versions(void); | ||
67 | int nfsd_create_serv(void); | ||
68 | |||
69 | extern int nfsd_max_blksize; | ||
70 | |||
71 | static inline int nfsd_v4client(struct svc_rqst *rq) | ||
72 | { | ||
73 | return rq->rq_prog == NFS_PROGRAM && rq->rq_vers == 4; | ||
74 | } | ||
75 | |||
76 | /* | ||
77 | * NFSv4 State | ||
78 | */ | ||
79 | #ifdef CONFIG_NFSD_V4 | ||
80 | extern unsigned int max_delegations; | ||
81 | int nfs4_state_init(void); | ||
82 | void nfsd4_free_slabs(void); | ||
83 | int nfs4_state_start(void); | ||
84 | void nfs4_state_shutdown(void); | ||
85 | time_t nfs4_lease_time(void); | ||
86 | void nfs4_reset_lease(time_t leasetime); | ||
87 | int nfs4_reset_recoverydir(char *recdir); | ||
88 | #else | ||
89 | static inline int nfs4_state_init(void) { return 0; } | ||
90 | static inline void nfsd4_free_slabs(void) { } | ||
91 | static inline int nfs4_state_start(void) { return 0; } | ||
92 | static inline void nfs4_state_shutdown(void) { } | ||
93 | static inline time_t nfs4_lease_time(void) { return 0; } | ||
94 | static inline void nfs4_reset_lease(time_t leasetime) { } | ||
95 | static inline int nfs4_reset_recoverydir(char *recdir) { return 0; } | ||
96 | #endif | ||
97 | |||
98 | /* | ||
99 | * lockd binding | ||
100 | */ | ||
101 | void nfsd_lockd_init(void); | ||
102 | void nfsd_lockd_shutdown(void); | ||
103 | |||
104 | |||
105 | /* | ||
106 | * These macros provide pre-xdr'ed values for faster operation. | ||
107 | */ | ||
108 | #define nfs_ok cpu_to_be32(NFS_OK) | ||
109 | #define nfserr_perm cpu_to_be32(NFSERR_PERM) | ||
110 | #define nfserr_noent cpu_to_be32(NFSERR_NOENT) | ||
111 | #define nfserr_io cpu_to_be32(NFSERR_IO) | ||
112 | #define nfserr_nxio cpu_to_be32(NFSERR_NXIO) | ||
113 | #define nfserr_eagain cpu_to_be32(NFSERR_EAGAIN) | ||
114 | #define nfserr_acces cpu_to_be32(NFSERR_ACCES) | ||
115 | #define nfserr_exist cpu_to_be32(NFSERR_EXIST) | ||
116 | #define nfserr_xdev cpu_to_be32(NFSERR_XDEV) | ||
117 | #define nfserr_nodev cpu_to_be32(NFSERR_NODEV) | ||
118 | #define nfserr_notdir cpu_to_be32(NFSERR_NOTDIR) | ||
119 | #define nfserr_isdir cpu_to_be32(NFSERR_ISDIR) | ||
120 | #define nfserr_inval cpu_to_be32(NFSERR_INVAL) | ||
121 | #define nfserr_fbig cpu_to_be32(NFSERR_FBIG) | ||
122 | #define nfserr_nospc cpu_to_be32(NFSERR_NOSPC) | ||
123 | #define nfserr_rofs cpu_to_be32(NFSERR_ROFS) | ||
124 | #define nfserr_mlink cpu_to_be32(NFSERR_MLINK) | ||
125 | #define nfserr_opnotsupp cpu_to_be32(NFSERR_OPNOTSUPP) | ||
126 | #define nfserr_nametoolong cpu_to_be32(NFSERR_NAMETOOLONG) | ||
127 | #define nfserr_notempty cpu_to_be32(NFSERR_NOTEMPTY) | ||
128 | #define nfserr_dquot cpu_to_be32(NFSERR_DQUOT) | ||
129 | #define nfserr_stale cpu_to_be32(NFSERR_STALE) | ||
130 | #define nfserr_remote cpu_to_be32(NFSERR_REMOTE) | ||
131 | #define nfserr_wflush cpu_to_be32(NFSERR_WFLUSH) | ||
132 | #define nfserr_badhandle cpu_to_be32(NFSERR_BADHANDLE) | ||
133 | #define nfserr_notsync cpu_to_be32(NFSERR_NOT_SYNC) | ||
134 | #define nfserr_badcookie cpu_to_be32(NFSERR_BAD_COOKIE) | ||
135 | #define nfserr_notsupp cpu_to_be32(NFSERR_NOTSUPP) | ||
136 | #define nfserr_toosmall cpu_to_be32(NFSERR_TOOSMALL) | ||
137 | #define nfserr_serverfault cpu_to_be32(NFSERR_SERVERFAULT) | ||
138 | #define nfserr_badtype cpu_to_be32(NFSERR_BADTYPE) | ||
139 | #define nfserr_jukebox cpu_to_be32(NFSERR_JUKEBOX) | ||
140 | #define nfserr_denied cpu_to_be32(NFSERR_DENIED) | ||
141 | #define nfserr_deadlock cpu_to_be32(NFSERR_DEADLOCK) | ||
142 | #define nfserr_expired cpu_to_be32(NFSERR_EXPIRED) | ||
143 | #define nfserr_bad_cookie cpu_to_be32(NFSERR_BAD_COOKIE) | ||
144 | #define nfserr_same cpu_to_be32(NFSERR_SAME) | ||
145 | #define nfserr_clid_inuse cpu_to_be32(NFSERR_CLID_INUSE) | ||
146 | #define nfserr_stale_clientid cpu_to_be32(NFSERR_STALE_CLIENTID) | ||
147 | #define nfserr_resource cpu_to_be32(NFSERR_RESOURCE) | ||
148 | #define nfserr_moved cpu_to_be32(NFSERR_MOVED) | ||
149 | #define nfserr_nofilehandle cpu_to_be32(NFSERR_NOFILEHANDLE) | ||
150 | #define nfserr_minor_vers_mismatch cpu_to_be32(NFSERR_MINOR_VERS_MISMATCH) | ||
151 | #define nfserr_share_denied cpu_to_be32(NFSERR_SHARE_DENIED) | ||
152 | #define nfserr_stale_stateid cpu_to_be32(NFSERR_STALE_STATEID) | ||
153 | #define nfserr_old_stateid cpu_to_be32(NFSERR_OLD_STATEID) | ||
154 | #define nfserr_bad_stateid cpu_to_be32(NFSERR_BAD_STATEID) | ||
155 | #define nfserr_bad_seqid cpu_to_be32(NFSERR_BAD_SEQID) | ||
156 | #define nfserr_symlink cpu_to_be32(NFSERR_SYMLINK) | ||
157 | #define nfserr_not_same cpu_to_be32(NFSERR_NOT_SAME) | ||
158 | #define nfserr_restorefh cpu_to_be32(NFSERR_RESTOREFH) | ||
159 | #define nfserr_attrnotsupp cpu_to_be32(NFSERR_ATTRNOTSUPP) | ||
160 | #define nfserr_bad_xdr cpu_to_be32(NFSERR_BAD_XDR) | ||
161 | #define nfserr_openmode cpu_to_be32(NFSERR_OPENMODE) | ||
162 | #define nfserr_locks_held cpu_to_be32(NFSERR_LOCKS_HELD) | ||
163 | #define nfserr_op_illegal cpu_to_be32(NFSERR_OP_ILLEGAL) | ||
164 | #define nfserr_grace cpu_to_be32(NFSERR_GRACE) | ||
165 | #define nfserr_no_grace cpu_to_be32(NFSERR_NO_GRACE) | ||
166 | #define nfserr_reclaim_bad cpu_to_be32(NFSERR_RECLAIM_BAD) | ||
167 | #define nfserr_badname cpu_to_be32(NFSERR_BADNAME) | ||
168 | #define nfserr_cb_path_down cpu_to_be32(NFSERR_CB_PATH_DOWN) | ||
169 | #define nfserr_locked cpu_to_be32(NFSERR_LOCKED) | ||
170 | #define nfserr_wrongsec cpu_to_be32(NFSERR_WRONGSEC) | ||
171 | #define nfserr_badiomode cpu_to_be32(NFS4ERR_BADIOMODE) | ||
172 | #define nfserr_badlayout cpu_to_be32(NFS4ERR_BADLAYOUT) | ||
173 | #define nfserr_bad_session_digest cpu_to_be32(NFS4ERR_BAD_SESSION_DIGEST) | ||
174 | #define nfserr_badsession cpu_to_be32(NFS4ERR_BADSESSION) | ||
175 | #define nfserr_badslot cpu_to_be32(NFS4ERR_BADSLOT) | ||
176 | #define nfserr_complete_already cpu_to_be32(NFS4ERR_COMPLETE_ALREADY) | ||
177 | #define nfserr_conn_not_bound_to_session cpu_to_be32(NFS4ERR_CONN_NOT_BOUND_TO_SESSION) | ||
178 | #define nfserr_deleg_already_wanted cpu_to_be32(NFS4ERR_DELEG_ALREADY_WANTED) | ||
179 | #define nfserr_back_chan_busy cpu_to_be32(NFS4ERR_BACK_CHAN_BUSY) | ||
180 | #define nfserr_layouttrylater cpu_to_be32(NFS4ERR_LAYOUTTRYLATER) | ||
181 | #define nfserr_layoutunavailable cpu_to_be32(NFS4ERR_LAYOUTUNAVAILABLE) | ||
182 | #define nfserr_nomatching_layout cpu_to_be32(NFS4ERR_NOMATCHING_LAYOUT) | ||
183 | #define nfserr_recallconflict cpu_to_be32(NFS4ERR_RECALLCONFLICT) | ||
184 | #define nfserr_unknown_layouttype cpu_to_be32(NFS4ERR_UNKNOWN_LAYOUTTYPE) | ||
185 | #define nfserr_seq_misordered cpu_to_be32(NFS4ERR_SEQ_MISORDERED) | ||
186 | #define nfserr_sequence_pos cpu_to_be32(NFS4ERR_SEQUENCE_POS) | ||
187 | #define nfserr_req_too_big cpu_to_be32(NFS4ERR_REQ_TOO_BIG) | ||
188 | #define nfserr_rep_too_big cpu_to_be32(NFS4ERR_REP_TOO_BIG) | ||
189 | #define nfserr_rep_too_big_to_cache cpu_to_be32(NFS4ERR_REP_TOO_BIG_TO_CACHE) | ||
190 | #define nfserr_retry_uncached_rep cpu_to_be32(NFS4ERR_RETRY_UNCACHED_REP) | ||
191 | #define nfserr_unsafe_compound cpu_to_be32(NFS4ERR_UNSAFE_COMPOUND) | ||
192 | #define nfserr_too_many_ops cpu_to_be32(NFS4ERR_TOO_MANY_OPS) | ||
193 | #define nfserr_op_not_in_session cpu_to_be32(NFS4ERR_OP_NOT_IN_SESSION) | ||
194 | #define nfserr_hash_alg_unsupp cpu_to_be32(NFS4ERR_HASH_ALG_UNSUPP) | ||
195 | #define nfserr_clientid_busy cpu_to_be32(NFS4ERR_CLIENTID_BUSY) | ||
196 | #define nfserr_pnfs_io_hole cpu_to_be32(NFS4ERR_PNFS_IO_HOLE) | ||
197 | #define nfserr_seq_false_retry cpu_to_be32(NFS4ERR_SEQ_FALSE_RETRY) | ||
198 | #define nfserr_bad_high_slot cpu_to_be32(NFS4ERR_BAD_HIGH_SLOT) | ||
199 | #define nfserr_deadsession cpu_to_be32(NFS4ERR_DEADSESSION) | ||
200 | #define nfserr_encr_alg_unsupp cpu_to_be32(NFS4ERR_ENCR_ALG_UNSUPP) | ||
201 | #define nfserr_pnfs_no_layout cpu_to_be32(NFS4ERR_PNFS_NO_LAYOUT) | ||
202 | #define nfserr_not_only_op cpu_to_be32(NFS4ERR_NOT_ONLY_OP) | ||
203 | #define nfserr_wrong_cred cpu_to_be32(NFS4ERR_WRONG_CRED) | ||
204 | #define nfserr_wrong_type cpu_to_be32(NFS4ERR_WRONG_TYPE) | ||
205 | #define nfserr_dirdeleg_unavail cpu_to_be32(NFS4ERR_DIRDELEG_UNAVAIL) | ||
206 | #define nfserr_reject_deleg cpu_to_be32(NFS4ERR_REJECT_DELEG) | ||
207 | #define nfserr_returnconflict cpu_to_be32(NFS4ERR_RETURNCONFLICT) | ||
208 | #define nfserr_deleg_revoked cpu_to_be32(NFS4ERR_DELEG_REVOKED) | ||
209 | |||
210 | /* error codes for internal use */ | ||
211 | /* if a request fails due to kmalloc failure, it gets dropped. | ||
212 | * Client should resend eventually | ||
213 | */ | ||
214 | #define nfserr_dropit cpu_to_be32(30000) | ||
215 | /* end-of-file indicator in readdir */ | ||
216 | #define nfserr_eof cpu_to_be32(30001) | ||
217 | /* replay detected */ | ||
218 | #define nfserr_replay_me cpu_to_be32(11001) | ||
219 | /* nfs41 replay detected */ | ||
220 | #define nfserr_replay_cache cpu_to_be32(11002) | ||
221 | |||
222 | /* Check for dir entries '.' and '..' */ | ||
223 | #define isdotent(n, l) (l < 3 && n[0] == '.' && (l == 1 || n[1] == '.')) | ||
224 | |||
225 | /* | ||
226 | * Time of server startup | ||
227 | */ | ||
228 | extern struct timeval nfssvc_boot; | ||
229 | |||
230 | #ifdef CONFIG_NFSD_V4 | ||
231 | |||
232 | /* before processing a COMPOUND operation, we have to check that there | ||
233 | * is enough space in the buffer for XDR encode to succeed. otherwise, | ||
234 | * we might process an operation with side effects, and be unable to | ||
235 | * tell the client that the operation succeeded. | ||
236 | * | ||
237 | * COMPOUND_SLACK_SPACE - this is the minimum bytes of buffer space | ||
238 | * needed to encode an "ordinary" _successful_ operation. (GETATTR, | ||
239 | * READ, READDIR, and READLINK have their own buffer checks.) if we | ||
240 | * fall below this level, we fail the next operation with NFS4ERR_RESOURCE. | ||
241 | * | ||
242 | * COMPOUND_ERR_SLACK_SPACE - this is the minimum bytes of buffer space | ||
243 | * needed to encode an operation which has failed with NFS4ERR_RESOURCE. | ||
244 | * care is taken to ensure that we never fall below this level for any | ||
245 | * reason. | ||
246 | */ | ||
247 | #define COMPOUND_SLACK_SPACE 140 /* OP_GETFH */ | ||
248 | #define COMPOUND_ERR_SLACK_SPACE 12 /* OP_SETATTR */ | ||
249 | |||
250 | #define NFSD_LEASE_TIME (nfs4_lease_time()) | ||
251 | #define NFSD_LAUNDROMAT_MINTIMEOUT 10 /* seconds */ | ||
252 | |||
253 | /* | ||
254 | * The following attributes are currently not supported by the NFSv4 server: | ||
255 | * ARCHIVE (deprecated anyway) | ||
256 | * HIDDEN (unlikely to be supported any time soon) | ||
257 | * MIMETYPE (unlikely to be supported any time soon) | ||
258 | * QUOTA_* (will be supported in a forthcoming patch) | ||
259 | * SYSTEM (unlikely to be supported any time soon) | ||
260 | * TIME_BACKUP (unlikely to be supported any time soon) | ||
261 | * TIME_CREATE (unlikely to be supported any time soon) | ||
262 | */ | ||
263 | #define NFSD4_SUPPORTED_ATTRS_WORD0 \ | ||
264 | (FATTR4_WORD0_SUPPORTED_ATTRS | FATTR4_WORD0_TYPE | FATTR4_WORD0_FH_EXPIRE_TYPE \ | ||
265 | | FATTR4_WORD0_CHANGE | FATTR4_WORD0_SIZE | FATTR4_WORD0_LINK_SUPPORT \ | ||
266 | | FATTR4_WORD0_SYMLINK_SUPPORT | FATTR4_WORD0_NAMED_ATTR | FATTR4_WORD0_FSID \ | ||
267 | | FATTR4_WORD0_UNIQUE_HANDLES | FATTR4_WORD0_LEASE_TIME | FATTR4_WORD0_RDATTR_ERROR \ | ||
268 | | FATTR4_WORD0_ACLSUPPORT | FATTR4_WORD0_CANSETTIME | FATTR4_WORD0_CASE_INSENSITIVE \ | ||
269 | | FATTR4_WORD0_CASE_PRESERVING | FATTR4_WORD0_CHOWN_RESTRICTED \ | ||
270 | | FATTR4_WORD0_FILEHANDLE | FATTR4_WORD0_FILEID | FATTR4_WORD0_FILES_AVAIL \ | ||
271 | | FATTR4_WORD0_FILES_FREE | FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_FS_LOCATIONS | FATTR4_WORD0_HOMOGENEOUS \ | ||
272 | | FATTR4_WORD0_MAXFILESIZE | FATTR4_WORD0_MAXLINK | FATTR4_WORD0_MAXNAME \ | ||
273 | | FATTR4_WORD0_MAXREAD | FATTR4_WORD0_MAXWRITE | FATTR4_WORD0_ACL) | ||
274 | |||
275 | #define NFSD4_SUPPORTED_ATTRS_WORD1 \ | ||
276 | (FATTR4_WORD1_MODE | FATTR4_WORD1_NO_TRUNC | FATTR4_WORD1_NUMLINKS \ | ||
277 | | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP | FATTR4_WORD1_RAWDEV \ | ||
278 | | FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE | FATTR4_WORD1_SPACE_TOTAL \ | ||
279 | | FATTR4_WORD1_SPACE_USED | FATTR4_WORD1_TIME_ACCESS | FATTR4_WORD1_TIME_ACCESS_SET \ | ||
280 | | FATTR4_WORD1_TIME_DELTA | FATTR4_WORD1_TIME_METADATA \ | ||
281 | | FATTR4_WORD1_TIME_MODIFY | FATTR4_WORD1_TIME_MODIFY_SET | FATTR4_WORD1_MOUNTED_ON_FILEID) | ||
282 | |||
283 | #define NFSD4_SUPPORTED_ATTRS_WORD2 0 | ||
284 | |||
285 | #define NFSD4_1_SUPPORTED_ATTRS_WORD0 \ | ||
286 | NFSD4_SUPPORTED_ATTRS_WORD0 | ||
287 | |||
288 | #define NFSD4_1_SUPPORTED_ATTRS_WORD1 \ | ||
289 | NFSD4_SUPPORTED_ATTRS_WORD1 | ||
290 | |||
291 | #define NFSD4_1_SUPPORTED_ATTRS_WORD2 \ | ||
292 | (NFSD4_SUPPORTED_ATTRS_WORD2 | FATTR4_WORD2_SUPPATTR_EXCLCREAT) | ||
293 | |||
294 | static inline u32 nfsd_suppattrs0(u32 minorversion) | ||
295 | { | ||
296 | return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD0 | ||
297 | : NFSD4_SUPPORTED_ATTRS_WORD0; | ||
298 | } | ||
299 | |||
300 | static inline u32 nfsd_suppattrs1(u32 minorversion) | ||
301 | { | ||
302 | return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD1 | ||
303 | : NFSD4_SUPPORTED_ATTRS_WORD1; | ||
304 | } | ||
305 | |||
306 | static inline u32 nfsd_suppattrs2(u32 minorversion) | ||
307 | { | ||
308 | return minorversion ? NFSD4_1_SUPPORTED_ATTRS_WORD2 | ||
309 | : NFSD4_SUPPORTED_ATTRS_WORD2; | ||
310 | } | ||
311 | |||
312 | /* These will return ERR_INVAL if specified in GETATTR or READDIR. */ | ||
313 | #define NFSD_WRITEONLY_ATTRS_WORD1 \ | ||
314 | (FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) | ||
315 | |||
316 | /* These are the only attrs allowed in CREATE/OPEN/SETATTR. */ | ||
317 | #define NFSD_WRITEABLE_ATTRS_WORD0 \ | ||
318 | (FATTR4_WORD0_SIZE | FATTR4_WORD0_ACL ) | ||
319 | #define NFSD_WRITEABLE_ATTRS_WORD1 \ | ||
320 | (FATTR4_WORD1_MODE | FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP \ | ||
321 | | FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET) | ||
322 | #define NFSD_WRITEABLE_ATTRS_WORD2 0 | ||
323 | |||
324 | #define NFSD_SUPPATTR_EXCLCREAT_WORD0 \ | ||
325 | NFSD_WRITEABLE_ATTRS_WORD0 | ||
326 | /* | ||
327 | * we currently store the exclusive create verifier in the v_{a,m}time | ||
328 | * attributes so the client can't set these at create time using EXCLUSIVE4_1 | ||
329 | */ | ||
330 | #define NFSD_SUPPATTR_EXCLCREAT_WORD1 \ | ||
331 | (NFSD_WRITEABLE_ATTRS_WORD1 & \ | ||
332 | ~(FATTR4_WORD1_TIME_ACCESS_SET | FATTR4_WORD1_TIME_MODIFY_SET)) | ||
333 | #define NFSD_SUPPATTR_EXCLCREAT_WORD2 \ | ||
334 | NFSD_WRITEABLE_ATTRS_WORD2 | ||
335 | |||
336 | #endif /* CONFIG_NFSD_V4 */ | ||
337 | |||
338 | #endif /* LINUX_NFSD_NFSD_H */ | ||
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 01965b2f3a76..55c8e63af0be 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/nfsd/nfsfh.c | ||
3 | * | ||
4 | * NFS server file handle treatment. | 2 | * NFS server file handle treatment. |
5 | * | 3 | * |
6 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> | 4 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> |
@@ -9,19 +7,11 @@ | |||
9 | * ... and again Southern-Winter 2001 to support export_operations | 7 | * ... and again Southern-Winter 2001 to support export_operations |
10 | */ | 8 | */ |
11 | 9 | ||
12 | #include <linux/slab.h> | ||
13 | #include <linux/fs.h> | ||
14 | #include <linux/unistd.h> | ||
15 | #include <linux/string.h> | ||
16 | #include <linux/stat.h> | ||
17 | #include <linux/dcache.h> | ||
18 | #include <linux/exportfs.h> | 10 | #include <linux/exportfs.h> |
19 | #include <linux/mount.h> | ||
20 | 11 | ||
21 | #include <linux/sunrpc/clnt.h> | ||
22 | #include <linux/sunrpc/svc.h> | ||
23 | #include <linux/sunrpc/svcauth_gss.h> | 12 | #include <linux/sunrpc/svcauth_gss.h> |
24 | #include <linux/nfsd/nfsd.h> | 13 | #include "nfsd.h" |
14 | #include "vfs.h" | ||
25 | #include "auth.h" | 15 | #include "auth.h" |
26 | 16 | ||
27 | #define NFSDDBG_FACILITY NFSDDBG_FH | 17 | #define NFSDDBG_FACILITY NFSDDBG_FH |
@@ -96,8 +86,10 @@ nfsd_mode_check(struct svc_rqst *rqstp, umode_t mode, int type) | |||
96 | static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, | 86 | static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, |
97 | struct svc_export *exp) | 87 | struct svc_export *exp) |
98 | { | 88 | { |
89 | int flags = nfsexp_flags(rqstp, exp); | ||
90 | |||
99 | /* Check if the request originated from a secure port. */ | 91 | /* Check if the request originated from a secure port. */ |
100 | if (!rqstp->rq_secure && EX_SECURE(exp)) { | 92 | if (!rqstp->rq_secure && !(flags & NFSEXP_INSECURE_PORT)) { |
101 | RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); | 93 | RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); |
102 | dprintk(KERN_WARNING | 94 | dprintk(KERN_WARNING |
103 | "nfsd: request from insecure port %s!\n", | 95 | "nfsd: request from insecure port %s!\n", |
@@ -109,6 +101,36 @@ static __be32 nfsd_setuser_and_check_port(struct svc_rqst *rqstp, | |||
109 | return nfserrno(nfsd_setuser(rqstp, exp)); | 101 | return nfserrno(nfsd_setuser(rqstp, exp)); |
110 | } | 102 | } |
111 | 103 | ||
104 | static inline __be32 check_pseudo_root(struct svc_rqst *rqstp, | ||
105 | struct dentry *dentry, struct svc_export *exp) | ||
106 | { | ||
107 | if (!(exp->ex_flags & NFSEXP_V4ROOT)) | ||
108 | return nfs_ok; | ||
109 | /* | ||
110 | * v2/v3 clients have no need for the V4ROOT export--they use | ||
111 | * the mount protocl instead; also, further V4ROOT checks may be | ||
112 | * in v4-specific code, in which case v2/v3 clients could bypass | ||
113 | * them. | ||
114 | */ | ||
115 | if (!nfsd_v4client(rqstp)) | ||
116 | return nfserr_stale; | ||
117 | /* | ||
118 | * We're exposing only the directories and symlinks that have to be | ||
119 | * traversed on the way to real exports: | ||
120 | */ | ||
121 | if (unlikely(!S_ISDIR(dentry->d_inode->i_mode) && | ||
122 | !S_ISLNK(dentry->d_inode->i_mode))) | ||
123 | return nfserr_stale; | ||
124 | /* | ||
125 | * A pseudoroot export gives permission to access only one | ||
126 | * single directory; the kernel has to make another upcall | ||
127 | * before granting access to anything else under it: | ||
128 | */ | ||
129 | if (unlikely(dentry != exp->ex_path.dentry)) | ||
130 | return nfserr_stale; | ||
131 | return nfs_ok; | ||
132 | } | ||
133 | |||
112 | /* | 134 | /* |
113 | * Use the given filehandle to look up the corresponding export and | 135 | * Use the given filehandle to look up the corresponding export and |
114 | * dentry. On success, the results are used to set fh_export and | 136 | * dentry. On success, the results are used to set fh_export and |
@@ -232,14 +254,6 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp) | |||
232 | goto out; | 254 | goto out; |
233 | } | 255 | } |
234 | 256 | ||
235 | if (exp->ex_flags & NFSEXP_NOSUBTREECHECK) { | ||
236 | error = nfsd_setuser_and_check_port(rqstp, exp); | ||
237 | if (error) { | ||
238 | dput(dentry); | ||
239 | goto out; | ||
240 | } | ||
241 | } | ||
242 | |||
243 | if (S_ISDIR(dentry->d_inode->i_mode) && | 257 | if (S_ISDIR(dentry->d_inode->i_mode) && |
244 | (dentry->d_flags & DCACHE_DISCONNECTED)) { | 258 | (dentry->d_flags & DCACHE_DISCONNECTED)) { |
245 | printk("nfsd: find_fh_dentry returned a DISCONNECTED directory: %s/%s\n", | 259 | printk("nfsd: find_fh_dentry returned a DISCONNECTED directory: %s/%s\n", |
@@ -294,28 +308,32 @@ fh_verify(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, int access) | |||
294 | error = nfsd_set_fh_dentry(rqstp, fhp); | 308 | error = nfsd_set_fh_dentry(rqstp, fhp); |
295 | if (error) | 309 | if (error) |
296 | goto out; | 310 | goto out; |
297 | dentry = fhp->fh_dentry; | ||
298 | exp = fhp->fh_export; | ||
299 | } else { | ||
300 | /* | ||
301 | * just rechecking permissions | ||
302 | * (e.g. nfsproc_create calls fh_verify, then nfsd_create | ||
303 | * does as well) | ||
304 | */ | ||
305 | dprintk("nfsd: fh_verify - just checking\n"); | ||
306 | dentry = fhp->fh_dentry; | ||
307 | exp = fhp->fh_export; | ||
308 | /* | ||
309 | * Set user creds for this exportpoint; necessary even | ||
310 | * in the "just checking" case because this may be a | ||
311 | * filehandle that was created by fh_compose, and that | ||
312 | * is about to be used in another nfsv4 compound | ||
313 | * operation. | ||
314 | */ | ||
315 | error = nfsd_setuser_and_check_port(rqstp, exp); | ||
316 | if (error) | ||
317 | goto out; | ||
318 | } | 311 | } |
312 | dentry = fhp->fh_dentry; | ||
313 | exp = fhp->fh_export; | ||
314 | /* | ||
315 | * We still have to do all these permission checks, even when | ||
316 | * fh_dentry is already set: | ||
317 | * - fh_verify may be called multiple times with different | ||
318 | * "access" arguments (e.g. nfsd_proc_create calls | ||
319 | * fh_verify(...,NFSD_MAY_EXEC) first, then later (in | ||
320 | * nfsd_create) calls fh_verify(...,NFSD_MAY_CREATE). | ||
321 | * - in the NFSv4 case, the filehandle may have been filled | ||
322 | * in by fh_compose, and given a dentry, but further | ||
323 | * compound operations performed with that filehandle | ||
324 | * still need permissions checks. In the worst case, a | ||
325 | * mountpoint crossing may have changed the export | ||
326 | * options, and we may now need to use a different uid | ||
327 | * (for example, if different id-squashing options are in | ||
328 | * effect on the new filesystem). | ||
329 | */ | ||
330 | error = check_pseudo_root(rqstp, dentry, exp); | ||
331 | if (error) | ||
332 | goto out; | ||
333 | |||
334 | error = nfsd_setuser_and_check_port(rqstp, exp); | ||
335 | if (error) | ||
336 | goto out; | ||
319 | 337 | ||
320 | error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type); | 338 | error = nfsd_mode_check(rqstp, dentry->d_inode->i_mode, type); |
321 | if (error) | 339 | if (error) |
diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h new file mode 100644 index 000000000000..cdfb8c6a4206 --- /dev/null +++ b/fs/nfsd/nfsfh.h | |||
@@ -0,0 +1,208 @@ | |||
1 | /* Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> */ | ||
2 | |||
3 | #ifndef _LINUX_NFSD_FH_INT_H | ||
4 | #define _LINUX_NFSD_FH_INT_H | ||
5 | |||
6 | #include <linux/nfsd/nfsfh.h> | ||
7 | |||
8 | enum nfsd_fsid { | ||
9 | FSID_DEV = 0, | ||
10 | FSID_NUM, | ||
11 | FSID_MAJOR_MINOR, | ||
12 | FSID_ENCODE_DEV, | ||
13 | FSID_UUID4_INUM, | ||
14 | FSID_UUID8, | ||
15 | FSID_UUID16, | ||
16 | FSID_UUID16_INUM, | ||
17 | }; | ||
18 | |||
19 | enum fsid_source { | ||
20 | FSIDSOURCE_DEV, | ||
21 | FSIDSOURCE_FSID, | ||
22 | FSIDSOURCE_UUID, | ||
23 | }; | ||
24 | extern enum fsid_source fsid_source(struct svc_fh *fhp); | ||
25 | |||
26 | |||
27 | /* This might look a little large to "inline" but in all calls except | ||
28 | * one, 'vers' is constant so moste of the function disappears. | ||
29 | */ | ||
30 | static inline void mk_fsid(int vers, u32 *fsidv, dev_t dev, ino_t ino, | ||
31 | u32 fsid, unsigned char *uuid) | ||
32 | { | ||
33 | u32 *up; | ||
34 | switch(vers) { | ||
35 | case FSID_DEV: | ||
36 | fsidv[0] = htonl((MAJOR(dev)<<16) | | ||
37 | MINOR(dev)); | ||
38 | fsidv[1] = ino_t_to_u32(ino); | ||
39 | break; | ||
40 | case FSID_NUM: | ||
41 | fsidv[0] = fsid; | ||
42 | break; | ||
43 | case FSID_MAJOR_MINOR: | ||
44 | fsidv[0] = htonl(MAJOR(dev)); | ||
45 | fsidv[1] = htonl(MINOR(dev)); | ||
46 | fsidv[2] = ino_t_to_u32(ino); | ||
47 | break; | ||
48 | |||
49 | case FSID_ENCODE_DEV: | ||
50 | fsidv[0] = new_encode_dev(dev); | ||
51 | fsidv[1] = ino_t_to_u32(ino); | ||
52 | break; | ||
53 | |||
54 | case FSID_UUID4_INUM: | ||
55 | /* 4 byte fsid and inode number */ | ||
56 | up = (u32*)uuid; | ||
57 | fsidv[0] = ino_t_to_u32(ino); | ||
58 | fsidv[1] = up[0] ^ up[1] ^ up[2] ^ up[3]; | ||
59 | break; | ||
60 | |||
61 | case FSID_UUID8: | ||
62 | /* 8 byte fsid */ | ||
63 | up = (u32*)uuid; | ||
64 | fsidv[0] = up[0] ^ up[2]; | ||
65 | fsidv[1] = up[1] ^ up[3]; | ||
66 | break; | ||
67 | |||
68 | case FSID_UUID16: | ||
69 | /* 16 byte fsid - NFSv3+ only */ | ||
70 | memcpy(fsidv, uuid, 16); | ||
71 | break; | ||
72 | |||
73 | case FSID_UUID16_INUM: | ||
74 | /* 8 byte inode and 16 byte fsid */ | ||
75 | *(u64*)fsidv = (u64)ino; | ||
76 | memcpy(fsidv+2, uuid, 16); | ||
77 | break; | ||
78 | default: BUG(); | ||
79 | } | ||
80 | } | ||
81 | |||
82 | static inline int key_len(int type) | ||
83 | { | ||
84 | switch(type) { | ||
85 | case FSID_DEV: return 8; | ||
86 | case FSID_NUM: return 4; | ||
87 | case FSID_MAJOR_MINOR: return 12; | ||
88 | case FSID_ENCODE_DEV: return 8; | ||
89 | case FSID_UUID4_INUM: return 8; | ||
90 | case FSID_UUID8: return 8; | ||
91 | case FSID_UUID16: return 16; | ||
92 | case FSID_UUID16_INUM: return 24; | ||
93 | default: return 0; | ||
94 | } | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * Shorthand for dprintk()'s | ||
99 | */ | ||
100 | extern char * SVCFH_fmt(struct svc_fh *fhp); | ||
101 | |||
102 | /* | ||
103 | * Function prototypes | ||
104 | */ | ||
105 | __be32 fh_verify(struct svc_rqst *, struct svc_fh *, int, int); | ||
106 | __be32 fh_compose(struct svc_fh *, struct svc_export *, struct dentry *, struct svc_fh *); | ||
107 | __be32 fh_update(struct svc_fh *); | ||
108 | void fh_put(struct svc_fh *); | ||
109 | |||
110 | static __inline__ struct svc_fh * | ||
111 | fh_copy(struct svc_fh *dst, struct svc_fh *src) | ||
112 | { | ||
113 | WARN_ON(src->fh_dentry || src->fh_locked); | ||
114 | |||
115 | *dst = *src; | ||
116 | return dst; | ||
117 | } | ||
118 | |||
119 | static inline void | ||
120 | fh_copy_shallow(struct knfsd_fh *dst, struct knfsd_fh *src) | ||
121 | { | ||
122 | dst->fh_size = src->fh_size; | ||
123 | memcpy(&dst->fh_base, &src->fh_base, src->fh_size); | ||
124 | } | ||
125 | |||
126 | static __inline__ struct svc_fh * | ||
127 | fh_init(struct svc_fh *fhp, int maxsize) | ||
128 | { | ||
129 | memset(fhp, 0, sizeof(*fhp)); | ||
130 | fhp->fh_maxsize = maxsize; | ||
131 | return fhp; | ||
132 | } | ||
133 | |||
134 | #ifdef CONFIG_NFSD_V3 | ||
135 | /* | ||
136 | * Fill in the pre_op attr for the wcc data | ||
137 | */ | ||
138 | static inline void | ||
139 | fill_pre_wcc(struct svc_fh *fhp) | ||
140 | { | ||
141 | struct inode *inode; | ||
142 | |||
143 | inode = fhp->fh_dentry->d_inode; | ||
144 | if (!fhp->fh_pre_saved) { | ||
145 | fhp->fh_pre_mtime = inode->i_mtime; | ||
146 | fhp->fh_pre_ctime = inode->i_ctime; | ||
147 | fhp->fh_pre_size = inode->i_size; | ||
148 | fhp->fh_pre_change = inode->i_version; | ||
149 | fhp->fh_pre_saved = 1; | ||
150 | } | ||
151 | } | ||
152 | |||
153 | extern void fill_post_wcc(struct svc_fh *); | ||
154 | #else | ||
155 | #define fill_pre_wcc(ignored) | ||
156 | #define fill_post_wcc(notused) | ||
157 | #endif /* CONFIG_NFSD_V3 */ | ||
158 | |||
159 | |||
160 | /* | ||
161 | * Lock a file handle/inode | ||
162 | * NOTE: both fh_lock and fh_unlock are done "by hand" in | ||
163 | * vfs.c:nfsd_rename as it needs to grab 2 i_mutex's at once | ||
164 | * so, any changes here should be reflected there. | ||
165 | */ | ||
166 | |||
167 | static inline void | ||
168 | fh_lock_nested(struct svc_fh *fhp, unsigned int subclass) | ||
169 | { | ||
170 | struct dentry *dentry = fhp->fh_dentry; | ||
171 | struct inode *inode; | ||
172 | |||
173 | BUG_ON(!dentry); | ||
174 | |||
175 | if (fhp->fh_locked) { | ||
176 | printk(KERN_WARNING "fh_lock: %s/%s already locked!\n", | ||
177 | dentry->d_parent->d_name.name, dentry->d_name.name); | ||
178 | return; | ||
179 | } | ||
180 | |||
181 | inode = dentry->d_inode; | ||
182 | mutex_lock_nested(&inode->i_mutex, subclass); | ||
183 | fill_pre_wcc(fhp); | ||
184 | fhp->fh_locked = 1; | ||
185 | } | ||
186 | |||
187 | static inline void | ||
188 | fh_lock(struct svc_fh *fhp) | ||
189 | { | ||
190 | fh_lock_nested(fhp, I_MUTEX_NORMAL); | ||
191 | } | ||
192 | |||
193 | /* | ||
194 | * Unlock a file handle/inode | ||
195 | */ | ||
196 | static inline void | ||
197 | fh_unlock(struct svc_fh *fhp) | ||
198 | { | ||
199 | BUG_ON(!fhp->fh_dentry); | ||
200 | |||
201 | if (fhp->fh_locked) { | ||
202 | fill_post_wcc(fhp); | ||
203 | mutex_unlock(&fhp->fh_dentry->d_inode->i_mutex); | ||
204 | fhp->fh_locked = 0; | ||
205 | } | ||
206 | } | ||
207 | |||
208 | #endif /* _LINUX_NFSD_FH_INT_H */ | ||
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index 0eb9c820b7a6..a047ad6111ef 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c | |||
@@ -1,29 +1,14 @@ | |||
1 | /* | 1 | /* |
2 | * nfsproc2.c Process version 2 NFS requests. | ||
3 | * linux/fs/nfsd/nfs2proc.c | ||
4 | * | ||
5 | * Process version 2 NFS requests. | 2 | * Process version 2 NFS requests. |
6 | * | 3 | * |
7 | * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de> | 4 | * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de> |
8 | */ | 5 | */ |
9 | 6 | ||
10 | #include <linux/linkage.h> | ||
11 | #include <linux/time.h> | ||
12 | #include <linux/errno.h> | ||
13 | #include <linux/fs.h> | ||
14 | #include <linux/stat.h> | ||
15 | #include <linux/fcntl.h> | ||
16 | #include <linux/net.h> | ||
17 | #include <linux/in.h> | ||
18 | #include <linux/namei.h> | 7 | #include <linux/namei.h> |
19 | #include <linux/unistd.h> | ||
20 | #include <linux/slab.h> | ||
21 | 8 | ||
22 | #include <linux/sunrpc/clnt.h> | 9 | #include "cache.h" |
23 | #include <linux/sunrpc/svc.h> | 10 | #include "xdr.h" |
24 | #include <linux/nfsd/nfsd.h> | 11 | #include "vfs.h" |
25 | #include <linux/nfsd/cache.h> | ||
26 | #include <linux/nfsd/xdr.h> | ||
27 | 12 | ||
28 | typedef struct svc_rqst svc_rqst; | 13 | typedef struct svc_rqst svc_rqst; |
29 | typedef struct svc_buf svc_buf; | 14 | typedef struct svc_buf svc_buf; |
@@ -758,6 +743,7 @@ nfserrno (int errno) | |||
758 | { nfserr_io, -ETXTBSY }, | 743 | { nfserr_io, -ETXTBSY }, |
759 | { nfserr_notsupp, -EOPNOTSUPP }, | 744 | { nfserr_notsupp, -EOPNOTSUPP }, |
760 | { nfserr_toosmall, -ETOOSMALL }, | 745 | { nfserr_toosmall, -ETOOSMALL }, |
746 | { nfserr_serverfault, -ESERVERFAULT }, | ||
761 | }; | 747 | }; |
762 | int i; | 748 | int i; |
763 | 749 | ||
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 67ea83eedd43..171699eb07c8 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/nfsd/nfssvc.c | ||
3 | * | ||
4 | * Central processing for nfsd. | 2 | * Central processing for nfsd. |
5 | * | 3 | * |
6 | * Authors: Olaf Kirch (okir@monad.swb.de) | 4 | * Authors: Olaf Kirch (okir@monad.swb.de) |
@@ -8,33 +6,19 @@ | |||
8 | * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> | 6 | * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> |
9 | */ | 7 | */ |
10 | 8 | ||
11 | #include <linux/module.h> | ||
12 | #include <linux/sched.h> | 9 | #include <linux/sched.h> |
13 | #include <linux/time.h> | ||
14 | #include <linux/errno.h> | ||
15 | #include <linux/nfs.h> | ||
16 | #include <linux/in.h> | ||
17 | #include <linux/uio.h> | ||
18 | #include <linux/unistd.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/smp.h> | ||
21 | #include <linux/freezer.h> | 10 | #include <linux/freezer.h> |
22 | #include <linux/fs_struct.h> | 11 | #include <linux/fs_struct.h> |
23 | #include <linux/kthread.h> | ||
24 | #include <linux/swap.h> | 12 | #include <linux/swap.h> |
25 | 13 | ||
26 | #include <linux/sunrpc/types.h> | ||
27 | #include <linux/sunrpc/stats.h> | 14 | #include <linux/sunrpc/stats.h> |
28 | #include <linux/sunrpc/svc.h> | ||
29 | #include <linux/sunrpc/svcsock.h> | 15 | #include <linux/sunrpc/svcsock.h> |
30 | #include <linux/sunrpc/cache.h> | ||
31 | #include <linux/nfsd/nfsd.h> | ||
32 | #include <linux/nfsd/stats.h> | ||
33 | #include <linux/nfsd/cache.h> | ||
34 | #include <linux/nfsd/syscall.h> | ||
35 | #include <linux/lockd/bind.h> | 16 | #include <linux/lockd/bind.h> |
36 | #include <linux/nfsacl.h> | 17 | #include <linux/nfsacl.h> |
37 | #include <linux/seq_file.h> | 18 | #include <linux/seq_file.h> |
19 | #include "nfsd.h" | ||
20 | #include "cache.h" | ||
21 | #include "vfs.h" | ||
38 | 22 | ||
39 | #define NFSDDBG_FACILITY NFSDDBG_SVC | 23 | #define NFSDDBG_FACILITY NFSDDBG_SVC |
40 | 24 | ||
diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index afd08e2c90a5..4ce005dbf3e6 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c | |||
@@ -1,20 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/nfsd/nfsxdr.c | ||
3 | * | ||
4 | * XDR support for nfsd | 2 | * XDR support for nfsd |
5 | * | 3 | * |
6 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> | 4 | * Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> |
7 | */ | 5 | */ |
8 | 6 | ||
9 | #include <linux/types.h> | 7 | #include "xdr.h" |
10 | #include <linux/time.h> | ||
11 | #include <linux/nfs.h> | ||
12 | #include <linux/vfs.h> | ||
13 | #include <linux/sunrpc/xdr.h> | ||
14 | #include <linux/sunrpc/svc.h> | ||
15 | #include <linux/nfsd/nfsd.h> | ||
16 | #include <linux/nfsd/xdr.h> | ||
17 | #include <linux/mm.h> | ||
18 | #include "auth.h" | 8 | #include "auth.h" |
19 | 9 | ||
20 | #define NFSDDBG_FACILITY NFSDDBG_XDR | 10 | #define NFSDDBG_FACILITY NFSDDBG_XDR |
diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h new file mode 100644 index 000000000000..fefeae27f25e --- /dev/null +++ b/fs/nfsd/state.h | |||
@@ -0,0 +1,408 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2001 The Regents of the University of Michigan. | ||
3 | * All rights reserved. | ||
4 | * | ||
5 | * Kendrick Smith <kmsmith@umich.edu> | ||
6 | * Andy Adamson <andros@umich.edu> | ||
7 | * | ||
8 | * Redistribution and use in source and binary forms, with or without | ||
9 | * modification, are permitted provided that the following conditions | ||
10 | * are met: | ||
11 | * | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in the | ||
16 | * documentation and/or other materials provided with the distribution. | ||
17 | * 3. Neither the name of the University nor the names of its | ||
18 | * contributors may be used to endorse or promote products derived | ||
19 | * from this software without specific prior written permission. | ||
20 | * | ||
21 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
22 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
23 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
24 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
26 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
27 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
28 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
29 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
30 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
31 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
32 | * | ||
33 | */ | ||
34 | |||
35 | #ifndef _NFSD4_STATE_H | ||
36 | #define _NFSD4_STATE_H | ||
37 | |||
38 | #include <linux/nfsd/nfsfh.h> | ||
39 | #include "nfsfh.h" | ||
40 | |||
41 | typedef struct { | ||
42 | u32 cl_boot; | ||
43 | u32 cl_id; | ||
44 | } clientid_t; | ||
45 | |||
46 | typedef struct { | ||
47 | u32 so_boot; | ||
48 | u32 so_stateownerid; | ||
49 | u32 so_fileid; | ||
50 | } stateid_opaque_t; | ||
51 | |||
52 | typedef struct { | ||
53 | u32 si_generation; | ||
54 | stateid_opaque_t si_opaque; | ||
55 | } stateid_t; | ||
56 | #define si_boot si_opaque.so_boot | ||
57 | #define si_stateownerid si_opaque.so_stateownerid | ||
58 | #define si_fileid si_opaque.so_fileid | ||
59 | |||
60 | #define STATEID_FMT "(%08x/%08x/%08x/%08x)" | ||
61 | #define STATEID_VAL(s) \ | ||
62 | (s)->si_boot, \ | ||
63 | (s)->si_stateownerid, \ | ||
64 | (s)->si_fileid, \ | ||
65 | (s)->si_generation | ||
66 | |||
67 | struct nfsd4_cb_sequence { | ||
68 | /* args/res */ | ||
69 | u32 cbs_minorversion; | ||
70 | struct nfs4_client *cbs_clp; | ||
71 | }; | ||
72 | |||
73 | struct nfs4_delegation { | ||
74 | struct list_head dl_perfile; | ||
75 | struct list_head dl_perclnt; | ||
76 | struct list_head dl_recall_lru; /* delegation recalled */ | ||
77 | atomic_t dl_count; /* ref count */ | ||
78 | struct nfs4_client *dl_client; | ||
79 | struct nfs4_file *dl_file; | ||
80 | struct file_lock *dl_flock; | ||
81 | struct file *dl_vfs_file; | ||
82 | u32 dl_type; | ||
83 | time_t dl_time; | ||
84 | /* For recall: */ | ||
85 | u32 dl_ident; | ||
86 | stateid_t dl_stateid; | ||
87 | struct knfsd_fh dl_fh; | ||
88 | int dl_retries; | ||
89 | }; | ||
90 | |||
91 | /* client delegation callback info */ | ||
92 | struct nfs4_cb_conn { | ||
93 | /* SETCLIENTID info */ | ||
94 | struct sockaddr_storage cb_addr; | ||
95 | size_t cb_addrlen; | ||
96 | u32 cb_prog; | ||
97 | u32 cb_minorversion; | ||
98 | u32 cb_ident; /* minorversion 0 only */ | ||
99 | /* RPC client info */ | ||
100 | atomic_t cb_set; /* successful CB_NULL call */ | ||
101 | struct rpc_clnt * cb_client; | ||
102 | }; | ||
103 | |||
104 | /* Maximum number of slots per session. 160 is useful for long haul TCP */ | ||
105 | #define NFSD_MAX_SLOTS_PER_SESSION 160 | ||
106 | /* Maximum number of operations per session compound */ | ||
107 | #define NFSD_MAX_OPS_PER_COMPOUND 16 | ||
108 | /* Maximum session per slot cache size */ | ||
109 | #define NFSD_SLOT_CACHE_SIZE 1024 | ||
110 | /* Maximum number of NFSD_SLOT_CACHE_SIZE slots per session */ | ||
111 | #define NFSD_CACHE_SIZE_SLOTS_PER_SESSION 32 | ||
112 | #define NFSD_MAX_MEM_PER_SESSION \ | ||
113 | (NFSD_CACHE_SIZE_SLOTS_PER_SESSION * NFSD_SLOT_CACHE_SIZE) | ||
114 | |||
115 | struct nfsd4_slot { | ||
116 | bool sl_inuse; | ||
117 | bool sl_cachethis; | ||
118 | u16 sl_opcnt; | ||
119 | u32 sl_seqid; | ||
120 | __be32 sl_status; | ||
121 | u32 sl_datalen; | ||
122 | char sl_data[]; | ||
123 | }; | ||
124 | |||
125 | struct nfsd4_channel_attrs { | ||
126 | u32 headerpadsz; | ||
127 | u32 maxreq_sz; | ||
128 | u32 maxresp_sz; | ||
129 | u32 maxresp_cached; | ||
130 | u32 maxops; | ||
131 | u32 maxreqs; | ||
132 | u32 nr_rdma_attrs; | ||
133 | u32 rdma_attrs; | ||
134 | }; | ||
135 | |||
136 | struct nfsd4_create_session { | ||
137 | clientid_t clientid; | ||
138 | struct nfs4_sessionid sessionid; | ||
139 | u32 seqid; | ||
140 | u32 flags; | ||
141 | struct nfsd4_channel_attrs fore_channel; | ||
142 | struct nfsd4_channel_attrs back_channel; | ||
143 | u32 callback_prog; | ||
144 | u32 uid; | ||
145 | u32 gid; | ||
146 | }; | ||
147 | |||
148 | /* The single slot clientid cache structure */ | ||
149 | struct nfsd4_clid_slot { | ||
150 | u32 sl_seqid; | ||
151 | __be32 sl_status; | ||
152 | struct nfsd4_create_session sl_cr_ses; | ||
153 | }; | ||
154 | |||
155 | struct nfsd4_session { | ||
156 | struct kref se_ref; | ||
157 | struct list_head se_hash; /* hash by sessionid */ | ||
158 | struct list_head se_perclnt; | ||
159 | u32 se_flags; | ||
160 | struct nfs4_client *se_client; /* for expire_client */ | ||
161 | struct nfs4_sessionid se_sessionid; | ||
162 | struct nfsd4_channel_attrs se_fchannel; | ||
163 | struct nfsd4_channel_attrs se_bchannel; | ||
164 | struct nfsd4_slot *se_slots[]; /* forward channel slots */ | ||
165 | }; | ||
166 | |||
167 | static inline void | ||
168 | nfsd4_put_session(struct nfsd4_session *ses) | ||
169 | { | ||
170 | extern void free_session(struct kref *kref); | ||
171 | kref_put(&ses->se_ref, free_session); | ||
172 | } | ||
173 | |||
174 | static inline void | ||
175 | nfsd4_get_session(struct nfsd4_session *ses) | ||
176 | { | ||
177 | kref_get(&ses->se_ref); | ||
178 | } | ||
179 | |||
180 | /* formatted contents of nfs4_sessionid */ | ||
181 | struct nfsd4_sessionid { | ||
182 | clientid_t clientid; | ||
183 | u32 sequence; | ||
184 | u32 reserved; | ||
185 | }; | ||
186 | |||
187 | #define HEXDIR_LEN 33 /* hex version of 16 byte md5 of cl_name plus '\0' */ | ||
188 | |||
189 | /* | ||
190 | * struct nfs4_client - one per client. Clientids live here. | ||
191 | * o Each nfs4_client is hashed by clientid. | ||
192 | * | ||
193 | * o Each nfs4_clients is also hashed by name | ||
194 | * (the opaque quantity initially sent by the client to identify itself). | ||
195 | * | ||
196 | * o cl_perclient list is used to ensure no dangling stateowner references | ||
197 | * when we expire the nfs4_client | ||
198 | */ | ||
199 | struct nfs4_client { | ||
200 | struct list_head cl_idhash; /* hash by cl_clientid.id */ | ||
201 | struct list_head cl_strhash; /* hash by cl_name */ | ||
202 | struct list_head cl_openowners; | ||
203 | struct list_head cl_delegations; | ||
204 | struct list_head cl_lru; /* tail queue */ | ||
205 | struct xdr_netobj cl_name; /* id generated by client */ | ||
206 | char cl_recdir[HEXDIR_LEN]; /* recovery dir */ | ||
207 | nfs4_verifier cl_verifier; /* generated by client */ | ||
208 | time_t cl_time; /* time of last lease renewal */ | ||
209 | struct sockaddr_storage cl_addr; /* client ipaddress */ | ||
210 | u32 cl_flavor; /* setclientid pseudoflavor */ | ||
211 | char *cl_principal; /* setclientid principal name */ | ||
212 | struct svc_cred cl_cred; /* setclientid principal */ | ||
213 | clientid_t cl_clientid; /* generated by server */ | ||
214 | nfs4_verifier cl_confirm; /* generated by server */ | ||
215 | struct nfs4_cb_conn cl_cb_conn; /* callback info */ | ||
216 | atomic_t cl_count; /* ref count */ | ||
217 | u32 cl_firststate; /* recovery dir creation */ | ||
218 | |||
219 | /* for nfs41 */ | ||
220 | struct list_head cl_sessions; | ||
221 | struct nfsd4_clid_slot cl_cs_slot; /* create_session slot */ | ||
222 | u32 cl_exchange_flags; | ||
223 | struct nfs4_sessionid cl_sessionid; | ||
224 | |||
225 | /* for nfs41 callbacks */ | ||
226 | /* We currently support a single back channel with a single slot */ | ||
227 | unsigned long cl_cb_slot_busy; | ||
228 | u32 cl_cb_seq_nr; | ||
229 | struct svc_xprt *cl_cb_xprt; /* 4.1 callback transport */ | ||
230 | struct rpc_wait_queue cl_cb_waitq; /* backchannel callers may */ | ||
231 | /* wait here for slots */ | ||
232 | }; | ||
233 | |||
234 | /* struct nfs4_client_reset | ||
235 | * one per old client. Populates reset_str_hashtbl. Filled from conf_id_hashtbl | ||
236 | * upon lease reset, or from upcall to state_daemon (to read in state | ||
237 | * from non-volitile storage) upon reboot. | ||
238 | */ | ||
239 | struct nfs4_client_reclaim { | ||
240 | struct list_head cr_strhash; /* hash by cr_name */ | ||
241 | char cr_recdir[HEXDIR_LEN]; /* recover dir */ | ||
242 | }; | ||
243 | |||
244 | static inline void | ||
245 | update_stateid(stateid_t *stateid) | ||
246 | { | ||
247 | stateid->si_generation++; | ||
248 | } | ||
249 | |||
250 | /* A reasonable value for REPLAY_ISIZE was estimated as follows: | ||
251 | * The OPEN response, typically the largest, requires | ||
252 | * 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) + 8(verifier) + | ||
253 | * 4(deleg. type) + 8(deleg. stateid) + 4(deleg. recall flag) + | ||
254 | * 20(deleg. space limit) + ~32(deleg. ace) = 112 bytes | ||
255 | */ | ||
256 | |||
257 | #define NFSD4_REPLAY_ISIZE 112 | ||
258 | |||
259 | /* | ||
260 | * Replay buffer, where the result of the last seqid-mutating operation | ||
261 | * is cached. | ||
262 | */ | ||
263 | struct nfs4_replay { | ||
264 | __be32 rp_status; | ||
265 | unsigned int rp_buflen; | ||
266 | char *rp_buf; | ||
267 | unsigned intrp_allocated; | ||
268 | struct knfsd_fh rp_openfh; | ||
269 | char rp_ibuf[NFSD4_REPLAY_ISIZE]; | ||
270 | }; | ||
271 | |||
272 | /* | ||
273 | * nfs4_stateowner can either be an open_owner, or a lock_owner | ||
274 | * | ||
275 | * so_idhash: stateid_hashtbl[] for open owner, lockstateid_hashtbl[] | ||
276 | * for lock_owner | ||
277 | * so_strhash: ownerstr_hashtbl[] for open_owner, lock_ownerstr_hashtbl[] | ||
278 | * for lock_owner | ||
279 | * so_perclient: nfs4_client->cl_perclient entry - used when nfs4_client | ||
280 | * struct is reaped. | ||
281 | * so_perfilestate: heads the list of nfs4_stateid (either open or lock) | ||
282 | * and is used to ensure no dangling nfs4_stateid references when we | ||
283 | * release a stateowner. | ||
284 | * so_perlockowner: (open) nfs4_stateid->st_perlockowner entry - used when | ||
285 | * close is called to reap associated byte-range locks | ||
286 | * so_close_lru: (open) stateowner is placed on this list instead of being | ||
287 | * reaped (when so_perfilestate is empty) to hold the last close replay. | ||
288 | * reaped by laundramat thread after lease period. | ||
289 | */ | ||
290 | struct nfs4_stateowner { | ||
291 | struct kref so_ref; | ||
292 | struct list_head so_idhash; /* hash by so_id */ | ||
293 | struct list_head so_strhash; /* hash by op_name */ | ||
294 | struct list_head so_perclient; | ||
295 | struct list_head so_stateids; | ||
296 | struct list_head so_perstateid; /* for lockowners only */ | ||
297 | struct list_head so_close_lru; /* tail queue */ | ||
298 | time_t so_time; /* time of placement on so_close_lru */ | ||
299 | int so_is_open_owner; /* 1=openowner,0=lockowner */ | ||
300 | u32 so_id; | ||
301 | struct nfs4_client * so_client; | ||
302 | /* after increment in ENCODE_SEQID_OP_TAIL, represents the next | ||
303 | * sequence id expected from the client: */ | ||
304 | u32 so_seqid; | ||
305 | struct xdr_netobj so_owner; /* open owner name */ | ||
306 | int so_confirmed; /* successful OPEN_CONFIRM? */ | ||
307 | struct nfs4_replay so_replay; | ||
308 | }; | ||
309 | |||
310 | /* | ||
311 | * nfs4_file: a file opened by some number of (open) nfs4_stateowners. | ||
312 | * o fi_perfile list is used to search for conflicting | ||
313 | * share_acces, share_deny on the file. | ||
314 | */ | ||
315 | struct nfs4_file { | ||
316 | atomic_t fi_ref; | ||
317 | struct list_head fi_hash; /* hash by "struct inode *" */ | ||
318 | struct list_head fi_stateids; | ||
319 | struct list_head fi_delegations; | ||
320 | struct inode *fi_inode; | ||
321 | u32 fi_id; /* used with stateowner->so_id | ||
322 | * for stateid_hashtbl hash */ | ||
323 | bool fi_had_conflict; | ||
324 | }; | ||
325 | |||
326 | /* | ||
327 | * nfs4_stateid can either be an open stateid or (eventually) a lock stateid | ||
328 | * | ||
329 | * (open)nfs4_stateid: one per (open)nfs4_stateowner, nfs4_file | ||
330 | * | ||
331 | * st_hash: stateid_hashtbl[] entry or lockstateid_hashtbl entry | ||
332 | * st_perfile: file_hashtbl[] entry. | ||
333 | * st_perfile_state: nfs4_stateowner->so_perfilestate | ||
334 | * st_perlockowner: (open stateid) list of lock nfs4_stateowners | ||
335 | * st_access_bmap: used only for open stateid | ||
336 | * st_deny_bmap: used only for open stateid | ||
337 | * st_openstp: open stateid lock stateid was derived from | ||
338 | * | ||
339 | * XXX: open stateids and lock stateids have diverged sufficiently that | ||
340 | * we should consider defining separate structs for the two cases. | ||
341 | */ | ||
342 | |||
343 | struct nfs4_stateid { | ||
344 | struct list_head st_hash; | ||
345 | struct list_head st_perfile; | ||
346 | struct list_head st_perstateowner; | ||
347 | struct list_head st_lockowners; | ||
348 | struct nfs4_stateowner * st_stateowner; | ||
349 | struct nfs4_file * st_file; | ||
350 | stateid_t st_stateid; | ||
351 | struct file * st_vfs_file; | ||
352 | unsigned long st_access_bmap; | ||
353 | unsigned long st_deny_bmap; | ||
354 | struct nfs4_stateid * st_openstp; | ||
355 | }; | ||
356 | |||
357 | /* flags for preprocess_seqid_op() */ | ||
358 | #define HAS_SESSION 0x00000001 | ||
359 | #define CONFIRM 0x00000002 | ||
360 | #define OPEN_STATE 0x00000004 | ||
361 | #define LOCK_STATE 0x00000008 | ||
362 | #define RD_STATE 0x00000010 | ||
363 | #define WR_STATE 0x00000020 | ||
364 | #define CLOSE_STATE 0x00000040 | ||
365 | |||
366 | #define seqid_mutating_err(err) \ | ||
367 | (((err) != nfserr_stale_clientid) && \ | ||
368 | ((err) != nfserr_bad_seqid) && \ | ||
369 | ((err) != nfserr_stale_stateid) && \ | ||
370 | ((err) != nfserr_bad_stateid)) | ||
371 | |||
372 | struct nfsd4_compound_state; | ||
373 | |||
374 | extern __be32 nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, | ||
375 | stateid_t *stateid, int flags, struct file **filp); | ||
376 | extern void nfs4_lock_state(void); | ||
377 | extern void nfs4_unlock_state(void); | ||
378 | extern int nfs4_in_grace(void); | ||
379 | extern __be32 nfs4_check_open_reclaim(clientid_t *clid); | ||
380 | extern void put_nfs4_client(struct nfs4_client *clp); | ||
381 | extern void nfs4_free_stateowner(struct kref *kref); | ||
382 | extern int set_callback_cred(void); | ||
383 | extern void nfsd4_probe_callback(struct nfs4_client *clp); | ||
384 | extern void nfsd4_cb_recall(struct nfs4_delegation *dp); | ||
385 | extern void nfs4_put_delegation(struct nfs4_delegation *dp); | ||
386 | extern __be32 nfs4_make_rec_clidname(char *clidname, struct xdr_netobj *clname); | ||
387 | extern void nfsd4_init_recdir(char *recdir_name); | ||
388 | extern int nfsd4_recdir_load(void); | ||
389 | extern void nfsd4_shutdown_recdir(void); | ||
390 | extern int nfs4_client_to_reclaim(const char *name); | ||
391 | extern int nfs4_has_reclaimed_state(const char *name, bool use_exchange_id); | ||
392 | extern void nfsd4_recdir_purge_old(void); | ||
393 | extern int nfsd4_create_clid_dir(struct nfs4_client *clp); | ||
394 | extern void nfsd4_remove_clid_dir(struct nfs4_client *clp); | ||
395 | |||
396 | static inline void | ||
397 | nfs4_put_stateowner(struct nfs4_stateowner *so) | ||
398 | { | ||
399 | kref_put(&so->so_ref, nfs4_free_stateowner); | ||
400 | } | ||
401 | |||
402 | static inline void | ||
403 | nfs4_get_stateowner(struct nfs4_stateowner *so) | ||
404 | { | ||
405 | kref_get(&so->so_ref); | ||
406 | } | ||
407 | |||
408 | #endif /* NFSD4_STATE_H */ | ||
diff --git a/fs/nfsd/stats.c b/fs/nfsd/stats.c index 71944cddf680..5232d3e8fb2f 100644 --- a/fs/nfsd/stats.c +++ b/fs/nfsd/stats.c | |||
@@ -1,6 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * linux/fs/nfsd/stats.c | ||
3 | * | ||
4 | * procfs-based user access to knfsd statistics | 2 | * procfs-based user access to knfsd statistics |
5 | * | 3 | * |
6 | * /proc/net/rpc/nfsd | 4 | * /proc/net/rpc/nfsd |
@@ -23,18 +21,13 @@ | |||
23 | * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> | 21 | * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de> |
24 | */ | 22 | */ |
25 | 23 | ||
26 | #include <linux/kernel.h> | ||
27 | #include <linux/time.h> | ||
28 | #include <linux/proc_fs.h> | ||
29 | #include <linux/seq_file.h> | 24 | #include <linux/seq_file.h> |
30 | #include <linux/stat.h> | ||
31 | #include <linux/module.h> | 25 | #include <linux/module.h> |
32 | |||
33 | #include <linux/sunrpc/svc.h> | ||
34 | #include <linux/sunrpc/stats.h> | 26 | #include <linux/sunrpc/stats.h> |
35 | #include <linux/nfsd/nfsd.h> | ||
36 | #include <linux/nfsd/stats.h> | 27 | #include <linux/nfsd/stats.h> |
37 | 28 | ||
29 | #include "nfsd.h" | ||
30 | |||
38 | struct nfsd_stats nfsdstats; | 31 | struct nfsd_stats nfsdstats; |
39 | struct svc_stat nfsd_svcstats = { | 32 | struct svc_stat nfsd_svcstats = { |
40 | .program = &nfsd_program, | 33 | .program = &nfsd_program, |
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index a293f0273263..8715d194561a 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -1,7 +1,5 @@ | |||
1 | #define MSNFS /* HACK HACK */ | 1 | #define MSNFS /* HACK HACK */ |
2 | /* | 2 | /* |
3 | * linux/fs/nfsd/vfs.c | ||
4 | * | ||
5 | * File operations used by nfsd. Some of these have been ripped from | 3 | * File operations used by nfsd. Some of these have been ripped from |
6 | * other parts of the kernel because they weren't exported, others | 4 | * other parts of the kernel because they weren't exported, others |
7 | * are partial duplicates with added or changed functionality. | 5 | * are partial duplicates with added or changed functionality. |
@@ -16,48 +14,31 @@ | |||
16 | * Zerocpy NFS support (C) 2002 Hirokazu Takahashi <taka@valinux.co.jp> | 14 | * Zerocpy NFS support (C) 2002 Hirokazu Takahashi <taka@valinux.co.jp> |
17 | */ | 15 | */ |
18 | 16 | ||
19 | #include <linux/string.h> | ||
20 | #include <linux/time.h> | ||
21 | #include <linux/errno.h> | ||
22 | #include <linux/fs.h> | 17 | #include <linux/fs.h> |
23 | #include <linux/file.h> | 18 | #include <linux/file.h> |
24 | #include <linux/mount.h> | ||
25 | #include <linux/major.h> | ||
26 | #include <linux/splice.h> | 19 | #include <linux/splice.h> |
27 | #include <linux/proc_fs.h> | ||
28 | #include <linux/stat.h> | ||
29 | #include <linux/fcntl.h> | 20 | #include <linux/fcntl.h> |
30 | #include <linux/net.h> | ||
31 | #include <linux/unistd.h> | ||
32 | #include <linux/slab.h> | ||
33 | #include <linux/pagemap.h> | ||
34 | #include <linux/in.h> | ||
35 | #include <linux/module.h> | ||
36 | #include <linux/namei.h> | 21 | #include <linux/namei.h> |
37 | #include <linux/vfs.h> | ||
38 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
39 | #include <linux/sunrpc/svc.h> | ||
40 | #include <linux/nfsd/nfsd.h> | ||
41 | #ifdef CONFIG_NFSD_V3 | ||
42 | #include <linux/nfs3.h> | ||
43 | #include <linux/nfsd/xdr3.h> | ||
44 | #endif /* CONFIG_NFSD_V3 */ | ||
45 | #include <linux/nfsd/nfsfh.h> | ||
46 | #include <linux/quotaops.h> | 23 | #include <linux/quotaops.h> |
47 | #include <linux/fsnotify.h> | 24 | #include <linux/fsnotify.h> |
48 | #include <linux/posix_acl.h> | ||
49 | #include <linux/posix_acl_xattr.h> | 25 | #include <linux/posix_acl_xattr.h> |
50 | #include <linux/xattr.h> | 26 | #include <linux/xattr.h> |
27 | #include <linux/jhash.h> | ||
28 | #include <linux/ima.h> | ||
29 | #include <asm/uaccess.h> | ||
30 | |||
31 | #ifdef CONFIG_NFSD_V3 | ||
32 | #include "xdr3.h" | ||
33 | #endif /* CONFIG_NFSD_V3 */ | ||
34 | |||
51 | #ifdef CONFIG_NFSD_V4 | 35 | #ifdef CONFIG_NFSD_V4 |
52 | #include <linux/nfs4.h> | ||
53 | #include <linux/nfs4_acl.h> | 36 | #include <linux/nfs4_acl.h> |
54 | #include <linux/nfsd_idmap.h> | 37 | #include <linux/nfsd_idmap.h> |
55 | #include <linux/security.h> | ||
56 | #endif /* CONFIG_NFSD_V4 */ | 38 | #endif /* CONFIG_NFSD_V4 */ |
57 | #include <linux/jhash.h> | ||
58 | #include <linux/ima.h> | ||
59 | 39 | ||
60 | #include <asm/uaccess.h> | 40 | #include "nfsd.h" |
41 | #include "vfs.h" | ||
61 | 42 | ||
62 | #define NFSDDBG_FACILITY NFSDDBG_FILEOP | 43 | #define NFSDDBG_FACILITY NFSDDBG_FILEOP |
63 | 44 | ||
@@ -89,12 +70,6 @@ struct raparm_hbucket { | |||
89 | #define RAPARM_HASH_MASK (RAPARM_HASH_SIZE-1) | 70 | #define RAPARM_HASH_MASK (RAPARM_HASH_SIZE-1) |
90 | static struct raparm_hbucket raparm_hash[RAPARM_HASH_SIZE]; | 71 | static struct raparm_hbucket raparm_hash[RAPARM_HASH_SIZE]; |
91 | 72 | ||
92 | static inline int | ||
93 | nfsd_v4client(struct svc_rqst *rq) | ||
94 | { | ||
95 | return rq->rq_prog == NFS_PROGRAM && rq->rq_vers == 4; | ||
96 | } | ||
97 | |||
98 | /* | 73 | /* |
99 | * Called from nfsd_lookup and encode_dirent. Check if we have crossed | 74 | * Called from nfsd_lookup and encode_dirent. Check if we have crossed |
100 | * a mount point. | 75 | * a mount point. |
@@ -116,8 +91,16 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, | |||
116 | 91 | ||
117 | exp2 = rqst_exp_get_by_name(rqstp, &path); | 92 | exp2 = rqst_exp_get_by_name(rqstp, &path); |
118 | if (IS_ERR(exp2)) { | 93 | if (IS_ERR(exp2)) { |
119 | if (PTR_ERR(exp2) != -ENOENT) | 94 | err = PTR_ERR(exp2); |
120 | err = PTR_ERR(exp2); | 95 | /* |
96 | * We normally allow NFS clients to continue | ||
97 | * "underneath" a mountpoint that is not exported. | ||
98 | * The exception is V4ROOT, where no traversal is ever | ||
99 | * allowed without an explicit export of the new | ||
100 | * directory. | ||
101 | */ | ||
102 | if (err == -ENOENT && !(exp->ex_flags & NFSEXP_V4ROOT)) | ||
103 | err = 0; | ||
121 | path_put(&path); | 104 | path_put(&path); |
122 | goto out; | 105 | goto out; |
123 | } | 106 | } |
@@ -141,6 +124,53 @@ out: | |||
141 | return err; | 124 | return err; |
142 | } | 125 | } |
143 | 126 | ||
127 | static void follow_to_parent(struct path *path) | ||
128 | { | ||
129 | struct dentry *dp; | ||
130 | |||
131 | while (path->dentry == path->mnt->mnt_root && follow_up(path)) | ||
132 | ; | ||
133 | dp = dget_parent(path->dentry); | ||
134 | dput(path->dentry); | ||
135 | path->dentry = dp; | ||
136 | } | ||
137 | |||
138 | static int nfsd_lookup_parent(struct svc_rqst *rqstp, struct dentry *dparent, struct svc_export **exp, struct dentry **dentryp) | ||
139 | { | ||
140 | struct svc_export *exp2; | ||
141 | struct path path = {.mnt = mntget((*exp)->ex_path.mnt), | ||
142 | .dentry = dget(dparent)}; | ||
143 | |||
144 | follow_to_parent(&path); | ||
145 | |||
146 | exp2 = rqst_exp_parent(rqstp, &path); | ||
147 | if (PTR_ERR(exp2) == -ENOENT) { | ||
148 | *dentryp = dget(dparent); | ||
149 | } else if (IS_ERR(exp2)) { | ||
150 | path_put(&path); | ||
151 | return PTR_ERR(exp2); | ||
152 | } else { | ||
153 | *dentryp = dget(path.dentry); | ||
154 | exp_put(*exp); | ||
155 | *exp = exp2; | ||
156 | } | ||
157 | path_put(&path); | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * For nfsd purposes, we treat V4ROOT exports as though there was an | ||
163 | * export at *every* directory. | ||
164 | */ | ||
165 | int nfsd_mountpoint(struct dentry *dentry, struct svc_export *exp) | ||
166 | { | ||
167 | if (d_mountpoint(dentry)) | ||
168 | return 1; | ||
169 | if (!(exp->ex_flags & NFSEXP_V4ROOT)) | ||
170 | return 0; | ||
171 | return dentry->d_inode != NULL; | ||
172 | } | ||
173 | |||
144 | __be32 | 174 | __be32 |
145 | nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, | 175 | nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, |
146 | const char *name, unsigned int len, | 176 | const char *name, unsigned int len, |
@@ -169,35 +199,13 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
169 | dentry = dget(dparent); | 199 | dentry = dget(dparent); |
170 | else if (dparent != exp->ex_path.dentry) | 200 | else if (dparent != exp->ex_path.dentry) |
171 | dentry = dget_parent(dparent); | 201 | dentry = dget_parent(dparent); |
172 | else if (!EX_NOHIDE(exp)) | 202 | else if (!EX_NOHIDE(exp) && !nfsd_v4client(rqstp)) |
173 | dentry = dget(dparent); /* .. == . just like at / */ | 203 | dentry = dget(dparent); /* .. == . just like at / */ |
174 | else { | 204 | else { |
175 | /* checking mountpoint crossing is very different when stepping up */ | 205 | /* checking mountpoint crossing is very different when stepping up */ |
176 | struct svc_export *exp2 = NULL; | 206 | host_err = nfsd_lookup_parent(rqstp, dparent, &exp, &dentry); |
177 | struct dentry *dp; | 207 | if (host_err) |
178 | struct path path = {.mnt = mntget(exp->ex_path.mnt), | ||
179 | .dentry = dget(dparent)}; | ||
180 | |||
181 | while (path.dentry == path.mnt->mnt_root && | ||
182 | follow_up(&path)) | ||
183 | ; | ||
184 | dp = dget_parent(path.dentry); | ||
185 | dput(path.dentry); | ||
186 | path.dentry = dp; | ||
187 | |||
188 | exp2 = rqst_exp_parent(rqstp, &path); | ||
189 | if (PTR_ERR(exp2) == -ENOENT) { | ||
190 | dentry = dget(dparent); | ||
191 | } else if (IS_ERR(exp2)) { | ||
192 | host_err = PTR_ERR(exp2); | ||
193 | path_put(&path); | ||
194 | goto out_nfserr; | 208 | goto out_nfserr; |
195 | } else { | ||
196 | dentry = dget(path.dentry); | ||
197 | exp_put(exp); | ||
198 | exp = exp2; | ||
199 | } | ||
200 | path_put(&path); | ||
201 | } | 209 | } |
202 | } else { | 210 | } else { |
203 | fh_lock(fhp); | 211 | fh_lock(fhp); |
@@ -208,7 +216,7 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
208 | /* | 216 | /* |
209 | * check if we have crossed a mount point ... | 217 | * check if we have crossed a mount point ... |
210 | */ | 218 | */ |
211 | if (d_mountpoint(dentry)) { | 219 | if (nfsd_mountpoint(dentry, exp)) { |
212 | if ((host_err = nfsd_cross_mnt(rqstp, &dentry, &exp))) { | 220 | if ((host_err = nfsd_cross_mnt(rqstp, &dentry, &exp))) { |
213 | dput(dentry); | 221 | dput(dentry); |
214 | goto out_nfserr; | 222 | goto out_nfserr; |
@@ -745,7 +753,7 @@ nfsd_open(struct svc_rqst *rqstp, struct svc_fh *fhp, int type, | |||
745 | if (IS_ERR(*filp)) | 753 | if (IS_ERR(*filp)) |
746 | host_err = PTR_ERR(*filp); | 754 | host_err = PTR_ERR(*filp); |
747 | else | 755 | else |
748 | ima_counts_get(*filp); | 756 | host_err = ima_file_check(*filp, access); |
749 | out_nfserr: | 757 | out_nfserr: |
750 | err = nfserrno(host_err); | 758 | err = nfserrno(host_err); |
751 | out: | 759 | out: |
@@ -774,12 +782,9 @@ static inline int nfsd_dosync(struct file *filp, struct dentry *dp, | |||
774 | int (*fsync) (struct file *, struct dentry *, int); | 782 | int (*fsync) (struct file *, struct dentry *, int); |
775 | int err; | 783 | int err; |
776 | 784 | ||
777 | err = filemap_fdatawrite(inode->i_mapping); | 785 | err = filemap_write_and_wait(inode->i_mapping); |
778 | if (err == 0 && fop && (fsync = fop->fsync)) | 786 | if (err == 0 && fop && (fsync = fop->fsync)) |
779 | err = fsync(filp, dp, 0); | 787 | err = fsync(filp, dp, 0); |
780 | if (err == 0) | ||
781 | err = filemap_fdatawait(inode->i_mapping); | ||
782 | |||
783 | return err; | 788 | return err; |
784 | } | 789 | } |
785 | 790 | ||
@@ -2124,8 +2129,6 @@ nfsd_permission(struct svc_rqst *rqstp, struct svc_export *exp, | |||
2124 | */ | 2129 | */ |
2125 | path.mnt = exp->ex_path.mnt; | 2130 | path.mnt = exp->ex_path.mnt; |
2126 | path.dentry = dentry; | 2131 | path.dentry = dentry; |
2127 | err = ima_path_check(&path, acc & (MAY_READ | MAY_WRITE | MAY_EXEC), | ||
2128 | IMA_COUNT_LEAVE); | ||
2129 | nfsd_out: | 2132 | nfsd_out: |
2130 | return err? nfserrno(err) : 0; | 2133 | return err? nfserrno(err) : 0; |
2131 | } | 2134 | } |
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h new file mode 100644 index 000000000000..4b1de0a9ea75 --- /dev/null +++ b/fs/nfsd/vfs.h | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * Copyright (C) 1995-1997 Olaf Kirch <okir@monad.swb.de> | ||
3 | */ | ||
4 | |||
5 | #ifndef LINUX_NFSD_VFS_H | ||
6 | #define LINUX_NFSD_VFS_H | ||
7 | |||
8 | #include "nfsfh.h" | ||
9 | |||
10 | /* | ||
11 | * Flags for nfsd_permission | ||
12 | */ | ||
13 | #define NFSD_MAY_NOP 0 | ||
14 | #define NFSD_MAY_EXEC 1 /* == MAY_EXEC */ | ||
15 | #define NFSD_MAY_WRITE 2 /* == MAY_WRITE */ | ||
16 | #define NFSD_MAY_READ 4 /* == MAY_READ */ | ||
17 | #define NFSD_MAY_SATTR 8 | ||
18 | #define NFSD_MAY_TRUNC 16 | ||
19 | #define NFSD_MAY_LOCK 32 | ||
20 | #define NFSD_MAY_OWNER_OVERRIDE 64 | ||
21 | #define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/ | ||
22 | #define NFSD_MAY_BYPASS_GSS_ON_ROOT 256 | ||
23 | |||
24 | #define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) | ||
25 | #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) | ||
26 | |||
27 | /* | ||
28 | * Callback function for readdir | ||
29 | */ | ||
30 | typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int); | ||
31 | |||
32 | /* nfsd/vfs.c */ | ||
33 | int fh_lock_parent(struct svc_fh *, struct dentry *); | ||
34 | int nfsd_racache_init(int); | ||
35 | void nfsd_racache_shutdown(void); | ||
36 | int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, | ||
37 | struct svc_export **expp); | ||
38 | __be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *, | ||
39 | const char *, unsigned int, struct svc_fh *); | ||
40 | __be32 nfsd_lookup_dentry(struct svc_rqst *, struct svc_fh *, | ||
41 | const char *, unsigned int, | ||
42 | struct svc_export **, struct dentry **); | ||
43 | __be32 nfsd_setattr(struct svc_rqst *, struct svc_fh *, | ||
44 | struct iattr *, int, time_t); | ||
45 | int nfsd_mountpoint(struct dentry *, struct svc_export *); | ||
46 | #ifdef CONFIG_NFSD_V4 | ||
47 | __be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *, | ||
48 | struct nfs4_acl *); | ||
49 | int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **); | ||
50 | #endif /* CONFIG_NFSD_V4 */ | ||
51 | __be32 nfsd_create(struct svc_rqst *, struct svc_fh *, | ||
52 | char *name, int len, struct iattr *attrs, | ||
53 | int type, dev_t rdev, struct svc_fh *res); | ||
54 | #ifdef CONFIG_NFSD_V3 | ||
55 | __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); | ||
56 | __be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *, | ||
57 | char *name, int len, struct iattr *attrs, | ||
58 | struct svc_fh *res, int createmode, | ||
59 | u32 *verifier, int *truncp, int *created); | ||
60 | __be32 nfsd_commit(struct svc_rqst *, struct svc_fh *, | ||
61 | loff_t, unsigned long); | ||
62 | #endif /* CONFIG_NFSD_V3 */ | ||
63 | __be32 nfsd_open(struct svc_rqst *, struct svc_fh *, int, | ||
64 | int, struct file **); | ||
65 | void nfsd_close(struct file *); | ||
66 | __be32 nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *, | ||
67 | loff_t, struct kvec *, int, unsigned long *); | ||
68 | __be32 nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *, | ||
69 | loff_t, struct kvec *,int, unsigned long *, int *); | ||
70 | __be32 nfsd_readlink(struct svc_rqst *, struct svc_fh *, | ||
71 | char *, int *); | ||
72 | __be32 nfsd_symlink(struct svc_rqst *, struct svc_fh *, | ||
73 | char *name, int len, char *path, int plen, | ||
74 | struct svc_fh *res, struct iattr *); | ||
75 | __be32 nfsd_link(struct svc_rqst *, struct svc_fh *, | ||
76 | char *, int, struct svc_fh *); | ||
77 | __be32 nfsd_rename(struct svc_rqst *, | ||
78 | struct svc_fh *, char *, int, | ||
79 | struct svc_fh *, char *, int); | ||
80 | __be32 nfsd_remove(struct svc_rqst *, | ||
81 | struct svc_fh *, char *, int); | ||
82 | __be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type, | ||
83 | char *name, int len); | ||
84 | int nfsd_truncate(struct svc_rqst *, struct svc_fh *, | ||
85 | unsigned long size); | ||
86 | __be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, | ||
87 | loff_t *, struct readdir_cd *, filldir_t); | ||
88 | __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, | ||
89 | struct kstatfs *, int access); | ||
90 | |||
91 | int nfsd_notify_change(struct inode *, struct iattr *); | ||
92 | __be32 nfsd_permission(struct svc_rqst *, struct svc_export *, | ||
93 | struct dentry *, int); | ||
94 | int nfsd_sync_dir(struct dentry *dp); | ||
95 | |||
96 | #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) | ||
97 | struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int); | ||
98 | int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *); | ||
99 | #endif | ||
100 | |||
101 | #endif /* LINUX_NFSD_VFS_H */ | ||
diff --git a/fs/nfsd/xdr.h b/fs/nfsd/xdr.h new file mode 100644 index 000000000000..53b1863dd8f6 --- /dev/null +++ b/fs/nfsd/xdr.h | |||
@@ -0,0 +1,173 @@ | |||
1 | /* XDR types for nfsd. This is mainly a typing exercise. */ | ||
2 | |||
3 | #ifndef LINUX_NFSD_H | ||
4 | #define LINUX_NFSD_H | ||
5 | |||
6 | #include <linux/vfs.h> | ||
7 | #include "nfsd.h" | ||
8 | #include "nfsfh.h" | ||
9 | |||
10 | struct nfsd_fhandle { | ||
11 | struct svc_fh fh; | ||
12 | }; | ||
13 | |||
14 | struct nfsd_sattrargs { | ||
15 | struct svc_fh fh; | ||
16 | struct iattr attrs; | ||
17 | }; | ||
18 | |||
19 | struct nfsd_diropargs { | ||
20 | struct svc_fh fh; | ||
21 | char * name; | ||
22 | unsigned int len; | ||
23 | }; | ||
24 | |||
25 | struct nfsd_readargs { | ||
26 | struct svc_fh fh; | ||
27 | __u32 offset; | ||
28 | __u32 count; | ||
29 | int vlen; | ||
30 | }; | ||
31 | |||
32 | struct nfsd_writeargs { | ||
33 | svc_fh fh; | ||
34 | __u32 offset; | ||
35 | int len; | ||
36 | int vlen; | ||
37 | }; | ||
38 | |||
39 | struct nfsd_createargs { | ||
40 | struct svc_fh fh; | ||
41 | char * name; | ||
42 | unsigned int len; | ||
43 | struct iattr attrs; | ||
44 | }; | ||
45 | |||
46 | struct nfsd_renameargs { | ||
47 | struct svc_fh ffh; | ||
48 | char * fname; | ||
49 | unsigned int flen; | ||
50 | struct svc_fh tfh; | ||
51 | char * tname; | ||
52 | unsigned int tlen; | ||
53 | }; | ||
54 | |||
55 | struct nfsd_readlinkargs { | ||
56 | struct svc_fh fh; | ||
57 | char * buffer; | ||
58 | }; | ||
59 | |||
60 | struct nfsd_linkargs { | ||
61 | struct svc_fh ffh; | ||
62 | struct svc_fh tfh; | ||
63 | char * tname; | ||
64 | unsigned int tlen; | ||
65 | }; | ||
66 | |||
67 | struct nfsd_symlinkargs { | ||
68 | struct svc_fh ffh; | ||
69 | char * fname; | ||
70 | unsigned int flen; | ||
71 | char * tname; | ||
72 | unsigned int tlen; | ||
73 | struct iattr attrs; | ||
74 | }; | ||
75 | |||
76 | struct nfsd_readdirargs { | ||
77 | struct svc_fh fh; | ||
78 | __u32 cookie; | ||
79 | __u32 count; | ||
80 | __be32 * buffer; | ||
81 | }; | ||
82 | |||
83 | struct nfsd_attrstat { | ||
84 | struct svc_fh fh; | ||
85 | struct kstat stat; | ||
86 | }; | ||
87 | |||
88 | struct nfsd_diropres { | ||
89 | struct svc_fh fh; | ||
90 | struct kstat stat; | ||
91 | }; | ||
92 | |||
93 | struct nfsd_readlinkres { | ||
94 | int len; | ||
95 | }; | ||
96 | |||
97 | struct nfsd_readres { | ||
98 | struct svc_fh fh; | ||
99 | unsigned long count; | ||
100 | struct kstat stat; | ||
101 | }; | ||
102 | |||
103 | struct nfsd_readdirres { | ||
104 | int count; | ||
105 | |||
106 | struct readdir_cd common; | ||
107 | __be32 * buffer; | ||
108 | int buflen; | ||
109 | __be32 * offset; | ||
110 | }; | ||
111 | |||
112 | struct nfsd_statfsres { | ||
113 | struct kstatfs stats; | ||
114 | }; | ||
115 | |||
116 | /* | ||
117 | * Storage requirements for XDR arguments and results. | ||
118 | */ | ||
119 | union nfsd_xdrstore { | ||
120 | struct nfsd_sattrargs sattr; | ||
121 | struct nfsd_diropargs dirop; | ||
122 | struct nfsd_readargs read; | ||
123 | struct nfsd_writeargs write; | ||
124 | struct nfsd_createargs create; | ||
125 | struct nfsd_renameargs rename; | ||
126 | struct nfsd_linkargs link; | ||
127 | struct nfsd_symlinkargs symlink; | ||
128 | struct nfsd_readdirargs readdir; | ||
129 | }; | ||
130 | |||
131 | #define NFS2_SVC_XDRSIZE sizeof(union nfsd_xdrstore) | ||
132 | |||
133 | |||
134 | int nfssvc_decode_void(struct svc_rqst *, __be32 *, void *); | ||
135 | int nfssvc_decode_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); | ||
136 | int nfssvc_decode_sattrargs(struct svc_rqst *, __be32 *, | ||
137 | struct nfsd_sattrargs *); | ||
138 | int nfssvc_decode_diropargs(struct svc_rqst *, __be32 *, | ||
139 | struct nfsd_diropargs *); | ||
140 | int nfssvc_decode_readargs(struct svc_rqst *, __be32 *, | ||
141 | struct nfsd_readargs *); | ||
142 | int nfssvc_decode_writeargs(struct svc_rqst *, __be32 *, | ||
143 | struct nfsd_writeargs *); | ||
144 | int nfssvc_decode_createargs(struct svc_rqst *, __be32 *, | ||
145 | struct nfsd_createargs *); | ||
146 | int nfssvc_decode_renameargs(struct svc_rqst *, __be32 *, | ||
147 | struct nfsd_renameargs *); | ||
148 | int nfssvc_decode_readlinkargs(struct svc_rqst *, __be32 *, | ||
149 | struct nfsd_readlinkargs *); | ||
150 | int nfssvc_decode_linkargs(struct svc_rqst *, __be32 *, | ||
151 | struct nfsd_linkargs *); | ||
152 | int nfssvc_decode_symlinkargs(struct svc_rqst *, __be32 *, | ||
153 | struct nfsd_symlinkargs *); | ||
154 | int nfssvc_decode_readdirargs(struct svc_rqst *, __be32 *, | ||
155 | struct nfsd_readdirargs *); | ||
156 | int nfssvc_encode_void(struct svc_rqst *, __be32 *, void *); | ||
157 | int nfssvc_encode_attrstat(struct svc_rqst *, __be32 *, struct nfsd_attrstat *); | ||
158 | int nfssvc_encode_diropres(struct svc_rqst *, __be32 *, struct nfsd_diropres *); | ||
159 | int nfssvc_encode_readlinkres(struct svc_rqst *, __be32 *, struct nfsd_readlinkres *); | ||
160 | int nfssvc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd_readres *); | ||
161 | int nfssvc_encode_statfsres(struct svc_rqst *, __be32 *, struct nfsd_statfsres *); | ||
162 | int nfssvc_encode_readdirres(struct svc_rqst *, __be32 *, struct nfsd_readdirres *); | ||
163 | |||
164 | int nfssvc_encode_entry(void *, const char *name, | ||
165 | int namlen, loff_t offset, u64 ino, unsigned int); | ||
166 | |||
167 | int nfssvc_release_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); | ||
168 | |||
169 | /* Helper functions for NFSv2 ACL code */ | ||
170 | __be32 *nfs2svc_encode_fattr(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp); | ||
171 | __be32 *nfs2svc_decode_fh(__be32 *p, struct svc_fh *fhp); | ||
172 | |||
173 | #endif /* LINUX_NFSD_H */ | ||
diff --git a/fs/nfsd/xdr3.h b/fs/nfsd/xdr3.h new file mode 100644 index 000000000000..7df980eb0562 --- /dev/null +++ b/fs/nfsd/xdr3.h | |||
@@ -0,0 +1,344 @@ | |||
1 | /* | ||
2 | * XDR types for NFSv3 in nfsd. | ||
3 | * | ||
4 | * Copyright (C) 1996-1998, Olaf Kirch <okir@monad.swb.de> | ||
5 | */ | ||
6 | |||
7 | #ifndef _LINUX_NFSD_XDR3_H | ||
8 | #define _LINUX_NFSD_XDR3_H | ||
9 | |||
10 | #include "xdr.h" | ||
11 | |||
12 | struct nfsd3_sattrargs { | ||
13 | struct svc_fh fh; | ||
14 | struct iattr attrs; | ||
15 | int check_guard; | ||
16 | time_t guardtime; | ||
17 | }; | ||
18 | |||
19 | struct nfsd3_diropargs { | ||
20 | struct svc_fh fh; | ||
21 | char * name; | ||
22 | unsigned int len; | ||
23 | }; | ||
24 | |||
25 | struct nfsd3_accessargs { | ||
26 | struct svc_fh fh; | ||
27 | unsigned int access; | ||
28 | }; | ||
29 | |||
30 | struct nfsd3_readargs { | ||
31 | struct svc_fh fh; | ||
32 | __u64 offset; | ||
33 | __u32 count; | ||
34 | int vlen; | ||
35 | }; | ||
36 | |||
37 | struct nfsd3_writeargs { | ||
38 | svc_fh fh; | ||
39 | __u64 offset; | ||
40 | __u32 count; | ||
41 | int stable; | ||
42 | __u32 len; | ||
43 | int vlen; | ||
44 | }; | ||
45 | |||
46 | struct nfsd3_createargs { | ||
47 | struct svc_fh fh; | ||
48 | char * name; | ||
49 | unsigned int len; | ||
50 | int createmode; | ||
51 | struct iattr attrs; | ||
52 | __be32 * verf; | ||
53 | }; | ||
54 | |||
55 | struct nfsd3_mknodargs { | ||
56 | struct svc_fh fh; | ||
57 | char * name; | ||
58 | unsigned int len; | ||
59 | __u32 ftype; | ||
60 | __u32 major, minor; | ||
61 | struct iattr attrs; | ||
62 | }; | ||
63 | |||
64 | struct nfsd3_renameargs { | ||
65 | struct svc_fh ffh; | ||
66 | char * fname; | ||
67 | unsigned int flen; | ||
68 | struct svc_fh tfh; | ||
69 | char * tname; | ||
70 | unsigned int tlen; | ||
71 | }; | ||
72 | |||
73 | struct nfsd3_readlinkargs { | ||
74 | struct svc_fh fh; | ||
75 | char * buffer; | ||
76 | }; | ||
77 | |||
78 | struct nfsd3_linkargs { | ||
79 | struct svc_fh ffh; | ||
80 | struct svc_fh tfh; | ||
81 | char * tname; | ||
82 | unsigned int tlen; | ||
83 | }; | ||
84 | |||
85 | struct nfsd3_symlinkargs { | ||
86 | struct svc_fh ffh; | ||
87 | char * fname; | ||
88 | unsigned int flen; | ||
89 | char * tname; | ||
90 | unsigned int tlen; | ||
91 | struct iattr attrs; | ||
92 | }; | ||
93 | |||
94 | struct nfsd3_readdirargs { | ||
95 | struct svc_fh fh; | ||
96 | __u64 cookie; | ||
97 | __u32 dircount; | ||
98 | __u32 count; | ||
99 | __be32 * verf; | ||
100 | __be32 * buffer; | ||
101 | }; | ||
102 | |||
103 | struct nfsd3_commitargs { | ||
104 | struct svc_fh fh; | ||
105 | __u64 offset; | ||
106 | __u32 count; | ||
107 | }; | ||
108 | |||
109 | struct nfsd3_getaclargs { | ||
110 | struct svc_fh fh; | ||
111 | int mask; | ||
112 | }; | ||
113 | |||
114 | struct posix_acl; | ||
115 | struct nfsd3_setaclargs { | ||
116 | struct svc_fh fh; | ||
117 | int mask; | ||
118 | struct posix_acl *acl_access; | ||
119 | struct posix_acl *acl_default; | ||
120 | }; | ||
121 | |||
122 | struct nfsd3_attrstat { | ||
123 | __be32 status; | ||
124 | struct svc_fh fh; | ||
125 | struct kstat stat; | ||
126 | }; | ||
127 | |||
128 | /* LOOKUP, CREATE, MKDIR, SYMLINK, MKNOD */ | ||
129 | struct nfsd3_diropres { | ||
130 | __be32 status; | ||
131 | struct svc_fh dirfh; | ||
132 | struct svc_fh fh; | ||
133 | }; | ||
134 | |||
135 | struct nfsd3_accessres { | ||
136 | __be32 status; | ||
137 | struct svc_fh fh; | ||
138 | __u32 access; | ||
139 | }; | ||
140 | |||
141 | struct nfsd3_readlinkres { | ||
142 | __be32 status; | ||
143 | struct svc_fh fh; | ||
144 | __u32 len; | ||
145 | }; | ||
146 | |||
147 | struct nfsd3_readres { | ||
148 | __be32 status; | ||
149 | struct svc_fh fh; | ||
150 | unsigned long count; | ||
151 | int eof; | ||
152 | }; | ||
153 | |||
154 | struct nfsd3_writeres { | ||
155 | __be32 status; | ||
156 | struct svc_fh fh; | ||
157 | unsigned long count; | ||
158 | int committed; | ||
159 | }; | ||
160 | |||
161 | struct nfsd3_renameres { | ||
162 | __be32 status; | ||
163 | struct svc_fh ffh; | ||
164 | struct svc_fh tfh; | ||
165 | }; | ||
166 | |||
167 | struct nfsd3_linkres { | ||
168 | __be32 status; | ||
169 | struct svc_fh tfh; | ||
170 | struct svc_fh fh; | ||
171 | }; | ||
172 | |||
173 | struct nfsd3_readdirres { | ||
174 | __be32 status; | ||
175 | struct svc_fh fh; | ||
176 | int count; | ||
177 | __be32 verf[2]; | ||
178 | |||
179 | struct readdir_cd common; | ||
180 | __be32 * buffer; | ||
181 | int buflen; | ||
182 | __be32 * offset; | ||
183 | __be32 * offset1; | ||
184 | struct svc_rqst * rqstp; | ||
185 | |||
186 | }; | ||
187 | |||
188 | struct nfsd3_fsstatres { | ||
189 | __be32 status; | ||
190 | struct kstatfs stats; | ||
191 | __u32 invarsec; | ||
192 | }; | ||
193 | |||
194 | struct nfsd3_fsinfores { | ||
195 | __be32 status; | ||
196 | __u32 f_rtmax; | ||
197 | __u32 f_rtpref; | ||
198 | __u32 f_rtmult; | ||
199 | __u32 f_wtmax; | ||
200 | __u32 f_wtpref; | ||
201 | __u32 f_wtmult; | ||
202 | __u32 f_dtpref; | ||
203 | __u64 f_maxfilesize; | ||
204 | __u32 f_properties; | ||
205 | }; | ||
206 | |||
207 | struct nfsd3_pathconfres { | ||
208 | __be32 status; | ||
209 | __u32 p_link_max; | ||
210 | __u32 p_name_max; | ||
211 | __u32 p_no_trunc; | ||
212 | __u32 p_chown_restricted; | ||
213 | __u32 p_case_insensitive; | ||
214 | __u32 p_case_preserving; | ||
215 | }; | ||
216 | |||
217 | struct nfsd3_commitres { | ||
218 | __be32 status; | ||
219 | struct svc_fh fh; | ||
220 | }; | ||
221 | |||
222 | struct nfsd3_getaclres { | ||
223 | __be32 status; | ||
224 | struct svc_fh fh; | ||
225 | int mask; | ||
226 | struct posix_acl *acl_access; | ||
227 | struct posix_acl *acl_default; | ||
228 | }; | ||
229 | |||
230 | /* dummy type for release */ | ||
231 | struct nfsd3_fhandle_pair { | ||
232 | __u32 dummy; | ||
233 | struct svc_fh fh1; | ||
234 | struct svc_fh fh2; | ||
235 | }; | ||
236 | |||
237 | /* | ||
238 | * Storage requirements for XDR arguments and results. | ||
239 | */ | ||
240 | union nfsd3_xdrstore { | ||
241 | struct nfsd3_sattrargs sattrargs; | ||
242 | struct nfsd3_diropargs diropargs; | ||
243 | struct nfsd3_readargs readargs; | ||
244 | struct nfsd3_writeargs writeargs; | ||
245 | struct nfsd3_createargs createargs; | ||
246 | struct nfsd3_renameargs renameargs; | ||
247 | struct nfsd3_linkargs linkargs; | ||
248 | struct nfsd3_symlinkargs symlinkargs; | ||
249 | struct nfsd3_readdirargs readdirargs; | ||
250 | struct nfsd3_diropres diropres; | ||
251 | struct nfsd3_accessres accessres; | ||
252 | struct nfsd3_readlinkres readlinkres; | ||
253 | struct nfsd3_readres readres; | ||
254 | struct nfsd3_writeres writeres; | ||
255 | struct nfsd3_renameres renameres; | ||
256 | struct nfsd3_linkres linkres; | ||
257 | struct nfsd3_readdirres readdirres; | ||
258 | struct nfsd3_fsstatres fsstatres; | ||
259 | struct nfsd3_fsinfores fsinfores; | ||
260 | struct nfsd3_pathconfres pathconfres; | ||
261 | struct nfsd3_commitres commitres; | ||
262 | struct nfsd3_getaclres getaclres; | ||
263 | }; | ||
264 | |||
265 | #define NFS3_SVC_XDRSIZE sizeof(union nfsd3_xdrstore) | ||
266 | |||
267 | int nfs3svc_decode_fhandle(struct svc_rqst *, __be32 *, struct nfsd_fhandle *); | ||
268 | int nfs3svc_decode_sattrargs(struct svc_rqst *, __be32 *, | ||
269 | struct nfsd3_sattrargs *); | ||
270 | int nfs3svc_decode_diropargs(struct svc_rqst *, __be32 *, | ||
271 | struct nfsd3_diropargs *); | ||
272 | int nfs3svc_decode_accessargs(struct svc_rqst *, __be32 *, | ||
273 | struct nfsd3_accessargs *); | ||
274 | int nfs3svc_decode_readargs(struct svc_rqst *, __be32 *, | ||
275 | struct nfsd3_readargs *); | ||
276 | int nfs3svc_decode_writeargs(struct svc_rqst *, __be32 *, | ||
277 | struct nfsd3_writeargs *); | ||
278 | int nfs3svc_decode_createargs(struct svc_rqst *, __be32 *, | ||
279 | struct nfsd3_createargs *); | ||
280 | int nfs3svc_decode_mkdirargs(struct svc_rqst *, __be32 *, | ||
281 | struct nfsd3_createargs *); | ||
282 | int nfs3svc_decode_mknodargs(struct svc_rqst *, __be32 *, | ||
283 | struct nfsd3_mknodargs *); | ||
284 | int nfs3svc_decode_renameargs(struct svc_rqst *, __be32 *, | ||
285 | struct nfsd3_renameargs *); | ||
286 | int nfs3svc_decode_readlinkargs(struct svc_rqst *, __be32 *, | ||
287 | struct nfsd3_readlinkargs *); | ||
288 | int nfs3svc_decode_linkargs(struct svc_rqst *, __be32 *, | ||
289 | struct nfsd3_linkargs *); | ||
290 | int nfs3svc_decode_symlinkargs(struct svc_rqst *, __be32 *, | ||
291 | struct nfsd3_symlinkargs *); | ||
292 | int nfs3svc_decode_readdirargs(struct svc_rqst *, __be32 *, | ||
293 | struct nfsd3_readdirargs *); | ||
294 | int nfs3svc_decode_readdirplusargs(struct svc_rqst *, __be32 *, | ||
295 | struct nfsd3_readdirargs *); | ||
296 | int nfs3svc_decode_commitargs(struct svc_rqst *, __be32 *, | ||
297 | struct nfsd3_commitargs *); | ||
298 | int nfs3svc_encode_voidres(struct svc_rqst *, __be32 *, void *); | ||
299 | int nfs3svc_encode_attrstat(struct svc_rqst *, __be32 *, | ||
300 | struct nfsd3_attrstat *); | ||
301 | int nfs3svc_encode_wccstat(struct svc_rqst *, __be32 *, | ||
302 | struct nfsd3_attrstat *); | ||
303 | int nfs3svc_encode_diropres(struct svc_rqst *, __be32 *, | ||
304 | struct nfsd3_diropres *); | ||
305 | int nfs3svc_encode_accessres(struct svc_rqst *, __be32 *, | ||
306 | struct nfsd3_accessres *); | ||
307 | int nfs3svc_encode_readlinkres(struct svc_rqst *, __be32 *, | ||
308 | struct nfsd3_readlinkres *); | ||
309 | int nfs3svc_encode_readres(struct svc_rqst *, __be32 *, struct nfsd3_readres *); | ||
310 | int nfs3svc_encode_writeres(struct svc_rqst *, __be32 *, struct nfsd3_writeres *); | ||
311 | int nfs3svc_encode_createres(struct svc_rqst *, __be32 *, | ||
312 | struct nfsd3_diropres *); | ||
313 | int nfs3svc_encode_renameres(struct svc_rqst *, __be32 *, | ||
314 | struct nfsd3_renameres *); | ||
315 | int nfs3svc_encode_linkres(struct svc_rqst *, __be32 *, | ||
316 | struct nfsd3_linkres *); | ||
317 | int nfs3svc_encode_readdirres(struct svc_rqst *, __be32 *, | ||
318 | struct nfsd3_readdirres *); | ||
319 | int nfs3svc_encode_fsstatres(struct svc_rqst *, __be32 *, | ||
320 | struct nfsd3_fsstatres *); | ||
321 | int nfs3svc_encode_fsinfores(struct svc_rqst *, __be32 *, | ||
322 | struct nfsd3_fsinfores *); | ||
323 | int nfs3svc_encode_pathconfres(struct svc_rqst *, __be32 *, | ||
324 | struct nfsd3_pathconfres *); | ||
325 | int nfs3svc_encode_commitres(struct svc_rqst *, __be32 *, | ||
326 | struct nfsd3_commitres *); | ||
327 | |||
328 | int nfs3svc_release_fhandle(struct svc_rqst *, __be32 *, | ||
329 | struct nfsd3_attrstat *); | ||
330 | int nfs3svc_release_fhandle2(struct svc_rqst *, __be32 *, | ||
331 | struct nfsd3_fhandle_pair *); | ||
332 | int nfs3svc_encode_entry(void *, const char *name, | ||
333 | int namlen, loff_t offset, u64 ino, | ||
334 | unsigned int); | ||
335 | int nfs3svc_encode_entry_plus(void *, const char *name, | ||
336 | int namlen, loff_t offset, u64 ino, | ||
337 | unsigned int); | ||
338 | /* Helper functions for NFSv3 ACL code */ | ||
339 | __be32 *nfs3svc_encode_post_op_attr(struct svc_rqst *rqstp, __be32 *p, | ||
340 | struct svc_fh *fhp); | ||
341 | __be32 *nfs3svc_decode_fh(__be32 *p, struct svc_fh *fhp); | ||
342 | |||
343 | |||
344 | #endif /* _LINUX_NFSD_XDR3_H */ | ||
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h new file mode 100644 index 000000000000..efa337739534 --- /dev/null +++ b/fs/nfsd/xdr4.h | |||
@@ -0,0 +1,562 @@ | |||
1 | /* | ||
2 | * Server-side types for NFSv4. | ||
3 | * | ||
4 | * Copyright (c) 2002 The Regents of the University of Michigan. | ||
5 | * All rights reserved. | ||
6 | * | ||
7 | * Kendrick Smith <kmsmith@umich.edu> | ||
8 | * Andy Adamson <andros@umich.edu> | ||
9 | * | ||
10 | * Redistribution and use in source and binary forms, with or without | ||
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * | ||
14 | * 1. Redistributions of source code must retain the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer. | ||
16 | * 2. Redistributions in binary form must reproduce the above copyright | ||
17 | * notice, this list of conditions and the following disclaimer in the | ||
18 | * documentation and/or other materials provided with the distribution. | ||
19 | * 3. Neither the name of the University nor the names of its | ||
20 | * contributors may be used to endorse or promote products derived | ||
21 | * from this software without specific prior written permission. | ||
22 | * | ||
23 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
24 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
25 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
26 | * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
28 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
29 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR | ||
30 | * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
31 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
32 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
33 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
34 | * | ||
35 | */ | ||
36 | |||
37 | #ifndef _LINUX_NFSD_XDR4_H | ||
38 | #define _LINUX_NFSD_XDR4_H | ||
39 | |||
40 | #include "state.h" | ||
41 | #include "nfsd.h" | ||
42 | |||
43 | #define NFSD4_MAX_TAGLEN 128 | ||
44 | #define XDR_LEN(n) (((n) + 3) & ~3) | ||
45 | |||
46 | struct nfsd4_compound_state { | ||
47 | struct svc_fh current_fh; | ||
48 | struct svc_fh save_fh; | ||
49 | struct nfs4_stateowner *replay_owner; | ||
50 | /* For sessions DRC */ | ||
51 | struct nfsd4_session *session; | ||
52 | struct nfsd4_slot *slot; | ||
53 | __be32 *datap; | ||
54 | size_t iovlen; | ||
55 | u32 minorversion; | ||
56 | u32 status; | ||
57 | }; | ||
58 | |||
59 | static inline bool nfsd4_has_session(struct nfsd4_compound_state *cs) | ||
60 | { | ||
61 | return cs->slot != NULL; | ||
62 | } | ||
63 | |||
64 | struct nfsd4_change_info { | ||
65 | u32 atomic; | ||
66 | bool change_supported; | ||
67 | u32 before_ctime_sec; | ||
68 | u32 before_ctime_nsec; | ||
69 | u64 before_change; | ||
70 | u32 after_ctime_sec; | ||
71 | u32 after_ctime_nsec; | ||
72 | u64 after_change; | ||
73 | }; | ||
74 | |||
75 | struct nfsd4_access { | ||
76 | u32 ac_req_access; /* request */ | ||
77 | u32 ac_supported; /* response */ | ||
78 | u32 ac_resp_access; /* response */ | ||
79 | }; | ||
80 | |||
81 | struct nfsd4_close { | ||
82 | u32 cl_seqid; /* request */ | ||
83 | stateid_t cl_stateid; /* request+response */ | ||
84 | struct nfs4_stateowner * cl_stateowner; /* response */ | ||
85 | }; | ||
86 | |||
87 | struct nfsd4_commit { | ||
88 | u64 co_offset; /* request */ | ||
89 | u32 co_count; /* request */ | ||
90 | nfs4_verifier co_verf; /* response */ | ||
91 | }; | ||
92 | |||
93 | struct nfsd4_create { | ||
94 | u32 cr_namelen; /* request */ | ||
95 | char * cr_name; /* request */ | ||
96 | u32 cr_type; /* request */ | ||
97 | union { /* request */ | ||
98 | struct { | ||
99 | u32 namelen; | ||
100 | char *name; | ||
101 | } link; /* NF4LNK */ | ||
102 | struct { | ||
103 | u32 specdata1; | ||
104 | u32 specdata2; | ||
105 | } dev; /* NF4BLK, NF4CHR */ | ||
106 | } u; | ||
107 | u32 cr_bmval[3]; /* request */ | ||
108 | struct iattr cr_iattr; /* request */ | ||
109 | struct nfsd4_change_info cr_cinfo; /* response */ | ||
110 | struct nfs4_acl *cr_acl; | ||
111 | }; | ||
112 | #define cr_linklen u.link.namelen | ||
113 | #define cr_linkname u.link.name | ||
114 | #define cr_specdata1 u.dev.specdata1 | ||
115 | #define cr_specdata2 u.dev.specdata2 | ||
116 | |||
117 | struct nfsd4_delegreturn { | ||
118 | stateid_t dr_stateid; | ||
119 | }; | ||
120 | |||
121 | struct nfsd4_getattr { | ||
122 | u32 ga_bmval[3]; /* request */ | ||
123 | struct svc_fh *ga_fhp; /* response */ | ||
124 | }; | ||
125 | |||
126 | struct nfsd4_link { | ||
127 | u32 li_namelen; /* request */ | ||
128 | char * li_name; /* request */ | ||
129 | struct nfsd4_change_info li_cinfo; /* response */ | ||
130 | }; | ||
131 | |||
132 | struct nfsd4_lock_denied { | ||
133 | clientid_t ld_clientid; | ||
134 | struct nfs4_stateowner *ld_sop; | ||
135 | u64 ld_start; | ||
136 | u64 ld_length; | ||
137 | u32 ld_type; | ||
138 | }; | ||
139 | |||
140 | struct nfsd4_lock { | ||
141 | /* request */ | ||
142 | u32 lk_type; | ||
143 | u32 lk_reclaim; /* boolean */ | ||
144 | u64 lk_offset; | ||
145 | u64 lk_length; | ||
146 | u32 lk_is_new; | ||
147 | union { | ||
148 | struct { | ||
149 | u32 open_seqid; | ||
150 | stateid_t open_stateid; | ||
151 | u32 lock_seqid; | ||
152 | clientid_t clientid; | ||
153 | struct xdr_netobj owner; | ||
154 | } new; | ||
155 | struct { | ||
156 | stateid_t lock_stateid; | ||
157 | u32 lock_seqid; | ||
158 | } old; | ||
159 | } v; | ||
160 | |||
161 | /* response */ | ||
162 | union { | ||
163 | struct { | ||
164 | stateid_t stateid; | ||
165 | } ok; | ||
166 | struct nfsd4_lock_denied denied; | ||
167 | } u; | ||
168 | /* The lk_replay_owner is the open owner in the open_to_lock_owner | ||
169 | * case and the lock owner otherwise: */ | ||
170 | struct nfs4_stateowner *lk_replay_owner; | ||
171 | }; | ||
172 | #define lk_new_open_seqid v.new.open_seqid | ||
173 | #define lk_new_open_stateid v.new.open_stateid | ||
174 | #define lk_new_lock_seqid v.new.lock_seqid | ||
175 | #define lk_new_clientid v.new.clientid | ||
176 | #define lk_new_owner v.new.owner | ||
177 | #define lk_old_lock_stateid v.old.lock_stateid | ||
178 | #define lk_old_lock_seqid v.old.lock_seqid | ||
179 | |||
180 | #define lk_rflags u.ok.rflags | ||
181 | #define lk_resp_stateid u.ok.stateid | ||
182 | #define lk_denied u.denied | ||
183 | |||
184 | |||
185 | struct nfsd4_lockt { | ||
186 | u32 lt_type; | ||
187 | clientid_t lt_clientid; | ||
188 | struct xdr_netobj lt_owner; | ||
189 | u64 lt_offset; | ||
190 | u64 lt_length; | ||
191 | struct nfs4_stateowner * lt_stateowner; | ||
192 | struct nfsd4_lock_denied lt_denied; | ||
193 | }; | ||
194 | |||
195 | |||
196 | struct nfsd4_locku { | ||
197 | u32 lu_type; | ||
198 | u32 lu_seqid; | ||
199 | stateid_t lu_stateid; | ||
200 | u64 lu_offset; | ||
201 | u64 lu_length; | ||
202 | struct nfs4_stateowner *lu_stateowner; | ||
203 | }; | ||
204 | |||
205 | |||
206 | struct nfsd4_lookup { | ||
207 | u32 lo_len; /* request */ | ||
208 | char * lo_name; /* request */ | ||
209 | }; | ||
210 | |||
211 | struct nfsd4_putfh { | ||
212 | u32 pf_fhlen; /* request */ | ||
213 | char *pf_fhval; /* request */ | ||
214 | }; | ||
215 | |||
216 | struct nfsd4_open { | ||
217 | u32 op_claim_type; /* request */ | ||
218 | struct xdr_netobj op_fname; /* request - everything but CLAIM_PREV */ | ||
219 | u32 op_delegate_type; /* request - CLAIM_PREV only */ | ||
220 | stateid_t op_delegate_stateid; /* request - response */ | ||
221 | u32 op_create; /* request */ | ||
222 | u32 op_createmode; /* request */ | ||
223 | u32 op_bmval[3]; /* request */ | ||
224 | struct iattr iattr; /* UNCHECKED4, GUARDED4, EXCLUSIVE4_1 */ | ||
225 | nfs4_verifier verf; /* EXCLUSIVE4 */ | ||
226 | clientid_t op_clientid; /* request */ | ||
227 | struct xdr_netobj op_owner; /* request */ | ||
228 | u32 op_seqid; /* request */ | ||
229 | u32 op_share_access; /* request */ | ||
230 | u32 op_share_deny; /* request */ | ||
231 | stateid_t op_stateid; /* response */ | ||
232 | u32 op_recall; /* recall */ | ||
233 | struct nfsd4_change_info op_cinfo; /* response */ | ||
234 | u32 op_rflags; /* response */ | ||
235 | int op_truncate; /* used during processing */ | ||
236 | struct nfs4_stateowner *op_stateowner; /* used during processing */ | ||
237 | struct nfs4_acl *op_acl; | ||
238 | }; | ||
239 | #define op_iattr iattr | ||
240 | #define op_verf verf | ||
241 | |||
242 | struct nfsd4_open_confirm { | ||
243 | stateid_t oc_req_stateid /* request */; | ||
244 | u32 oc_seqid /* request */; | ||
245 | stateid_t oc_resp_stateid /* response */; | ||
246 | struct nfs4_stateowner * oc_stateowner; /* response */ | ||
247 | }; | ||
248 | |||
249 | struct nfsd4_open_downgrade { | ||
250 | stateid_t od_stateid; | ||
251 | u32 od_seqid; | ||
252 | u32 od_share_access; | ||
253 | u32 od_share_deny; | ||
254 | struct nfs4_stateowner *od_stateowner; | ||
255 | }; | ||
256 | |||
257 | |||
258 | struct nfsd4_read { | ||
259 | stateid_t rd_stateid; /* request */ | ||
260 | u64 rd_offset; /* request */ | ||
261 | u32 rd_length; /* request */ | ||
262 | int rd_vlen; | ||
263 | struct file *rd_filp; | ||
264 | |||
265 | struct svc_rqst *rd_rqstp; /* response */ | ||
266 | struct svc_fh * rd_fhp; /* response */ | ||
267 | }; | ||
268 | |||
269 | struct nfsd4_readdir { | ||
270 | u64 rd_cookie; /* request */ | ||
271 | nfs4_verifier rd_verf; /* request */ | ||
272 | u32 rd_dircount; /* request */ | ||
273 | u32 rd_maxcount; /* request */ | ||
274 | u32 rd_bmval[3]; /* request */ | ||
275 | struct svc_rqst *rd_rqstp; /* response */ | ||
276 | struct svc_fh * rd_fhp; /* response */ | ||
277 | |||
278 | struct readdir_cd common; | ||
279 | __be32 * buffer; | ||
280 | int buflen; | ||
281 | __be32 * offset; | ||
282 | }; | ||
283 | |||
284 | struct nfsd4_release_lockowner { | ||
285 | clientid_t rl_clientid; | ||
286 | struct xdr_netobj rl_owner; | ||
287 | }; | ||
288 | struct nfsd4_readlink { | ||
289 | struct svc_rqst *rl_rqstp; /* request */ | ||
290 | struct svc_fh * rl_fhp; /* request */ | ||
291 | }; | ||
292 | |||
293 | struct nfsd4_remove { | ||
294 | u32 rm_namelen; /* request */ | ||
295 | char * rm_name; /* request */ | ||
296 | struct nfsd4_change_info rm_cinfo; /* response */ | ||
297 | }; | ||
298 | |||
299 | struct nfsd4_rename { | ||
300 | u32 rn_snamelen; /* request */ | ||
301 | char * rn_sname; /* request */ | ||
302 | u32 rn_tnamelen; /* request */ | ||
303 | char * rn_tname; /* request */ | ||
304 | struct nfsd4_change_info rn_sinfo; /* response */ | ||
305 | struct nfsd4_change_info rn_tinfo; /* response */ | ||
306 | }; | ||
307 | |||
308 | struct nfsd4_secinfo { | ||
309 | u32 si_namelen; /* request */ | ||
310 | char *si_name; /* request */ | ||
311 | struct svc_export *si_exp; /* response */ | ||
312 | }; | ||
313 | |||
314 | struct nfsd4_setattr { | ||
315 | stateid_t sa_stateid; /* request */ | ||
316 | u32 sa_bmval[3]; /* request */ | ||
317 | struct iattr sa_iattr; /* request */ | ||
318 | struct nfs4_acl *sa_acl; | ||
319 | }; | ||
320 | |||
321 | struct nfsd4_setclientid { | ||
322 | nfs4_verifier se_verf; /* request */ | ||
323 | u32 se_namelen; /* request */ | ||
324 | char * se_name; /* request */ | ||
325 | u32 se_callback_prog; /* request */ | ||
326 | u32 se_callback_netid_len; /* request */ | ||
327 | char * se_callback_netid_val; /* request */ | ||
328 | u32 se_callback_addr_len; /* request */ | ||
329 | char * se_callback_addr_val; /* request */ | ||
330 | u32 se_callback_ident; /* request */ | ||
331 | clientid_t se_clientid; /* response */ | ||
332 | nfs4_verifier se_confirm; /* response */ | ||
333 | }; | ||
334 | |||
335 | struct nfsd4_setclientid_confirm { | ||
336 | clientid_t sc_clientid; | ||
337 | nfs4_verifier sc_confirm; | ||
338 | }; | ||
339 | |||
340 | /* also used for NVERIFY */ | ||
341 | struct nfsd4_verify { | ||
342 | u32 ve_bmval[3]; /* request */ | ||
343 | u32 ve_attrlen; /* request */ | ||
344 | char * ve_attrval; /* request */ | ||
345 | }; | ||
346 | |||
347 | struct nfsd4_write { | ||
348 | stateid_t wr_stateid; /* request */ | ||
349 | u64 wr_offset; /* request */ | ||
350 | u32 wr_stable_how; /* request */ | ||
351 | u32 wr_buflen; /* request */ | ||
352 | int wr_vlen; | ||
353 | |||
354 | u32 wr_bytes_written; /* response */ | ||
355 | u32 wr_how_written; /* response */ | ||
356 | nfs4_verifier wr_verifier; /* response */ | ||
357 | }; | ||
358 | |||
359 | struct nfsd4_exchange_id { | ||
360 | nfs4_verifier verifier; | ||
361 | struct xdr_netobj clname; | ||
362 | u32 flags; | ||
363 | clientid_t clientid; | ||
364 | u32 seqid; | ||
365 | int spa_how; | ||
366 | }; | ||
367 | |||
368 | struct nfsd4_sequence { | ||
369 | struct nfs4_sessionid sessionid; /* request/response */ | ||
370 | u32 seqid; /* request/response */ | ||
371 | u32 slotid; /* request/response */ | ||
372 | u32 maxslots; /* request/response */ | ||
373 | u32 cachethis; /* request */ | ||
374 | #if 0 | ||
375 | u32 target_maxslots; /* response */ | ||
376 | u32 status_flags; /* response */ | ||
377 | #endif /* not yet */ | ||
378 | }; | ||
379 | |||
380 | struct nfsd4_destroy_session { | ||
381 | struct nfs4_sessionid sessionid; | ||
382 | }; | ||
383 | |||
384 | struct nfsd4_op { | ||
385 | int opnum; | ||
386 | __be32 status; | ||
387 | union { | ||
388 | struct nfsd4_access access; | ||
389 | struct nfsd4_close close; | ||
390 | struct nfsd4_commit commit; | ||
391 | struct nfsd4_create create; | ||
392 | struct nfsd4_delegreturn delegreturn; | ||
393 | struct nfsd4_getattr getattr; | ||
394 | struct svc_fh * getfh; | ||
395 | struct nfsd4_link link; | ||
396 | struct nfsd4_lock lock; | ||
397 | struct nfsd4_lockt lockt; | ||
398 | struct nfsd4_locku locku; | ||
399 | struct nfsd4_lookup lookup; | ||
400 | struct nfsd4_verify nverify; | ||
401 | struct nfsd4_open open; | ||
402 | struct nfsd4_open_confirm open_confirm; | ||
403 | struct nfsd4_open_downgrade open_downgrade; | ||
404 | struct nfsd4_putfh putfh; | ||
405 | struct nfsd4_read read; | ||
406 | struct nfsd4_readdir readdir; | ||
407 | struct nfsd4_readlink readlink; | ||
408 | struct nfsd4_remove remove; | ||
409 | struct nfsd4_rename rename; | ||
410 | clientid_t renew; | ||
411 | struct nfsd4_secinfo secinfo; | ||
412 | struct nfsd4_setattr setattr; | ||
413 | struct nfsd4_setclientid setclientid; | ||
414 | struct nfsd4_setclientid_confirm setclientid_confirm; | ||
415 | struct nfsd4_verify verify; | ||
416 | struct nfsd4_write write; | ||
417 | struct nfsd4_release_lockowner release_lockowner; | ||
418 | |||
419 | /* NFSv4.1 */ | ||
420 | struct nfsd4_exchange_id exchange_id; | ||
421 | struct nfsd4_create_session create_session; | ||
422 | struct nfsd4_destroy_session destroy_session; | ||
423 | struct nfsd4_sequence sequence; | ||
424 | } u; | ||
425 | struct nfs4_replay * replay; | ||
426 | }; | ||
427 | |||
428 | struct nfsd4_compoundargs { | ||
429 | /* scratch variables for XDR decode */ | ||
430 | __be32 * p; | ||
431 | __be32 * end; | ||
432 | struct page ** pagelist; | ||
433 | int pagelen; | ||
434 | __be32 tmp[8]; | ||
435 | __be32 * tmpp; | ||
436 | struct tmpbuf { | ||
437 | struct tmpbuf *next; | ||
438 | void (*release)(const void *); | ||
439 | void *buf; | ||
440 | } *to_free; | ||
441 | |||
442 | struct svc_rqst *rqstp; | ||
443 | |||
444 | u32 taglen; | ||
445 | char * tag; | ||
446 | u32 minorversion; | ||
447 | u32 opcnt; | ||
448 | struct nfsd4_op *ops; | ||
449 | struct nfsd4_op iops[8]; | ||
450 | }; | ||
451 | |||
452 | struct nfsd4_compoundres { | ||
453 | /* scratch variables for XDR encode */ | ||
454 | __be32 * p; | ||
455 | __be32 * end; | ||
456 | struct xdr_buf * xbuf; | ||
457 | struct svc_rqst * rqstp; | ||
458 | |||
459 | u32 taglen; | ||
460 | char * tag; | ||
461 | u32 opcnt; | ||
462 | __be32 * tagp; /* tag, opcount encode location */ | ||
463 | struct nfsd4_compound_state cstate; | ||
464 | }; | ||
465 | |||
466 | static inline bool nfsd4_is_solo_sequence(struct nfsd4_compoundres *resp) | ||
467 | { | ||
468 | struct nfsd4_compoundargs *args = resp->rqstp->rq_argp; | ||
469 | return resp->opcnt == 1 && args->ops[0].opnum == OP_SEQUENCE; | ||
470 | } | ||
471 | |||
472 | static inline bool nfsd4_not_cached(struct nfsd4_compoundres *resp) | ||
473 | { | ||
474 | return !resp->cstate.slot->sl_cachethis || nfsd4_is_solo_sequence(resp); | ||
475 | } | ||
476 | |||
477 | #define NFS4_SVC_XDRSIZE sizeof(struct nfsd4_compoundargs) | ||
478 | |||
479 | static inline void | ||
480 | set_change_info(struct nfsd4_change_info *cinfo, struct svc_fh *fhp) | ||
481 | { | ||
482 | BUG_ON(!fhp->fh_pre_saved || !fhp->fh_post_saved); | ||
483 | cinfo->atomic = 1; | ||
484 | cinfo->change_supported = IS_I_VERSION(fhp->fh_dentry->d_inode); | ||
485 | if (cinfo->change_supported) { | ||
486 | cinfo->before_change = fhp->fh_pre_change; | ||
487 | cinfo->after_change = fhp->fh_post_change; | ||
488 | } else { | ||
489 | cinfo->before_ctime_sec = fhp->fh_pre_ctime.tv_sec; | ||
490 | cinfo->before_ctime_nsec = fhp->fh_pre_ctime.tv_nsec; | ||
491 | cinfo->after_ctime_sec = fhp->fh_post_attr.ctime.tv_sec; | ||
492 | cinfo->after_ctime_nsec = fhp->fh_post_attr.ctime.tv_nsec; | ||
493 | } | ||
494 | } | ||
495 | |||
496 | int nfs4svc_encode_voidres(struct svc_rqst *, __be32 *, void *); | ||
497 | int nfs4svc_decode_compoundargs(struct svc_rqst *, __be32 *, | ||
498 | struct nfsd4_compoundargs *); | ||
499 | int nfs4svc_encode_compoundres(struct svc_rqst *, __be32 *, | ||
500 | struct nfsd4_compoundres *); | ||
501 | void nfsd4_encode_operation(struct nfsd4_compoundres *, struct nfsd4_op *); | ||
502 | void nfsd4_encode_replay(struct nfsd4_compoundres *resp, struct nfsd4_op *op); | ||
503 | __be32 nfsd4_encode_fattr(struct svc_fh *fhp, struct svc_export *exp, | ||
504 | struct dentry *dentry, __be32 *buffer, int *countp, | ||
505 | u32 *bmval, struct svc_rqst *, int ignore_crossmnt); | ||
506 | extern __be32 nfsd4_setclientid(struct svc_rqst *rqstp, | ||
507 | struct nfsd4_compound_state *, | ||
508 | struct nfsd4_setclientid *setclid); | ||
509 | extern __be32 nfsd4_setclientid_confirm(struct svc_rqst *rqstp, | ||
510 | struct nfsd4_compound_state *, | ||
511 | struct nfsd4_setclientid_confirm *setclientid_confirm); | ||
512 | extern void nfsd4_store_cache_entry(struct nfsd4_compoundres *resp); | ||
513 | extern __be32 nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, | ||
514 | struct nfsd4_sequence *seq); | ||
515 | extern __be32 nfsd4_exchange_id(struct svc_rqst *rqstp, | ||
516 | struct nfsd4_compound_state *, | ||
517 | struct nfsd4_exchange_id *); | ||
518 | extern __be32 nfsd4_create_session(struct svc_rqst *, | ||
519 | struct nfsd4_compound_state *, | ||
520 | struct nfsd4_create_session *); | ||
521 | extern __be32 nfsd4_sequence(struct svc_rqst *, | ||
522 | struct nfsd4_compound_state *, | ||
523 | struct nfsd4_sequence *); | ||
524 | extern __be32 nfsd4_destroy_session(struct svc_rqst *, | ||
525 | struct nfsd4_compound_state *, | ||
526 | struct nfsd4_destroy_session *); | ||
527 | extern __be32 nfsd4_process_open1(struct nfsd4_compound_state *, | ||
528 | struct nfsd4_open *open); | ||
529 | extern __be32 nfsd4_process_open2(struct svc_rqst *rqstp, | ||
530 | struct svc_fh *current_fh, struct nfsd4_open *open); | ||
531 | extern __be32 nfsd4_open_confirm(struct svc_rqst *rqstp, | ||
532 | struct nfsd4_compound_state *, struct nfsd4_open_confirm *oc); | ||
533 | extern __be32 nfsd4_close(struct svc_rqst *rqstp, | ||
534 | struct nfsd4_compound_state *, | ||
535 | struct nfsd4_close *close); | ||
536 | extern __be32 nfsd4_open_downgrade(struct svc_rqst *rqstp, | ||
537 | struct nfsd4_compound_state *, | ||
538 | struct nfsd4_open_downgrade *od); | ||
539 | extern __be32 nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *, | ||
540 | struct nfsd4_lock *lock); | ||
541 | extern __be32 nfsd4_lockt(struct svc_rqst *rqstp, | ||
542 | struct nfsd4_compound_state *, | ||
543 | struct nfsd4_lockt *lockt); | ||
544 | extern __be32 nfsd4_locku(struct svc_rqst *rqstp, | ||
545 | struct nfsd4_compound_state *, | ||
546 | struct nfsd4_locku *locku); | ||
547 | extern __be32 | ||
548 | nfsd4_release_lockowner(struct svc_rqst *rqstp, | ||
549 | struct nfsd4_compound_state *, | ||
550 | struct nfsd4_release_lockowner *rlockowner); | ||
551 | extern void nfsd4_release_compoundargs(struct nfsd4_compoundargs *); | ||
552 | extern __be32 nfsd4_delegreturn(struct svc_rqst *rqstp, | ||
553 | struct nfsd4_compound_state *, struct nfsd4_delegreturn *dr); | ||
554 | extern __be32 nfsd4_renew(struct svc_rqst *rqstp, | ||
555 | struct nfsd4_compound_state *, clientid_t *clid); | ||
556 | #endif | ||
557 | |||
558 | /* | ||
559 | * Local variables: | ||
560 | * c-basic-offset: 8 | ||
561 | * End: | ||
562 | */ | ||