|
@@ -881,6 +881,24 @@ out:
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
+static int fill_in_write_vector(struct kvec *vec, struct nfsd4_write *write)
|
|
|
+{
|
|
|
+ int i = 1;
|
|
|
+ int buflen = write->wr_buflen;
|
|
|
+
|
|
|
+ vec[0].iov_base = write->wr_head.iov_base;
|
|
|
+ vec[0].iov_len = min_t(int, buflen, write->wr_head.iov_len);
|
|
|
+ buflen -= vec[0].iov_len;
|
|
|
+
|
|
|
+ while (buflen) {
|
|
|
+ vec[i].iov_base = page_address(write->wr_pagelist[i - 1]);
|
|
|
+ vec[i].iov_len = min_t(int, PAGE_SIZE, buflen);
|
|
|
+ buflen -= vec[i].iov_len;
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ return i;
|
|
|
+}
|
|
|
+
|
|
|
static __be32
|
|
|
nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
|
|
struct nfsd4_write *write)
|
|
@@ -889,6 +907,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
|
|
struct file *filp = NULL;
|
|
|
__be32 status = nfs_ok;
|
|
|
unsigned long cnt;
|
|
|
+ int nvecs;
|
|
|
|
|
|
/* no need to check permission - this will be done in nfsd_write() */
|
|
|
|
|
@@ -911,8 +930,11 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
|
|
|
write->wr_how_written = write->wr_stable_how;
|
|
|
gen_boot_verifier(&write->wr_verifier);
|
|
|
|
|
|
+ nvecs = fill_in_write_vector(rqstp->rq_vec, write);
|
|
|
+ WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec));
|
|
|
+
|
|
|
status = nfsd_write(rqstp, &cstate->current_fh, filp,
|
|
|
- write->wr_offset, rqstp->rq_vec, write->wr_vlen,
|
|
|
+ write->wr_offset, rqstp->rq_vec, nvecs,
|
|
|
&cnt, &write->wr_how_written);
|
|
|
if (filp)
|
|
|
fput(filp);
|