Skip to content

Commit

Permalink
Merge tag 'nfsd-4.17' of git://linux-nfs.org/~bfields/linux
Browse files Browse the repository at this point in the history
Pull nfsd updates from Bruce Fields:
 "Chuck Lever did a bunch of work on nfsd tracepoints, on RDMA, and on
  server xdr decoding (with an eye towards eliminating a data copy in
  the RDMA case).

  I did some refactoring of the delegation code in preparation for
  eliminating some delegation self-conflicts and implementing write
  delegations"

* tag 'nfsd-4.17' of git://linux-nfs.org/~bfields/linux: (40 commits)
  nfsd: fix incorrect umasks
  sunrpc: remove incorrect HMAC request initialization
  NFSD: Clean up legacy NFS SYMLINK argument XDR decoders
  NFSD: Clean up legacy NFS WRITE argument XDR decoders
  nfsd: Trace NFSv4 COMPOUND execution
  nfsd: Add I/O trace points in the NFSv4 read proc
  nfsd: Add I/O trace points in the NFSv4 write path
  nfsd: Add "nfsd_" to trace point names
  nfsd: Record request byte count, not count of vectors
  nfsd: Fix NFSD trace points
  svc: Report xprt dequeue latency
  sunrpc: Report per-RPC execution stats
  sunrpc: Re-purpose trace_svc_process
  sunrpc: Save remote presentation address in svc_xprt for trace events
  sunrpc: Simplify trace_svc_recv
  sunrpc: Simplify do_enqueue tracing
  sunrpc: Move trace_svc_xprt_dequeue()
  sunrpc: Update show_svc_xprt_flags() to include recently added flags
  svc: Simplify ->xpo_secure_port
  sunrpc: Remove unneeded pointer dereference
  ...
  • Loading branch information
Linus Torvalds committed Apr 6, 2018
2 parents 274c0e7 + 880a3a5 commit 5e4d659
Show file tree
Hide file tree
Showing 31 changed files with 721 additions and 515 deletions.
4 changes: 2 additions & 2 deletions fs/lockd/svc.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ static struct task_struct *nlmsvc_task;
static struct svc_rqst *nlmsvc_rqst;
unsigned long nlmsvc_timeout;

atomic_t nlm_ntf_refcnt = ATOMIC_INIT(0);
DECLARE_WAIT_QUEUE_HEAD(nlm_ntf_wq);
static atomic_t nlm_ntf_refcnt = ATOMIC_INIT(0);
static DECLARE_WAIT_QUEUE_HEAD(nlm_ntf_wq);

unsigned int lockd_net_id;

Expand Down
18 changes: 16 additions & 2 deletions fs/nfsd/nfs3proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ nfsd3_proc_write(struct svc_rqst *rqstp)
struct nfsd3_writeres *resp = rqstp->rq_resp;
__be32 nfserr;
unsigned long cnt = argp->len;
unsigned int nvecs;

dprintk("nfsd: WRITE(3) %s %d bytes at %Lu%s\n",
SVCFH_fmt(&argp->fh),
Expand All @@ -201,9 +202,12 @@ nfsd3_proc_write(struct svc_rqst *rqstp)

fh_copy(&resp->fh, &argp->fh);
resp->committed = argp->stable;
nvecs = svc_fill_write_vector(rqstp, &argp->first, cnt);
if (!nvecs)
RETURN_STATUS(nfserr_io);
nfserr = nfsd_write(rqstp, &resp->fh, argp->offset,
rqstp->rq_vec, argp->vlen,
&cnt, resp->committed);
rqstp->rq_vec, nvecs, &cnt,
resp->committed);
resp->count = cnt;
RETURN_STATUS(nfserr);
}
Expand Down Expand Up @@ -279,6 +283,16 @@ nfsd3_proc_symlink(struct svc_rqst *rqstp)
struct nfsd3_diropres *resp = rqstp->rq_resp;
__be32 nfserr;

if (argp->tlen == 0)
RETURN_STATUS(nfserr_inval);
if (argp->tlen > NFS3_MAXPATHLEN)
RETURN_STATUS(nfserr_nametoolong);

argp->tname = svc_fill_symlink_pathname(rqstp, &argp->first,
argp->tlen);
if (IS_ERR(argp->tname))
RETURN_STATUS(nfserrno(PTR_ERR(argp->tname)));

dprintk("nfsd: SYMLINK(3) %s %.*s -> %.*s\n",
SVCFH_fmt(&argp->ffh),
argp->flen, argp->fname,
Expand Down
67 changes: 16 additions & 51 deletions fs/nfsd/nfs3xdr.c
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ int
nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
{
struct nfsd3_writeargs *args = rqstp->rq_argp;
unsigned int len, v, hdr, dlen;
unsigned int len, hdr, dlen;
u32 max_blocksize = svc_max_payload(rqstp);
struct kvec *head = rqstp->rq_arg.head;
struct kvec *tail = rqstp->rq_arg.tail;
Expand Down Expand Up @@ -433,17 +433,9 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
args->count = max_blocksize;
len = args->len = max_blocksize;
}
rqstp->rq_vec[0].iov_base = (void*)p;
rqstp->rq_vec[0].iov_len = head->iov_len - hdr;
v = 0;
while (len > rqstp->rq_vec[v].iov_len) {
len -= rqstp->rq_vec[v].iov_len;
v++;
rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_pages[v]);
rqstp->rq_vec[v].iov_len = PAGE_SIZE;
}
rqstp->rq_vec[v].iov_len = len;
args->vlen = v + 1;

args->first.iov_base = (void *)p;
args->first.iov_len = head->iov_len - hdr;
return 1;
}

Expand Down Expand Up @@ -489,51 +481,24 @@ int
nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p)
{
struct nfsd3_symlinkargs *args = rqstp->rq_argp;
unsigned int len, avail;
char *old, *new;
struct kvec *vec;
char *base = (char *)p;
size_t dlen;

if (!(p = decode_fh(p, &args->ffh)) ||
!(p = decode_filename(p, &args->fname, &args->flen))
)
!(p = decode_filename(p, &args->fname, &args->flen)))
return 0;
p = decode_sattr3(p, &args->attrs);

/* now decode the pathname, which might be larger than the first page.
* As we have to check for nul's anyway, we copy it into a new page
* This page appears in the rq_res.pages list, but as pages_len is always
* 0, it won't get in the way
*/
len = ntohl(*p++);
if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE)
return 0;
args->tname = new = page_address(*(rqstp->rq_next_page++));
args->tlen = len;
/* first copy and check from the first page */
old = (char*)p;
vec = &rqstp->rq_arg.head[0];
if ((void *)old > vec->iov_base + vec->iov_len)
return 0;
avail = vec->iov_len - (old - (char*)vec->iov_base);
while (len && avail && *old) {
*new++ = *old++;
len--;
avail--;
}
/* now copy next page if there is one */
if (len && !avail && rqstp->rq_arg.page_len) {
avail = min_t(unsigned int, rqstp->rq_arg.page_len, PAGE_SIZE);
old = page_address(rqstp->rq_arg.pages[0]);
}
while (len && avail && *old) {
*new++ = *old++;
len--;
avail--;
}
*new = '\0';
if (len)
return 0;
args->tlen = ntohl(*p++);

args->first.iov_base = p;
args->first.iov_len = rqstp->rq_arg.head[0].iov_len;
args->first.iov_len -= (char *)p - base;

dlen = args->first.iov_len + rqstp->rq_arg.page_len +
rqstp->rq_arg.tail[0].iov_len;
if (dlen < XDR_QUADLEN(args->tlen) << 2)
return 0;
return 1;
}

Expand Down
4 changes: 2 additions & 2 deletions fs/nfsd/nfs4callback.c
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,8 @@ static int nfs_cb_stat_to_errno(int status)
return -status;
}

static int decode_cb_op_status(struct xdr_stream *xdr, enum nfs_opnum4 expected,
int *status)
static int decode_cb_op_status(struct xdr_stream *xdr,
enum nfs_cb_opnum4 expected, int *status)
{
__be32 *p;
u32 op;
Expand Down
16 changes: 8 additions & 8 deletions fs/nfsd/nfs4layouts.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ nfsd4_free_layout_stateid(struct nfs4_stid *stid)
struct nfs4_client *clp = ls->ls_stid.sc_client;
struct nfs4_file *fp = ls->ls_stid.sc_file;

trace_layoutstate_free(&ls->ls_stid.sc_stateid);
trace_nfsd_layoutstate_free(&ls->ls_stid.sc_stateid);

spin_lock(&clp->cl_lock);
list_del_init(&ls->ls_perclnt);
Expand Down Expand Up @@ -264,7 +264,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,
list_add(&ls->ls_perfile, &fp->fi_lo_states);
spin_unlock(&fp->fi_lock);

trace_layoutstate_alloc(&ls->ls_stid.sc_stateid);
trace_nfsd_layoutstate_alloc(&ls->ls_stid.sc_stateid);
return ls;
}

Expand Down Expand Up @@ -334,7 +334,7 @@ nfsd4_recall_file_layout(struct nfs4_layout_stateid *ls)
if (list_empty(&ls->ls_layouts))
goto out_unlock;

trace_layout_recall(&ls->ls_stid.sc_stateid);
trace_nfsd_layout_recall(&ls->ls_stid.sc_stateid);

refcount_inc(&ls->ls_stid.sc_count);
nfsd4_run_cb(&ls->ls_recall);
Expand Down Expand Up @@ -507,7 +507,7 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp,
false, lrp->lr_layout_type,
&ls);
if (nfserr) {
trace_layout_return_lookup_fail(&lrp->lr_sid);
trace_nfsd_layout_return_lookup_fail(&lrp->lr_sid);
return nfserr;
}

Expand All @@ -523,7 +523,7 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp,
nfs4_inc_and_copy_stateid(&lrp->lr_sid, &ls->ls_stid);
lrp->lrs_present = 1;
} else {
trace_layoutstate_unhash(&ls->ls_stid.sc_stateid);
trace_nfsd_layoutstate_unhash(&ls->ls_stid.sc_stateid);
nfs4_unhash_stid(&ls->ls_stid);
lrp->lrs_present = 0;
}
Expand Down Expand Up @@ -694,7 +694,7 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task)
/*
* Unknown error or non-responding client, we'll need to fence.
*/
trace_layout_recall_fail(&ls->ls_stid.sc_stateid);
trace_nfsd_layout_recall_fail(&ls->ls_stid.sc_stateid);

ops = nfsd4_layout_ops[ls->ls_layout_type];
if (ops->fence_client)
Expand All @@ -703,7 +703,7 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task)
nfsd4_cb_layout_fail(ls);
return -1;
case -NFS4ERR_NOMATCHING_LAYOUT:
trace_layout_recall_done(&ls->ls_stid.sc_stateid);
trace_nfsd_layout_recall_done(&ls->ls_stid.sc_stateid);
task->tk_status = 0;
return 1;
}
Expand All @@ -716,7 +716,7 @@ nfsd4_cb_layout_release(struct nfsd4_callback *cb)
container_of(cb, struct nfs4_layout_stateid, ls_recall);
LIST_HEAD(reaplist);

trace_layout_recall_release(&ls->ls_stid.sc_stateid);
trace_nfsd_layout_recall_release(&ls->ls_stid.sc_stateid);

nfsd4_return_all_layouts(ls, &reaplist);
nfsd4_free_layouts(&reaplist);
Expand Down
38 changes: 25 additions & 13 deletions fs/nfsd/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <linux/fs_struct.h>
#include <linux/file.h>
#include <linux/falloc.h>
#include <linux/slab.h>
Expand Down Expand Up @@ -252,11 +253,13 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
* Note: create modes (UNCHECKED,GUARDED...) are the same
* in NFSv4 as in v3 except EXCLUSIVE4_1.
*/
current->fs->umask = open->op_umask;
status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
open->op_fname.len, &open->op_iattr,
*resfh, open->op_createmode,
(u32 *)open->op_verf.data,
&open->op_truncate, &open->op_created);
current->fs->umask = 0;

if (!status && open->op_label.len)
nfsd4_security_inode_setsecctx(*resfh, &open->op_label, open->op_bmval);
Expand Down Expand Up @@ -603,6 +606,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (status)
return status;

current->fs->umask = create->cr_umask;
switch (create->cr_type) {
case NF4LNK:
status = nfsd_symlink(rqstp, &cstate->current_fh,
Expand All @@ -611,20 +615,22 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
break;

case NF4BLK:
status = nfserr_inval;
rdev = MKDEV(create->cr_specdata1, create->cr_specdata2);
if (MAJOR(rdev) != create->cr_specdata1 ||
MINOR(rdev) != create->cr_specdata2)
return nfserr_inval;
goto out_umask;
status = nfsd_create(rqstp, &cstate->current_fh,
create->cr_name, create->cr_namelen,
&create->cr_iattr, S_IFBLK, rdev, &resfh);
break;

case NF4CHR:
status = nfserr_inval;
rdev = MKDEV(create->cr_specdata1, create->cr_specdata2);
if (MAJOR(rdev) != create->cr_specdata1 ||
MINOR(rdev) != create->cr_specdata2)
return nfserr_inval;
goto out_umask;
status = nfsd_create(rqstp, &cstate->current_fh,
create->cr_name, create->cr_namelen,
&create->cr_iattr,S_IFCHR, rdev, &resfh);
Expand Down Expand Up @@ -668,6 +674,8 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
fh_dup2(&cstate->current_fh, &resfh);
out:
fh_put(&resfh);
out_umask:
current->fs->umask = 0;
return status;
}

Expand Down Expand Up @@ -751,6 +759,9 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (read->rd_offset >= OFFSET_MAX)
return nfserr_inval;

trace_nfsd_read_start(rqstp, &cstate->current_fh,
read->rd_offset, read->rd_length);

/*
* If we do a zero copy read, then a client will see read data
* that reflects the state of the file *after* performing the
Expand Down Expand Up @@ -783,6 +794,8 @@ nfsd4_read_release(union nfsd4_op_u *u)
{
if (u->read.rd_filp)
fput(u->read.rd_filp);
trace_nfsd_read_done(u->read.rd_rqstp, u->read.rd_fhp,
u->read.rd_offset, u->read.rd_length);
}

static __be32
Expand Down Expand Up @@ -1001,14 +1014,16 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
if (write->wr_offset >= OFFSET_MAX)
return nfserr_inval;

cnt = write->wr_buflen;
trace_nfsd_write_start(rqstp, &cstate->current_fh,
write->wr_offset, cnt);
status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
stateid, WR_STATE, &filp, NULL);
if (status) {
dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
return status;
}

cnt = write->wr_buflen;
write->wr_how_written = write->wr_stable_how;
gen_boot_verifier(&write->wr_verifier, SVC_NET(rqstp));

Expand All @@ -1021,7 +1036,8 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
fput(filp);

write->wr_bytes_written = cnt;

trace_nfsd_write_done(rqstp, &cstate->current_fh,
write->wr_offset, cnt);
return status;
}

Expand Down Expand Up @@ -1106,7 +1122,6 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
else {
copy->cp_res.wr_bytes_written = bytes;
copy->cp_res.wr_stable_how = NFS_UNSTABLE;
copy->cp_consecutive = 1;
copy->cp_synchronous = 1;
gen_boot_verifier(&copy->cp_res.wr_verifier, SVC_NET(rqstp));
status = nfs_ok;
Expand Down Expand Up @@ -1412,7 +1427,7 @@ nfsd4_layoutget(struct svc_rqst *rqstp,
nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lgp->lg_sid,
true, lgp->lg_layout_type, &ls);
if (nfserr) {
trace_layout_get_lookup_fail(&lgp->lg_sid);
trace_nfsd_layout_get_lookup_fail(&lgp->lg_sid);
goto out;
}

Expand Down Expand Up @@ -1481,7 +1496,7 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp,
false, lcp->lc_layout_type,
&ls);
if (nfserr) {
trace_layout_commit_lookup_fail(&lcp->lc_sid);
trace_nfsd_layout_commit_lookup_fail(&lcp->lc_sid);
/* fixup error code as per RFC5661 */
if (nfserr == nfserr_bad_stateid)
nfserr = nfserr_badlayout;
Expand Down Expand Up @@ -1714,12 +1729,10 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
goto encode_op;
}

trace_nfsd_compound(rqstp, args->opcnt);
while (!status && resp->opcnt < args->opcnt) {
op = &args->ops[resp->opcnt++];

dprintk("nfsv4 compound op #%d/%d: %d (%s)\n",
resp->opcnt, args->opcnt, op->opnum,
nfsd4_op_name(op->opnum));
/*
* The XDR decode routines may have pre-set op->status;
* for example, if there is a miscellaneous XDR error
Expand Down Expand Up @@ -1793,9 +1806,8 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
status = op->status;
}

dprintk("nfsv4 compound op %p opcnt %d #%d: %d: status %d\n",
args->ops, args->opcnt, resp->opcnt, op->opnum,
be32_to_cpu(status));
trace_nfsd_compound_status(args->opcnt, resp->opcnt, status,
nfsd4_op_name(op->opnum));

nfsd4_cstate_clear_replay(cstate);
nfsd4_increment_op_stats(op->opnum);
Expand Down
Loading

0 comments on commit 5e4d659

Please sign in to comment.