]> Git Repo - linux.git/blobdiff - fs/nfsd/nfs3xdr.c
nfsd: allow nfsv3 readdir request to be larger.
[linux.git] / fs / nfsd / nfs3xdr.c
index 3192b544a441506567423dc3b92c0200a76b80cf..93fea246f676ebec32213bbf3a023ea395fc01a3 100644 (file)
@@ -165,6 +165,7 @@ static __be32 *
 encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
              struct kstat *stat)
 {
+       struct timespec ts;
        *p++ = htonl(nfs3_ftypes[(stat->mode & S_IFMT) >> 12]);
        *p++ = htonl((u32) (stat->mode & S_IALLUGO));
        *p++ = htonl((u32) stat->nlink);
@@ -180,9 +181,12 @@ encode_fattr3(struct svc_rqst *rqstp, __be32 *p, struct svc_fh *fhp,
        *p++ = htonl((u32) MINOR(stat->rdev));
        p = encode_fsid(p, fhp);
        p = xdr_encode_hyper(p, stat->ino);
-       p = encode_time3(p, &stat->atime);
-       p = encode_time3(p, &stat->mtime);
-       p = encode_time3(p, &stat->ctime);
+       ts = timespec64_to_timespec(stat->atime);
+       p = encode_time3(p, &ts);
+       ts = timespec64_to_timespec(stat->mtime);
+       p = encode_time3(p, &ts);
+       ts = timespec64_to_timespec(stat->ctime);
+       p = encode_time3(p, &ts);
 
        return p;
 }
@@ -271,8 +275,8 @@ void fill_pre_wcc(struct svc_fh *fhp)
                stat.size  = inode->i_size;
        }
 
-       fhp->fh_pre_mtime = stat.mtime;
-       fhp->fh_pre_ctime = stat.ctime;
+       fhp->fh_pre_mtime = timespec64_to_timespec(stat.mtime);
+       fhp->fh_pre_ctime = timespec64_to_timespec(stat.ctime);
        fhp->fh_pre_size  = stat.size;
        fhp->fh_pre_change = nfsd4_change_attribute(&stat, inode);
        fhp->fh_pre_saved = true;
@@ -569,6 +573,8 @@ int
 nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)
 {
        struct nfsd3_readdirargs *args = rqstp->rq_argp;
+       u32 max_blocksize = svc_max_payload(rqstp);
+
        p = decode_fh(p, &args->fh);
        if (!p)
                return 0;
@@ -576,7 +582,7 @@ nfs3svc_decode_readdirargs(struct svc_rqst *rqstp, __be32 *p)
        args->verf   = p; p += 2;
        args->dircount = ~0;
        args->count  = ntohl(*p++);
-       args->count  = min_t(u32, args->count, PAGE_SIZE);
+       args->count  = min_t(u32, args->count, max_blocksize);
        args->buffer = page_address(*(rqstp->rq_next_page++));
 
        return xdr_argsize_check(rqstp, p);
@@ -917,6 +923,7 @@ encode_entry(struct readdir_cd *ccd, const char *name, int namlen,
                } else {
                        xdr_encode_hyper(cd->offset, offset64);
                }
+               cd->offset = NULL;
        }
 
        /*
This page took 0.03431 seconds and 4 git commands to generate.