aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2018-03-28 13:29:11 -0400
committerJ. Bruce Fields <bfields@redhat.com>2018-04-03 15:08:15 -0400
commit87c5942e8fae81ac296267654a047eb2db81592b (patch)
treede00193297b93692cfc86f475fe7cb6d6dbdc56a
parentd890be159a71395bd4ceca09233a8a56d7da69ee (diff)
nfsd: Add I/O trace points in the NFSv4 read proc
NFSv4 read compound processing invokes nfsd_splice_read and nfs_readv directly, so the trace points currently in nfsd_read are not invoked for NFSv4 reads. Move the NFSD READ trace points to common helpers so that NFSv4 reads are captured. Also, record any local I/O error that occurs, the total count of bytes that were actually returned, and whether splice or vectored read was used. Signed-off-by: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
-rw-r--r--fs/nfsd/nfs4proc.c5
-rw-r--r--fs/nfsd/nfs4xdr.c10
-rw-r--r--fs/nfsd/trace.h4
-rw-r--r--fs/nfsd/vfs.c34
-rw-r--r--fs/nfsd/vfs.h11
5 files changed, 39 insertions, 25 deletions
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index b773b314f599..250e0c550fd8 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -751,6 +751,9 @@ nfsd4_read(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
751 if (read->rd_offset >= OFFSET_MAX) 751 if (read->rd_offset >= OFFSET_MAX)
752 return nfserr_inval; 752 return nfserr_inval;
753 753
754 trace_nfsd_read_start(rqstp, &cstate->current_fh,
755 read->rd_offset, read->rd_length);
756
754 /* 757 /*
755 * If we do a zero copy read, then a client will see read data 758 * If we do a zero copy read, then a client will see read data
756 * that reflects the state of the file *after* performing the 759 * that reflects the state of the file *after* performing the
@@ -783,6 +786,8 @@ nfsd4_read_release(union nfsd4_op_u *u)
783{ 786{
784 if (u->read.rd_filp) 787 if (u->read.rd_filp)
785 fput(u->read.rd_filp); 788 fput(u->read.rd_filp);
789 trace_nfsd_read_done(u->read.rd_rqstp, u->read.rd_fhp,
790 u->read.rd_offset, u->read.rd_length);
786} 791}
787 792
788static __be32 793static __be32
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 9f8ef2c6e508..dd72cdf3662e 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -3427,8 +3427,9 @@ static __be32 nfsd4_encode_splice_read(
3427 return nfserr_resource; 3427 return nfserr_resource;
3428 3428
3429 len = maxcount; 3429 len = maxcount;
3430 nfserr = nfsd_splice_read(read->rd_rqstp, file, 3430 nfserr = nfsd_splice_read(read->rd_rqstp, read->rd_fhp,
3431 read->rd_offset, &maxcount); 3431 file, read->rd_offset, &maxcount);
3432 read->rd_length = maxcount;
3432 if (nfserr) { 3433 if (nfserr) {
3433 /* 3434 /*
3434 * nfsd_splice_actor may have already messed with the 3435 * nfsd_splice_actor may have already messed with the
@@ -3511,8 +3512,9 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp,
3511 read->rd_vlen = v; 3512 read->rd_vlen = v;
3512 3513
3513 len = maxcount; 3514 len = maxcount;
3514 nfserr = nfsd_readv(file, read->rd_offset, resp->rqstp->rq_vec, 3515 nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset,
3515 read->rd_vlen, &maxcount); 3516 resp->rqstp->rq_vec, read->rd_vlen, &maxcount);
3517 read->rd_length = maxcount;
3516 if (nfserr) 3518 if (nfserr)
3517 return nfserr; 3519 return nfserr;
3518 xdr_truncate_encode(xdr, starting_len + 8 + ((maxcount+3)&~3)); 3520 xdr_truncate_encode(xdr, starting_len + 8 + ((maxcount+3)&~3));
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h
index 653e9ee754d2..a8bbd9d00a9e 100644
--- a/fs/nfsd/trace.h
+++ b/fs/nfsd/trace.h
@@ -43,7 +43,8 @@ DEFINE_EVENT(nfsd_io_class, nfsd_##name, \
43 TP_ARGS(rqstp, fhp, offset, len)) 43 TP_ARGS(rqstp, fhp, offset, len))
44 44
45DEFINE_NFSD_IO_EVENT(read_start); 45DEFINE_NFSD_IO_EVENT(read_start);
46DEFINE_NFSD_IO_EVENT(read_opened); 46DEFINE_NFSD_IO_EVENT(read_splice);
47DEFINE_NFSD_IO_EVENT(read_vector);
47DEFINE_NFSD_IO_EVENT(read_io_done); 48DEFINE_NFSD_IO_EVENT(read_io_done);
48DEFINE_NFSD_IO_EVENT(read_done); 49DEFINE_NFSD_IO_EVENT(read_done);
49DEFINE_NFSD_IO_EVENT(write_start); 50DEFINE_NFSD_IO_EVENT(write_start);
@@ -82,6 +83,7 @@ DEFINE_EVENT(nfsd_err_class, nfsd_##name, \
82 int len), \ 83 int len), \
83 TP_ARGS(rqstp, fhp, offset, len)) 84 TP_ARGS(rqstp, fhp, offset, len))
84 85
86DEFINE_NFSD_ERR_EVENT(read_err);
85DEFINE_NFSD_ERR_EVENT(write_err); 87DEFINE_NFSD_ERR_EVENT(write_err);
86 88
87#include "state.h" 89#include "state.h"
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index ee59a0b24fab..2410b093a2e6 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -881,20 +881,24 @@ static int nfsd_direct_splice_actor(struct pipe_inode_info *pipe,
881 return __splice_from_pipe(pipe, sd, nfsd_splice_actor); 881 return __splice_from_pipe(pipe, sd, nfsd_splice_actor);
882} 882}
883 883
884static __be32 884static __be32 nfsd_finish_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
885nfsd_finish_read(struct file *file, unsigned long *count, int host_err) 885 struct file *file, loff_t offset,
886 unsigned long *count, int host_err)
886{ 887{
887 if (host_err >= 0) { 888 if (host_err >= 0) {
888 nfsdstats.io_read += host_err; 889 nfsdstats.io_read += host_err;
889 *count = host_err; 890 *count = host_err;
890 fsnotify_access(file); 891 fsnotify_access(file);
892 trace_nfsd_read_io_done(rqstp, fhp, offset, *count);
891 return 0; 893 return 0;
892 } else 894 } else {
895 trace_nfsd_read_err(rqstp, fhp, offset, host_err);
893 return nfserrno(host_err); 896 return nfserrno(host_err);
897 }
894} 898}
895 899
896__be32 nfsd_splice_read(struct svc_rqst *rqstp, 900__be32 nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
897 struct file *file, loff_t offset, unsigned long *count) 901 struct file *file, loff_t offset, unsigned long *count)
898{ 902{
899 struct splice_desc sd = { 903 struct splice_desc sd = {
900 .len = 0, 904 .len = 0,
@@ -904,21 +908,23 @@ __be32 nfsd_splice_read(struct svc_rqst *rqstp,
904 }; 908 };
905 int host_err; 909 int host_err;
906 910
911 trace_nfsd_read_splice(rqstp, fhp, offset, *count);
907 rqstp->rq_next_page = rqstp->rq_respages + 1; 912 rqstp->rq_next_page = rqstp->rq_respages + 1;
908 host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor); 913 host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor);
909 return nfsd_finish_read(file, count, host_err); 914 return nfsd_finish_read(rqstp, fhp, file, offset, count, host_err);
910} 915}
911 916
912__be32 nfsd_readv(struct file *file, loff_t offset, struct kvec *vec, int vlen, 917__be32 nfsd_readv(struct svc_rqst *rqstp, struct svc_fh *fhp,
913 unsigned long *count) 918 struct file *file, loff_t offset,
919 struct kvec *vec, int vlen, unsigned long *count)
914{ 920{
915 struct iov_iter iter; 921 struct iov_iter iter;
916 int host_err; 922 int host_err;
917 923
924 trace_nfsd_read_vector(rqstp, fhp, offset, *count);
918 iov_iter_kvec(&iter, READ | ITER_KVEC, vec, vlen, *count); 925 iov_iter_kvec(&iter, READ | ITER_KVEC, vec, vlen, *count);
919 host_err = vfs_iter_read(file, &iter, &offset, 0); 926 host_err = vfs_iter_read(file, &iter, &offset, 0);
920 927 return nfsd_finish_read(rqstp, fhp, file, offset, count, host_err);
921 return nfsd_finish_read(file, count, host_err);
922} 928}
923 929
924/* 930/*
@@ -1034,14 +1040,10 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
1034 1040
1035 ra = nfsd_init_raparms(file); 1041 ra = nfsd_init_raparms(file);
1036 1042
1037 trace_nfsd_read_opened(rqstp, fhp, offset, *count);
1038
1039 if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &rqstp->rq_flags)) 1043 if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &rqstp->rq_flags))
1040 err = nfsd_splice_read(rqstp, file, offset, count); 1044 err = nfsd_splice_read(rqstp, fhp, file, offset, count);
1041 else 1045 else
1042 err = nfsd_readv(file, offset, vec, vlen, count); 1046 err = nfsd_readv(rqstp, fhp, file, offset, vec, vlen, count);
1043
1044 trace_nfsd_read_io_done(rqstp, fhp, offset, *count);
1045 1047
1046 if (ra) 1048 if (ra)
1047 nfsd_put_raparams(file, ra); 1049 nfsd_put_raparams(file, ra);
diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
index be6d8e00453f..a7e107309f76 100644
--- a/fs/nfsd/vfs.h
+++ b/fs/nfsd/vfs.h
@@ -78,10 +78,13 @@ __be32 nfsd_commit(struct svc_rqst *, struct svc_fh *,
78__be32 nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t, 78__be32 nfsd_open(struct svc_rqst *, struct svc_fh *, umode_t,
79 int, struct file **); 79 int, struct file **);
80struct raparms; 80struct raparms;
81__be32 nfsd_splice_read(struct svc_rqst *, 81__be32 nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp,
82 struct file *, loff_t, unsigned long *); 82 struct file *file, loff_t offset,
83__be32 nfsd_readv(struct file *, loff_t, struct kvec *, int, 83 unsigned long *count);
84 unsigned long *); 84__be32 nfsd_readv(struct svc_rqst *rqstp, struct svc_fh *fhp,
85 struct file *file, loff_t offset,
86 struct kvec *vec, int vlen,
87 unsigned long *count);
85__be32 nfsd_read(struct svc_rqst *, struct svc_fh *, 88__be32 nfsd_read(struct svc_rqst *, struct svc_fh *,
86 loff_t, struct kvec *, int, unsigned long *); 89 loff_t, struct kvec *, int, unsigned long *);
87__be32 nfsd_write(struct svc_rqst *, struct svc_fh *, loff_t, 90__be32 nfsd_write(struct svc_rqst *, struct svc_fh *, loff_t,