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)) );