aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfsd/nfs4xdr.c
diff options
context:
space:
mode:
authorAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
committerAndrea Bastoni <bastoni@cs.unc.edu>2010-05-30 19:16:45 -0400
commitada47b5fe13d89735805b566185f4885f5a3f750 (patch)
tree644b88f8a71896307d71438e9b3af49126ffb22b /fs/nfsd/nfs4xdr.c
parent43e98717ad40a4ae64545b5ba047c7b86aa44f4f (diff)
parent3280f21d43ee541f97f8cda5792150d2dbec20d5 (diff)
Merge branch 'wip-2.6.34' into old-private-masterarchived-private-master
Diffstat (limited to 'fs/nfsd/nfs4xdr.c')
-rw-r--r--fs/nfsd/nfs4xdr.c51
1 files changed, 27 insertions, 24 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 0fbd50cee1f6..34ccf815ea8a 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -40,24 +40,17 @@
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> 43#include <linux/slab.h>
44#include <linux/smp.h>
45#include <linux/fs.h>
46#include <linux/namei.h> 44#include <linux/namei.h>
47#include <linux/vfs.h> 45#include <linux/statfs.h>
48#include <linux/utsname.h> 46#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> 47#include <linux/nfsd_idmap.h>
56#include <linux/nfs4.h>
57#include <linux/nfs4_acl.h> 48#include <linux/nfs4_acl.h>
58#include <linux/sunrpc/gss_api.h>
59#include <linux/sunrpc/svcauth_gss.h> 49#include <linux/sunrpc/svcauth_gss.h>
60 50
51#include "xdr4.h"
52#include "vfs.h"
53
61#define NFSDDBG_FACILITY NFSDDBG_XDR 54#define NFSDDBG_FACILITY NFSDDBG_XDR
62 55
63/* 56/*
@@ -168,10 +161,10 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
168 argp->p = page_address(argp->pagelist[0]); 161 argp->p = page_address(argp->pagelist[0]);
169 argp->pagelist++; 162 argp->pagelist++;
170 if (argp->pagelen < PAGE_SIZE) { 163 if (argp->pagelen < PAGE_SIZE) {
171 argp->end = p + (argp->pagelen>>2); 164 argp->end = argp->p + (argp->pagelen>>2);
172 argp->pagelen = 0; 165 argp->pagelen = 0;
173 } else { 166 } else {
174 argp->end = p + (PAGE_SIZE>>2); 167 argp->end = argp->p + (PAGE_SIZE>>2);
175 argp->pagelen -= PAGE_SIZE; 168 argp->pagelen -= PAGE_SIZE;
176 } 169 }
177 memcpy(((char*)p)+avail, argp->p, (nbytes - avail)); 170 memcpy(((char*)p)+avail, argp->p, (nbytes - avail));
@@ -1433,16 +1426,16 @@ nfsd4_decode_compound(struct nfsd4_compoundargs *argp)
1433 argp->p = page_address(argp->pagelist[0]); 1426 argp->p = page_address(argp->pagelist[0]);
1434 argp->pagelist++; 1427 argp->pagelist++;
1435 if (argp->pagelen < PAGE_SIZE) { 1428 if (argp->pagelen < PAGE_SIZE) {
1436 argp->end = p + (argp->pagelen>>2); 1429 argp->end = argp->p + (argp->pagelen>>2);
1437 argp->pagelen = 0; 1430 argp->pagelen = 0;
1438 } else { 1431 } else {
1439 argp->end = p + (PAGE_SIZE>>2); 1432 argp->end = argp->p + (PAGE_SIZE>>2);
1440 argp->pagelen -= PAGE_SIZE; 1433 argp->pagelen -= PAGE_SIZE;
1441 } 1434 }
1442 } 1435 }
1443 op->opnum = ntohl(*argp->p++); 1436 op->opnum = ntohl(*argp->p++);
1444 1437
1445 if (op->opnum >= OP_ACCESS && op->opnum < ops->nops) 1438 if (op->opnum >= FIRST_NFS4_OP && op->opnum <= LAST_NFS4_OP)
1446 op->status = ops->decoders[op->opnum](argp, &op->u); 1439 op->status = ops->decoders[op->opnum](argp, &op->u);
1447 else { 1440 else {
1448 op->opnum = OP_ILLEGAL; 1441 op->opnum = OP_ILLEGAL;
@@ -1536,7 +1529,7 @@ static void write_cinfo(__be32 **p, struct nfsd4_change_info *c)
1536 } } while (0); 1529 } } while (0);
1537 1530
1538/* Encode as an array of strings the string given with components 1531/* Encode as an array of strings the string given with components
1539 * seperated @sep. 1532 * separated @sep.
1540 */ 1533 */
1541static __be32 nfsd4_encode_components(char sep, char *components, 1534static __be32 nfsd4_encode_components(char sep, char *components,
1542 __be32 **pp, int *buflen) 1535 __be32 **pp, int *buflen)
@@ -2129,9 +2122,15 @@ out_acl:
2129 * and this is the root of a cross-mounted filesystem. 2122 * and this is the root of a cross-mounted filesystem.
2130 */ 2123 */
2131 if (ignore_crossmnt == 0 && 2124 if (ignore_crossmnt == 0 &&
2132 exp->ex_path.mnt->mnt_root->d_inode == dentry->d_inode) { 2125 dentry == exp->ex_path.mnt->mnt_root) {
2133 err = vfs_getattr(exp->ex_path.mnt->mnt_parent, 2126 struct path path = exp->ex_path;
2134 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);
2135 if (err) 2134 if (err)
2136 goto out_nfserr; 2135 goto out_nfserr;
2137 } 2136 }
@@ -2204,11 +2203,14 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
2204 * we will not follow the cross mount and will fill the attribtutes 2203 * we will not follow the cross mount and will fill the attribtutes
2205 * directly from the mountpoint dentry. 2204 * directly from the mountpoint dentry.
2206 */ 2205 */
2207 if (d_mountpoint(dentry) && !attributes_need_mount(cd->rd_bmval)) 2206 if (nfsd_mountpoint(dentry, exp)) {
2208 ignore_crossmnt = 1;
2209 else if (d_mountpoint(dentry)) {
2210 int err; 2207 int err;
2211 2208
2209 if (!(exp->ex_flags & NFSEXP_V4ROOT)
2210 && !attributes_need_mount(cd->rd_bmval)) {
2211 ignore_crossmnt = 1;
2212 goto out_encode;
2213 }
2212 /* 2214 /*
2213 * Why the heck aren't we just using nfsd_lookup?? 2215 * Why the heck aren't we just using nfsd_lookup??
2214 * Different "."/".." handling? Something else? 2216 * Different "."/".." handling? Something else?
@@ -2224,6 +2226,7 @@ nfsd4_encode_dirent_fattr(struct nfsd4_readdir *cd,
2224 goto out_put; 2226 goto out_put;
2225 2227
2226 } 2228 }
2229out_encode:
2227 nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval, 2230 nfserr = nfsd4_encode_fattr(NULL, exp, dentry, p, buflen, cd->rd_bmval,
2228 cd->rd_rqstp, ignore_crossmnt); 2231 cd->rd_rqstp, ignore_crossmnt);
2229out_put: 2232out_put: