diff options
38 files changed, 296 insertions, 224 deletions
diff --git a/Documentation/filesystems/00-INDEX b/Documentation/filesystems/00-INDEX index f15621ee5599..658154f52557 100644 --- a/Documentation/filesystems/00-INDEX +++ b/Documentation/filesystems/00-INDEX | |||
@@ -1,7 +1,5 @@ | |||
1 | 00-INDEX | 1 | 00-INDEX |
2 | - this file (info on some of the filesystems supported by linux). | 2 | - this file (info on some of the filesystems supported by linux). |
3 | Exporting | ||
4 | - explanation of how to make filesystems exportable. | ||
5 | Locking | 3 | Locking |
6 | - info on locking rules as they pertain to Linux VFS. | 4 | - info on locking rules as they pertain to Linux VFS. |
7 | 9p.txt | 5 | 9p.txt |
@@ -66,12 +64,8 @@ mandatory-locking.txt | |||
66 | - info on the Linux implementation of Sys V mandatory file locking. | 64 | - info on the Linux implementation of Sys V mandatory file locking. |
67 | ncpfs.txt | 65 | ncpfs.txt |
68 | - info on Novell Netware(tm) filesystem using NCP protocol. | 66 | - info on Novell Netware(tm) filesystem using NCP protocol. |
69 | nfs41-server.txt | 67 | nfs/ |
70 | - info on the Linux server implementation of NFSv4 minor version 1. | 68 | - nfs-related documentation. |
71 | nfs-rdma.txt | ||
72 | - how to install and setup the Linux NFS/RDMA client and server software. | ||
73 | nfsroot.txt | ||
74 | - short guide on setting up a diskless box with NFS root filesystem. | ||
75 | nilfs2.txt | 69 | nilfs2.txt |
76 | - info and mount options for the NILFS2 filesystem. | 70 | - info and mount options for the NILFS2 filesystem. |
77 | ntfs.txt | 71 | ntfs.txt |
@@ -90,8 +84,6 @@ relay.txt | |||
90 | - info on relay, for efficient streaming from kernel to user space. | 84 | - info on relay, for efficient streaming from kernel to user space. |
91 | romfs.txt | 85 | romfs.txt |
92 | - description of the ROMFS filesystem. | 86 | - description of the ROMFS filesystem. |
93 | rpc-cache.txt | ||
94 | - introduction to the caching mechanisms in the sunrpc layer. | ||
95 | seq_file.txt | 87 | seq_file.txt |
96 | - how to use the seq_file API | 88 | - how to use the seq_file API |
97 | sharedsubtree.txt | 89 | sharedsubtree.txt |
diff --git a/Documentation/filesystems/nfs/00-INDEX b/Documentation/filesystems/nfs/00-INDEX new file mode 100644 index 000000000000..2f68cd688769 --- /dev/null +++ b/Documentation/filesystems/nfs/00-INDEX | |||
@@ -0,0 +1,16 @@ | |||
1 | 00-INDEX | ||
2 | - this file (nfs-related documentation). | ||
3 | Exporting | ||
4 | - explanation of how to make filesystems exportable. | ||
5 | knfsd-stats.txt | ||
6 | - statistics which the NFS server makes available to user space. | ||
7 | nfs.txt | ||
8 | - nfs client, and DNS resolution for fs_locations. | ||
9 | nfs41-server.txt | ||
10 | - info on the Linux server implementation of NFSv4 minor version 1. | ||
11 | nfs-rdma.txt | ||
12 | - how to install and setup the Linux NFS/RDMA client and server software | ||
13 | nfsroot.txt | ||
14 | - short guide on setting up a diskless box with NFS root filesystem. | ||
15 | rpc-cache.txt | ||
16 | - introduction to the caching mechanisms in the sunrpc layer. | ||
diff --git a/Documentation/filesystems/Exporting b/Documentation/filesystems/nfs/Exporting index 87019d2b5981..87019d2b5981 100644 --- a/Documentation/filesystems/Exporting +++ b/Documentation/filesystems/nfs/Exporting | |||
diff --git a/Documentation/filesystems/knfsd-stats.txt b/Documentation/filesystems/nfs/knfsd-stats.txt index 64ced5149d37..64ced5149d37 100644 --- a/Documentation/filesystems/knfsd-stats.txt +++ b/Documentation/filesystems/nfs/knfsd-stats.txt | |||
diff --git a/Documentation/filesystems/nfs-rdma.txt b/Documentation/filesystems/nfs/nfs-rdma.txt index e386f7e4bcee..e386f7e4bcee 100644 --- a/Documentation/filesystems/nfs-rdma.txt +++ b/Documentation/filesystems/nfs/nfs-rdma.txt | |||
diff --git a/Documentation/filesystems/nfs.txt b/Documentation/filesystems/nfs/nfs.txt index f50f26ce6cd0..f50f26ce6cd0 100644 --- a/Documentation/filesystems/nfs.txt +++ b/Documentation/filesystems/nfs/nfs.txt | |||
diff --git a/Documentation/filesystems/nfs41-server.txt b/Documentation/filesystems/nfs/nfs41-server.txt index 5920fe26e6ff..1bd0d0c05171 100644 --- a/Documentation/filesystems/nfs41-server.txt +++ b/Documentation/filesystems/nfs/nfs41-server.txt | |||
@@ -41,7 +41,7 @@ interoperability problems with future clients. Known issues: | |||
41 | conformant with the spec (for example, we don't use kerberos | 41 | conformant with the spec (for example, we don't use kerberos |
42 | on the backchannel correctly). | 42 | on the backchannel correctly). |
43 | - no trunking support: no clients currently take advantage of | 43 | - no trunking support: no clients currently take advantage of |
44 | trunking, but this is a mandatory failure, and its use is | 44 | trunking, but this is a mandatory feature, and its use is |
45 | recommended to clients in a number of places. (E.g. to ensure | 45 | recommended to clients in a number of places. (E.g. to ensure |
46 | timely renewal in case an existing connection's retry timeouts | 46 | timely renewal in case an existing connection's retry timeouts |
47 | have gotten too long; see section 8.3 of the draft.) | 47 | have gotten too long; see section 8.3 of the draft.) |
@@ -213,3 +213,10 @@ The following cases aren't supported yet: | |||
213 | DESTROY_CLIENTID, DESTROY_SESSION, EXCHANGE_ID. | 213 | DESTROY_CLIENTID, DESTROY_SESSION, EXCHANGE_ID. |
214 | * DESTROY_SESSION MUST be the final operation in the COMPOUND request. | 214 | * DESTROY_SESSION MUST be the final operation in the COMPOUND request. |
215 | 215 | ||
216 | Nonstandard compound limitations: | ||
217 | * No support for a sessions fore channel RPC compound that requires both a | ||
218 | ca_maxrequestsize request and a ca_maxresponsesize reply, so we may | ||
219 | fail to live up to the promise we made in CREATE_SESSION fore channel | ||
220 | negotiation. | ||
221 | * No more than one IO operation (read, write, readdir) allowed per | ||
222 | compound. | ||
diff --git a/Documentation/filesystems/nfsroot.txt b/Documentation/filesystems/nfs/nfsroot.txt index 3ba0b945aaf8..3ba0b945aaf8 100644 --- a/Documentation/filesystems/nfsroot.txt +++ b/Documentation/filesystems/nfs/nfsroot.txt | |||
diff --git a/Documentation/filesystems/rpc-cache.txt b/Documentation/filesystems/nfs/rpc-cache.txt index 8a382bea6808..8a382bea6808 100644 --- a/Documentation/filesystems/rpc-cache.txt +++ b/Documentation/filesystems/nfs/rpc-cache.txt | |||
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index 92b888d540a6..a7e9746ee7ea 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting | |||
@@ -140,7 +140,7 @@ Callers of notify_change() need ->i_mutex now. | |||
140 | New super_block field "struct export_operations *s_export_op" for | 140 | New super_block field "struct export_operations *s_export_op" for |
141 | explicit support for exporting, e.g. via NFS. The structure is fully | 141 | explicit support for exporting, e.g. via NFS. The structure is fully |
142 | documented at its declaration in include/linux/fs.h, and in | 142 | documented at its declaration in include/linux/fs.h, and in |
143 | Documentation/filesystems/Exporting. | 143 | Documentation/filesystems/nfs/Exporting. |
144 | 144 | ||
145 | Briefly it allows for the definition of decode_fh and encode_fh operations | 145 | Briefly it allows for the definition of decode_fh and encode_fh operations |
146 | to encode and decode filehandles, and allows the filesystem to use | 146 | to encode and decode filehandles, and allows the filesystem to use |
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index 9107b387e91f..dab0f04b4264 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1017,7 +1017,7 @@ and is between 256 and 4096 characters. It is defined in the file | |||
1017 | No delay | 1017 | No delay |
1018 | 1018 | ||
1019 | ip= [IP_PNP] | 1019 | ip= [IP_PNP] |
1020 | See Documentation/filesystems/nfsroot.txt. | 1020 | See Documentation/filesystems/nfs/nfsroot.txt. |
1021 | 1021 | ||
1022 | ip2= [HW] Set IO/IRQ pairs for up to 4 IntelliPort boards | 1022 | ip2= [HW] Set IO/IRQ pairs for up to 4 IntelliPort boards |
1023 | See comment before ip2_setup() in | 1023 | See comment before ip2_setup() in |
@@ -1538,10 +1538,10 @@ and is between 256 and 4096 characters. It is defined in the file | |||
1538 | going to be removed in 2.6.29. | 1538 | going to be removed in 2.6.29. |
1539 | 1539 | ||
1540 | nfsaddrs= [NFS] | 1540 | nfsaddrs= [NFS] |
1541 | See Documentation/filesystems/nfsroot.txt. | 1541 | See Documentation/filesystems/nfs/nfsroot.txt. |
1542 | 1542 | ||
1543 | nfsroot= [NFS] nfs root filesystem for disk-less boxes. | 1543 | nfsroot= [NFS] nfs root filesystem for disk-less boxes. |
1544 | See Documentation/filesystems/nfsroot.txt. | 1544 | See Documentation/filesystems/nfs/nfsroot.txt. |
1545 | 1545 | ||
1546 | nfs.callback_tcpport= | 1546 | nfs.callback_tcpport= |
1547 | [NFS] set the TCP port on which the NFSv4 callback | 1547 | [NFS] set the TCP port on which the NFSv4 callback |
diff --git a/fs/cifs/export.c b/fs/cifs/export.c index 75949d6a5f1b..6177f7cca16a 100644 --- a/fs/cifs/export.c +++ b/fs/cifs/export.c | |||
@@ -24,7 +24,7 @@ | |||
24 | */ | 24 | */ |
25 | 25 | ||
26 | /* | 26 | /* |
27 | * See Documentation/filesystems/Exporting | 27 | * See Documentation/filesystems/nfs/Exporting |
28 | * and examples in fs/exportfs | 28 | * and examples in fs/exportfs |
29 | * | 29 | * |
30 | * Since cifs is a network file system, an "fsid" must be included for | 30 | * Since cifs is a network file system, an "fsid" must be included for |
diff --git a/fs/exportfs/expfs.c b/fs/exportfs/expfs.c index 197c7db583c7..e9e175949a63 100644 --- a/fs/exportfs/expfs.c +++ b/fs/exportfs/expfs.c | |||
@@ -6,7 +6,7 @@ | |||
6 | * and for mapping back from file handles to dentries. | 6 | * and for mapping back from file handles to dentries. |
7 | * | 7 | * |
8 | * For details on why we do all the strange and hairy things in here | 8 | * For details on why we do all the strange and hairy things in here |
9 | * take a look at Documentation/filesystems/Exporting. | 9 | * take a look at Documentation/filesystems/nfs/Exporting. |
10 | */ | 10 | */ |
11 | #include <linux/exportfs.h> | 11 | #include <linux/exportfs.h> |
12 | #include <linux/fs.h> | 12 | #include <linux/fs.h> |
diff --git a/fs/isofs/export.c b/fs/isofs/export.c index e81a30593ba9..ed752cb38474 100644 --- a/fs/isofs/export.c +++ b/fs/isofs/export.c | |||
@@ -9,7 +9,7 @@ | |||
9 | * | 9 | * |
10 | * The following files are helpful: | 10 | * The following files are helpful: |
11 | * | 11 | * |
12 | * Documentation/filesystems/Exporting | 12 | * Documentation/filesystems/nfs/Exporting |
13 | * fs/exportfs/expfs.c. | 13 | * fs/exportfs/expfs.c. |
14 | */ | 14 | */ |
15 | 15 | ||
diff --git a/fs/nfs/Kconfig b/fs/nfs/Kconfig index 2a77bc25d5af..59e5673b4597 100644 --- a/fs/nfs/Kconfig +++ b/fs/nfs/Kconfig | |||
@@ -90,7 +90,7 @@ config ROOT_NFS | |||
90 | If you want your system to mount its root file system via NFS, | 90 | If you want your system to mount its root file system via NFS, |
91 | choose Y here. This is common practice for managing systems | 91 | choose Y here. This is common practice for managing systems |
92 | without local permanent storage. For details, read | 92 | without local permanent storage. For details, read |
93 | <file:Documentation/filesystems/nfsroot.txt>. | 93 | <file:Documentation/filesystems/nfs/nfsroot.txt>. |
94 | 94 | ||
95 | Most people say N here. | 95 | Most people say N here. |
96 | 96 | ||
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index c1c9e035d4a4..b73baba3fb97 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c | |||
@@ -1320,6 +1320,23 @@ rqst_exp_parent(struct svc_rqst *rqstp, struct path *path) | |||
1320 | return exp; | 1320 | return exp; |
1321 | } | 1321 | } |
1322 | 1322 | ||
1323 | static struct svc_export *find_fsidzero_export(struct svc_rqst *rqstp) | ||
1324 | { | ||
1325 | struct svc_export *exp; | ||
1326 | u32 fsidv[2]; | ||
1327 | |||
1328 | mk_fsid(FSID_NUM, fsidv, 0, 0, 0, NULL); | ||
1329 | |||
1330 | exp = rqst_exp_find(rqstp, FSID_NUM, fsidv); | ||
1331 | /* | ||
1332 | * We shouldn't have accepting an nfsv4 request at all if we | ||
1333 | * don't have a pseudoexport!: | ||
1334 | */ | ||
1335 | if (IS_ERR(exp) && PTR_ERR(exp) == -ENOENT) | ||
1336 | exp = ERR_PTR(-ESERVERFAULT); | ||
1337 | return exp; | ||
1338 | } | ||
1339 | |||
1323 | /* | 1340 | /* |
1324 | * Called when we need the filehandle for the root of the pseudofs, | 1341 | * 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 | 1342 | * for a given NFSv4 client. The root is defined to be the |
@@ -1330,11 +1347,8 @@ exp_pseudoroot(struct svc_rqst *rqstp, struct svc_fh *fhp) | |||
1330 | { | 1347 | { |
1331 | struct svc_export *exp; | 1348 | struct svc_export *exp; |
1332 | __be32 rv; | 1349 | __be32 rv; |
1333 | u32 fsidv[2]; | ||
1334 | |||
1335 | mk_fsid(FSID_NUM, fsidv, 0, 0, 0, NULL); | ||
1336 | 1350 | ||
1337 | exp = rqst_exp_find(rqstp, FSID_NUM, fsidv); | 1351 | exp = find_fsidzero_export(rqstp); |
1338 | if (IS_ERR(exp)) | 1352 | if (IS_ERR(exp)) |
1339 | return nfserrno(PTR_ERR(exp)); | 1353 | return nfserrno(PTR_ERR(exp)); |
1340 | rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL); | 1354 | rv = fh_compose(fhp, exp, exp->ex_path.dentry, NULL); |
diff --git a/fs/nfsd/lockd.c b/fs/nfsd/lockd.c index b2786a5f9afe..812bc64874f6 100644 --- a/fs/nfsd/lockd.c +++ b/fs/nfsd/lockd.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/sunrpc/svc.h> | 16 | #include <linux/sunrpc/svc.h> |
17 | #include <linux/nfsd/nfsd.h> | 17 | #include <linux/nfsd/nfsd.h> |
18 | #include <linux/lockd/bind.h> | 18 | #include <linux/lockd/bind.h> |
19 | #include "vfs.h" | ||
19 | 20 | ||
20 | #define NFSDDBG_FACILITY NFSDDBG_LOCKD | 21 | #define NFSDDBG_FACILITY NFSDDBG_LOCKD |
21 | 22 | ||
diff --git a/fs/nfsd/nfs2acl.c b/fs/nfsd/nfs2acl.c index 4e3219e84116..38c883d48b02 100644 --- a/fs/nfsd/nfs2acl.c +++ b/fs/nfsd/nfs2acl.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <linux/nfsd/xdr3.h> | 14 | #include <linux/nfsd/xdr3.h> |
15 | #include <linux/posix_acl.h> | 15 | #include <linux/posix_acl.h> |
16 | #include <linux/nfsacl.h> | 16 | #include <linux/nfsacl.h> |
17 | #include "vfs.h" | ||
17 | 18 | ||
18 | #define NFSDDBG_FACILITY NFSDDBG_PROC | 19 | #define NFSDDBG_FACILITY NFSDDBG_PROC |
19 | #define RETURN_STATUS(st) { resp->status = (st); return (st); } | 20 | #define RETURN_STATUS(st) { resp->status = (st); return (st); } |
@@ -217,6 +218,16 @@ static int nfsaclsvc_decode_accessargs(struct svc_rqst *rqstp, __be32 *p, | |||
217 | * XDR encode functions | 218 | * XDR encode functions |
218 | */ | 219 | */ |
219 | 220 | ||
221 | /* | ||
222 | * There must be an encoding function for void results so svc_process | ||
223 | * will work properly. | ||
224 | */ | ||
225 | int | ||
226 | nfsaclsvc_encode_voidres(struct svc_rqst *rqstp, __be32 *p, void *dummy) | ||
227 | { | ||
228 | return xdr_ressize_check(rqstp, p); | ||
229 | } | ||
230 | |||
220 | /* GETACL */ | 231 | /* GETACL */ |
221 | static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, | 232 | static int nfsaclsvc_encode_getaclres(struct svc_rqst *rqstp, __be32 *p, |
222 | struct nfsd3_getaclres *resp) | 233 | struct nfsd3_getaclres *resp) |
@@ -308,7 +319,6 @@ static int nfsaclsvc_release_access(struct svc_rqst *rqstp, __be32 *p, | |||
308 | } | 319 | } |
309 | 320 | ||
310 | #define nfsaclsvc_decode_voidargs NULL | 321 | #define nfsaclsvc_decode_voidargs NULL |
311 | #define nfsaclsvc_encode_voidres NULL | ||
312 | #define nfsaclsvc_release_void NULL | 322 | #define nfsaclsvc_release_void NULL |
313 | #define nfsd3_fhandleargs nfsd_fhandle | 323 | #define nfsd3_fhandleargs nfsd_fhandle |
314 | #define nfsd3_attrstatres nfsd_attrstat | 324 | #define nfsd3_attrstatres nfsd_attrstat |
@@ -346,5 +356,5 @@ struct svc_version nfsd_acl_version2 = { | |||
346 | .vs_proc = nfsd_acl_procedures2, | 356 | .vs_proc = nfsd_acl_procedures2, |
347 | .vs_dispatch = nfsd_dispatch, | 357 | .vs_dispatch = nfsd_dispatch, |
348 | .vs_xdrsize = NFS3_SVC_XDRSIZE, | 358 | .vs_xdrsize = NFS3_SVC_XDRSIZE, |
349 | .vs_hidden = 1, | 359 | .vs_hidden = 0, |
350 | }; | 360 | }; |
diff --git a/fs/nfsd/nfs3acl.c b/fs/nfsd/nfs3acl.c index 9981dbb377a3..526d85a65f76 100644 --- a/fs/nfsd/nfs3acl.c +++ b/fs/nfsd/nfs3acl.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/nfsd/xdr3.h> | 13 | #include <linux/nfsd/xdr3.h> |
14 | #include <linux/posix_acl.h> | 14 | #include <linux/posix_acl.h> |
15 | #include <linux/nfsacl.h> | 15 | #include <linux/nfsacl.h> |
16 | #include "vfs.h" | ||
16 | 17 | ||
17 | #define RETURN_STATUS(st) { resp->status = (st); return (st); } | 18 | #define RETURN_STATUS(st) { resp->status = (st); return (st); } |
18 | 19 | ||
@@ -264,6 +265,6 @@ struct svc_version nfsd_acl_version3 = { | |||
264 | .vs_proc = nfsd_acl_procedures3, | 265 | .vs_proc = nfsd_acl_procedures3, |
265 | .vs_dispatch = nfsd_dispatch, | 266 | .vs_dispatch = nfsd_dispatch, |
266 | .vs_xdrsize = NFS3_SVC_XDRSIZE, | 267 | .vs_xdrsize = NFS3_SVC_XDRSIZE, |
267 | .vs_hidden = 1, | 268 | .vs_hidden = 0, |
268 | }; | 269 | }; |
269 | 270 | ||
diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index a713c418a922..1a259d313e14 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/nfsd/cache.h> | 25 | #include <linux/nfsd/cache.h> |
26 | #include <linux/nfsd/xdr3.h> | 26 | #include <linux/nfsd/xdr3.h> |
27 | #include <linux/nfs3.h> | 27 | #include <linux/nfs3.h> |
28 | #include "vfs.h" | ||
28 | 29 | ||
29 | #define NFSDDBG_FACILITY NFSDDBG_PROC | 30 | #define NFSDDBG_FACILITY NFSDDBG_PROC |
30 | 31 | ||
diff --git a/fs/nfsd/nfs4acl.c b/fs/nfsd/nfs4acl.c index 725d02f210e2..6d9c6aabc85e 100644 --- a/fs/nfsd/nfs4acl.c +++ b/fs/nfsd/nfs4acl.c | |||
@@ -389,7 +389,7 @@ sort_pacl(struct posix_acl *pacl) | |||
389 | sort_pacl_range(pacl, 1, i-1); | 389 | sort_pacl_range(pacl, 1, i-1); |
390 | 390 | ||
391 | BUG_ON(pacl->a_entries[i].e_tag != ACL_GROUP_OBJ); | 391 | BUG_ON(pacl->a_entries[i].e_tag != ACL_GROUP_OBJ); |
392 | j = i++; | 392 | j = ++i; |
393 | while (pacl->a_entries[j].e_tag == ACL_GROUP) | 393 | while (pacl->a_entries[j].e_tag == ACL_GROUP) |
394 | j++; | 394 | j++; |
395 | sort_pacl_range(pacl, i, j-1); | 395 | sort_pacl_range(pacl, i, j-1); |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index bebc0c2e1b0a..60a93cdefef5 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -48,6 +48,7 @@ | |||
48 | #include <linux/nfsd/xdr4.h> | 48 | #include <linux/nfsd/xdr4.h> |
49 | #include <linux/nfs4_acl.h> | 49 | #include <linux/nfs4_acl.h> |
50 | #include <linux/sunrpc/gss_api.h> | 50 | #include <linux/sunrpc/gss_api.h> |
51 | #include "vfs.h" | ||
51 | 52 | ||
52 | #define NFSDDBG_FACILITY NFSDDBG_PROC | 53 | #define NFSDDBG_FACILITY NFSDDBG_PROC |
53 | 54 | ||
diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index b5348405046b..c7a6b245c7ad 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include <linux/crypto.h> | 47 | #include <linux/crypto.h> |
48 | #include <linux/sched.h> | 48 | #include <linux/sched.h> |
49 | #include <linux/mount.h> | 49 | #include <linux/mount.h> |
50 | #include "vfs.h" | ||
50 | 51 | ||
51 | #define NFSDDBG_FACILITY NFSDDBG_PROC | 52 | #define NFSDDBG_FACILITY NFSDDBG_PROC |
52 | 53 | ||
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2153f9bdbebd..850960e5d626 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #include <linux/module.h> | 56 | #include <linux/module.h> |
57 | #include <linux/sunrpc/svcauth_gss.h> | 57 | #include <linux/sunrpc/svcauth_gss.h> |
58 | #include <linux/sunrpc/clnt.h> | 58 | #include <linux/sunrpc/clnt.h> |
59 | #include "vfs.h" | ||
59 | 60 | ||
60 | #define NFSDDBG_FACILITY NFSDDBG_PROC | 61 | #define NFSDDBG_FACILITY NFSDDBG_PROC |
61 | 62 | ||
@@ -477,13 +478,14 @@ static int set_forechannel_drc_size(struct nfsd4_channel_attrs *fchan) | |||
477 | 478 | ||
478 | /* | 479 | /* |
479 | * fchan holds the client values on input, and the server values on output | 480 | * fchan holds the client values on input, and the server values on output |
481 | * sv_max_mesg is the maximum payload plus one page for overhead. | ||
480 | */ | 482 | */ |
481 | static int init_forechannel_attrs(struct svc_rqst *rqstp, | 483 | static int init_forechannel_attrs(struct svc_rqst *rqstp, |
482 | struct nfsd4_channel_attrs *session_fchan, | 484 | struct nfsd4_channel_attrs *session_fchan, |
483 | struct nfsd4_channel_attrs *fchan) | 485 | struct nfsd4_channel_attrs *fchan) |
484 | { | 486 | { |
485 | int status = 0; | 487 | int status = 0; |
486 | __u32 maxcount = svc_max_payload(rqstp); | 488 | __u32 maxcount = nfsd_serv->sv_max_mesg; |
487 | 489 | ||
488 | /* headerpadsz set to zero in encode routine */ | 490 | /* headerpadsz set to zero in encode routine */ |
489 | 491 | ||
@@ -523,6 +525,15 @@ free_session_slots(struct nfsd4_session *ses) | |||
523 | kfree(ses->se_slots[i]); | 525 | kfree(ses->se_slots[i]); |
524 | } | 526 | } |
525 | 527 | ||
528 | /* | ||
529 | * We don't actually need to cache the rpc and session headers, so we | ||
530 | * can allocate a little less for each slot: | ||
531 | */ | ||
532 | static inline int slot_bytes(struct nfsd4_channel_attrs *ca) | ||
533 | { | ||
534 | return ca->maxresp_cached - NFSD_MIN_HDR_SEQ_SZ; | ||
535 | } | ||
536 | |||
526 | static int | 537 | static int |
527 | alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp, | 538 | alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp, |
528 | struct nfsd4_create_session *cses) | 539 | struct nfsd4_create_session *cses) |
@@ -554,7 +565,7 @@ alloc_init_session(struct svc_rqst *rqstp, struct nfs4_client *clp, | |||
554 | memcpy(new, &tmp, sizeof(*new)); | 565 | memcpy(new, &tmp, sizeof(*new)); |
555 | 566 | ||
556 | /* allocate each struct nfsd4_slot and data cache in one piece */ | 567 | /* allocate each struct nfsd4_slot and data cache in one piece */ |
557 | cachesize = new->se_fchannel.maxresp_cached - NFSD_MIN_HDR_SEQ_SZ; | 568 | cachesize = slot_bytes(&new->se_fchannel); |
558 | for (i = 0; i < new->se_fchannel.maxreqs; i++) { | 569 | for (i = 0; i < new->se_fchannel.maxreqs; i++) { |
559 | sp = kzalloc(sizeof(*sp) + cachesize, GFP_KERNEL); | 570 | sp = kzalloc(sizeof(*sp) + cachesize, GFP_KERNEL); |
560 | if (!sp) | 571 | if (!sp) |
@@ -628,10 +639,12 @@ void | |||
628 | free_session(struct kref *kref) | 639 | free_session(struct kref *kref) |
629 | { | 640 | { |
630 | struct nfsd4_session *ses; | 641 | struct nfsd4_session *ses; |
642 | int mem; | ||
631 | 643 | ||
632 | ses = container_of(kref, struct nfsd4_session, se_ref); | 644 | ses = container_of(kref, struct nfsd4_session, se_ref); |
633 | spin_lock(&nfsd_drc_lock); | 645 | spin_lock(&nfsd_drc_lock); |
634 | nfsd_drc_mem_used -= ses->se_fchannel.maxreqs * NFSD_SLOT_CACHE_SIZE; | 646 | mem = ses->se_fchannel.maxreqs * slot_bytes(&ses->se_fchannel); |
647 | nfsd_drc_mem_used -= mem; | ||
635 | spin_unlock(&nfsd_drc_lock); | 648 | spin_unlock(&nfsd_drc_lock); |
636 | free_session_slots(ses); | 649 | free_session_slots(ses); |
637 | kfree(ses); | 650 | kfree(ses); |
@@ -2404,11 +2417,8 @@ nfs4_open_delegation(struct svc_fh *fh, struct nfsd4_open *open, struct nfs4_sta | |||
2404 | 2417 | ||
2405 | memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid)); | 2418 | memcpy(&open->op_delegate_stateid, &dp->dl_stateid, sizeof(dp->dl_stateid)); |
2406 | 2419 | ||
2407 | dprintk("NFSD: delegation stateid=(%08x/%08x/%08x/%08x)\n\n", | 2420 | dprintk("NFSD: delegation stateid=" STATEID_FMT "\n", |
2408 | dp->dl_stateid.si_boot, | 2421 | 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: | 2422 | out: |
2413 | if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS | 2423 | if (open->op_claim_type == NFS4_OPEN_CLAIM_PREVIOUS |
2414 | && flag == NFS4_OPEN_DELEGATE_NONE | 2424 | && flag == NFS4_OPEN_DELEGATE_NONE |
@@ -2498,9 +2508,8 @@ nfsd4_process_open2(struct svc_rqst *rqstp, struct svc_fh *current_fh, struct nf | |||
2498 | 2508 | ||
2499 | status = nfs_ok; | 2509 | status = nfs_ok; |
2500 | 2510 | ||
2501 | dprintk("nfs4_process_open2: stateid=(%08x/%08x/%08x/%08x)\n", | 2511 | dprintk("%s: stateid=" STATEID_FMT "\n", __func__, |
2502 | stp->st_stateid.si_boot, stp->st_stateid.si_stateownerid, | 2512 | STATEID_VAL(&stp->st_stateid)); |
2503 | stp->st_stateid.si_fileid, stp->st_stateid.si_generation); | ||
2504 | out: | 2513 | out: |
2505 | if (fp) | 2514 | if (fp) |
2506 | put_nfs4_file(fp); | 2515 | put_nfs4_file(fp); |
@@ -2666,9 +2675,8 @@ STALE_STATEID(stateid_t *stateid) | |||
2666 | { | 2675 | { |
2667 | if (time_after((unsigned long)boot_time, | 2676 | if (time_after((unsigned long)boot_time, |
2668 | (unsigned long)stateid->si_boot)) { | 2677 | (unsigned long)stateid->si_boot)) { |
2669 | dprintk("NFSD: stale stateid (%08x/%08x/%08x/%08x)!\n", | 2678 | dprintk("NFSD: stale stateid " STATEID_FMT "!\n", |
2670 | stateid->si_boot, stateid->si_stateownerid, | 2679 | STATEID_VAL(stateid)); |
2671 | stateid->si_fileid, stateid->si_generation); | ||
2672 | return 1; | 2680 | return 1; |
2673 | } | 2681 | } |
2674 | return 0; | 2682 | return 0; |
@@ -2680,9 +2688,8 @@ EXPIRED_STATEID(stateid_t *stateid) | |||
2680 | if (time_before((unsigned long)boot_time, | 2688 | if (time_before((unsigned long)boot_time, |
2681 | ((unsigned long)stateid->si_boot)) && | 2689 | ((unsigned long)stateid->si_boot)) && |
2682 | time_before((unsigned long)(stateid->si_boot + lease_time), get_seconds())) { | 2690 | time_before((unsigned long)(stateid->si_boot + lease_time), get_seconds())) { |
2683 | dprintk("NFSD: expired stateid (%08x/%08x/%08x/%08x)!\n", | 2691 | dprintk("NFSD: expired stateid " STATEID_FMT "!\n", |
2684 | stateid->si_boot, stateid->si_stateownerid, | 2692 | STATEID_VAL(stateid)); |
2685 | stateid->si_fileid, stateid->si_generation); | ||
2686 | return 1; | 2693 | return 1; |
2687 | } | 2694 | } |
2688 | return 0; | 2695 | return 0; |
@@ -2696,9 +2703,8 @@ stateid_error_map(stateid_t *stateid) | |||
2696 | if (EXPIRED_STATEID(stateid)) | 2703 | if (EXPIRED_STATEID(stateid)) |
2697 | return nfserr_expired; | 2704 | return nfserr_expired; |
2698 | 2705 | ||
2699 | dprintk("NFSD: bad stateid (%08x/%08x/%08x/%08x)!\n", | 2706 | dprintk("NFSD: bad stateid " STATEID_FMT "!\n", |
2700 | stateid->si_boot, stateid->si_stateownerid, | 2707 | STATEID_VAL(stateid)); |
2701 | stateid->si_fileid, stateid->si_generation); | ||
2702 | return nfserr_bad_stateid; | 2708 | return nfserr_bad_stateid; |
2703 | } | 2709 | } |
2704 | 2710 | ||
@@ -2884,10 +2890,8 @@ nfs4_preprocess_seqid_op(struct nfsd4_compound_state *cstate, u32 seqid, | |||
2884 | struct svc_fh *current_fh = &cstate->current_fh; | 2890 | struct svc_fh *current_fh = &cstate->current_fh; |
2885 | __be32 status; | 2891 | __be32 status; |
2886 | 2892 | ||
2887 | dprintk("NFSD: preprocess_seqid_op: seqid=%d " | 2893 | dprintk("NFSD: %s: seqid=%d stateid = " STATEID_FMT "\n", __func__, |
2888 | "stateid = (%08x/%08x/%08x/%08x)\n", seqid, | 2894 | seqid, STATEID_VAL(stateid)); |
2889 | stateid->si_boot, stateid->si_stateownerid, stateid->si_fileid, | ||
2890 | stateid->si_generation); | ||
2891 | 2895 | ||
2892 | *stpp = NULL; | 2896 | *stpp = NULL; |
2893 | *sopp = NULL; | 2897 | *sopp = NULL; |
@@ -3019,12 +3023,8 @@ nfsd4_open_confirm(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
3019 | sop->so_confirmed = 1; | 3023 | sop->so_confirmed = 1; |
3020 | update_stateid(&stp->st_stateid); | 3024 | update_stateid(&stp->st_stateid); |
3021 | memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t)); | 3025 | memcpy(&oc->oc_resp_stateid, &stp->st_stateid, sizeof(stateid_t)); |
3022 | dprintk("NFSD: nfsd4_open_confirm: success, seqid=%d " | 3026 | dprintk("NFSD: %s: success, seqid=%d stateid=" STATEID_FMT "\n", |
3023 | "stateid=(%08x/%08x/%08x/%08x)\n", oc->oc_seqid, | 3027 | __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 | 3028 | ||
3029 | nfsd4_create_clid_dir(sop->so_client); | 3029 | nfsd4_create_clid_dir(sop->so_client); |
3030 | out: | 3030 | out: |
@@ -3283,9 +3283,8 @@ find_delegation_stateid(struct inode *ino, stateid_t *stid) | |||
3283 | struct nfs4_file *fp; | 3283 | struct nfs4_file *fp; |
3284 | struct nfs4_delegation *dl; | 3284 | struct nfs4_delegation *dl; |
3285 | 3285 | ||
3286 | dprintk("NFSD:find_delegation_stateid stateid=(%08x/%08x/%08x/%08x)\n", | 3286 | dprintk("NFSD: %s: stateid=" STATEID_FMT "\n", __func__, |
3287 | stid->si_boot, stid->si_stateownerid, | 3287 | STATEID_VAL(stid)); |
3288 | stid->si_fileid, stid->si_generation); | ||
3289 | 3288 | ||
3290 | fp = find_file(ino); | 3289 | fp = find_file(ino); |
3291 | if (!fp) | 3290 | if (!fp) |
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 0fbd50cee1f6..db0fc55670b3 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <linux/nfs4_acl.h> | 57 | #include <linux/nfs4_acl.h> |
58 | #include <linux/sunrpc/gss_api.h> | 58 | #include <linux/sunrpc/gss_api.h> |
59 | #include <linux/sunrpc/svcauth_gss.h> | 59 | #include <linux/sunrpc/svcauth_gss.h> |
60 | #include "vfs.h" | ||
60 | 61 | ||
61 | #define NFSDDBG_FACILITY NFSDDBG_XDR | 62 | #define NFSDDBG_FACILITY NFSDDBG_XDR |
62 | 63 | ||
diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index 01965b2f3a76..d0d8a217a3ea 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/sunrpc/svc.h> | 22 | #include <linux/sunrpc/svc.h> |
23 | #include <linux/sunrpc/svcauth_gss.h> | 23 | #include <linux/sunrpc/svcauth_gss.h> |
24 | #include <linux/nfsd/nfsd.h> | 24 | #include <linux/nfsd/nfsd.h> |
25 | #include "vfs.h" | ||
25 | #include "auth.h" | 26 | #include "auth.h" |
26 | 27 | ||
27 | #define NFSDDBG_FACILITY NFSDDBG_FH | 28 | #define NFSDDBG_FACILITY NFSDDBG_FH |
diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index 0eb9c820b7a6..6c967e1ba37b 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/nfsd/nfsd.h> | 24 | #include <linux/nfsd/nfsd.h> |
25 | #include <linux/nfsd/cache.h> | 25 | #include <linux/nfsd/cache.h> |
26 | #include <linux/nfsd/xdr.h> | 26 | #include <linux/nfsd/xdr.h> |
27 | #include "vfs.h" | ||
27 | 28 | ||
28 | typedef struct svc_rqst svc_rqst; | 29 | typedef struct svc_rqst svc_rqst; |
29 | typedef struct svc_buf svc_buf; | 30 | typedef struct svc_buf svc_buf; |
@@ -758,6 +759,7 @@ nfserrno (int errno) | |||
758 | { nfserr_io, -ETXTBSY }, | 759 | { nfserr_io, -ETXTBSY }, |
759 | { nfserr_notsupp, -EOPNOTSUPP }, | 760 | { nfserr_notsupp, -EOPNOTSUPP }, |
760 | { nfserr_toosmall, -ETOOSMALL }, | 761 | { nfserr_toosmall, -ETOOSMALL }, |
762 | { nfserr_serverfault, -ESERVERFAULT }, | ||
761 | }; | 763 | }; |
762 | int i; | 764 | int i; |
763 | 765 | ||
diff --git a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c index 67ea83eedd43..2944b31dcbe6 100644 --- a/fs/nfsd/nfssvc.c +++ b/fs/nfsd/nfssvc.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/lockd/bind.h> | 35 | #include <linux/lockd/bind.h> |
36 | #include <linux/nfsacl.h> | 36 | #include <linux/nfsacl.h> |
37 | #include <linux/seq_file.h> | 37 | #include <linux/seq_file.h> |
38 | #include "vfs.h" | ||
38 | 39 | ||
39 | #define NFSDDBG_FACILITY NFSDDBG_SVC | 40 | #define NFSDDBG_FACILITY NFSDDBG_SVC |
40 | 41 | ||
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index a293f0273263..a7038ede671a 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -56,6 +56,7 @@ | |||
56 | #endif /* CONFIG_NFSD_V4 */ | 56 | #endif /* CONFIG_NFSD_V4 */ |
57 | #include <linux/jhash.h> | 57 | #include <linux/jhash.h> |
58 | #include <linux/ima.h> | 58 | #include <linux/ima.h> |
59 | #include "vfs.h" | ||
59 | 60 | ||
60 | #include <asm/uaccess.h> | 61 | #include <asm/uaccess.h> |
61 | 62 | ||
@@ -141,6 +142,40 @@ out: | |||
141 | return err; | 142 | return err; |
142 | } | 143 | } |
143 | 144 | ||
145 | static void follow_to_parent(struct path *path) | ||
146 | { | ||
147 | struct dentry *dp; | ||
148 | |||
149 | while (path->dentry == path->mnt->mnt_root && follow_up(path)) | ||
150 | ; | ||
151 | dp = dget_parent(path->dentry); | ||
152 | dput(path->dentry); | ||
153 | path->dentry = dp; | ||
154 | } | ||
155 | |||
156 | static int nfsd_lookup_parent(struct svc_rqst *rqstp, struct dentry *dparent, struct svc_export **exp, struct dentry **dentryp) | ||
157 | { | ||
158 | struct svc_export *exp2; | ||
159 | struct path path = {.mnt = mntget((*exp)->ex_path.mnt), | ||
160 | .dentry = dget(dparent)}; | ||
161 | |||
162 | follow_to_parent(&path); | ||
163 | |||
164 | exp2 = rqst_exp_parent(rqstp, &path); | ||
165 | if (PTR_ERR(exp2) == -ENOENT) { | ||
166 | *dentryp = dget(dparent); | ||
167 | } else if (IS_ERR(exp2)) { | ||
168 | path_put(&path); | ||
169 | return PTR_ERR(exp2); | ||
170 | } else { | ||
171 | *dentryp = dget(path.dentry); | ||
172 | exp_put(*exp); | ||
173 | *exp = exp2; | ||
174 | } | ||
175 | path_put(&path); | ||
176 | return 0; | ||
177 | } | ||
178 | |||
144 | __be32 | 179 | __be32 |
145 | nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, | 180 | nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, |
146 | const char *name, unsigned int len, | 181 | const char *name, unsigned int len, |
@@ -169,35 +204,13 @@ nfsd_lookup_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
169 | dentry = dget(dparent); | 204 | dentry = dget(dparent); |
170 | else if (dparent != exp->ex_path.dentry) | 205 | else if (dparent != exp->ex_path.dentry) |
171 | dentry = dget_parent(dparent); | 206 | dentry = dget_parent(dparent); |
172 | else if (!EX_NOHIDE(exp)) | 207 | else if (!EX_NOHIDE(exp) && !nfsd_v4client(rqstp)) |
173 | dentry = dget(dparent); /* .. == . just like at / */ | 208 | dentry = dget(dparent); /* .. == . just like at / */ |
174 | else { | 209 | else { |
175 | /* checking mountpoint crossing is very different when stepping up */ | 210 | /* checking mountpoint crossing is very different when stepping up */ |
176 | struct svc_export *exp2 = NULL; | 211 | host_err = nfsd_lookup_parent(rqstp, dparent, &exp, &dentry); |
177 | struct dentry *dp; | 212 | 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; | 213 | goto out_nfserr; |
195 | } else { | ||
196 | dentry = dget(path.dentry); | ||
197 | exp_put(exp); | ||
198 | exp = exp2; | ||
199 | } | ||
200 | path_put(&path); | ||
201 | } | 214 | } |
202 | } else { | 215 | } else { |
203 | fh_lock(fhp); | 216 | fh_lock(fhp); |
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h new file mode 100644 index 000000000000..b8011fd2fcab --- /dev/null +++ b/fs/nfsd/vfs.h | |||
@@ -0,0 +1,98 @@ | |||
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 | /* | ||
9 | * Flags for nfsd_permission | ||
10 | */ | ||
11 | #define NFSD_MAY_NOP 0 | ||
12 | #define NFSD_MAY_EXEC 1 /* == MAY_EXEC */ | ||
13 | #define NFSD_MAY_WRITE 2 /* == MAY_WRITE */ | ||
14 | #define NFSD_MAY_READ 4 /* == MAY_READ */ | ||
15 | #define NFSD_MAY_SATTR 8 | ||
16 | #define NFSD_MAY_TRUNC 16 | ||
17 | #define NFSD_MAY_LOCK 32 | ||
18 | #define NFSD_MAY_OWNER_OVERRIDE 64 | ||
19 | #define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/ | ||
20 | #define NFSD_MAY_BYPASS_GSS_ON_ROOT 256 | ||
21 | |||
22 | #define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) | ||
23 | #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) | ||
24 | |||
25 | /* | ||
26 | * Callback function for readdir | ||
27 | */ | ||
28 | typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int); | ||
29 | |||
30 | /* nfsd/vfs.c */ | ||
31 | int fh_lock_parent(struct svc_fh *, struct dentry *); | ||
32 | int nfsd_racache_init(int); | ||
33 | void nfsd_racache_shutdown(void); | ||
34 | int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, | ||
35 | struct svc_export **expp); | ||
36 | __be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *, | ||
37 | const char *, unsigned int, struct svc_fh *); | ||
38 | __be32 nfsd_lookup_dentry(struct svc_rqst *, struct svc_fh *, | ||
39 | const char *, unsigned int, | ||
40 | struct svc_export **, struct dentry **); | ||
41 | __be32 nfsd_setattr(struct svc_rqst *, struct svc_fh *, | ||
42 | struct iattr *, int, time_t); | ||
43 | #ifdef CONFIG_NFSD_V4 | ||
44 | __be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *, | ||
45 | struct nfs4_acl *); | ||
46 | int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **); | ||
47 | #endif /* CONFIG_NFSD_V4 */ | ||
48 | __be32 nfsd_create(struct svc_rqst *, struct svc_fh *, | ||
49 | char *name, int len, struct iattr *attrs, | ||
50 | int type, dev_t rdev, struct svc_fh *res); | ||
51 | #ifdef CONFIG_NFSD_V3 | ||
52 | __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); | ||
53 | __be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *, | ||
54 | char *name, int len, struct iattr *attrs, | ||
55 | struct svc_fh *res, int createmode, | ||
56 | u32 *verifier, int *truncp, int *created); | ||
57 | __be32 nfsd_commit(struct svc_rqst *, struct svc_fh *, | ||
58 | loff_t, unsigned long); | ||
59 | #endif /* CONFIG_NFSD_V3 */ | ||
60 | __be32 nfsd_open(struct svc_rqst *, struct svc_fh *, int, | ||
61 | int, struct file **); | ||
62 | void nfsd_close(struct file *); | ||
63 | __be32 nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *, | ||
64 | loff_t, struct kvec *, int, unsigned long *); | ||
65 | __be32 nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *, | ||
66 | loff_t, struct kvec *,int, unsigned long *, int *); | ||
67 | __be32 nfsd_readlink(struct svc_rqst *, struct svc_fh *, | ||
68 | char *, int *); | ||
69 | __be32 nfsd_symlink(struct svc_rqst *, struct svc_fh *, | ||
70 | char *name, int len, char *path, int plen, | ||
71 | struct svc_fh *res, struct iattr *); | ||
72 | __be32 nfsd_link(struct svc_rqst *, struct svc_fh *, | ||
73 | char *, int, struct svc_fh *); | ||
74 | __be32 nfsd_rename(struct svc_rqst *, | ||
75 | struct svc_fh *, char *, int, | ||
76 | struct svc_fh *, char *, int); | ||
77 | __be32 nfsd_remove(struct svc_rqst *, | ||
78 | struct svc_fh *, char *, int); | ||
79 | __be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type, | ||
80 | char *name, int len); | ||
81 | int nfsd_truncate(struct svc_rqst *, struct svc_fh *, | ||
82 | unsigned long size); | ||
83 | __be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, | ||
84 | loff_t *, struct readdir_cd *, filldir_t); | ||
85 | __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, | ||
86 | struct kstatfs *, int access); | ||
87 | |||
88 | int nfsd_notify_change(struct inode *, struct iattr *); | ||
89 | __be32 nfsd_permission(struct svc_rqst *, struct svc_export *, | ||
90 | struct dentry *, int); | ||
91 | int nfsd_sync_dir(struct dentry *dp); | ||
92 | |||
93 | #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) | ||
94 | struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int); | ||
95 | int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *); | ||
96 | #endif | ||
97 | |||
98 | #endif /* LINUX_NFSD_VFS_H */ | ||
diff --git a/include/linux/exportfs.h b/include/linux/exportfs.h index 27e772cefb6a..dc12f416a49f 100644 --- a/include/linux/exportfs.h +++ b/include/linux/exportfs.h | |||
@@ -97,7 +97,7 @@ struct fid { | |||
97 | * @get_name: find the name for a given inode in a given directory | 97 | * @get_name: find the name for a given inode in a given directory |
98 | * @get_parent: find the parent of a given directory | 98 | * @get_parent: find the parent of a given directory |
99 | * | 99 | * |
100 | * See Documentation/filesystems/Exporting for details on how to use | 100 | * See Documentation/filesystems/nfs/Exporting for details on how to use |
101 | * this interface correctly. | 101 | * this interface correctly. |
102 | * | 102 | * |
103 | * encode_fh: | 103 | * encode_fh: |
diff --git a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h index 510ffdd5020e..e4518d090a8c 100644 --- a/include/linux/nfsd/nfsd.h +++ b/include/linux/nfsd/nfsd.h | |||
@@ -25,30 +25,10 @@ | |||
25 | */ | 25 | */ |
26 | #define NFSD_SUPPORTED_MINOR_VERSION 1 | 26 | #define NFSD_SUPPORTED_MINOR_VERSION 1 |
27 | 27 | ||
28 | /* | ||
29 | * Flags for nfsd_permission | ||
30 | */ | ||
31 | #define NFSD_MAY_NOP 0 | ||
32 | #define NFSD_MAY_EXEC 1 /* == MAY_EXEC */ | ||
33 | #define NFSD_MAY_WRITE 2 /* == MAY_WRITE */ | ||
34 | #define NFSD_MAY_READ 4 /* == MAY_READ */ | ||
35 | #define NFSD_MAY_SATTR 8 | ||
36 | #define NFSD_MAY_TRUNC 16 | ||
37 | #define NFSD_MAY_LOCK 32 | ||
38 | #define NFSD_MAY_OWNER_OVERRIDE 64 | ||
39 | #define NFSD_MAY_LOCAL_ACCESS 128 /* IRIX doing local access check on device special file*/ | ||
40 | #define NFSD_MAY_BYPASS_GSS_ON_ROOT 256 | ||
41 | |||
42 | #define NFSD_MAY_CREATE (NFSD_MAY_EXEC|NFSD_MAY_WRITE) | ||
43 | #define NFSD_MAY_REMOVE (NFSD_MAY_EXEC|NFSD_MAY_WRITE|NFSD_MAY_TRUNC) | ||
44 | |||
45 | /* | ||
46 | * Callback function for readdir | ||
47 | */ | ||
48 | struct readdir_cd { | 28 | struct readdir_cd { |
49 | __be32 err; /* 0, nfserr, or nfserr_eof */ | 29 | __be32 err; /* 0, nfserr, or nfserr_eof */ |
50 | }; | 30 | }; |
51 | typedef int (*nfsd_dirop_t)(struct inode *, struct dentry *, int, int); | 31 | |
52 | 32 | ||
53 | extern struct svc_program nfsd_program; | 33 | extern struct svc_program nfsd_program; |
54 | extern struct svc_version nfsd_version2, nfsd_version3, | 34 | extern struct svc_version nfsd_version2, nfsd_version3, |
@@ -73,69 +53,6 @@ int nfsd_nrpools(void); | |||
73 | int nfsd_get_nrthreads(int n, int *); | 53 | int nfsd_get_nrthreads(int n, int *); |
74 | int nfsd_set_nrthreads(int n, int *); | 54 | int nfsd_set_nrthreads(int n, int *); |
75 | 55 | ||
76 | /* nfsd/vfs.c */ | ||
77 | int fh_lock_parent(struct svc_fh *, struct dentry *); | ||
78 | int nfsd_racache_init(int); | ||
79 | void nfsd_racache_shutdown(void); | ||
80 | int nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, | ||
81 | struct svc_export **expp); | ||
82 | __be32 nfsd_lookup(struct svc_rqst *, struct svc_fh *, | ||
83 | const char *, unsigned int, struct svc_fh *); | ||
84 | __be32 nfsd_lookup_dentry(struct svc_rqst *, struct svc_fh *, | ||
85 | const char *, unsigned int, | ||
86 | struct svc_export **, struct dentry **); | ||
87 | __be32 nfsd_setattr(struct svc_rqst *, struct svc_fh *, | ||
88 | struct iattr *, int, time_t); | ||
89 | #ifdef CONFIG_NFSD_V4 | ||
90 | __be32 nfsd4_set_nfs4_acl(struct svc_rqst *, struct svc_fh *, | ||
91 | struct nfs4_acl *); | ||
92 | int nfsd4_get_nfs4_acl(struct svc_rqst *, struct dentry *, struct nfs4_acl **); | ||
93 | #endif /* CONFIG_NFSD_V4 */ | ||
94 | __be32 nfsd_create(struct svc_rqst *, struct svc_fh *, | ||
95 | char *name, int len, struct iattr *attrs, | ||
96 | int type, dev_t rdev, struct svc_fh *res); | ||
97 | #ifdef CONFIG_NFSD_V3 | ||
98 | __be32 nfsd_access(struct svc_rqst *, struct svc_fh *, u32 *, u32 *); | ||
99 | __be32 nfsd_create_v3(struct svc_rqst *, struct svc_fh *, | ||
100 | char *name, int len, struct iattr *attrs, | ||
101 | struct svc_fh *res, int createmode, | ||
102 | u32 *verifier, int *truncp, int *created); | ||
103 | __be32 nfsd_commit(struct svc_rqst *, struct svc_fh *, | ||
104 | loff_t, unsigned long); | ||
105 | #endif /* CONFIG_NFSD_V3 */ | ||
106 | __be32 nfsd_open(struct svc_rqst *, struct svc_fh *, int, | ||
107 | int, struct file **); | ||
108 | void nfsd_close(struct file *); | ||
109 | __be32 nfsd_read(struct svc_rqst *, struct svc_fh *, struct file *, | ||
110 | loff_t, struct kvec *, int, unsigned long *); | ||
111 | __be32 nfsd_write(struct svc_rqst *, struct svc_fh *,struct file *, | ||
112 | loff_t, struct kvec *,int, unsigned long *, int *); | ||
113 | __be32 nfsd_readlink(struct svc_rqst *, struct svc_fh *, | ||
114 | char *, int *); | ||
115 | __be32 nfsd_symlink(struct svc_rqst *, struct svc_fh *, | ||
116 | char *name, int len, char *path, int plen, | ||
117 | struct svc_fh *res, struct iattr *); | ||
118 | __be32 nfsd_link(struct svc_rqst *, struct svc_fh *, | ||
119 | char *, int, struct svc_fh *); | ||
120 | __be32 nfsd_rename(struct svc_rqst *, | ||
121 | struct svc_fh *, char *, int, | ||
122 | struct svc_fh *, char *, int); | ||
123 | __be32 nfsd_remove(struct svc_rqst *, | ||
124 | struct svc_fh *, char *, int); | ||
125 | __be32 nfsd_unlink(struct svc_rqst *, struct svc_fh *, int type, | ||
126 | char *name, int len); | ||
127 | int nfsd_truncate(struct svc_rqst *, struct svc_fh *, | ||
128 | unsigned long size); | ||
129 | __be32 nfsd_readdir(struct svc_rqst *, struct svc_fh *, | ||
130 | loff_t *, struct readdir_cd *, filldir_t); | ||
131 | __be32 nfsd_statfs(struct svc_rqst *, struct svc_fh *, | ||
132 | struct kstatfs *, int access); | ||
133 | |||
134 | int nfsd_notify_change(struct inode *, struct iattr *); | ||
135 | __be32 nfsd_permission(struct svc_rqst *, struct svc_export *, | ||
136 | struct dentry *, int); | ||
137 | int nfsd_sync_dir(struct dentry *dp); | ||
138 | |||
139 | #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) | 56 | #if defined(CONFIG_NFSD_V2_ACL) || defined(CONFIG_NFSD_V3_ACL) |
140 | #ifdef CONFIG_NFSD_V2_ACL | 57 | #ifdef CONFIG_NFSD_V2_ACL |
141 | extern struct svc_version nfsd_acl_version2; | 58 | extern struct svc_version nfsd_acl_version2; |
@@ -147,8 +64,6 @@ extern struct svc_version nfsd_acl_version3; | |||
147 | #else | 64 | #else |
148 | #define nfsd_acl_version3 NULL | 65 | #define nfsd_acl_version3 NULL |
149 | #endif | 66 | #endif |
150 | struct posix_acl *nfsd_get_posix_acl(struct svc_fh *, int); | ||
151 | int nfsd_set_posix_acl(struct svc_fh *, int, struct posix_acl *); | ||
152 | #endif | 67 | #endif |
153 | 68 | ||
154 | enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL }; | 69 | enum vers_op {NFSD_SET, NFSD_CLEAR, NFSD_TEST, NFSD_AVAIL }; |
diff --git a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h index b38d11324189..5aadf8aa3a97 100644 --- a/include/linux/nfsd/state.h +++ b/include/linux/nfsd/state.h | |||
@@ -60,6 +60,13 @@ typedef struct { | |||
60 | #define si_stateownerid si_opaque.so_stateownerid | 60 | #define si_stateownerid si_opaque.so_stateownerid |
61 | #define si_fileid si_opaque.so_fileid | 61 | #define si_fileid si_opaque.so_fileid |
62 | 62 | ||
63 | #define STATEID_FMT "(%08x/%08x/%08x/%08x)" | ||
64 | #define STATEID_VAL(s) \ | ||
65 | (s)->si_boot, \ | ||
66 | (s)->si_stateownerid, \ | ||
67 | (s)->si_fileid, \ | ||
68 | (s)->si_generation | ||
69 | |||
63 | struct nfsd4_cb_sequence { | 70 | struct nfsd4_cb_sequence { |
64 | /* args/res */ | 71 | /* args/res */ |
65 | u32 cbs_minorversion; | 72 | u32 cbs_minorversion; |
diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 52e8cb0a7569..d1567d627557 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h | |||
@@ -29,7 +29,6 @@ struct svc_pool_stats { | |||
29 | unsigned long packets; | 29 | unsigned long packets; |
30 | unsigned long sockets_queued; | 30 | unsigned long sockets_queued; |
31 | unsigned long threads_woken; | 31 | unsigned long threads_woken; |
32 | unsigned long overloads_avoided; | ||
33 | unsigned long threads_timedout; | 32 | unsigned long threads_timedout; |
34 | }; | 33 | }; |
35 | 34 | ||
@@ -50,7 +49,6 @@ struct svc_pool { | |||
50 | struct list_head sp_sockets; /* pending sockets */ | 49 | struct list_head sp_sockets; /* pending sockets */ |
51 | unsigned int sp_nrthreads; /* # of threads in pool */ | 50 | unsigned int sp_nrthreads; /* # of threads in pool */ |
52 | struct list_head sp_all_threads; /* all server threads */ | 51 | struct list_head sp_all_threads; /* all server threads */ |
53 | int sp_nwaking; /* number of threads woken but not yet active */ | ||
54 | struct svc_pool_stats sp_stats; /* statistics on pool operation */ | 52 | struct svc_pool_stats sp_stats; /* statistics on pool operation */ |
55 | } ____cacheline_aligned_in_smp; | 53 | } ____cacheline_aligned_in_smp; |
56 | 54 | ||
@@ -284,7 +282,6 @@ struct svc_rqst { | |||
284 | * cache pages */ | 282 | * cache pages */ |
285 | wait_queue_head_t rq_wait; /* synchronization */ | 283 | wait_queue_head_t rq_wait; /* synchronization */ |
286 | struct task_struct *rq_task; /* service thread */ | 284 | struct task_struct *rq_task; /* service thread */ |
287 | int rq_waking; /* 1 if thread is being woken */ | ||
288 | }; | 285 | }; |
289 | 286 | ||
290 | /* | 287 | /* |
diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 70491d9035eb..0c94a1ac2946 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig | |||
@@ -166,7 +166,7 @@ config IP_PNP_DHCP | |||
166 | 166 | ||
167 | If unsure, say Y. Note that if you want to use DHCP, a DHCP server | 167 | If unsure, say Y. Note that if you want to use DHCP, a DHCP server |
168 | must be operating on your network. Read | 168 | must be operating on your network. Read |
169 | <file:Documentation/filesystems/nfsroot.txt> for details. | 169 | <file:Documentation/filesystems/nfs/nfsroot.txt> for details. |
170 | 170 | ||
171 | config IP_PNP_BOOTP | 171 | config IP_PNP_BOOTP |
172 | bool "IP: BOOTP support" | 172 | bool "IP: BOOTP support" |
@@ -181,7 +181,7 @@ config IP_PNP_BOOTP | |||
181 | does BOOTP itself, providing all necessary information on the kernel | 181 | does BOOTP itself, providing all necessary information on the kernel |
182 | command line, you can say N here. If unsure, say Y. Note that if you | 182 | command line, you can say N here. If unsure, say Y. Note that if you |
183 | want to use BOOTP, a BOOTP server must be operating on your network. | 183 | want to use BOOTP, a BOOTP server must be operating on your network. |
184 | Read <file:Documentation/filesystems/nfsroot.txt> for details. | 184 | Read <file:Documentation/filesystems/nfs/nfsroot.txt> for details. |
185 | 185 | ||
186 | config IP_PNP_RARP | 186 | config IP_PNP_RARP |
187 | bool "IP: RARP support" | 187 | bool "IP: RARP support" |
@@ -194,7 +194,7 @@ config IP_PNP_RARP | |||
194 | older protocol which is being obsoleted by BOOTP and DHCP), say Y | 194 | older protocol which is being obsoleted by BOOTP and DHCP), say Y |
195 | here. Note that if you want to use RARP, a RARP server must be | 195 | here. Note that if you want to use RARP, a RARP server must be |
196 | operating on your network. Read | 196 | operating on your network. Read |
197 | <file:Documentation/filesystems/nfsroot.txt> for details. | 197 | <file:Documentation/filesystems/nfs/nfsroot.txt> for details. |
198 | 198 | ||
199 | # not yet ready.. | 199 | # not yet ready.. |
200 | # bool ' IP: ARP support' CONFIG_IP_PNP_ARP | 200 | # bool ' IP: ARP support' CONFIG_IP_PNP_ARP |
diff --git a/net/ipv4/ipconfig.c b/net/ipv4/ipconfig.c index f8d04c256454..7dcbf4706099 100644 --- a/net/ipv4/ipconfig.c +++ b/net/ipv4/ipconfig.c | |||
@@ -1447,7 +1447,7 @@ late_initcall(ip_auto_config); | |||
1447 | 1447 | ||
1448 | /* | 1448 | /* |
1449 | * Decode any IP configuration options in the "ip=" or "nfsaddrs=" kernel | 1449 | * Decode any IP configuration options in the "ip=" or "nfsaddrs=" kernel |
1450 | * command line parameter. See Documentation/filesystems/nfsroot.txt. | 1450 | * command line parameter. See Documentation/filesystems/nfs/nfsroot.txt. |
1451 | */ | 1451 | */ |
1452 | static int __init ic_proto_name(char *name) | 1452 | static int __init ic_proto_name(char *name) |
1453 | { | 1453 | { |
diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index df124f78ee48..2c58b75a236f 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c | |||
@@ -16,8 +16,6 @@ | |||
16 | 16 | ||
17 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT | 17 | #define RPCDBG_FACILITY RPCDBG_SVCXPRT |
18 | 18 | ||
19 | #define SVC_MAX_WAKING 5 | ||
20 | |||
21 | static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt); | 19 | static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt); |
22 | static int svc_deferred_recv(struct svc_rqst *rqstp); | 20 | static int svc_deferred_recv(struct svc_rqst *rqstp); |
23 | static struct cache_deferred_req *svc_defer(struct cache_req *req); | 21 | static struct cache_deferred_req *svc_defer(struct cache_req *req); |
@@ -306,7 +304,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) | |||
306 | struct svc_pool *pool; | 304 | struct svc_pool *pool; |
307 | struct svc_rqst *rqstp; | 305 | struct svc_rqst *rqstp; |
308 | int cpu; | 306 | int cpu; |
309 | int thread_avail; | ||
310 | 307 | ||
311 | if (!(xprt->xpt_flags & | 308 | if (!(xprt->xpt_flags & |
312 | ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED)))) | 309 | ((1<<XPT_CONN)|(1<<XPT_DATA)|(1<<XPT_CLOSE)|(1<<XPT_DEFERRED)))) |
@@ -318,6 +315,12 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) | |||
318 | 315 | ||
319 | spin_lock_bh(&pool->sp_lock); | 316 | spin_lock_bh(&pool->sp_lock); |
320 | 317 | ||
318 | if (!list_empty(&pool->sp_threads) && | ||
319 | !list_empty(&pool->sp_sockets)) | ||
320 | printk(KERN_ERR | ||
321 | "svc_xprt_enqueue: " | ||
322 | "threads and transports both waiting??\n"); | ||
323 | |||
321 | if (test_bit(XPT_DEAD, &xprt->xpt_flags)) { | 324 | if (test_bit(XPT_DEAD, &xprt->xpt_flags)) { |
322 | /* Don't enqueue dead transports */ | 325 | /* Don't enqueue dead transports */ |
323 | dprintk("svc: transport %p is dead, not enqueued\n", xprt); | 326 | dprintk("svc: transport %p is dead, not enqueued\n", xprt); |
@@ -358,15 +361,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) | |||
358 | } | 361 | } |
359 | 362 | ||
360 | process: | 363 | process: |
361 | /* Work out whether threads are available */ | 364 | if (!list_empty(&pool->sp_threads)) { |
362 | thread_avail = !list_empty(&pool->sp_threads); /* threads are asleep */ | ||
363 | if (pool->sp_nwaking >= SVC_MAX_WAKING) { | ||
364 | /* too many threads are runnable and trying to wake up */ | ||
365 | thread_avail = 0; | ||
366 | pool->sp_stats.overloads_avoided++; | ||
367 | } | ||
368 | |||
369 | if (thread_avail) { | ||
370 | rqstp = list_entry(pool->sp_threads.next, | 365 | rqstp = list_entry(pool->sp_threads.next, |
371 | struct svc_rqst, | 366 | struct svc_rqst, |
372 | rq_list); | 367 | rq_list); |
@@ -381,8 +376,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) | |||
381 | svc_xprt_get(xprt); | 376 | svc_xprt_get(xprt); |
382 | rqstp->rq_reserved = serv->sv_max_mesg; | 377 | rqstp->rq_reserved = serv->sv_max_mesg; |
383 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); | 378 | atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); |
384 | rqstp->rq_waking = 1; | ||
385 | pool->sp_nwaking++; | ||
386 | pool->sp_stats.threads_woken++; | 379 | pool->sp_stats.threads_woken++; |
387 | BUG_ON(xprt->xpt_pool != pool); | 380 | BUG_ON(xprt->xpt_pool != pool); |
388 | wake_up(&rqstp->rq_wait); | 381 | wake_up(&rqstp->rq_wait); |
@@ -651,11 +644,6 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) | |||
651 | return -EINTR; | 644 | return -EINTR; |
652 | 645 | ||
653 | spin_lock_bh(&pool->sp_lock); | 646 | spin_lock_bh(&pool->sp_lock); |
654 | if (rqstp->rq_waking) { | ||
655 | rqstp->rq_waking = 0; | ||
656 | pool->sp_nwaking--; | ||
657 | BUG_ON(pool->sp_nwaking < 0); | ||
658 | } | ||
659 | xprt = svc_xprt_dequeue(pool); | 647 | xprt = svc_xprt_dequeue(pool); |
660 | if (xprt) { | 648 | if (xprt) { |
661 | rqstp->rq_xprt = xprt; | 649 | rqstp->rq_xprt = xprt; |
@@ -1204,16 +1192,15 @@ static int svc_pool_stats_show(struct seq_file *m, void *p) | |||
1204 | struct svc_pool *pool = p; | 1192 | struct svc_pool *pool = p; |
1205 | 1193 | ||
1206 | if (p == SEQ_START_TOKEN) { | 1194 | if (p == SEQ_START_TOKEN) { |
1207 | seq_puts(m, "# pool packets-arrived sockets-enqueued threads-woken overloads-avoided threads-timedout\n"); | 1195 | seq_puts(m, "# pool packets-arrived sockets-enqueued threads-woken threads-timedout\n"); |
1208 | return 0; | 1196 | return 0; |
1209 | } | 1197 | } |
1210 | 1198 | ||
1211 | seq_printf(m, "%u %lu %lu %lu %lu %lu\n", | 1199 | seq_printf(m, "%u %lu %lu %lu %lu\n", |
1212 | pool->sp_id, | 1200 | pool->sp_id, |
1213 | pool->sp_stats.packets, | 1201 | pool->sp_stats.packets, |
1214 | pool->sp_stats.sockets_queued, | 1202 | pool->sp_stats.sockets_queued, |
1215 | pool->sp_stats.threads_woken, | 1203 | pool->sp_stats.threads_woken, |
1216 | pool->sp_stats.overloads_avoided, | ||
1217 | pool->sp_stats.threads_timedout); | 1204 | pool->sp_stats.threads_timedout); |
1218 | 1205 | ||
1219 | return 0; | 1206 | return 0; |
diff --git a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c index 117f68a8aa40..97cc3de7432e 100644 --- a/net/sunrpc/svcauth_unix.c +++ b/net/sunrpc/svcauth_unix.c | |||
@@ -655,23 +655,25 @@ static struct unix_gid *unix_gid_lookup(uid_t uid) | |||
655 | return NULL; | 655 | return NULL; |
656 | } | 656 | } |
657 | 657 | ||
658 | static int unix_gid_find(uid_t uid, struct group_info **gip, | 658 | static struct group_info *unix_gid_find(uid_t uid, struct svc_rqst *rqstp) |
659 | struct svc_rqst *rqstp) | ||
660 | { | 659 | { |
661 | struct unix_gid *ug = unix_gid_lookup(uid); | 660 | struct unix_gid *ug; |
661 | struct group_info *gi; | ||
662 | int ret; | ||
663 | |||
664 | ug = unix_gid_lookup(uid); | ||
662 | if (!ug) | 665 | if (!ug) |
663 | return -EAGAIN; | 666 | return ERR_PTR(-EAGAIN); |
664 | switch (cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle)) { | 667 | ret = cache_check(&unix_gid_cache, &ug->h, &rqstp->rq_chandle); |
668 | switch (ret) { | ||
665 | case -ENOENT: | 669 | case -ENOENT: |
666 | *gip = NULL; | 670 | return ERR_PTR(-ENOENT); |
667 | return 0; | ||
668 | case 0: | 671 | case 0: |
669 | *gip = ug->gi; | 672 | gi = get_group_info(ug->gi); |
670 | get_group_info(*gip); | ||
671 | cache_put(&ug->h, &unix_gid_cache); | 673 | cache_put(&ug->h, &unix_gid_cache); |
672 | return 0; | 674 | return gi; |
673 | default: | 675 | default: |
674 | return -EAGAIN; | 676 | return ERR_PTR(-EAGAIN); |
675 | } | 677 | } |
676 | } | 678 | } |
677 | 679 | ||
@@ -681,6 +683,8 @@ svcauth_unix_set_client(struct svc_rqst *rqstp) | |||
681 | struct sockaddr_in *sin; | 683 | struct sockaddr_in *sin; |
682 | struct sockaddr_in6 *sin6, sin6_storage; | 684 | struct sockaddr_in6 *sin6, sin6_storage; |
683 | struct ip_map *ipm; | 685 | struct ip_map *ipm; |
686 | struct group_info *gi; | ||
687 | struct svc_cred *cred = &rqstp->rq_cred; | ||
684 | 688 | ||
685 | switch (rqstp->rq_addr.ss_family) { | 689 | switch (rqstp->rq_addr.ss_family) { |
686 | case AF_INET: | 690 | case AF_INET: |
@@ -722,6 +726,17 @@ svcauth_unix_set_client(struct svc_rqst *rqstp) | |||
722 | ip_map_cached_put(rqstp, ipm); | 726 | ip_map_cached_put(rqstp, ipm); |
723 | break; | 727 | break; |
724 | } | 728 | } |
729 | |||
730 | gi = unix_gid_find(cred->cr_uid, rqstp); | ||
731 | switch (PTR_ERR(gi)) { | ||
732 | case -EAGAIN: | ||
733 | return SVC_DROP; | ||
734 | case -ENOENT: | ||
735 | break; | ||
736 | default: | ||
737 | put_group_info(cred->cr_group_info); | ||
738 | cred->cr_group_info = gi; | ||
739 | } | ||
725 | return SVC_OK; | 740 | return SVC_OK; |
726 | } | 741 | } |
727 | 742 | ||
@@ -818,19 +833,11 @@ svcauth_unix_accept(struct svc_rqst *rqstp, __be32 *authp) | |||
818 | slen = svc_getnl(argv); /* gids length */ | 833 | slen = svc_getnl(argv); /* gids length */ |
819 | if (slen > 16 || (len -= (slen + 2)*4) < 0) | 834 | if (slen > 16 || (len -= (slen + 2)*4) < 0) |
820 | goto badcred; | 835 | goto badcred; |
821 | if (unix_gid_find(cred->cr_uid, &cred->cr_group_info, rqstp) | 836 | cred->cr_group_info = groups_alloc(slen); |
822 | == -EAGAIN) | 837 | if (cred->cr_group_info == NULL) |
823 | return SVC_DROP; | 838 | return SVC_DROP; |
824 | if (cred->cr_group_info == NULL) { | 839 | for (i = 0; i < slen; i++) |
825 | cred->cr_group_info = groups_alloc(slen); | 840 | GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv); |
826 | if (cred->cr_group_info == NULL) | ||
827 | return SVC_DROP; | ||
828 | for (i = 0; i < slen; i++) | ||
829 | GROUP_AT(cred->cr_group_info, i) = svc_getnl(argv); | ||
830 | } else { | ||
831 | for (i = 0; i < slen ; i++) | ||
832 | svc_getnl(argv); | ||
833 | } | ||
834 | if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { | 841 | if (svc_getu32(argv) != htonl(RPC_AUTH_NULL) || svc_getu32(argv) != 0) { |
835 | *authp = rpc_autherr_badverf; | 842 | *authp = rpc_autherr_badverf; |
836 | return SVC_DENIED; | 843 | return SVC_DENIED; |