mirror of
https://github.com/versity/scoutfs.git
synced 2026-09-05 07:36:59 +00:00
scoutfs: add SK_ helpers for printing keys
Add some percpu string buffers so that we can pass formatted strings as arguments when printing keys. The percpu struct uses a different buffer for each argument. We wrap the whole print call in a wrapper that disables and enables preemption. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
+53
-2
@@ -116,9 +116,8 @@ void scoutfs_key_dec(struct scoutfs_key_buf *key)
|
||||
*
|
||||
* XXX nonprintable characters in the trace?
|
||||
*/
|
||||
int scoutfs_key_str(char *buf, struct scoutfs_key_buf *key)
|
||||
int scoutfs_key_str_size(char *buf, struct scoutfs_key_buf *key, size_t size)
|
||||
{
|
||||
size_t size = buf ? INT_MAX : 0;
|
||||
int len;
|
||||
u8 type;
|
||||
|
||||
@@ -170,3 +169,55 @@ int scoutfs_key_str(char *buf, struct scoutfs_key_buf *key)
|
||||
return snprintf_null(buf, size, "[truncated type %u len %u]",
|
||||
type, key->key_len);
|
||||
}
|
||||
|
||||
/*
|
||||
* A null buf can be set to find the length of the formatted string.
|
||||
*/
|
||||
int scoutfs_key_str(char *buf, struct scoutfs_key_buf *key)
|
||||
{
|
||||
return scoutfs_key_str_size(buf, key, buf ? INT_MAX : 0);
|
||||
}
|
||||
|
||||
#define MAX_STR_COUNT 10
|
||||
|
||||
struct key_strings {
|
||||
bool started;
|
||||
int next_str;
|
||||
char strings[MAX_STR_COUNT][SK_STR_BYTES];
|
||||
};
|
||||
|
||||
static DEFINE_PER_CPU(struct key_strings, percpu_key_strings);
|
||||
|
||||
void scoutfs_key_start_percpu(void)
|
||||
{
|
||||
struct key_strings *ks = this_cpu_ptr(&percpu_key_strings);
|
||||
|
||||
BUG_ON(ks->started);
|
||||
ks->started = true;
|
||||
get_cpu();
|
||||
}
|
||||
|
||||
char *scoutfs_key_percpu_string(void)
|
||||
{
|
||||
struct key_strings *ks = this_cpu_ptr(&percpu_key_strings);
|
||||
char *str;
|
||||
|
||||
BUG_ON(!ks->started);
|
||||
|
||||
str = ks->strings[ks->next_str++];
|
||||
BUG_ON(ks->next_str >= MAX_STR_COUNT);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
void scoutfs_key_finish_percpu(void)
|
||||
{
|
||||
struct key_strings *ks = this_cpu_ptr(&percpu_key_strings);
|
||||
|
||||
BUG_ON(!ks->started);
|
||||
|
||||
ks->next_str = 0;
|
||||
ks->started = false;
|
||||
|
||||
put_cpu();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,36 @@ 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_size(char *buf, struct scoutfs_key_buf *key, size_t size);
|
||||
int scoutfs_key_str(char *buf, struct scoutfs_key_buf *key);
|
||||
void scoutfs_key_start_percpu(void);
|
||||
char *scoutfs_key_percpu_string(void);
|
||||
void scoutfs_key_finish_percpu(void);
|
||||
|
||||
#define SK_PCPU(statements) do { \
|
||||
scoutfs_key_start_percpu(); \
|
||||
{ statements; } \
|
||||
scoutfs_key_finish_percpu(); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* The biggest keys are typically a little struct then a large name. The
|
||||
* string representation will tend to be mostly the name, but some of the
|
||||
* strict fields can blow up from say 8 bytes to 20 bytes. So we give
|
||||
* a lot of padding for that.
|
||||
*/
|
||||
#define SK_STR_BYTES (100 + SCOUTFS_MAX_KEY_SIZE)
|
||||
|
||||
#define SK_FMT "%s"
|
||||
#define SK_ARG(k) \
|
||||
({ \
|
||||
char *__str = scoutfs_key_percpu_string(); \
|
||||
scoutfs_key_str_size(__str, k, SK_STR_BYTES); \
|
||||
__str; \
|
||||
})
|
||||
|
||||
#define SK_TRACE_PRINTK(args...) SK_PCPU(trace_printk(args))
|
||||
#define SK_PRINTK(args...) SK_PCPU(printk(args))
|
||||
|
||||
/*
|
||||
* Initialize a small key in a larger allocated buffer. This lets
|
||||
|
||||
Reference in New Issue
Block a user