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:
Zach Brown
2016-07-05 17:49:13 -04:00
parent a069bdd945
commit 54044508fa
5 changed files with 117 additions and 2 deletions

View File

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

View File

@@ -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

View File

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

View File

@@ -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
View 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);
}