mirror of
https://github.com/versity/scoutfs.git
synced 2026-01-06 20:16:25 +00:00
scoutfs: add data_wait_err for reporting errors
Add support for reporting errors to data waiters via a new SCOUTFS_IOC_DATA_WAIT_ERR ioctl. This allows waiters to return an error to readers when staging fails. Signed-off-by: Benjamin LaHaise <bcrl@kvack.org> [zab: renamed to data_wait_err, took ino arg] Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
committed by
Zach Brown
parent
79e235af6e
commit
74f85ff93d
@@ -346,5 +346,22 @@ struct scoutfs_ioctl_statfs_more {
|
||||
#define SCOUTFS_IOC_STATFS_MORE _IOR(SCOUTFS_IOCTL_MAGIC, 10, \
|
||||
struct scoutfs_ioctl_statfs_more)
|
||||
|
||||
/*
|
||||
* Cause matching waiters to return an error.
|
||||
*
|
||||
* Find current waiters that match the inode, op, and block range to wake
|
||||
* up and return an error.
|
||||
*/
|
||||
struct scoutfs_ioctl_data_wait_err {
|
||||
__u64 ino;
|
||||
__u64 data_version;
|
||||
__u64 offset;
|
||||
__u64 count;
|
||||
__u64 op;
|
||||
__s64 err;
|
||||
};
|
||||
|
||||
#define SCOUTFS_IOC_DATA_WAIT_ERR _IOR(SCOUTFS_IOCTL_MAGIC, 11, \
|
||||
struct scoutfs_ioctl_data_wait_err)
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,6 +33,7 @@ typedef u16 __u16;
|
||||
typedef u32 __u32;
|
||||
typedef s32 __s32;
|
||||
typedef u64 __u64;
|
||||
typedef s64 __s64;
|
||||
|
||||
typedef u16 __sp_biwise __le16;
|
||||
typedef u16 __sp_biwise __be16;
|
||||
|
||||
@@ -14,25 +14,11 @@
|
||||
#include "format.h"
|
||||
#include "ioctl.h"
|
||||
#include "cmd.h"
|
||||
#include "parse.h"
|
||||
|
||||
static int parse_u64(char *str, u64 *val_ret)
|
||||
{
|
||||
unsigned long long ull;
|
||||
char *endptr = NULL;
|
||||
|
||||
ull = strtoull(str, &endptr, 0);
|
||||
if (*endptr != '\0' ||
|
||||
((ull == LLONG_MIN || ull == LLONG_MAX) &&
|
||||
errno == ERANGE)) {
|
||||
fprintf(stderr, "invalid 64bit value: '%s'\n", str);
|
||||
*val_ret = 0;
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*val_ret = ull;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#ifndef MAX_ERRNO
|
||||
#define MAX_ERRNO 4095
|
||||
#endif
|
||||
|
||||
#define OP_FMT "%s%s"
|
||||
|
||||
@@ -110,3 +96,71 @@ static void __attribute__((constructor)) waiting_ctor(void)
|
||||
cmd_register("data-waiting", "<ino> <iblock> <path>",
|
||||
"print ops waiting for data blocks", waiting_cmd);
|
||||
}
|
||||
|
||||
static int data_wait_err_cmd(int argc, char **argv)
|
||||
{
|
||||
struct scoutfs_ioctl_data_wait_err args;
|
||||
int fd = -1;
|
||||
int ret;
|
||||
|
||||
memset(&args, 0, sizeof(args));
|
||||
|
||||
if (argc != 8) {
|
||||
fprintf(stderr, "must specify path, ino, version, offset, count,op, and err\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = parse_u64(argv[2], &args.ino) ?:
|
||||
parse_u64(argv[3], &args.data_version) ?:
|
||||
parse_u64(argv[4], &args.offset) ?:
|
||||
parse_u64(argv[5], &args.count) ?:
|
||||
parse_s64(argv[7], &args.err);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if ((args.err >= 0) || (args.err < -MAX_ERRNO)) {
|
||||
fprintf(stderr, "err %lld invalid\n", args.err);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!strcmp(argv[6], "read")) {
|
||||
args.op = SCOUTFS_IOC_DWO_READ;
|
||||
} else if (!strcmp(argv[6], "write")) {
|
||||
args.op = SCOUTFS_IOC_DWO_WRITE;
|
||||
} else if (!strcmp(argv[6], "change_size")) {
|
||||
args.op = SCOUTFS_IOC_DWO_CHANGE_SIZE;
|
||||
} else {
|
||||
fprintf(stderr, "invalid data wait op: '%s'\n", argv[6]);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
fd = open(argv[1], O_RDONLY);
|
||||
if (fd < 0) {
|
||||
ret = -errno;
|
||||
fprintf(stderr, "failed to open '%s': %s (%d)\n",
|
||||
argv[1], strerror(errno), errno);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = ioctl(fd, SCOUTFS_IOC_DATA_WAIT_ERR, &args);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "data_wait_err returned %d: error %s (%d)\n",
|
||||
ret, strerror(errno), errno);
|
||||
ret = -EIO;
|
||||
goto out;
|
||||
}
|
||||
printf("data_wait_err found %d waiters.\n", ret);
|
||||
|
||||
out:
|
||||
if (fd > -1)
|
||||
close(fd);
|
||||
return ret;
|
||||
};
|
||||
|
||||
static void __attribute__((constructor)) data_wait_err_ctor(void)
|
||||
{
|
||||
cmd_register("data-wait-err", "<path> <ino> <vers> <offset> <count> <op> <err>",
|
||||
"return error from matching waiters",
|
||||
data_wait_err_cmd);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user