mirror of
https://github.com/versity/scoutfs.git
synced 2026-01-06 12:06:26 +00:00
Add inodes-since command
The kernel now has an ioctl to give us inode numbers with their sequence number for every inode that's been modified since a given tree update sequence number. Update mkfs and print to the on-disk format changes and add a trivial inodes-since command which calls the ioctl and prints the results. Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
@@ -91,9 +91,14 @@ struct scoutfs_btree_block {
|
||||
__le16 nr_items;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* The item sequence number is set to the dirty block's sequence number
|
||||
* when the item is modified. It is not changed by splits or merges.
|
||||
*/
|
||||
struct scoutfs_btree_item {
|
||||
struct scoutfs_key key;
|
||||
struct scoutfs_treap_node tnode;
|
||||
__le64 seq;
|
||||
__le16 val_len;
|
||||
char val[0];
|
||||
} __packed;
|
||||
|
||||
@@ -27,4 +27,23 @@ struct scoutfs_trace_record {
|
||||
#define SCOUTFS_IOC_GET_TRACE_RECORDS _IOW(SCOUTFS_IOCTL_MAGIC, 2, \
|
||||
struct scoutfs_ioctl_buf)
|
||||
|
||||
struct scoutfs_ioctl_ino_seq {
|
||||
__u64 ino;
|
||||
__u64 seq;
|
||||
} __packed;
|
||||
|
||||
struct scoutfs_ioctl_inodes_since {
|
||||
__u64 first_ino;
|
||||
__u64 last_ino;
|
||||
__u64 seq;
|
||||
struct scoutfs_ioctl_buf results;
|
||||
} __packed;
|
||||
|
||||
/*
|
||||
* Adds entries to the user's buffer for each inode whose sequence
|
||||
* number is greater than or equal to the given seq.
|
||||
*/
|
||||
#define SCOUTFS_IOC_INODES_SINCE _IOW(SCOUTFS_IOCTL_MAGIC, 3, \
|
||||
struct scoutfs_ioctl_inodes_since)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -125,6 +125,7 @@ static int write_new_fs(char *path, int fd)
|
||||
bt->nr_items = cpu_to_le16(1);
|
||||
|
||||
item = (void *)(bt + 1);
|
||||
item->seq = cpu_to_le64(1);
|
||||
item->key = root_key;
|
||||
item->tnode.parent = 0;
|
||||
item->tnode.left = 0;
|
||||
|
||||
@@ -99,9 +99,10 @@ static void print_block_ref(struct scoutfs_block_ref *ref)
|
||||
static void print_btree_item(unsigned int off, struct scoutfs_btree_item *item,
|
||||
u8 level)
|
||||
{
|
||||
printf(" item: key "SKF" val_len %u off %u tnode: parent %u left %u right %u "
|
||||
printf(" item: key "SKF" seq %llu val_len %u off %u tnode: parent %u left %u right %u "
|
||||
"prio %x\n",
|
||||
SKA(&item->key), le16_to_cpu(item->val_len), off,
|
||||
SKA(&item->key), le64_to_cpu(item->seq),
|
||||
le16_to_cpu(item->val_len), off,
|
||||
le16_to_cpu(item->tnode.parent),
|
||||
le16_to_cpu(item->tnode.left),
|
||||
le16_to_cpu(item->tnode.right),
|
||||
|
||||
89
utils/src/since.c
Normal file
89
utils/src/since.c
Normal file
@@ -0,0 +1,89 @@
|
||||
#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 "ioctl.h"
|
||||
#include "cmd.h"
|
||||
|
||||
static int since_cmd(int argc, char **argv)
|
||||
{
|
||||
struct scoutfs_ioctl_inodes_since args;
|
||||
struct scoutfs_ioctl_ino_seq *iseq;
|
||||
int len = 4 * 1024 * 1024;
|
||||
char *endptr;
|
||||
u64 nrs[3];
|
||||
void *ptr;
|
||||
int ret;
|
||||
int fd;
|
||||
u64 n;
|
||||
int i;
|
||||
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "must specify seq and path\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < array_size(nrs); i++) {
|
||||
n = strtoull(argv[i], &endptr, 0);
|
||||
if (*endptr != '\0' ||
|
||||
((n == LLONG_MIN || n == LLONG_MAX) && errno == ERANGE)) {
|
||||
fprintf(stderr, "error parsing 64bit value '%s'\n",
|
||||
argv[i]);
|
||||
return -EINVAL;
|
||||
}
|
||||
nrs[i] = n;
|
||||
}
|
||||
|
||||
fd = open(argv[3], O_RDONLY);
|
||||
if (fd < 0) {
|
||||
ret = -errno;
|
||||
fprintf(stderr, "failed to open '%s': %s (%d)\n",
|
||||
argv[3], strerror(errno), errno);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ptr = malloc(len);
|
||||
if (!ptr) {
|
||||
fprintf(stderr, "must specify seq and path\n");
|
||||
close(fd);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
args.first_ino = nrs[0];
|
||||
args.last_ino = nrs[1];
|
||||
args.seq = nrs[2];
|
||||
args.results.ptr = (intptr_t)ptr;
|
||||
args.results.len = len;
|
||||
|
||||
ret = ioctl(fd, SCOUTFS_IOC_INODES_SINCE, &args);
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
fprintf(stderr, "inodes_since ioctl failed: %s (%d)\n",
|
||||
strerror(errno), errno);
|
||||
goto out;
|
||||
}
|
||||
|
||||
n = ret / sizeof(*iseq);
|
||||
for (i = 0, iseq = ptr; i < n; i++, iseq++)
|
||||
printf("ino %llu seq %llu\n", iseq->ino, iseq->seq);
|
||||
|
||||
out:
|
||||
free(ptr);
|
||||
close(fd);
|
||||
return ret;
|
||||
};
|
||||
|
||||
static void __attribute__((constructor)) since_ctor(void)
|
||||
{
|
||||
cmd_register("inodes-since", "<first> <last> <seq> <path>",
|
||||
"print inodes modified since seq #", since_cmd);
|
||||
}
|
||||
Reference in New Issue
Block a user