Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions fs/nfsd/blocklayout.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ nfsd4_block_get_device_info_scsi(struct super_block *sb,

out_free_dev:
kfree(dev);
gdp->gd_device = NULL;
return ret;
}

Expand Down
7 changes: 4 additions & 3 deletions fs/nfsd/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -961,10 +961,11 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
static void
nfsd4_read_release(union nfsd4_op_u *u)
{
if (u->read.rd_nf)
if (u->read.rd_nf) {
trace_nfsd_read_done(u->read.rd_rqstp, u->read.rd_fhp,
u->read.rd_offset, u->read.rd_length);
nfsd_file_put(u->read.rd_nf);
trace_nfsd_read_done(u->read.rd_rqstp, u->read.rd_fhp,
u->read.rd_offset, u->read.rd_length);
}
}

static __be32
Expand Down
20 changes: 12 additions & 8 deletions fs/nfsd/nfs4xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -5312,10 +5312,8 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
__be32 *p;

p = xdr_reserve_space(xdr, 8);
if (!p) {
WARN_ON_ONCE(1);
return;
}
if (!p)
goto release;
*p++ = cpu_to_be32(op->opnum);
post_err_offset = xdr->buf->len;

Expand All @@ -5330,8 +5328,6 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
op->status = encoder(resp, op->status, &op->u);
if (op->status)
trace_nfsd_compound_encode_err(rqstp, op->opnum, op->status);
if (opdesc && opdesc->op_release)
opdesc->op_release(&op->u);
xdr_commit_encode(xdr);

/* nfsd4_check_resp_size guarantees enough room for error status */
Expand Down Expand Up @@ -5366,12 +5362,20 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op)
int len = xdr->buf->len - post_err_offset;

so->so_replay.rp_status = op->status;
so->so_replay.rp_buflen = len;
read_bytes_from_xdr_buf(xdr->buf, post_err_offset,
if (len <= NFSD4_REPLAY_ISIZE) {
so->so_replay.rp_buflen = len;
read_bytes_from_xdr_buf(xdr->buf,
post_err_offset,
so->so_replay.rp_buf, len);
} else {
so->so_replay.rp_buflen = 0;
}
}
status:
*p = op->status;
release:
if (opdesc && opdesc->op_release)
opdesc->op_release(&op->u);
}

/*
Expand Down
17 changes: 12 additions & 5 deletions fs/nfsd/state.h
Original file line number Diff line number Diff line change
Expand Up @@ -399,11 +399,18 @@ struct nfs4_client_reclaim {
struct xdr_netobj cr_princhash;
};

/* A reasonable value for REPLAY_ISIZE was estimated as follows:
* The OPEN response, typically the largest, requires
* 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) + 8(verifier) +
* 4(deleg. type) + 8(deleg. stateid) + 4(deleg. recall flag) +
* 20(deleg. space limit) + ~32(deleg. ace) = 112 bytes
/*
* REPLAY_ISIZE is sized for an OPEN response with delegation:
* 4(status) + 8(stateid) + 20(changeinfo) + 4(rflags) +
* 8(verifier) + 4(deleg. type) + 8(deleg. stateid) +
* 4(deleg. recall flag) + 20(deleg. space limit) +
* ~32(deleg. ace) = 112 bytes
*
* Some responses can exceed this. A LOCK denial includes the conflicting
* lock owner, which can be up to 1024 bytes (NFS4_OPAQUE_LIMIT). Responses
* larger than REPLAY_ISIZE are not cached in rp_ibuf; only rp_status is
* saved. Enlarging this constant increases the size of every
* nfs4_stateowner.
*/

#define NFSD4_REPLAY_ISIZE 112
Expand Down