]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-client.git/commitdiff
ceph: new tracepoints when adding and removing caps
authorJeff Layton <jlayton@kernel.org>
Tue, 30 Jul 2019 15:52:16 +0000 (11:52 -0400)
committerJeff Layton <jlayton@kernel.org>
Fri, 10 Jan 2020 16:54:25 +0000 (11:54 -0500)
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 <jlayton@kernel.org>
fs/ceph/Makefile
fs/ceph/caps.c
fs/ceph/trace.c [new file with mode: 0644]
fs/ceph/trace.h [new file with mode: 0644]

index c1da294418d14b86ea77feaa7027ea880b605ed3..4e14d09bdaebae7e70695e47f7942397386d045a 100644 (file)
@@ -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
index b96fb1378479eda1a96900e4a3b58a8f5d34d31a..db4602c83363e97d25a0e970d59505ecfe13dbb7 100644 (file)
@@ -13,6 +13,7 @@
 #include "super.h"
 #include "mds_client.h"
 #include "cache.h"
+#include "trace.h"
 #include <linux/ceph/decode.h>
 #include <linux/ceph/messenger.h>
 
@@ -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 (file)
index 0000000..19a67a8
--- /dev/null
@@ -0,0 +1,77 @@
+// SPDX-License-Identifier: GPL-2.0
+#define CREATE_TRACE_POINTS
+#include <linux/ceph/ceph_debug.h>
+#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 (file)
index 0000000..3a9a770
--- /dev/null
@@ -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 <linux/tracepoint.h>
+#include <linux/trace_seq.h>
+#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 <trace/define_trace.h>