scoutfs-utils: add stat command

The scoutfs stat command is modeled after stat(1) and uses the STAT_MORE
ioctl.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2017-05-16 14:39:03 -07:00
parent 9fc99a8c31
commit 08aaa5b430
3 changed files with 107 additions and 38 deletions

View File

@@ -10,6 +10,27 @@ struct scoutfs_ioctl_walk_inodes_entry {
__u64 ino;
} __packed;
/*
* Walk inodes in an index that is sorted by one of their fields.
*
* Each index is built from generic index items that have major and
* minor values that are set to the field being indexed. In time
* indices, for example, major is seconds and minor is nanoseconds.
*
* @first The first index entry that can be returned.
* @last The last index entry that can be returned.
* @entries_ptr Pointer to emory containing buffer for entry results.
* @nr_entries The number of entries that can fit in the buffer.
* @index Which index to walk, enumerated in _WALK_INODES_ constants.
*
* To start iterating first can be memset to 0 and last to 0xff. Then
* after each set of results first can be set to the last entry returned
* and then the fields can be incremented in reverse sort order (ino <
* minor < major) as each increasingly significant value wraps around to
* 0.
*
* If first is greater than last then the walk will return 0 entries.
*/
struct scoutfs_ioctl_walk_inodes {
struct scoutfs_ioctl_walk_inodes_entry first;
struct scoutfs_ioctl_walk_inodes_entry last;
@@ -107,4 +128,25 @@ struct scoutfs_ioctl_stage {
#define SCOUTFS_IOC_STAGE _IOW(SCOUTFS_IOCTL_MAGIC, 6, \
struct scoutfs_ioctl_stage)
/*
* Give the user inode fields that are not otherwise visible. statx()
* isn't always available and xattrs are relatively expensive.
*
* @valid_bytes stores the number of bytes that are valid in the
* structure. The caller sets this to the size of the struct that they
* understand. The kernel then fills and copies back the min of the
* size they and the user caller understand. The user can tell if a
* field is set if all of its bytes are within the valid_bytes that the
* kernel set on return.
*
* New fields are only added to the end of the struct.
*/
struct scoutfs_ioctl_stat_more {
__u64 valid_bytes;
__u64 data_version;
} __packed;
#define SCOUTFS_IOC_STAT_MORE _IOW(SCOUTFS_IOCTL_MAGIC, 7, \
struct scoutfs_ioctl_stat_more)
#endif

View File

@@ -193,41 +193,3 @@ static void __attribute__((constructor)) release_ctor(void)
cmd_register("release", "<path> <vers> <offset> <count>",
"mark file region offline and free extents", release_cmd);
}
static int data_version_cmd(int argc, char **argv)
{
u64 vers;
int ret;
int fd;
if (argc != 1) {
fprintf(stderr, "must specify path\n");
return -EINVAL;
}
fd = open(argv[0], O_RDWR);
if (fd < 0) {
ret = -errno;
fprintf(stderr, "failed to open '%s': %s (%d)\n",
argv[0], strerror(errno), errno);
return ret;
}
ret = ioctl(fd, SCOUTFS_IOC_DATA_VERSION, &vers);
if (ret < 0) {
ret = -errno;
fprintf(stderr, "data version ioctl failed: %s (%d)\n",
strerror(errno), errno);
} else {
printf("%llu\n", vers);
}
close(fd);
return ret;
};
static void __attribute__((constructor)) data_version_ctor(void)
{
cmd_register("data_version", "<path>",
"print the file's data version", data_version_cmd);
}

65
utils/src/stat.c Normal file
View File

@@ -0,0 +1,65 @@
#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 "sparse.h"
#include "util.h"
#include "format.h"
#include "ioctl.h"
#include "cmd.h"
static int stat_more_cmd(int argc, char **argv)
{
struct scoutfs_ioctl_stat_more stm;
char *path;
int ret;
int fd;
int i;
if (argc == 0) {
fprintf(stderr, "must specify at least one path argument\n");
return -EINVAL;
}
for (i = 0; i < argc; i++) {
path = argv[i];
fd = open(path, O_RDONLY);
if (fd < 0) {
ret = -errno;
fprintf(stderr, "failed to open '%s': %s (%d)\n",
path, strerror(errno), errno);
continue;
}
memset(&stm, 0, sizeof(stm));
stm.valid_bytes = sizeof(stm);
ret = ioctl(fd, SCOUTFS_IOC_STAT_MORE, &stm);
if (ret < 0) {
ret = -errno;
fprintf(stderr, "stat_more ioctl failed on '%s': "
"%s (%d)\n", path, strerror(errno), errno);
} else {
printf(" File: '%s'\n"
" data_version: %-20llu\n",
path, stm.data_version);
}
close(fd);
}
return 0;
}
static void __attribute__((constructor)) stat_more_ctor(void)
{
cmd_register("stat", "<path>",
"print scoutfs stat information for path", stat_more_cmd);
}