diff options
author | Christoph Hellwig <hch@lst.de> | 2014-08-16 20:02:22 -0400 |
---|---|---|
committer | Christoph Hellwig <hch@lst.de> | 2015-02-02 12:09:44 -0500 |
commit | 31ef83dc053835fc14741426e20c60dbbba8c13d (patch) | |
tree | 8c9a1cac8a5e29fa07b476d705d09ca0f79e40ee /fs/nfsd | |
parent | 18d1aef89ec14dd2c4afaa80b7b1b3497aa188c7 (diff) |
nfsd: add trace events
For now just a few simple events to trace the layout stateid lifetime, but
these already were enough to find several bugs in the Linux client layout
stateid handling.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Diffstat (limited to 'fs/nfsd')
-rw-r--r-- | fs/nfsd/Makefile | 7 | ||||
-rw-r--r-- | fs/nfsd/nfs4layouts.c | 16 | ||||
-rw-r--r-- | fs/nfsd/nfs4proc.c | 6 | ||||
-rw-r--r-- | fs/nfsd/trace.c | 5 | ||||
-rw-r--r-- | fs/nfsd/trace.h | 54 |
5 files changed, 85 insertions, 3 deletions
diff --git a/fs/nfsd/Makefile b/fs/nfsd/Makefile index 5806270a8567..6cba933880c5 100644 --- a/fs/nfsd/Makefile +++ b/fs/nfsd/Makefile | |||
@@ -2,9 +2,14 @@ | |||
2 | # Makefile for the Linux nfs server | 2 | # Makefile for the Linux nfs server |
3 | # | 3 | # |
4 | 4 | ||
5 | ccflags-y += -I$(src) # needed for trace events | ||
6 | |||
5 | obj-$(CONFIG_NFSD) += nfsd.o | 7 | obj-$(CONFIG_NFSD) += nfsd.o |
6 | 8 | ||
7 | nfsd-y := nfssvc.o nfsctl.o nfsproc.o nfsfh.o vfs.o \ | 9 | # this one should be compiled first, as the tracing macros can easily blow up |
10 | nfsd-y += trace.o | ||
11 | |||
12 | nfsd-y += nfssvc.o nfsctl.o nfsproc.o nfsfh.o vfs.o \ | ||
8 | export.o auth.o lockd.o nfscache.o nfsxdr.o stats.o | 13 | export.o auth.o lockd.o nfscache.o nfsxdr.o stats.o |
9 | nfsd-$(CONFIG_NFSD_FAULT_INJECTION) += fault_inject.o | 14 | nfsd-$(CONFIG_NFSD_FAULT_INJECTION) += fault_inject.o |
10 | nfsd-$(CONFIG_NFSD_V2_ACL) += nfs2acl.o | 15 | nfsd-$(CONFIG_NFSD_V2_ACL) += nfs2acl.o |
diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c index d926865df94f..60137c54b2f7 100644 --- a/fs/nfsd/nfs4layouts.c +++ b/fs/nfsd/nfs4layouts.c | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | #include "pnfs.h" | 10 | #include "pnfs.h" |
11 | #include "netns.h" | 11 | #include "netns.h" |
12 | #include "trace.h" | ||
12 | 13 | ||
13 | #define NFSDDBG_FACILITY NFSDDBG_PNFS | 14 | #define NFSDDBG_FACILITY NFSDDBG_PNFS |
14 | 15 | ||
@@ -125,6 +126,8 @@ nfsd4_free_layout_stateid(struct nfs4_stid *stid) | |||
125 | struct nfs4_client *clp = ls->ls_stid.sc_client; | 126 | struct nfs4_client *clp = ls->ls_stid.sc_client; |
126 | struct nfs4_file *fp = ls->ls_stid.sc_file; | 127 | struct nfs4_file *fp = ls->ls_stid.sc_file; |
127 | 128 | ||
129 | trace_layoutstate_free(&ls->ls_stid.sc_stateid); | ||
130 | |||
128 | spin_lock(&clp->cl_lock); | 131 | spin_lock(&clp->cl_lock); |
129 | list_del_init(&ls->ls_perclnt); | 132 | list_del_init(&ls->ls_perclnt); |
130 | spin_unlock(&clp->cl_lock); | 133 | spin_unlock(&clp->cl_lock); |
@@ -215,6 +218,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate, | |||
215 | list_add(&ls->ls_perfile, &fp->fi_lo_states); | 218 | list_add(&ls->ls_perfile, &fp->fi_lo_states); |
216 | spin_unlock(&fp->fi_lock); | 219 | spin_unlock(&fp->fi_lock); |
217 | 220 | ||
221 | trace_layoutstate_alloc(&ls->ls_stid.sc_stateid); | ||
218 | return ls; | 222 | return ls; |
219 | } | 223 | } |
220 | 224 | ||
@@ -280,6 +284,8 @@ nfsd4_recall_file_layout(struct nfs4_layout_stateid *ls) | |||
280 | if (list_empty(&ls->ls_layouts)) | 284 | if (list_empty(&ls->ls_layouts)) |
281 | goto out_unlock; | 285 | goto out_unlock; |
282 | 286 | ||
287 | trace_layout_recall(&ls->ls_stid.sc_stateid); | ||
288 | |||
283 | atomic_inc(&ls->ls_stid.sc_count); | 289 | atomic_inc(&ls->ls_stid.sc_count); |
284 | update_stateid(&ls->ls_stid.sc_stateid); | 290 | update_stateid(&ls->ls_stid.sc_stateid); |
285 | memcpy(&ls->ls_recall_sid, &ls->ls_stid.sc_stateid, sizeof(stateid_t)); | 291 | memcpy(&ls->ls_recall_sid, &ls->ls_stid.sc_stateid, sizeof(stateid_t)); |
@@ -454,8 +460,10 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp, | |||
454 | nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lrp->lr_sid, | 460 | nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lrp->lr_sid, |
455 | false, lrp->lr_layout_type, | 461 | false, lrp->lr_layout_type, |
456 | &ls); | 462 | &ls); |
457 | if (nfserr) | 463 | if (nfserr) { |
464 | trace_layout_return_lookup_fail(&lrp->lr_sid); | ||
458 | return nfserr; | 465 | return nfserr; |
466 | } | ||
459 | 467 | ||
460 | spin_lock(&ls->ls_lock); | 468 | spin_lock(&ls->ls_lock); |
461 | list_for_each_entry_safe(lp, n, &ls->ls_layouts, lo_perstate) { | 469 | list_for_each_entry_safe(lp, n, &ls->ls_layouts, lo_perstate) { |
@@ -472,6 +480,7 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp, | |||
472 | } | 480 | } |
473 | lrp->lrs_present = 1; | 481 | lrp->lrs_present = 1; |
474 | } else { | 482 | } else { |
483 | trace_layoutstate_unhash(&ls->ls_stid.sc_stateid); | ||
475 | nfs4_unhash_stid(&ls->ls_stid); | 484 | nfs4_unhash_stid(&ls->ls_stid); |
476 | lrp->lrs_present = 0; | 485 | lrp->lrs_present = 0; |
477 | } | 486 | } |
@@ -570,6 +579,8 @@ nfsd4_cb_layout_fail(struct nfs4_layout_stateid *ls) | |||
570 | 579 | ||
571 | rpc_ntop((struct sockaddr *)&clp->cl_addr, addr_str, sizeof(addr_str)); | 580 | rpc_ntop((struct sockaddr *)&clp->cl_addr, addr_str, sizeof(addr_str)); |
572 | 581 | ||
582 | nfsd4_cb_layout_fail(ls); | ||
583 | |||
573 | printk(KERN_WARNING | 584 | printk(KERN_WARNING |
574 | "nfsd: client %s failed to respond to layout recall. " | 585 | "nfsd: client %s failed to respond to layout recall. " |
575 | " Fencing..\n", addr_str); | 586 | " Fencing..\n", addr_str); |
@@ -597,6 +608,7 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task) | |||
597 | case 0: | 608 | case 0: |
598 | return 1; | 609 | return 1; |
599 | case -NFS4ERR_NOMATCHING_LAYOUT: | 610 | case -NFS4ERR_NOMATCHING_LAYOUT: |
611 | trace_layout_recall_done(&ls->ls_stid.sc_stateid); | ||
600 | task->tk_status = 0; | 612 | task->tk_status = 0; |
601 | return 1; | 613 | return 1; |
602 | case -NFS4ERR_DELAY: | 614 | case -NFS4ERR_DELAY: |
@@ -624,6 +636,8 @@ nfsd4_cb_layout_release(struct nfsd4_callback *cb) | |||
624 | container_of(cb, struct nfs4_layout_stateid, ls_recall); | 636 | container_of(cb, struct nfs4_layout_stateid, ls_recall); |
625 | LIST_HEAD(reaplist); | 637 | LIST_HEAD(reaplist); |
626 | 638 | ||
639 | trace_layout_recall_release(&ls->ls_stid.sc_stateid); | ||
640 | |||
627 | nfsd4_return_all_layouts(ls, &reaplist); | 641 | nfsd4_return_all_layouts(ls, &reaplist); |
628 | nfsd4_free_layouts(&reaplist); | 642 | nfsd4_free_layouts(&reaplist); |
629 | nfs4_put_stid(&ls->ls_stid); | 643 | nfs4_put_stid(&ls->ls_stid); |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index fa14359eb956..d30bea8d0277 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include "netns.h" | 44 | #include "netns.h" |
45 | #include "acl.h" | 45 | #include "acl.h" |
46 | #include "pnfs.h" | 46 | #include "pnfs.h" |
47 | #include "trace.h" | ||
47 | 48 | ||
48 | #ifdef CONFIG_NFSD_V4_SECURITY_LABEL | 49 | #ifdef CONFIG_NFSD_V4_SECURITY_LABEL |
49 | #include <linux/security.h> | 50 | #include <linux/security.h> |
@@ -1298,8 +1299,10 @@ nfsd4_layoutget(struct svc_rqst *rqstp, | |||
1298 | 1299 | ||
1299 | nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lgp->lg_sid, | 1300 | nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lgp->lg_sid, |
1300 | true, lgp->lg_layout_type, &ls); | 1301 | true, lgp->lg_layout_type, &ls); |
1301 | if (nfserr) | 1302 | if (nfserr) { |
1303 | trace_layout_get_lookup_fail(&lgp->lg_sid); | ||
1302 | goto out; | 1304 | goto out; |
1305 | } | ||
1303 | 1306 | ||
1304 | nfserr = nfserr_recallconflict; | 1307 | nfserr = nfserr_recallconflict; |
1305 | if (atomic_read(&ls->ls_stid.sc_file->fi_lo_recalls)) | 1308 | if (atomic_read(&ls->ls_stid.sc_file->fi_lo_recalls)) |
@@ -1359,6 +1362,7 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp, | |||
1359 | false, lcp->lc_layout_type, | 1362 | false, lcp->lc_layout_type, |
1360 | &ls); | 1363 | &ls); |
1361 | if (nfserr) { | 1364 | if (nfserr) { |
1365 | trace_layout_commit_lookup_fail(&lcp->lc_sid); | ||
1362 | /* fixup error code as per RFC5661 */ | 1366 | /* fixup error code as per RFC5661 */ |
1363 | if (nfserr == nfserr_bad_stateid) | 1367 | if (nfserr == nfserr_bad_stateid) |
1364 | nfserr = nfserr_badlayout; | 1368 | nfserr = nfserr_badlayout; |
diff --git a/fs/nfsd/trace.c b/fs/nfsd/trace.c new file mode 100644 index 000000000000..82f89070594c --- /dev/null +++ b/fs/nfsd/trace.c | |||
@@ -0,0 +1,5 @@ | |||
1 | |||
2 | #include "state.h" | ||
3 | |||
4 | #define CREATE_TRACE_POINTS | ||
5 | #include "trace.h" | ||
diff --git a/fs/nfsd/trace.h b/fs/nfsd/trace.h new file mode 100644 index 000000000000..c668520c344b --- /dev/null +++ b/fs/nfsd/trace.h | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2014 Christoph Hellwig. | ||
3 | */ | ||
4 | #undef TRACE_SYSTEM | ||
5 | #define TRACE_SYSTEM nfsd | ||
6 | |||
7 | #if !defined(_NFSD_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) | ||
8 | #define _NFSD_TRACE_H | ||
9 | |||
10 | #include <linux/tracepoint.h> | ||
11 | |||
12 | DECLARE_EVENT_CLASS(nfsd_stateid_class, | ||
13 | TP_PROTO(stateid_t *stp), | ||
14 | TP_ARGS(stp), | ||
15 | TP_STRUCT__entry( | ||
16 | __field(u32, cl_boot) | ||
17 | __field(u32, cl_id) | ||
18 | __field(u32, si_id) | ||
19 | __field(u32, si_generation) | ||
20 | ), | ||
21 | TP_fast_assign( | ||
22 | __entry->cl_boot = stp->si_opaque.so_clid.cl_boot; | ||
23 | __entry->cl_id = stp->si_opaque.so_clid.cl_id; | ||
24 | __entry->si_id = stp->si_opaque.so_id; | ||
25 | __entry->si_generation = stp->si_generation; | ||
26 | ), | ||
27 | TP_printk("client %08x:%08x stateid %08x:%08x", | ||
28 | __entry->cl_boot, | ||
29 | __entry->cl_id, | ||
30 | __entry->si_id, | ||
31 | __entry->si_generation) | ||
32 | ) | ||
33 | |||
34 | #define DEFINE_STATEID_EVENT(name) \ | ||
35 | DEFINE_EVENT(nfsd_stateid_class, name, \ | ||
36 | TP_PROTO(stateid_t *stp), \ | ||
37 | TP_ARGS(stp)) | ||
38 | DEFINE_STATEID_EVENT(layoutstate_alloc); | ||
39 | DEFINE_STATEID_EVENT(layoutstate_unhash); | ||
40 | DEFINE_STATEID_EVENT(layoutstate_free); | ||
41 | DEFINE_STATEID_EVENT(layout_get_lookup_fail); | ||
42 | DEFINE_STATEID_EVENT(layout_commit_lookup_fail); | ||
43 | DEFINE_STATEID_EVENT(layout_return_lookup_fail); | ||
44 | DEFINE_STATEID_EVENT(layout_recall); | ||
45 | DEFINE_STATEID_EVENT(layout_recall_done); | ||
46 | DEFINE_STATEID_EVENT(layout_recall_fail); | ||
47 | DEFINE_STATEID_EVENT(layout_recall_release); | ||
48 | |||
49 | #endif /* _NFSD_TRACE_H */ | ||
50 | |||
51 | #undef TRACE_INCLUDE_PATH | ||
52 | #define TRACE_INCLUDE_PATH . | ||
53 | #define TRACE_INCLUDE_FILE trace | ||
54 | #include <trace/define_trace.h> | ||