diff options
author | Jeff Layton <jlayton@poochiereds.net> | 2015-11-17 06:52:23 -0500 |
---|---|---|
committer | J. Bruce Fields <bfields@redhat.com> | 2016-01-14 17:32:51 -0500 |
commit | 6e8b50d16a757d53f8817acecba97c5d4aa1cf65 (patch) | |
tree | 1d8846d614705a8475543c575e026e87e6b3eaa8 /fs/nfsd | |
parent | 6b9b21073d3b250e17812cd562fffc9006962b39 (diff) |
nfsd: add new io class tracepoint
Add some new tracepoints in the nfsd read/write codepaths. The idea
is that this will give us the ability to measure how long each phase of
a read or write operation takes.
Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/nfsfh.h | 23 | ||||
-rw-r--r-- | fs/nfsd/trace.h | 41 | ||||
-rw-r--r-- | fs/nfsd/vfs.c | 15 |
3 files changed, 79 insertions, 0 deletions
diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h index 2087bae17582..0770bcb543c8 100644 --- a/fs/nfsd/nfsfh.h +++ b/fs/nfsd/nfsfh.h | |||
@@ -7,6 +7,7 @@ | |||
7 | #ifndef _LINUX_NFSD_NFSFH_H | 7 | #ifndef _LINUX_NFSD_NFSFH_H |
8 | #define _LINUX_NFSD_NFSFH_H | 8 | #define _LINUX_NFSD_NFSFH_H |
9 | 9 | ||
10 | #include <linux/crc32.h> | ||
10 | #include <linux/sunrpc/svc.h> | 11 | #include <linux/sunrpc/svc.h> |
11 | #include <uapi/linux/nfsd/nfsfh.h> | 12 | #include <uapi/linux/nfsd/nfsfh.h> |
12 | 13 | ||
@@ -205,6 +206,28 @@ static inline bool fh_fsid_match(struct knfsd_fh *fh1, struct knfsd_fh *fh2) | |||
205 | return true; | 206 | return true; |
206 | } | 207 | } |
207 | 208 | ||
209 | #ifdef CONFIG_CRC32 | ||
210 | /** | ||
211 | * knfsd_fh_hash - calculate the crc32 hash for the filehandle | ||
212 | * @fh - pointer to filehandle | ||
213 | * | ||
214 | * returns a crc32 hash for the filehandle that is compatible with | ||
215 | * the one displayed by "wireshark". | ||
216 | */ | ||
217 | |||
218 | static inline u32 | ||
219 | knfsd_fh_hash(struct knfsd_fh *fh) | ||
220 | { | ||
221 | return ~crc32_le(0xFFFFFFFF, (unsigned char *)&fh->fh_base, fh->fh_size); | ||
222 | } | ||
223 | #else | ||
224 | static inline u32 | ||
225 | knfsd_fh_hash(struct knfsd_fh *fh) | ||
226 | { | ||
227 | return 0; | ||
228 | } | ||
229 | #endif | ||
230 | |||
208 | #ifdef CONFIG_NFSD_V3 | 231 | #ifdef CONFIG_NFSD_V3 |
209 | /* | 232 | /* |
210 | * The wcc data stored in current_fh should be cleared | 233 | * The wcc data stored in current_fh should be cleared |
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h index 0befe762762b..3287041905da 100644 --- a/fs/nfsd/trace.h +++ b/fs/nfsd/trace.h | |||
@@ -8,6 +8,47 @@ | |||
8 | #define _NFSD_TRACE_H | 8 | #define _NFSD_TRACE_H |
9 | 9 | ||
10 | #include <linux/tracepoint.h> | 10 | #include <linux/tracepoint.h> |
11 | #include "nfsfh.h" | ||
12 | |||
13 | DECLARE_EVENT_CLASS(nfsd_io_class, | ||
14 | TP_PROTO(struct svc_rqst *rqstp, | ||
15 | struct svc_fh *fhp, | ||
16 | loff_t offset, | ||
17 | int len), | ||
18 | TP_ARGS(rqstp, fhp, offset, len), | ||
19 | TP_STRUCT__entry( | ||
20 | __field(__be32, xid) | ||
21 | __field_struct(struct knfsd_fh, fh) | ||
22 | __field(loff_t, offset) | ||
23 | __field(int, len) | ||
24 | ), | ||
25 | TP_fast_assign( | ||
26 | __entry->xid = rqstp->rq_xid, | ||
27 | fh_copy_shallow(&__entry->fh, &fhp->fh_handle); | ||
28 | __entry->offset = offset; | ||
29 | __entry->len = len; | ||
30 | ), | ||
31 | TP_printk("xid=0x%x fh=0x%x offset=%lld len=%d", | ||
32 | __be32_to_cpu(__entry->xid), knfsd_fh_hash(&__entry->fh), | ||
33 | __entry->offset, __entry->len) | ||
34 | ) | ||
35 | |||
36 | #define DEFINE_NFSD_IO_EVENT(name) \ | ||
37 | DEFINE_EVENT(nfsd_io_class, name, \ | ||
38 | TP_PROTO(struct svc_rqst *rqstp, \ | ||
39 | struct svc_fh *fhp, \ | ||
40 | loff_t offset, \ | ||
41 | int len), \ | ||
42 | TP_ARGS(rqstp, fhp, offset, len)) | ||
43 | |||
44 | DEFINE_NFSD_IO_EVENT(read_start); | ||
45 | DEFINE_NFSD_IO_EVENT(read_opened); | ||
46 | DEFINE_NFSD_IO_EVENT(read_io_done); | ||
47 | DEFINE_NFSD_IO_EVENT(read_done); | ||
48 | DEFINE_NFSD_IO_EVENT(write_start); | ||
49 | DEFINE_NFSD_IO_EVENT(write_opened); | ||
50 | DEFINE_NFSD_IO_EVENT(write_io_done); | ||
51 | DEFINE_NFSD_IO_EVENT(write_done); | ||
11 | 52 | ||
12 | #include "state.h" | 53 | #include "state.h" |
13 | 54 | ||
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 994d66fbb446..3257c59dc860 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c | |||
@@ -42,6 +42,7 @@ | |||
42 | 42 | ||
43 | #include "nfsd.h" | 43 | #include "nfsd.h" |
44 | #include "vfs.h" | 44 | #include "vfs.h" |
45 | #include "trace.h" | ||
45 | 46 | ||
46 | #define NFSDDBG_FACILITY NFSDDBG_FILEOP | 47 | #define NFSDDBG_FACILITY NFSDDBG_FILEOP |
47 | 48 | ||
@@ -983,16 +984,23 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, | |||
983 | struct raparms *ra; | 984 | struct raparms *ra; |
984 | __be32 err; | 985 | __be32 err; |
985 | 986 | ||
987 | trace_read_start(rqstp, fhp, offset, vlen); | ||
986 | err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); | 988 | err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_READ, &file); |
987 | if (err) | 989 | if (err) |
988 | return err; | 990 | return err; |
989 | 991 | ||
990 | ra = nfsd_init_raparms(file); | 992 | ra = nfsd_init_raparms(file); |
993 | |||
994 | trace_read_opened(rqstp, fhp, offset, vlen); | ||
991 | err = nfsd_vfs_read(rqstp, file, offset, vec, vlen, count); | 995 | err = nfsd_vfs_read(rqstp, file, offset, vec, vlen, count); |
996 | trace_read_io_done(rqstp, fhp, offset, vlen); | ||
997 | |||
992 | if (ra) | 998 | if (ra) |
993 | nfsd_put_raparams(file, ra); | 999 | nfsd_put_raparams(file, ra); |
994 | fput(file); | 1000 | fput(file); |
995 | 1001 | ||
1002 | trace_read_done(rqstp, fhp, offset, vlen); | ||
1003 | |||
996 | return err; | 1004 | return err; |
997 | } | 1005 | } |
998 | 1006 | ||
@@ -1008,24 +1016,31 @@ nfsd_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, | |||
1008 | { | 1016 | { |
1009 | __be32 err = 0; | 1017 | __be32 err = 0; |
1010 | 1018 | ||
1019 | trace_write_start(rqstp, fhp, offset, vlen); | ||
1020 | |||
1011 | if (file) { | 1021 | if (file) { |
1012 | err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry, | 1022 | err = nfsd_permission(rqstp, fhp->fh_export, fhp->fh_dentry, |
1013 | NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE); | 1023 | NFSD_MAY_WRITE|NFSD_MAY_OWNER_OVERRIDE); |
1014 | if (err) | 1024 | if (err) |
1015 | goto out; | 1025 | goto out; |
1026 | trace_write_opened(rqstp, fhp, offset, vlen); | ||
1016 | err = nfsd_vfs_write(rqstp, fhp, file, offset, vec, vlen, cnt, | 1027 | err = nfsd_vfs_write(rqstp, fhp, file, offset, vec, vlen, cnt, |
1017 | stablep); | 1028 | stablep); |
1029 | trace_write_io_done(rqstp, fhp, offset, vlen); | ||
1018 | } else { | 1030 | } else { |
1019 | err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_WRITE, &file); | 1031 | err = nfsd_open(rqstp, fhp, S_IFREG, NFSD_MAY_WRITE, &file); |
1020 | if (err) | 1032 | if (err) |
1021 | goto out; | 1033 | goto out; |
1022 | 1034 | ||
1035 | trace_write_opened(rqstp, fhp, offset, vlen); | ||
1023 | if (cnt) | 1036 | if (cnt) |
1024 | err = nfsd_vfs_write(rqstp, fhp, file, offset, vec, vlen, | 1037 | err = nfsd_vfs_write(rqstp, fhp, file, offset, vec, vlen, |
1025 | cnt, stablep); | 1038 | cnt, stablep); |
1039 | trace_write_io_done(rqstp, fhp, offset, vlen); | ||
1026 | fput(file); | 1040 | fput(file); |
1027 | } | 1041 | } |
1028 | out: | 1042 | out: |
1043 | trace_write_done(rqstp, fhp, offset, vlen); | ||
1029 | return err; | 1044 | return err; |
1030 | } | 1045 | } |
1031 | 1046 | ||