scoutfs-utils: add item cache keys commands

Add ioctls to get the keys for cached ranges and items and print them.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2017-06-15 22:09:01 -07:00
parent 51ae302d81
commit c6eaccbf90
2 changed files with 158 additions and 0 deletions

View File

@@ -29,7 +29,18 @@ struct scoutfs_ioctl_walk_inodes_entry {
* minor < major) as each increasingly significant value wraps around to
* 0.
*
* These indexes are not strictly consistent. The items that back these
* index entries aren't updated with cluster locks so they're not
* guaranteed to be visible the moment you read after writing. They're
* only visible when the transaction that updated them is synced.
*
* In addition, the seq indexes will only allow walking through sequence
* space that has been consistent. This prevents old dirty entries from
* becoming visible after newer stable entries are displayed.
*
* If first is greater than last then the walk will return 0 entries.
*
* XXX invalidate before reading.
*/
struct scoutfs_ioctl_walk_inodes {
struct scoutfs_ioctl_walk_inodes_entry first;
@@ -153,4 +164,20 @@ struct scoutfs_ioctl_stat_more {
#define SCOUTFS_IOC_STAT_MORE _IOW(SCOUTFS_IOCTL_MAGIC, 7, \
struct scoutfs_ioctl_stat_more)
struct scoutfs_ioctl_item_cache_keys {
__u64 key_ptr;
__u64 key_len;
__u64 buf_ptr;
__u64 buf_len;
__u8 which;
} __packed;
enum {
SCOUTFS_IOC_ITEM_CACHE_KEYS_ITEMS = 0,
SCOUTFS_IOC_ITEM_CACHE_KEYS_RANGES,
};
#define SCOUTFS_IOC_ITEM_CACHE_KEYS _IOW(SCOUTFS_IOCTL_MAGIC, 8, \
struct scoutfs_ioctl_item_cache_keys)
#endif

131
utils/src/item-cache-keys.c Normal file
View File

@@ -0,0 +1,131 @@
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <limits.h>
#include "sparse.h"
#include "util.h"
#include "format.h"
#include "ioctl.h"
#include "cmd.h"
#include "key.h"
#define BUF_SIZE (64 * 1024)
static int item_cache_keys(int argc, char **argv, int which)
{
struct scoutfs_ioctl_item_cache_keys ick;
unsigned nr;
u16 key_len;
void *buf;
void *ptr;
int ret;
int fd;
if (argc != 1) {
fprintf(stderr, "too many arguments, only scoutfs path needed");
return -EINVAL;
}
buf = malloc(BUF_SIZE);
if (!buf) {
ret = -errno;
fprintf(stderr, "failed to allocate buf: %s (%d)\n",
strerror(errno), errno);
return ret;
}
fd = open(argv[0], O_RDONLY);
if (fd < 0) {
ret = -errno;
fprintf(stderr, "failed to open '%s': %s (%d)\n",
argv[0], strerror(errno), errno);
free(buf);
return ret;
}
ick.buf_ptr = (unsigned long)buf;
ick.buf_len = BUF_SIZE;
ick.key_ptr = 0;
ick.key_len = 0;
ick.which = which;
nr = 1;
for (;;) {
ret = ioctl(fd, SCOUTFS_IOC_ITEM_CACHE_KEYS, &ick);
if (ret < 0) {
ret = -errno;
fprintf(stderr, "walk_inodes ioctl failed: %s (%d)\n",
strerror(errno), errno);
break;
} else if (ret == 0) {
break;
}
ptr = (void *)(unsigned long)ick.buf_ptr;
while (ret) {
if (ret < sizeof(key_len)) {
fprintf(stderr, "truncated len: %d\n", ret);
ret = -EINVAL;
break;
}
memcpy(&key_len, ptr, sizeof(key_len));
ptr += sizeof(key_len);
ret -= sizeof(key_len);
if (ret < key_len) {
fprintf(stderr, "key len %d < buffer %d\n",
key_len, ret);
ret = -EINVAL;
break;
}
print_key(ptr, key_len);
if (which == SCOUTFS_IOC_ITEM_CACHE_KEYS_ITEMS ||
(nr % 2) == 0)
printf("\n");
else
printf(" - ");
ick.key_ptr = (unsigned long)ptr;
ick.key_len = key_len;
ptr += key_len;
ret -= key_len;
nr++;
}
if (ret < 0)
break;
}
close(fd);
free(buf);
return ret;
};
static int item_keys(int argc, char **argv)
{
return item_cache_keys(argc, argv, SCOUTFS_IOC_ITEM_CACHE_KEYS_ITEMS);
}
static int range_keys(int argc, char **argv)
{
return item_cache_keys(argc, argv, SCOUTFS_IOC_ITEM_CACHE_KEYS_RANGES);
}
static void __attribute__((constructor)) item_cache_key_ctor(void)
{
cmd_register("item-cache-keys", "<path>",
"print range of indexed inodes", item_keys);
cmd_register("item-cache-range-keys", "<path>",
"print range of indexed inodes", range_keys);
}