]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/nfsd/nfs4xdr.c
Merge branch 'for-5.5/whiskers' into for-linus
[linux.git] / fs / nfsd / nfs4xdr.c
index 442811809f3dbf02eadce650678cac140b829ba0..533d0fc3c96b8fa43c2465489d00ab8f326085e0 100644 (file)
@@ -49,6 +49,7 @@
 #include "cache.h"
 #include "netns.h"
 #include "pnfs.h"
+#include "filecache.h"
 
 #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
 #include <linux/security.h>
@@ -203,6 +204,13 @@ static __be32 *read_buf(struct nfsd4_compoundargs *argp, u32 nbytes)
        return p;
 }
 
+static unsigned int compoundargs_bytes_left(struct nfsd4_compoundargs *argp)
+{
+       unsigned int this = (char *)argp->end - (char *)argp->p;
+
+       return this + argp->pagelen;
+}
+
 static int zero_clientid(clientid_t *clid)
 {
        return (clid->cl_boot == 0) && (clid->cl_id == 0);
@@ -211,10 +219,10 @@ static int zero_clientid(clientid_t *clid)
 /**
  * svcxdr_tmpalloc - allocate memory to be freed after compound processing
  * @argp: NFSv4 compound argument structure
- * @p: pointer to be freed (with kfree())
+ * @len: length of buffer to allocate
  *
- * Marks @p to be freed when processing the compound operation
- * described in @argp finishes.
+ * Allocates a buffer of size @len to be freed when processing the compound
+ * operation described in @argp finishes.
  */
 static void *
 svcxdr_tmpalloc(struct nfsd4_compoundargs *argp, u32 len)
@@ -347,7 +355,12 @@ nfsd4_decode_fattr(struct nfsd4_compoundargs *argp, u32 *bmval,
                READ_BUF(4); len += 4;
                nace = be32_to_cpup(p++);
 
-               if (nace > NFS4_ACL_MAX)
+               if (nace > compoundargs_bytes_left(argp)/20)
+                       /*
+                        * Even with 4-byte names there wouldn't be
+                        * space for that many aces; something fishy is
+                        * going on:
+                        */
                        return nfserr_fbig;
 
                *acl = svcxdr_tmpalloc(argp, nfs4_acl_bytes(nace));
@@ -1418,7 +1431,6 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
                            struct nfsd4_create_session *sess)
 {
        DECODE_HEAD;
-       u32 dummy;
 
        READ_BUF(16);
        COPYMEM(&sess->clientid, 8);
@@ -1427,7 +1439,7 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
 
        /* Fore channel attrs */
        READ_BUF(28);
-       dummy = be32_to_cpup(p++); /* headerpadsz is always 0 */
+       p++; /* headerpadsz is always 0 */
        sess->fore_channel.maxreq_sz = be32_to_cpup(p++);
        sess->fore_channel.maxresp_sz = be32_to_cpup(p++);
        sess->fore_channel.maxresp_cached = be32_to_cpup(p++);
@@ -1444,7 +1456,7 @@ nfsd4_decode_create_session(struct nfsd4_compoundargs *argp,
 
        /* Back channel attrs */
        READ_BUF(28);
-       dummy = be32_to_cpup(p++); /* headerpadsz is always 0 */
+       p++; /* headerpadsz is always 0 */
        sess->back_channel.maxreq_sz = be32_to_cpup(p++);
        sess->back_channel.maxresp_sz = be32_to_cpup(p++);
        sess->back_channel.maxresp_cached = be32_to_cpup(p++);
@@ -1736,7 +1748,6 @@ static __be32
 nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
 {
        DECODE_HEAD;
-       unsigned int tmp;
 
        status = nfsd4_decode_stateid(argp, &copy->cp_src_stateid);
        if (status)
@@ -1751,7 +1762,7 @@ nfsd4_decode_copy(struct nfsd4_compoundargs *argp, struct nfsd4_copy *copy)
        p = xdr_decode_hyper(p, &copy->cp_count);
        p++; /* ca_consecutive: we always do consecutive copies */
        copy->cp_synchronous = be32_to_cpup(p++);
-       tmp = be32_to_cpup(p); /* Source server list not supported */
+       /* tmp = be32_to_cpup(p); Source server list not supported */
 
        DECODE_TAIL;
 }
@@ -3217,9 +3228,8 @@ nfsd4_encode_create(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_
        if (!p)
                return nfserr_resource;
        encode_cinfo(p, &create->cr_cinfo);
-       nfserr = nfsd4_encode_bitmap(xdr, create->cr_bmval[0],
+       return nfsd4_encode_bitmap(xdr, create->cr_bmval[0],
                        create->cr_bmval[1], create->cr_bmval[2]);
-       return 0;
 }
 
 static __be32
@@ -3462,7 +3472,7 @@ static __be32 nfsd4_encode_splice_read(
 
        len = maxcount;
        nfserr = nfsd_splice_read(read->rd_rqstp, read->rd_fhp,
-                                 file, read->rd_offset, &maxcount);
+                                 file, read->rd_offset, &maxcount, &eof);
        read->rd_length = maxcount;
        if (nfserr) {
                /*
@@ -3474,9 +3484,6 @@ static __be32 nfsd4_encode_splice_read(
                return nfserr;
        }
 
-       eof = nfsd_eof_on_read(len, maxcount, read->rd_offset,
-                               d_inode(read->rd_fhp->fh_dentry)->i_size);
-
        *(p++) = htonl(eof);
        *(p++) = htonl(maxcount);
 
@@ -3547,15 +3554,13 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp,
 
        len = maxcount;
        nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset,
-                           resp->rqstp->rq_vec, read->rd_vlen, &maxcount);
+                           resp->rqstp->rq_vec, read->rd_vlen, &maxcount,
+                           &eof);
        read->rd_length = maxcount;
        if (nfserr)
                return nfserr;
        xdr_truncate_encode(xdr, starting_len + 8 + ((maxcount+3)&~3));
 
-       eof = nfsd_eof_on_read(len, maxcount, read->rd_offset,
-                               d_inode(read->rd_fhp->fh_dentry)->i_size);
-
        tmp = htonl(eof);
        write_bytes_to_xdr_buf(xdr->buf, starting_len    , &tmp, 4);
        tmp = htonl(maxcount);
@@ -3574,11 +3579,14 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
 {
        unsigned long maxcount;
        struct xdr_stream *xdr = &resp->xdr;
-       struct file *file = read->rd_filp;
+       struct file *file;
        int starting_len = xdr->buf->len;
-       struct raparms *ra = NULL;
        __be32 *p;
 
+       if (nfserr)
+               return nfserr;
+       file = read->rd_nf->nf_file;
+
        p = xdr_reserve_space(xdr, 8); /* eof flag and byte count */
        if (!p) {
                WARN_ON_ONCE(test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags));
@@ -3596,18 +3604,12 @@ nfsd4_encode_read(struct nfsd4_compoundres *resp, __be32 nfserr,
                         (xdr->buf->buflen - xdr->buf->len));
        maxcount = min_t(unsigned long, maxcount, read->rd_length);
 
-       if (read->rd_tmp_file)
-               ra = nfsd_init_raparms(file);
-
        if (file->f_op->splice_read &&
            test_bit(RQ_SPLICE_OK, &resp->rqstp->rq_flags))
                nfserr = nfsd4_encode_splice_read(resp, read, file, maxcount);
        else
                nfserr = nfsd4_encode_readv(resp, read, file, maxcount);
 
-       if (ra)
-               nfsd_put_raparams(file, ra);
-
        if (nfserr)
                xdr_truncate_encode(xdr, starting_len);