From 955d940c647b9ef5d33a0ecded6443a0942abcfe Mon Sep 17 00:00:00 2001 From: Zach Brown Date: Wed, 15 Feb 2017 13:10:27 -0800 Subject: [PATCH] Restore key tracing Now that the keys are a contiguous buffer we can format them for the trace buffers with a much more straight forward type check around per-key snprintfs. We can get rid of all the weird kvec code that tried to deal with keys that straddled vectors. With that fixed we can uncomment out the tracing statements that were waiting the key formatting. I was testing with xattr keys so they're added as the code is updated. The rest of the key types will be added seperately as they're used. Signed-off-by: Zach Brown --- kmod/src/item.c | 4 +- kmod/src/key.c | 67 ++++++++++++++++++ kmod/src/key.h | 2 + kmod/src/kvec.c | 148 --------------------------------------- kmod/src/kvec.h | 2 - kmod/src/manifest.c | 2 +- kmod/src/scoutfs_trace.h | 30 ++++---- 7 files changed, 88 insertions(+), 167 deletions(-) diff --git a/kmod/src/item.c b/kmod/src/item.c index e489005f..606c80e9 100644 --- a/kmod/src/item.c +++ b/kmod/src/item.c @@ -539,7 +539,7 @@ int scoutfs_item_lookup(struct super_block *sb, struct scoutfs_key_buf *key, unsigned long flags; int ret; -// trace_scoutfs_item_lookup(sb, key, val); + trace_scoutfs_item_lookup(sb, key, val); end = scoutfs_key_alloc(sb, SCOUTFS_MAX_KEY_SIZE); if (!end) { @@ -944,7 +944,7 @@ int scoutfs_item_insert_batch(struct super_block *sb, struct list_head *list, unsigned long flags; int ret; -// trace_scoutfs_item_insert_batch(sb, start, end); + trace_scoutfs_item_insert_batch(sb, start, end); if (WARN_ON_ONCE(scoutfs_key_compare(start, end) > 0)) return -EINVAL; diff --git a/kmod/src/key.c b/kmod/src/key.c index 04891839..abcfac9f 100644 --- a/kmod/src/key.c +++ b/kmod/src/key.c @@ -106,3 +106,70 @@ void scoutfs_key_dec(struct scoutfs_key_buf *key) extend_zeros(key); scoutfs_key_dec_cur_len(key); } + +/* return the bytes of the string including the null term */ +#define snprintf_null(buf, size, fmt, args...) \ + (snprintf((buf), (size), fmt, ##args) + 1) + +/* + * Write the null-terminated string that describes the key to the + * buffer. The bytes copied (including the null) is returned. A null + * buffer can be used to find the string size without writing anything. + * + * XXX nonprintable characters in the trace? + */ +int scoutfs_key_str(char *buf, struct scoutfs_key_buf *key) +{ + size_t size = buf ? INT_MAX : 0; + int len; + u8 type; + + if (key->key_len == 0) + return snprintf_null(buf, size, "[0 len]"); + + type = *(u8 *)key->data; + + switch(type) { + + case SCOUTFS_INODE_KEY: { + struct scoutfs_inode_key *ikey = key->data; + + if (key->key_len < sizeof(struct scoutfs_inode_key)) + break; + + return snprintf_null(buf, size, "ino.%llu", + be64_to_cpu(ikey->ino)); + } + + case SCOUTFS_XATTR_KEY: { + struct scoutfs_xattr_key *xkey = key->data; + + len = (int)key->key_len - offsetof(struct scoutfs_xattr_key, + name[1]); + if (len <= 0) + break; + + return snprintf_null(buf, size, "xat.%llu.%.*s", + be64_to_cpu(xkey->ino), len, xkey->name); + } + + case SCOUTFS_DIRENT_KEY: { + struct scoutfs_dirent_key *dkey = key->data; + + len = (int)key->key_len - offsetof(struct scoutfs_dirent_key, + name[1]); + if (len <= 0) + break; + + return snprintf_null(buf, size, "dnt.%llu.%.*s", + be64_to_cpu(dkey->ino), len, dkey->name); + } + + default: + return snprintf_null(buf, size, "[unknown type %u len %u]", + type, key->key_len); + } + + return snprintf_null(buf, size, "[truncated type %u len %u]", + type, key->key_len); +} diff --git a/kmod/src/key.h b/kmod/src/key.h index 3c108555..26f4b499 100644 --- a/kmod/src/key.h +++ b/kmod/src/key.h @@ -19,6 +19,8 @@ void scoutfs_key_inc_cur_len(struct scoutfs_key_buf *key); void scoutfs_key_dec(struct scoutfs_key_buf *key); void scoutfs_key_dec_cur_len(struct scoutfs_key_buf *key); +int scoutfs_key_str(char *buf, struct scoutfs_key_buf *key); + /* * Initialize a small key in a larger allocated buffer. This lets * callers, for example, search for a small key and get a larger key diff --git a/kmod/src/kvec.c b/kmod/src/kvec.c index 422a4fc5..ca4bcf22 100644 --- a/kmod/src/kvec.c +++ b/kmod/src/kvec.c @@ -76,12 +76,6 @@ static size_t iter_contig(struct iter *iter) return 0; } -/* count of bytes remaining in the iteration */ -static size_t iter_count(struct iter *iter) -{ - return iter->count; -} - /* * Return the result of memcmp between the min of the two total lengths. * If their shorter lengths are equal than the shorter length is considered @@ -296,145 +290,3 @@ void scoutfs_kvec_clone_less(struct kvec *dst, struct kvec *src) scoutfs_kvec_memcmp(src, dst) < 0) scoutfs_kvec_clone(dst, src); } - -/* - * Copy bytes from the kvec iterator into the dest buffer, zeroing the - * remainder of the buffer if there aren't enough bytes available in - * the iterator. If the tail bool is set then the kvec data is copied - * into the tail of the buffer and the head is zeroed. - */ -static bool iter_memcpy_zero(void *dst, struct iter *src, size_t len, bool tail) -{ - size_t ctg; - size_t diff; - - if (len == 0 || iter_count(src) == 0) - return false; - - if (iter_count(src) < len) { - diff = len - iter_count(src); - if (tail) { - memset(dst, 0, diff); - dst += diff; - } else { - memset(dst + len - diff, 0, diff); - } - len = iter_count(src); - } - - while ((ctg = min(len, iter_contig(src)))) { - memcpy(dst, iter_ptr(src), ctg); - iter_advance(src, ctg); - dst += ctg; - len -= ctg; - } - - return true; -} - -static int iter_puts_printable(char *dst, struct iter *src) -{ - int len = iter_count(src); - size_t ctg; - int i; - - while ((ctg = iter_contig(src))) { - memcpy(dst, iter_ptr(src), ctg); - iter_advance(src, ctg); - - for (i = 0; i < ctg; i++) { - if (!isprint(dst[i])) - dst[i] = '_'; - } - - dst += ctg; - } - - return len; -} - -#define EMPTY_STR "''" -#define U64_U_BYTES 20 -#define U64_D_BYTES 21 -#define U64_X_BYTES 16 - -/* - * XXX figure out what to do about corrupt keys. - */ - -unsigned scoutfs_kvec_key_strlen(struct kvec *key) -{ - struct iter iter; - unsigned len = 0; - u8 type; - - iter_init(&iter, key); - - if (iter_count(&iter) == 0) { - len = sizeof(EMPTY_STR) - 1; - goto out; - } - - iter_memcpy_zero(&type, &iter, sizeof(type), false); - - len = 4; /* "typ." */ - - switch(type) { - case SCOUTFS_INODE_KEY: - len += U64_U_BYTES; - break; - case SCOUTFS_DIRENT_KEY: - len += U64_U_BYTES + (iter_count(&iter) - 8); - break; - case SCOUTFS_MAX_UNUSED_KEY: - break; - default: - /* hex of everything after the type */ - len += (scoutfs_kvec_length(key) - 1) * 2; - break; - } - -out: - return len + 1; /* null term */ -} - -void scoutfs_kvec_key_sprintf(char *buf, struct kvec *key) -{ - struct iter iter; - __be64 be; - u8 type; - - iter_init(&iter, key); - - if (iter_contig(&iter) == 0) { - buf += sprintf(buf, EMPTY_STR); - goto done; - } - - iter_memcpy_zero(&type, &iter, sizeof(type), false); - - switch(type) { - case SCOUTFS_INODE_KEY: - buf += sprintf(buf, "ino."); - iter_memcpy_zero(&be, &iter, sizeof(be), false); - buf += sprintf(buf, "%llu", be64_to_cpu(be)); - break; - case SCOUTFS_DIRENT_KEY: - buf += sprintf(buf, "den."); - iter_memcpy_zero(&be, &iter, sizeof(be), false); - buf += sprintf(buf, "%llu.", be64_to_cpu(be)); - buf += iter_puts_printable(buf, &iter); - break; - case SCOUTFS_MAX_UNUSED_KEY: - buf += sprintf(buf, "max"); - break; - default: - buf += sprintf(buf, "unk."); - while (iter_memcpy_zero(&be, &iter, sizeof(be), true)) - buf += sprintf(buf, "%llx", be64_to_cpu(be)); - break; - } - -done: - *buf = '\0'; -} diff --git a/kmod/src/kvec.h b/kmod/src/kvec.h index 444a8116..c078e802 100644 --- a/kmod/src/kvec.h +++ b/kmod/src/kvec.h @@ -66,8 +66,6 @@ int scoutfs_kvec_alloc_key(struct kvec *kvec); void scoutfs_kvec_init_key(struct kvec *kvec); void scoutfs_kvec_set_max_key(struct kvec *kvec); void scoutfs_kvec_clone_less(struct kvec *dst, struct kvec *src); -unsigned scoutfs_kvec_key_strlen(struct kvec *key); -void scoutfs_kvec_key_sprintf(char *buf, struct kvec *key); void scoutfs_kvec_be_inc(struct kvec *kvec); void scoutfs_kvec_be_dec(struct kvec *kvec); diff --git a/kmod/src/manifest.c b/kmod/src/manifest.c index f8c4edb5..fd2aeda8 100644 --- a/kmod/src/manifest.c +++ b/kmod/src/manifest.c @@ -194,7 +194,7 @@ int scoutfs_manifest_add(struct super_block *sb, unsigned bytes; int ret; -// trace_scoutfs_manifest_add(sb, first, last, segno, seq, level); + trace_scoutfs_manifest_add(sb, first, last, segno, seq, level); key_bytes = first->key_len + last->key_len; bytes = offsetof(struct scoutfs_manifest_entry, keys[key_bytes]); diff --git a/kmod/src/scoutfs_trace.h b/kmod/src/scoutfs_trace.h index 669b99f4..6b5a828c 100644 --- a/kmod/src/scoutfs_trace.h +++ b/kmod/src/scoutfs_trace.h @@ -181,19 +181,19 @@ TRACE_EVENT(scoutfs_scan_orphans, ); TRACE_EVENT(scoutfs_manifest_add, - TP_PROTO(struct super_block *sb, struct kvec *first, - struct kvec *last, u64 segno, u64 seq, u8 level), + TP_PROTO(struct super_block *sb, struct scoutfs_key_buf *first, + struct scoutfs_key_buf *last, u64 segno, u64 seq, u8 level), TP_ARGS(sb, first, last, segno, seq, level), TP_STRUCT__entry( - __dynamic_array(char, first, scoutfs_kvec_key_strlen(first)) - __dynamic_array(char, last, scoutfs_kvec_key_strlen(last)) + __dynamic_array(char, first, scoutfs_key_str(NULL, first)) + __dynamic_array(char, last, scoutfs_key_str(NULL, last)) __field(u64, segno) __field(u64, seq) __field(u8, level) ), TP_fast_assign( - scoutfs_kvec_key_sprintf(__get_dynamic_array(first), first); - scoutfs_kvec_key_sprintf(__get_dynamic_array(last), last); + scoutfs_key_str(__get_dynamic_array(first), first); + scoutfs_key_str(__get_dynamic_array(last), last); __entry->segno = segno; __entry->seq = seq; __entry->level = level; @@ -204,27 +204,29 @@ TRACE_EVENT(scoutfs_manifest_add, ); TRACE_EVENT(scoutfs_item_lookup, - TP_PROTO(struct super_block *sb, struct kvec *key, struct kvec *val), + TP_PROTO(struct super_block *sb, struct scoutfs_key_buf *key, + struct kvec *val), TP_ARGS(sb, key, val), TP_STRUCT__entry( - __dynamic_array(char, key, scoutfs_kvec_key_strlen(key)) + __dynamic_array(char, key, scoutfs_key_str(NULL, key)) ), TP_fast_assign( - scoutfs_kvec_key_sprintf(__get_dynamic_array(key), key); + scoutfs_key_str(__get_dynamic_array(key), key); ), TP_printk("key %s", __get_str(key)) ); TRACE_EVENT(scoutfs_item_insert_batch, - TP_PROTO(struct super_block *sb, struct kvec *start, struct kvec *end), + TP_PROTO(struct super_block *sb, struct scoutfs_key_buf *start, + struct scoutfs_key_buf *end), TP_ARGS(sb, start, end), TP_STRUCT__entry( - __dynamic_array(char, start, scoutfs_kvec_key_strlen(start)) - __dynamic_array(char, end, scoutfs_kvec_key_strlen(end)) + __dynamic_array(char, start, scoutfs_key_str(NULL, start)) + __dynamic_array(char, end, scoutfs_key_str(NULL, end)) ), TP_fast_assign( - scoutfs_kvec_key_sprintf(__get_dynamic_array(start), start); - scoutfs_kvec_key_sprintf(__get_dynamic_array(end), end); + scoutfs_key_str(__get_dynamic_array(start), start); + scoutfs_key_str(__get_dynamic_array(end), end); ), TP_printk("start %s end %s", __get_str(start), __get_str(end)) );