Commit 31ef83dc authored by Christoph Hellwig's avatar Christoph Hellwig

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: default avatarChristoph Hellwig <hch@lst.de>
parent 18d1aef8
...@@ -2,9 +2,14 @@ ...@@ -2,9 +2,14 @@
# Makefile for the Linux nfs server # Makefile for the Linux nfs server
# #
ccflags-y += -I$(src) # needed for trace events
obj-$(CONFIG_NFSD) += nfsd.o obj-$(CONFIG_NFSD) += nfsd.o
nfsd-y := nfssvc.o nfsctl.o nfsproc.o nfsfh.o vfs.o \ # this one should be compiled first, as the tracing macros can easily blow up
nfsd-y += trace.o
nfsd-y += nfssvc.o nfsctl.o nfsproc.o nfsfh.o vfs.o \
export.o auth.o lockd.o nfscache.o nfsxdr.o stats.o export.o auth.o lockd.o nfscache.o nfsxdr.o stats.o
nfsd-$(CONFIG_NFSD_FAULT_INJECTION) += fault_inject.o nfsd-$(CONFIG_NFSD_FAULT_INJECTION) += fault_inject.o
nfsd-$(CONFIG_NFSD_V2_ACL) += nfs2acl.o nfsd-$(CONFIG_NFSD_V2_ACL) += nfs2acl.o
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "pnfs.h" #include "pnfs.h"
#include "netns.h" #include "netns.h"
#include "trace.h"
#define NFSDDBG_FACILITY NFSDDBG_PNFS #define NFSDDBG_FACILITY NFSDDBG_PNFS
...@@ -125,6 +126,8 @@ nfsd4_free_layout_stateid(struct nfs4_stid *stid) ...@@ -125,6 +126,8 @@ nfsd4_free_layout_stateid(struct nfs4_stid *stid)
struct nfs4_client *clp = ls->ls_stid.sc_client; struct nfs4_client *clp = ls->ls_stid.sc_client;
struct nfs4_file *fp = ls->ls_stid.sc_file; struct nfs4_file *fp = ls->ls_stid.sc_file;
trace_layoutstate_free(&ls->ls_stid.sc_stateid);
spin_lock(&clp->cl_lock); spin_lock(&clp->cl_lock);
list_del_init(&ls->ls_perclnt); list_del_init(&ls->ls_perclnt);
spin_unlock(&clp->cl_lock); spin_unlock(&clp->cl_lock);
...@@ -215,6 +218,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate, ...@@ -215,6 +218,7 @@ nfsd4_alloc_layout_stateid(struct nfsd4_compound_state *cstate,
list_add(&ls->ls_perfile, &fp->fi_lo_states); list_add(&ls->ls_perfile, &fp->fi_lo_states);
spin_unlock(&fp->fi_lock); spin_unlock(&fp->fi_lock);
trace_layoutstate_alloc(&ls->ls_stid.sc_stateid);
return ls; return ls;
} }
...@@ -280,6 +284,8 @@ nfsd4_recall_file_layout(struct nfs4_layout_stateid *ls) ...@@ -280,6 +284,8 @@ nfsd4_recall_file_layout(struct nfs4_layout_stateid *ls)
if (list_empty(&ls->ls_layouts)) if (list_empty(&ls->ls_layouts))
goto out_unlock; goto out_unlock;
trace_layout_recall(&ls->ls_stid.sc_stateid);
atomic_inc(&ls->ls_stid.sc_count); atomic_inc(&ls->ls_stid.sc_count);
update_stateid(&ls->ls_stid.sc_stateid); update_stateid(&ls->ls_stid.sc_stateid);
memcpy(&ls->ls_recall_sid, &ls->ls_stid.sc_stateid, sizeof(stateid_t)); 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,8 +460,10 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp,
nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lrp->lr_sid, nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lrp->lr_sid,
false, lrp->lr_layout_type, false, lrp->lr_layout_type,
&ls); &ls);
if (nfserr) if (nfserr) {
trace_layout_return_lookup_fail(&lrp->lr_sid);
return nfserr; return nfserr;
}
spin_lock(&ls->ls_lock); spin_lock(&ls->ls_lock);
list_for_each_entry_safe(lp, n, &ls->ls_layouts, lo_perstate) { 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,6 +480,7 @@ nfsd4_return_file_layouts(struct svc_rqst *rqstp,
} }
lrp->lrs_present = 1; lrp->lrs_present = 1;
} else { } else {
trace_layoutstate_unhash(&ls->ls_stid.sc_stateid);
nfs4_unhash_stid(&ls->ls_stid); nfs4_unhash_stid(&ls->ls_stid);
lrp->lrs_present = 0; lrp->lrs_present = 0;
} }
...@@ -570,6 +579,8 @@ nfsd4_cb_layout_fail(struct nfs4_layout_stateid *ls) ...@@ -570,6 +579,8 @@ nfsd4_cb_layout_fail(struct nfs4_layout_stateid *ls)
rpc_ntop((struct sockaddr *)&clp->cl_addr, addr_str, sizeof(addr_str)); rpc_ntop((struct sockaddr *)&clp->cl_addr, addr_str, sizeof(addr_str));
nfsd4_cb_layout_fail(ls);
printk(KERN_WARNING printk(KERN_WARNING
"nfsd: client %s failed to respond to layout recall. " "nfsd: client %s failed to respond to layout recall. "
" Fencing..\n", addr_str); " Fencing..\n", addr_str);
...@@ -597,6 +608,7 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task) ...@@ -597,6 +608,7 @@ nfsd4_cb_layout_done(struct nfsd4_callback *cb, struct rpc_task *task)
case 0: case 0:
return 1; return 1;
case -NFS4ERR_NOMATCHING_LAYOUT: case -NFS4ERR_NOMATCHING_LAYOUT:
trace_layout_recall_done(&ls->ls_stid.sc_stateid);
task->tk_status = 0; task->tk_status = 0;
return 1; return 1;
case -NFS4ERR_DELAY: case -NFS4ERR_DELAY:
...@@ -624,6 +636,8 @@ nfsd4_cb_layout_release(struct nfsd4_callback *cb) ...@@ -624,6 +636,8 @@ nfsd4_cb_layout_release(struct nfsd4_callback *cb)
container_of(cb, struct nfs4_layout_stateid, ls_recall); container_of(cb, struct nfs4_layout_stateid, ls_recall);
LIST_HEAD(reaplist); LIST_HEAD(reaplist);
trace_layout_recall_release(&ls->ls_stid.sc_stateid);
nfsd4_return_all_layouts(ls, &reaplist); nfsd4_return_all_layouts(ls, &reaplist);
nfsd4_free_layouts(&reaplist); nfsd4_free_layouts(&reaplist);
nfs4_put_stid(&ls->ls_stid); nfs4_put_stid(&ls->ls_stid);
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "netns.h" #include "netns.h"
#include "acl.h" #include "acl.h"
#include "pnfs.h" #include "pnfs.h"
#include "trace.h"
#ifdef CONFIG_NFSD_V4_SECURITY_LABEL #ifdef CONFIG_NFSD_V4_SECURITY_LABEL
#include <linux/security.h> #include <linux/security.h>
...@@ -1298,8 +1299,10 @@ nfsd4_layoutget(struct svc_rqst *rqstp, ...@@ -1298,8 +1299,10 @@ nfsd4_layoutget(struct svc_rqst *rqstp,
nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lgp->lg_sid, nfserr = nfsd4_preprocess_layout_stateid(rqstp, cstate, &lgp->lg_sid,
true, lgp->lg_layout_type, &ls); true, lgp->lg_layout_type, &ls);
if (nfserr) if (nfserr) {
trace_layout_get_lookup_fail(&lgp->lg_sid);
goto out; goto out;
}
nfserr = nfserr_recallconflict; nfserr = nfserr_recallconflict;
if (atomic_read(&ls->ls_stid.sc_file->fi_lo_recalls)) if (atomic_read(&ls->ls_stid.sc_file->fi_lo_recalls))
...@@ -1359,6 +1362,7 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp, ...@@ -1359,6 +1362,7 @@ nfsd4_layoutcommit(struct svc_rqst *rqstp,
false, lcp->lc_layout_type, false, lcp->lc_layout_type,
&ls); &ls);
if (nfserr) { if (nfserr) {
trace_layout_commit_lookup_fail(&lcp->lc_sid);
/* fixup error code as per RFC5661 */ /* fixup error code as per RFC5661 */
if (nfserr == nfserr_bad_stateid) if (nfserr == nfserr_bad_stateid)
nfserr = nfserr_badlayout; nfserr = nfserr_badlayout;
......
#include "state.h"
#define CREATE_TRACE_POINTS
#include "trace.h"
/*
* Copyright (c) 2014 Christoph Hellwig.
*/
#undef TRACE_SYSTEM
#define TRACE_SYSTEM nfsd
#if !defined(_NFSD_TRACE_H) || defined(TRACE_HEADER_MULTI_READ)
#define _NFSD_TRACE_H
#include <linux/tracepoint.h>
DECLARE_EVENT_CLASS(nfsd_stateid_class,
TP_PROTO(stateid_t *stp),
TP_ARGS(stp),
TP_STRUCT__entry(
__field(u32, cl_boot)
__field(u32, cl_id)
__field(u32, si_id)
__field(u32, si_generation)
),
TP_fast_assign(
__entry->cl_boot = stp->si_opaque.so_clid.cl_boot;
__entry->cl_id = stp->si_opaque.so_clid.cl_id;
__entry->si_id = stp->si_opaque.so_id;
__entry->si_generation = stp->si_generation;
),
TP_printk("client %08x:%08x stateid %08x:%08x",
__entry->cl_boot,
__entry->cl_id,
__entry->si_id,
__entry->si_generation)
)
#define DEFINE_STATEID_EVENT(name) \
DEFINE_EVENT(nfsd_stateid_class, name, \
TP_PROTO(stateid_t *stp), \
TP_ARGS(stp))
DEFINE_STATEID_EVENT(layoutstate_alloc);
DEFINE_STATEID_EVENT(layoutstate_unhash);
DEFINE_STATEID_EVENT(layoutstate_free);
DEFINE_STATEID_EVENT(layout_get_lookup_fail);
DEFINE_STATEID_EVENT(layout_commit_lookup_fail);
DEFINE_STATEID_EVENT(layout_return_lookup_fail);
DEFINE_STATEID_EVENT(layout_recall);
DEFINE_STATEID_EVENT(layout_recall_done);
DEFINE_STATEID_EVENT(layout_recall_fail);
DEFINE_STATEID_EVENT(layout_recall_release);
#endif /* _NFSD_TRACE_H */
#undef TRACE_INCLUDE_PATH
#define TRACE_INCLUDE_PATH .
#define TRACE_INCLUDE_FILE trace
#include <trace/define_trace.h>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment