From de93c78b48541bceee0a0a39dc14241c8e1f082e Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 30 Jul 2019 11:52:16 -0400 Subject: [PATCH] ceph: new tracepoints when adding and removing caps Add support for two new tracepoints surrounding the adding/updating and removing of caps from the cache. To support this, we also add new functions for printing cap strings a'la ceph_cap_string(). Signed-off-by: Jeff Layton --- fs/ceph/Makefile | 3 +- fs/ceph/caps.c | 7 +++++ fs/ceph/trace.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ fs/ceph/trace.h | 56 +++++++++++++++++++++++++++++++++++ 4 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 fs/ceph/trace.c create mode 100644 fs/ceph/trace.h diff --git a/fs/ceph/Makefile b/fs/ceph/Makefile index c1da294418d14..4e14d09bdaeba 100644 --- a/fs/ceph/Makefile +++ b/fs/ceph/Makefile @@ -3,12 +3,13 @@ # Makefile for CEPH filesystem. # +ccflags-y += -I$(src) # needed for trace events obj-$(CONFIG_CEPH_FS) += ceph.o ceph-y := super.o inode.o dir.o file.o locks.o addr.o ioctl.o \ export.o caps.o snap.o xattr.o quota.o io.o \ mds_client.o mdsmap.o strings.o ceph_frag.o \ - debugfs.o + debugfs.o trace.o ceph-$(CONFIG_CEPH_FSCACHE) += cache.o ceph-$(CONFIG_CEPH_FS_POSIX_ACL) += acl.o diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index b96fb1378479e..db4602c83363e 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -13,6 +13,7 @@ #include "super.h" #include "mds_client.h" #include "cache.h" +#include "trace.h" #include #include @@ -756,6 +757,8 @@ void ceph_add_cap(struct inode *inode, if (fmode >= 0) __ceph_get_fmode(ci, fmode); + + trace_ceph_add_cap(cap); } /* @@ -1074,6 +1077,7 @@ void __ceph_remove_cap(struct ceph_cap *cap, bool queue_release) int removed = 0; dout("__ceph_remove_cap %p from %p\n", cap, &ci->vfs_inode); + trace_ceph_remove_cap(cap); /* remove from inode's cap rbtree, and clear auth cap */ rb_erase(&cap->ci_node, &ci->i_caps); @@ -3382,8 +3386,11 @@ static void handle_cap_grant(struct inode *inode, * pending revocation */ wake = true; } + BUG_ON(cap->issued & ~cap->implemented); + trace_ceph_handle_cap_grant(cap); + if (extra_info->inline_version > 0 && extra_info->inline_version >= ci->i_inline_version) { ci->i_inline_version = extra_info->inline_version; diff --git a/fs/ceph/trace.c b/fs/ceph/trace.c new file mode 100644 index 0000000000000..19a67a8457e5e --- /dev/null +++ b/fs/ceph/trace.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0 +#define CREATE_TRACE_POINTS +#include +#include "trace.h" + +#define CEPH_CAP_BASE_MASK (CEPH_CAP_GSHARED|CEPH_CAP_GEXCL) +#define CEPH_CAP_FILE_MASK (CEPH_CAP_GSHARED | \ + CEPH_CAP_GEXCL | \ + CEPH_CAP_GCACHE | \ + CEPH_CAP_GRD | \ + CEPH_CAP_GWR | \ + CEPH_CAP_GBUFFER | \ + CEPH_CAP_GWREXTEND | \ + CEPH_CAP_GLAZYIO) + +static void +trace_gcap_string(struct trace_seq *p, int c) +{ + if (c & CEPH_CAP_GSHARED) + trace_seq_putc(p, 's'); + if (c & CEPH_CAP_GEXCL) + trace_seq_putc(p, 'x'); + if (c & CEPH_CAP_GCACHE) + trace_seq_putc(p, 'c'); + if (c & CEPH_CAP_GRD) + trace_seq_putc(p, 'r'); + if (c & CEPH_CAP_GWR) + trace_seq_putc(p, 'w'); + if (c & CEPH_CAP_GBUFFER) + trace_seq_putc(p, 'b'); + if (c & CEPH_CAP_GWREXTEND) + trace_seq_putc(p, 'a'); + if (c & CEPH_CAP_GLAZYIO) + trace_seq_putc(p, 'l'); +} + +const char * +trace_ceph_cap_string(struct trace_seq *p, int caps) +{ + int c; + const char *ret = trace_seq_buffer_ptr(p); + + if (caps == 0) { + trace_seq_putc(p, '-'); + goto out; + } + + if (caps & CEPH_CAP_PIN) + trace_seq_putc(p, 'p'); + + c = (caps >> CEPH_CAP_SAUTH) & CEPH_CAP_BASE_MASK; + if (c) { + trace_seq_putc(p, 'A'); + trace_gcap_string(p, c); + } + + c = (caps >> CEPH_CAP_SLINK) & CEPH_CAP_BASE_MASK; + if (c) { + trace_seq_putc(p, 'L'); + trace_gcap_string(p, c); + } + + c = (caps >> CEPH_CAP_SXATTR) & CEPH_CAP_BASE_MASK; + if (c) { + trace_seq_putc(p, 'X'); + trace_gcap_string(p, c); + } + + c = (caps >> CEPH_CAP_SFILE) & CEPH_CAP_FILE_MASK; + if (c) { + trace_seq_putc(p, 'F'); + trace_gcap_string(p, c); + } +out: + trace_seq_putc(p, '\0'); + return ret; +} diff --git a/fs/ceph/trace.h b/fs/ceph/trace.h new file mode 100644 index 0000000000000..3a9a7706c5537 --- /dev/null +++ b/fs/ceph/trace.h @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM ceph + +#if !defined(_CEPH_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _CEPH_TRACE_H + +#include +#include +#include "super.h" + +const char *trace_ceph_cap_string(struct trace_seq *p, int caps); +#define show_caps(caps) ({ trace_ceph_cap_string(p, caps); }) + +#define show_snapid(snap) \ + __print_symbolic_u64(snap, {CEPH_NOSNAP, "NOSNAP" }) + +DECLARE_EVENT_CLASS(ceph_cap_class, + TP_PROTO(struct ceph_cap *cap), + TP_ARGS(cap), + TP_STRUCT__entry( + __field(u64, ino) + __field(u64, snap) + __field(int, issued) + __field(int, implemented) + __field(int, mds) + __field(int, mds_wanted) + ), + TP_fast_assign( + __entry->ino = cap->ci->i_vino.ino; + __entry->snap = cap->ci->i_vino.snap; + __entry->issued = cap->issued; + __entry->implemented = cap->implemented; + __entry->mds = cap->mds; + __entry->mds_wanted = cap->mds_wanted; + ), + TP_printk("ino=%s:0x%llx mds=%d issued=%s implemented=%s mds_wanted=%s", + show_snapid(__entry->snap), __entry->ino, __entry->mds, + show_caps(__entry->issued), show_caps(__entry->implemented), + show_caps(__entry->mds_wanted)) +) + +#define DEFINE_CEPH_CAP_EVENT(name) \ +DEFINE_EVENT(ceph_cap_class, ceph_##name, \ + TP_PROTO(struct ceph_cap *cap), \ + TP_ARGS(cap)) + +DEFINE_CEPH_CAP_EVENT(add_cap); +DEFINE_CEPH_CAP_EVENT(remove_cap); +DEFINE_CEPH_CAP_EVENT(handle_cap_grant); + +#endif /* _CEPH_TRACE_H */ + +#define TRACE_INCLUDE_PATH . +#define TRACE_INCLUDE_FILE trace +#include -- 2.39.5