Skip to content

Commit 5e4d659

Browse files
committed
Merge tag 'nfsd-4.17' of git://linux-nfs.org/~bfields/linux
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 ...
2 parents 274c0e7 + 880a3a5 commit 5e4d659

31 files changed

+721
-515
lines changed

fs/lockd/svc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,8 @@ static struct task_struct *nlmsvc_task;
5757
static struct svc_rqst *nlmsvc_rqst;
5858
unsigned long nlmsvc_timeout;
5959

60-
atomic_t nlm_ntf_refcnt = ATOMIC_INIT(0);
61-
DECLARE_WAIT_QUEUE_HEAD(nlm_ntf_wq);
60+
static atomic_t nlm_ntf_refcnt = ATOMIC_INIT(0);
61+
static DECLARE_WAIT_QUEUE_HEAD(nlm_ntf_wq);
6262

6363
unsigned int lockd_net_id;
6464

fs/nfsd/nfs3proc.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ nfsd3_proc_write(struct svc_rqst *rqstp)
192192
struct nfsd3_writeres *resp = rqstp->rq_resp;
193193
__be32 nfserr;
194194
unsigned long cnt = argp->len;
195+
unsigned int nvecs;
195196

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

202203
fh_copy(&resp->fh, &argp->fh);
203204
resp->committed = argp->stable;
205+
nvecs = svc_fill_write_vector(rqstp, &argp->first, cnt);
206+
if (!nvecs)
207+
RETURN_STATUS(nfserr_io);
204208
nfserr = nfsd_write(rqstp, &resp->fh, argp->offset,
205-
rqstp->rq_vec, argp->vlen,
206-
&cnt, resp->committed);
209+
rqstp->rq_vec, nvecs, &cnt,
210+
resp->committed);
207211
resp->count = cnt;
208212
RETURN_STATUS(nfserr);
209213
}
@@ -279,6 +283,16 @@ nfsd3_proc_symlink(struct svc_rqst *rqstp)
279283
struct nfsd3_diropres *resp = rqstp->rq_resp;
280284
__be32 nfserr;
281285

286+
if (argp->tlen == 0)
287+
RETURN_STATUS(nfserr_inval);
288+
if (argp->tlen > NFS3_MAXPATHLEN)
289+
RETURN_STATUS(nfserr_nametoolong);
290+
291+
argp->tname = svc_fill_symlink_pathname(rqstp, &argp->first,
292+
argp->tlen);
293+
if (IS_ERR(argp->tname))
294+
RETURN_STATUS(nfserrno(PTR_ERR(argp->tname)));
295+
282296
dprintk("nfsd: SYMLINK(3) %s %.*s -> %.*s\n",
283297
SVCFH_fmt(&argp->ffh),
284298
argp->flen, argp->fname,

fs/nfsd/nfs3xdr.c

Lines changed: 16 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ int
391391
nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
392392
{
393393
struct nfsd3_writeargs *args = rqstp->rq_argp;
394-
unsigned int len, v, hdr, dlen;
394+
unsigned int len, hdr, dlen;
395395
u32 max_blocksize = svc_max_payload(rqstp);
396396
struct kvec *head = rqstp->rq_arg.head;
397397
struct kvec *tail = rqstp->rq_arg.tail;
@@ -433,17 +433,9 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
433433
args->count = max_blocksize;
434434
len = args->len = max_blocksize;
435435
}
436-
rqstp->rq_vec[0].iov_base = (void*)p;
437-
rqstp->rq_vec[0].iov_len = head->iov_len - hdr;
438-
v = 0;
439-
while (len > rqstp->rq_vec[v].iov_len) {
440-
len -= rqstp->rq_vec[v].iov_len;
441-
v++;
442-
rqstp->rq_vec[v].iov_base = page_address(rqstp->rq_pages[v]);
443-
rqstp->rq_vec[v].iov_len = PAGE_SIZE;
444-
}
445-
rqstp->rq_vec[v].iov_len = len;
446-
args->vlen = v + 1;
436+
437+
args->first.iov_base = (void *)p;
438+
args->first.iov_len = head->iov_len - hdr;
447439
return 1;
448440
}
449441

@@ -489,51 +481,24 @@ int
489481
nfs3svc_decode_symlinkargs(struct svc_rqst *rqstp, __be32 *p)
490482
{
491483
struct nfsd3_symlinkargs *args = rqstp->rq_argp;
492-
unsigned int len, avail;
493-
char *old, *new;
494-
struct kvec *vec;
484+
char *base = (char *)p;
485+
size_t dlen;
495486

496487
if (!(p = decode_fh(p, &args->ffh)) ||
497-
!(p = decode_filename(p, &args->fname, &args->flen))
498-
)
488+
!(p = decode_filename(p, &args->fname, &args->flen)))
499489
return 0;
500490
p = decode_sattr3(p, &args->attrs);
501491

502-
/* now decode the pathname, which might be larger than the first page.
503-
* As we have to check for nul's anyway, we copy it into a new page
504-
* This page appears in the rq_res.pages list, but as pages_len is always
505-
* 0, it won't get in the way
506-
*/
507-
len = ntohl(*p++);
508-
if (len == 0 || len > NFS3_MAXPATHLEN || len >= PAGE_SIZE)
509-
return 0;
510-
args->tname = new = page_address(*(rqstp->rq_next_page++));
511-
args->tlen = len;
512-
/* first copy and check from the first page */
513-
old = (char*)p;
514-
vec = &rqstp->rq_arg.head[0];
515-
if ((void *)old > vec->iov_base + vec->iov_len)
516-
return 0;
517-
avail = vec->iov_len - (old - (char*)vec->iov_base);
518-
while (len && avail && *old) {
519-
*new++ = *old++;
520-
len--;
521-
avail--;
522-
}
523-
/* now copy next page if there is one */
524-
if (len && !avail && rqstp->rq_arg.page_len) {
525-
avail = min_t(unsigned int, rqstp->rq_arg.page_len, PAGE_SIZE);
526-
old = page_address(rqstp->rq_arg.pages[0]);
527-
}
528-
while (len && avail && *old) {
529-
*new++ = *old++;
530-
len--;
531-
avail--;
532-
}
533-
*new = '\0';
534-
if (len)
535-
return 0;
492+
args->tlen = ntohl(*p++);
493+
494+
args->first.iov_base = p;
495+
args->first.iov_len = rqstp->rq_arg.head[0].iov_len;
496+
args->first.iov_len -= (char *)p - base;
536497

498+
dlen = args->first.iov_len + rqstp->rq_arg.page_len +
499+
rqstp->rq_arg.tail[0].iov_len;
500+
if (dlen < XDR_QUADLEN(args->tlen) << 2)
501+
return 0;
537502
return 1;
538503
}
539504

fs/nfsd/nfs4callback.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,8 @@ static int nfs_cb_stat_to_errno(int status)
223223
return -status;
224224
}
225225

226-
static int decode_cb_op_status(struct xdr_stream *xdr, enum nfs_opnum4 expected,
227-
int *status)
226+
static int decode_cb_op_status(struct xdr_stream *xdr,
227+
enum nfs_cb_opnum4 expected, int *status)
228228
{
229229
__be32 *p;
230230
u32 op;

fs/nfsd/nfs4layouts.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ nfsd4_free_layout_stateid(struct nfs4_stid *stid)
165165
struct nfs4_client *clp = ls->ls_stid.sc_client;
166166
struct nfs4_file *fp = ls->ls_stid.sc_file;
167167

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

170170
spin_lock(&clp->cl_lock);
171171
list_del_init(&ls->ls_perclnt);
@@ -264,7 +264,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,
264264
list_add(&ls->ls_perfile, &fp->fi_lo_states);
265265
spin_unlock(&fp->fi_lock);
266266

267-
trace_layoutstate_alloc(&ls->ls_stid.sc_stateid);
267+
trace_nfsd_layoutstate_alloc(&ls->ls_stid.sc_stateid);
268268
return ls;
269269
}
270270

@@ -334,7 +334,7 @@ nfsd4_recall_file_layout(struct nfs4_layout_stateid *ls)
334334
if (list_empty(&ls->ls_layouts))
335335
goto out_unlock;
336336

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

339339
refcount_inc(&ls->ls_stid.sc_count);
340340
nfsd4_run_cb(&ls->ls_recall);
@@ -507,7 +507,7 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp,
507507
false, lrp->lr_layout_type,
508508
&ls);
509509
if (nfserr) {
510-
trace_layout_return_lookup_fail(&lrp->lr_sid);
510+
trace_nfsd_layout_return_lookup_fail(&lrp->lr_sid);
511511
return nfserr;
512512
}
513513

@@ -523,7 +523,7 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp,
523523
nfs4_inc_and_copy_stateid(&lrp->lr_sid, &ls->ls_stid);
524524
lrp->lrs_present = 1;
525525
} else {
526-
trace_layoutstate_unhash(&ls->ls_stid.sc_stateid);
526+
trace_nfsd_layoutstate_unhash(&ls->ls_stid.sc_stateid);
527527
nfs4_unhash_stid(&ls->ls_stid);
528528
lrp->lrs_present = 0;
529529
}
@@ -694,7 +694,7 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task)
694694
/*
695695
* Unknown error or non-responding client, we'll need to fence.
696696
*/
697-
trace_layout_recall_fail(&ls->ls_stid.sc_stateid);
697+
trace_nfsd_layout_recall_fail(&ls->ls_stid.sc_stateid);
698698

699699
ops = nfsd4_layout_ops[ls->ls_layout_type];
700700
if (ops->fence_client)
@@ -703,7 +703,7 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task)
703703
nfsd4_cb_layout_fail(ls);
704704
return -1;
705705
case -NFS4ERR_NOMATCHING_LAYOUT:
706-
trace_layout_recall_done(&ls->ls_stid.sc_stateid);
706+
trace_nfsd_layout_recall_done(&ls->ls_stid.sc_stateid);
707707
task->tk_status = 0;
708708
return 1;
709709
}
@@ -716,7 +716,7 @@ nfsd4_cb_layout_release(struct nfsd4_callback *cb)
716716
container_of(cb, struct nfs4_layout_stateid, ls_recall);
717717
LIST_HEAD(reaplist);
718718

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

721721
nfsd4_return_all_layouts(ls, &reaplist);
722722
nfsd4_free_layouts(&reaplist);

fs/nfsd/nfs4proc.c

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3333
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3434
*/
35+
#include <linux/fs_struct.h>
3536
#include <linux/file.h>
3637
#include <linux/falloc.h>
3738
#include <linux/slab.h>
@@ -252,11 +253,13 @@ do_open_lookup(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, stru
252253
* Note: create modes (UNCHECKED,GUARDED...) are the same
253254
* in NFSv4 as in v3 except EXCLUSIVE4_1.
254255
*/
256+
current->fs->umask = open->op_umask;
255257
status = do_nfsd_create(rqstp, current_fh, open->op_fname.data,
256258
open->op_fname.len, &open->op_iattr,
257259
*resfh, open->op_createmode,
258260
(u32 *)open->op_verf.data,
259261
&open->op_truncate, &open->op_created);
262+
current->fs->umask = 0;
260263

261264
if (!status && open->op_label.len)
262265
nfsd4_security_inode_setsecctx(*resfh, &open->op_label, open->op_bmval);
@@ -603,6 +606,7 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
603606
if (status)
604607
return status;
605608

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

613617
case NF4BLK:
618+
status = nfserr_inval;
614619
rdev = MKDEV(create->cr_specdata1, create->cr_specdata2);
615620
if (MAJOR(rdev) != create->cr_specdata1 ||
616621
MINOR(rdev) != create->cr_specdata2)
617-
return nfserr_inval;
622+
goto out_umask;
618623
status = nfsd_create(rqstp, &cstate->current_fh,
619624
create->cr_name, create->cr_namelen,
620625
&create->cr_iattr, S_IFBLK, rdev, &resfh);
621626
break;
622627

623628
case NF4CHR:
629+
status = nfserr_inval;
624630
rdev = MKDEV(create->cr_specdata1, create->cr_specdata2);
625631
if (MAJOR(rdev) != create->cr_specdata1 ||
626632
MINOR(rdev) != create->cr_specdata2)
627-
return nfserr_inval;
633+
goto out_umask;
628634
status = nfsd_create(rqstp, &cstate->current_fh,
629635
create->cr_name, create->cr_namelen,
630636
&create->cr_iattr,S_IFCHR, rdev, &resfh);
@@ -668,6 +674,8 @@ nfsd4_create(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
668674
fh_dup2(&cstate->current_fh, &resfh);
669675
out:
670676
fh_put(&resfh);
677+
out_umask:
678+
current->fs->umask = 0;
671679
return status;
672680
}
673681

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

762+
trace_nfsd_read_start(rqstp, &cstate->current_fh,
763+
read->rd_offset, read->rd_length);
764+
754765
/*
755766
* If we do a zero copy read, then a client will see read data
756767
* that reflects the state of the file *after* performing the
@@ -783,6 +794,8 @@ nfsd4_read_release(union nfsd4_op_u *u)
783794
{
784795
if (u->read.rd_filp)
785796
fput(u->read.rd_filp);
797+
trace_nfsd_read_done(u->read.rd_rqstp, u->read.rd_fhp,
798+
u->read.rd_offset, u->read.rd_length);
786799
}
787800

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

1017+
cnt = write->wr_buflen;
1018+
trace_nfsd_write_start(rqstp, &cstate->current_fh,
1019+
write->wr_offset, cnt);
10041020
status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
10051021
stateid, WR_STATE, &filp, NULL);
10061022
if (status) {
10071023
dprintk("NFSD: nfsd4_write: couldn't process stateid!\n");
10081024
return status;
10091025
}
10101026

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

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

10231038
write->wr_bytes_written = cnt;
1024-
1039+
trace_nfsd_write_done(rqstp, &cstate->current_fh,
1040+
write->wr_offset, cnt);
10251041
return status;
10261042
}
10271043

@@ -1106,7 +1122,6 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
11061122
else {
11071123
copy->cp_res.wr_bytes_written = bytes;
11081124
copy->cp_res.wr_stable_how = NFS_UNSTABLE;
1109-
copy->cp_consecutive = 1;
11101125
copy->cp_synchronous = 1;
11111126
gen_boot_verifier(&copy->cp_res.wr_verifier, SVC_NET(rqstp));
11121127
status = nfs_ok;
@@ -1412,7 +1427,7 @@ nfsd4_layoutget(struct svc_rqst *rqstp,
14121427
nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lgp->lg_sid,
14131428
true, lgp->lg_layout_type, &ls);
14141429
if (nfserr) {
1415-
trace_layout_get_lookup_fail(&lgp->lg_sid);
1430+
trace_nfsd_layout_get_lookup_fail(&lgp->lg_sid);
14161431
goto out;
14171432
}
14181433

@@ -1481,7 +1496,7 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp,
14811496
false, lcp->lc_layout_type,
14821497
&ls);
14831498
if (nfserr) {
1484-
trace_layout_commit_lookup_fail(&lcp->lc_sid);
1499+
trace_nfsd_layout_commit_lookup_fail(&lcp->lc_sid);
14851500
/* fixup error code as per RFC5661 */
14861501
if (nfserr == nfserr_bad_stateid)
14871502
nfserr = nfserr_badlayout;
@@ -1714,12 +1729,10 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
17141729
goto encode_op;
17151730
}
17161731

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

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

1796-
dprintk("nfsv4 compound op %p opcnt %d #%d: %d: status %d\n",
1797-
args->ops, args->opcnt, resp->opcnt, op->opnum,
1798-
be32_to_cpu(status));
1809+
trace_nfsd_compound_status(args->opcnt, resp->opcnt, status,
1810+
nfsd4_op_name(op->opnum));
17991811

18001812
nfsd4_cstate_clear_replay(cstate);
18011813
nfsd4_increment_op_stats(op->opnum);

0 commit comments

Comments
 (0)