nfsd: fix failure to set eof in readdir in some situations
[safe/jmp/linux-2.6] / fs / nfsd / nfs3proc.c
index a12663f..9dbd2eb 100644 (file)
@@ -56,17 +56,19 @@ static __be32
 nfsd3_proc_getattr(struct svc_rqst *rqstp, struct nfsd_fhandle  *argp,
                                           struct nfsd3_attrstat *resp)
 {
-       int     err, nfserr;
+       int     err;
+       __be32  nfserr;
 
        dprintk("nfsd: GETATTR(3)  %s\n",
                SVCFH_fmt(&argp->fh));
 
        fh_copy(&resp->fh, &argp->fh);
-       nfserr = fh_verify(rqstp, &resp->fh, 0, MAY_NOP);
+       nfserr = fh_verify(rqstp, &resp->fh, 0,
+                       NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
        if (nfserr)
                RETURN_STATUS(nfserr);
 
-       err = vfs_getattr(resp->fh.fh_export->ex_mnt,
+       err = vfs_getattr(resp->fh.fh_export->ex_path.mnt,
                          resp->fh.fh_dentry, &resp->stat);
        nfserr = nfserrno(err);
 
@@ -80,7 +82,7 @@ static __be32
 nfsd3_proc_setattr(struct svc_rqst *rqstp, struct nfsd3_sattrargs *argp,
                                           struct nfsd3_attrstat  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: SETATTR(3)  %s\n",
                                SVCFH_fmt(&argp->fh));
@@ -98,7 +100,7 @@ static __be32
 nfsd3_proc_lookup(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
                                          struct nfsd3_diropres  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: LOOKUP(3)   %s %.*s\n",
                                SVCFH_fmt(&argp->fh),
@@ -122,7 +124,7 @@ static __be32
 nfsd3_proc_access(struct svc_rqst *rqstp, struct nfsd3_accessargs *argp,
                                          struct nfsd3_accessres *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: ACCESS(3)   %s 0x%x\n",
                                SVCFH_fmt(&argp->fh),
@@ -141,7 +143,7 @@ static __be32
 nfsd3_proc_readlink(struct svc_rqst *rqstp, struct nfsd3_readlinkargs *argp,
                                           struct nfsd3_readlinkres *resp)
 {
-       int nfserr;
+       __be32 nfserr;
 
        dprintk("nfsd: READLINK(3) %s\n", SVCFH_fmt(&argp->fh));
 
@@ -159,7 +161,7 @@ static __be32
 nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
                                        struct nfsd3_readres  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
        u32     max_blocksize = svc_max_payload(rqstp);
 
        dprintk("nfsd: READ(3) %s %lu bytes at %lu\n",
@@ -176,7 +178,7 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp,
        if (max_blocksize < resp->count)
                resp->count = max_blocksize;
 
-       svc_reserve(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + resp->count +4);
+       svc_reserve_auth(rqstp, ((1 + NFS3_POST_OP_ATTR_WORDS + 3)<<2) + resp->count +4);
 
        fh_copy(&resp->fh, &argp->fh);
        nfserr = nfsd_read(rqstp, &resp->fh, NULL,
@@ -199,7 +201,7 @@ static __be32
 nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp,
                                         struct nfsd3_writeres  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: WRITE(3)    %s %d bytes at %ld%s\n",
                                SVCFH_fmt(&argp->fh),
@@ -229,7 +231,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
 {
        svc_fh          *dirfhp, *newfhp = NULL;
        struct iattr    *attr;
-       u32             nfserr;
+       __be32          nfserr;
 
        dprintk("nfsd: CREATE(3)   %s %.*s\n",
                                SVCFH_fmt(&argp->fh),
@@ -241,7 +243,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
        attr   = &argp->attrs;
 
        /* Get the directory inode */
-       nfserr = fh_verify(rqstp, dirfhp, S_IFDIR, MAY_CREATE);
+       nfserr = fh_verify(rqstp, dirfhp, S_IFDIR, NFSD_MAY_CREATE);
        if (nfserr)
                RETURN_STATUS(nfserr);
 
@@ -257,7 +259,7 @@ nfsd3_proc_create(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
        /* Now create the file and set attributes */
        nfserr = nfsd_create_v3(rqstp, dirfhp, argp->name, argp->len,
                                attr, newfhp,
-                               argp->createmode, argp->verf, NULL);
+                               argp->createmode, argp->verf, NULL, NULL);
 
        RETURN_STATUS(nfserr);
 }
@@ -269,7 +271,7 @@ static __be32
 nfsd3_proc_mkdir(struct svc_rqst *rqstp, struct nfsd3_createargs *argp,
                                         struct nfsd3_diropres   *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: MKDIR(3)    %s %.*s\n",
                                SVCFH_fmt(&argp->fh),
@@ -289,7 +291,7 @@ static __be32
 nfsd3_proc_symlink(struct svc_rqst *rqstp, struct nfsd3_symlinkargs *argp,
                                           struct nfsd3_diropres    *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: SYMLINK(3)  %s %.*s -> %.*s\n",
                                SVCFH_fmt(&argp->ffh),
@@ -311,7 +313,8 @@ static __be32
 nfsd3_proc_mknod(struct svc_rqst *rqstp, struct nfsd3_mknodargs *argp,
                                         struct nfsd3_diropres  *resp)
 {
-       int     nfserr, type;
+       __be32  nfserr;
+       int type;
        dev_t   rdev = 0;
 
        dprintk("nfsd: MKNOD(3)    %s %.*s\n",
@@ -347,7 +350,7 @@ static __be32
 nfsd3_proc_remove(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
                                          struct nfsd3_attrstat  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: REMOVE(3)   %s %.*s\n",
                                SVCFH_fmt(&argp->fh),
@@ -367,7 +370,7 @@ static __be32
 nfsd3_proc_rmdir(struct svc_rqst *rqstp, struct nfsd3_diropargs *argp,
                                         struct nfsd3_attrstat  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: RMDIR(3)    %s %.*s\n",
                                SVCFH_fmt(&argp->fh),
@@ -383,7 +386,7 @@ static __be32
 nfsd3_proc_rename(struct svc_rqst *rqstp, struct nfsd3_renameargs *argp,
                                          struct nfsd3_renameres  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: RENAME(3)   %s %.*s ->\n",
                                SVCFH_fmt(&argp->ffh),
@@ -405,7 +408,7 @@ static __be32
 nfsd3_proc_link(struct svc_rqst *rqstp, struct nfsd3_linkargs *argp,
                                        struct nfsd3_linkres  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: LINK(3)     %s ->\n",
                                SVCFH_fmt(&argp->ffh));
@@ -428,7 +431,8 @@ static __be32
 nfsd3_proc_readdir(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
                                           struct nfsd3_readdirres  *resp)
 {
-       int             nfserr, count;
+       __be32          nfserr;
+       int             count;
 
        dprintk("nfsd: READDIR(3)  %s %d bytes at %d\n",
                                SVCFH_fmt(&argp->fh),
@@ -463,7 +467,8 @@ static __be32
 nfsd3_proc_readdirplus(struct svc_rqst *rqstp, struct nfsd3_readdirargs *argp,
                                               struct nfsd3_readdirres  *resp)
 {
-       int     nfserr, count = 0;
+       __be32  nfserr;
+       int     count = 0;
        loff_t  offset;
        int     i;
        caddr_t page_addr = NULL;
@@ -521,12 +526,12 @@ static __be32
 nfsd3_proc_fsstat(struct svc_rqst * rqstp, struct nfsd_fhandle    *argp,
                                           struct nfsd3_fsstatres *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: FSSTAT(3)   %s\n",
                                SVCFH_fmt(&argp->fh));
 
-       nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats);
+       nfserr = nfsd_statfs(rqstp, &argp->fh, &resp->stats, 0);
        fh_put(&argp->fh);
        RETURN_STATUS(nfserr);
 }
@@ -538,7 +543,7 @@ static __be32
 nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle    *argp,
                                           struct nfsd3_fsinfores *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
        u32     max_blocksize = svc_max_payload(rqstp);
 
        dprintk("nfsd: FSINFO(3)   %s\n",
@@ -554,7 +559,8 @@ nfsd3_proc_fsinfo(struct svc_rqst * rqstp, struct nfsd_fhandle    *argp,
        resp->f_maxfilesize = ~(u32) 0;
        resp->f_properties = NFS3_FSF_DEFAULT;
 
-       nfserr = fh_verify(rqstp, &argp->fh, 0, MAY_NOP);
+       nfserr = fh_verify(rqstp, &argp->fh, 0,
+                       NFSD_MAY_NOP | NFSD_MAY_BYPASS_GSS_ON_ROOT);
 
        /* Check special features of the file system. May request
         * different read/write sizes for file systems known to have
@@ -580,7 +586,7 @@ static __be32
 nfsd3_proc_pathconf(struct svc_rqst * rqstp, struct nfsd_fhandle      *argp,
                                             struct nfsd3_pathconfres *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: PATHCONF(3) %s\n",
                                SVCFH_fmt(&argp->fh));
@@ -593,7 +599,7 @@ nfsd3_proc_pathconf(struct svc_rqst * rqstp, struct nfsd_fhandle      *argp,
        resp->p_case_insensitive = 0;
        resp->p_case_preserving = 1;
 
-       nfserr = fh_verify(rqstp, &argp->fh, 0, MAY_NOP);
+       nfserr = fh_verify(rqstp, &argp->fh, 0, NFSD_MAY_NOP);
 
        if (nfserr == 0) {
                struct super_block *sb = argp->fh.fh_dentry->d_inode->i_sb;
@@ -623,7 +629,7 @@ static __be32
 nfsd3_proc_commit(struct svc_rqst * rqstp, struct nfsd3_commitargs *argp,
                                           struct nfsd3_commitres  *resp)
 {
-       int     nfserr;
+       __be32  nfserr;
 
        dprintk("nfsd: COMMIT(3)   %s %u@%Lu\n",
                                SVCFH_fmt(&argp->fh),