aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4xdr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r--fs/nfsd/nfs4xdr.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index a8587e90fd5a..34ccf815ea8a 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -40,6 +40,7 @@
40 * at the end of nfs4svc_decode_compoundargs. 40 * at the end of nfs4svc_decode_compoundargs.
41 */ 41 */
42 42
43#include <linux/slab.h>
43#include <linux/namei.h> 44#include <linux/namei.h>
44#include <linux/statfs.h> 45#include <linux/statfs.h>
45#include <linux/utsname.h> 46#include <linux/utsname.h>
@@ -160,10 +161,10 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
160 argp->p = page_address(argp->pagelist[0]); 161 argp->p = page_address(argp->pagelist[0]);
161 argp->pagelist++; 162 argp->pagelist++;
162 if (argp->pagelen < PAGE_SIZE) { 163 if (argp->pagelen < PAGE_SIZE) {
163 argp->end = p + (argp->pagelen>>2); 164 argp->end = argp->p + (argp->pagelen>>2);
164 argp->pagelen = 0; 165 argp->pagelen = 0;
165 } else { 166 } else {
166 argp->end = p + (PAGE_SIZE>>2); 167 argp->end = argp->p + (PAGE_SIZE>>2);
167 argp->pagelen -= PAGE_SIZE; 168 argp->pagelen -= PAGE_SIZE;
168 } 169 }
169 memcpy(((char*)p)+avail, argp->p, (nbytes - avail)); 170 memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
@@ -1425,16 +1426,16 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1425 argp->p = page_address(argp->pagelist[0]); 1426 argp->p = page_address(argp->pagelist[0]);
1426 argp->pagelist++; 1427 argp->pagelist++;
1427 if (argp->pagelen < PAGE_SIZE) { 1428 if (argp->pagelen < PAGE_SIZE) {
1428 argp->end = p + (argp->pagelen>>2); 1429 argp->end = argp->p + (argp->pagelen>>2);
1429 argp->pagelen = 0; 1430 argp->pagelen = 0;
1430 } else { 1431 } else {
1431 argp->end = p + (PAGE_SIZE>>2); 1432 argp->end = argp->p + (PAGE_SIZE>>2);
1432 argp->pagelen -= PAGE_SIZE; 1433 argp->pagelen -= PAGE_SIZE;
1433 } 1434 }
1434 } 1435 }
1435 op->opnum = ntohl(*argp->p++); 1436 op->opnum = ntohl(*argp->p++);
1436 1437
1437 if (op->opnum >= OP_ACCESS && op->opnum < ops->nops) 1438 if (op->opnum >= FIRST_NFS4_OP && op->opnum <= LAST_NFS4_OP)
1438 op->status = ops->decoders[op->opnum](argp, &op->u); 1439 op->status = ops->decoders[op->opnum](argp, &op->u);
1439 else { 1440 else {
1440 op->opnum = OP_ILLEGAL; 1441 op->opnum = OP_ILLEGAL;
@@ -1528,7 +1529,7 @@ static void write_cinfo(__be32 **p, struct nfsd4_change_info *c)
1528 } } while (0); 1529 } } while (0);
1529 1530
1530/* Encode as an array of strings the string given with components 1531/* Encode as an array of strings the string given with components
1531 * seperated @sep. 1532 * separated @sep.
1532 */ 1533 */
1533static __be32 nfsd4_encode_components(char sep, char *components, 1534static __be32 nfsd4_encode_components(char sep, char *components,
1534 __be32 **pp, int *buflen) 1535 __be32 **pp, int *buflen)
@@ -2121,9 +2122,15 @@ out_acl:
2121 * and this is the root of a cross-mounted filesystem. 2122 * and this is the root of a cross-mounted filesystem.
2122 */ 2123 */
2123 if (ignore_crossmnt == 0 && 2124 if (ignore_crossmnt == 0 &&
2124 exp->ex_path.mnt->mnt_root->d_inode == dentry->d_inode) { 2125 dentry == exp->ex_path.mnt->mnt_root) {
2125 err = vfs_getattr(exp->ex_path.mnt->mnt_parent, 2126 struct path path = exp->ex_path;
2126 exp->ex_path.mnt->mnt_mountpoint, &stat); 2127 path_get(&path);
2128 while (follow_up(&path)) {
2129 if (path.dentry != path.mnt->mnt_root)
2130 break;
2131 }
2132 err = vfs_getattr(path.mnt, path.dentry, &stat);
2133 path_put(&path);
2127 if (err) 2134 if (err)
2128 goto out_nfserr; 2135 goto out_nfserr;
2129 } 2136 }