Skip to content

Commit 6a2f774

Browse files
committed
NFSD: Fix zero-length NFSv3 WRITEs
The Linux NFS server currently responds to a zero-length NFSv3 WRITE request with NFS3ERR_IO. It responds to a zero-length NFSv4 WRITE with NFS4_OK and count of zero. RFC 1813 says of the WRITE procedure's @count argument: count The number of bytes of data to be written. If count is 0, the WRITE will succeed and return a count of 0, barring errors due to permissions checking. RFC 8881 has similar language for NFSv4, though NFSv4 removed the explicit @count argument because that value is already contained in the opaque payload array. The synthetic client pynfs's WRT4 and WRT15 tests do emit zero- length WRITEs to exercise this spec requirement. Commit fdec611 ("nfsd4: zero-length WRITE should succeed") addressed the same problem there with the same fix. But interestingly the Linux NFS client does not appear to emit zero- length WRITEs, instead squelching them. I'm not aware of a test that can generate such WRITEs for NFSv3, so I wrote a naive C program to generate a zero-length WRITE and test this fix. Fixes: 8154ef2 ("NFSD: Clean up legacy NFS WRITE argument XDR decoders") Reported-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Cc: stable@vger.kernel.org Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
1 parent 47446d7 commit 6a2f774

File tree

2 files changed

+1
-10
lines changed

2 files changed

+1
-10
lines changed

fs/nfsd/nfs3proc.c

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -202,15 +202,11 @@ nfsd3_proc_write(struct svc_rqst *rqstp)
202202
fh_copy(&resp->fh, &argp->fh);
203203
resp->committed = argp->stable;
204204
nvecs = svc_fill_write_vector(rqstp, &argp->payload);
205-
if (!nvecs) {
206-
resp->status = nfserr_io;
207-
goto out;
208-
}
205+
209206
resp->status = nfsd_write(rqstp, &resp->fh, argp->offset,
210207
rqstp->rq_vec, nvecs, &cnt,
211208
resp->committed, resp->verf);
212209
resp->count = cnt;
213-
out:
214210
return rpc_success;
215211
}
216212

fs/nfsd/nfsproc.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -235,10 +235,6 @@ nfsd_proc_write(struct svc_rqst *rqstp)
235235
argp->len, argp->offset);
236236

237237
nvecs = svc_fill_write_vector(rqstp, &argp->payload);
238-
if (!nvecs) {
239-
resp->status = nfserr_io;
240-
goto out;
241-
}
242238

243239
resp->status = nfsd_write(rqstp, fh_copy(&resp->fh, &argp->fh),
244240
argp->offset, rqstp->rq_vec, nvecs,
@@ -247,7 +243,6 @@ nfsd_proc_write(struct svc_rqst *rqstp)
247243
resp->status = fh_getattr(&resp->fh, &resp->stat);
248244
else if (resp->status == nfserr_jukebox)
249245
return rpc_drop_reply;
250-
out:
251246
return rpc_success;
252247
}
253248

0 commit comments

Comments
 (0)