diff --git a/utils/src/ioctl.h b/utils/src/ioctl.h index 447b4f8e..b8e8aa40 100644 --- a/utils/src/ioctl.h +++ b/utils/src/ioctl.h @@ -122,8 +122,30 @@ struct scoutfs_ioctl_ino_path { #define SCOUTFS_IOC_DATA_VERSION _IOW(SCOUTFS_IOCTL_MAGIC, 4, __u64) +/* + * "Release" a contiguous range of logical blocks of file data. + * Released blocks are removed from the file system like truncation, but + * an offline record is left behind to trigger demand staging if the + * file is read. + * + * The starting block offset and number of blocks to release are in + * units 4KB blocks. + * + * The specified range can extend past i_size and can straddle sparse + * regions or blocks that are already offline. The only change it makes + * is to free and mark offline any existing blocks that intersect with + * the region. + * + * Returns 0 if the operation succeeds. If an error is returned then + * some partial region of the blocks in the region may have been marked + * offline. + * + * If the operation succeeds then inode metadata that reflects file data + * contents are not updated. This is intended to be transparent to the + * presentation of the data in the file. + */ struct scoutfs_ioctl_release { - __u64 offset; + __u64 block; __u64 count; __u64 data_version; } __packed; diff --git a/utils/src/stage_release.c b/utils/src/stage_release.c index 61750b1a..1efbaa7d 100644 --- a/utils/src/stage_release.c +++ b/utils/src/stage_release.c @@ -127,7 +127,7 @@ static int release_cmd(int argc, char **argv) { struct scoutfs_ioctl_release args; char *endptr = NULL; - u64 offset; + u64 block; u64 count; u64 vers; int ret; @@ -155,10 +155,10 @@ static int release_cmd(int argc, char **argv) goto out; } - offset = strtoull(argv[2], &endptr, 0); + block = strtoull(argv[2], &endptr, 0); if (*endptr != '\0' || - ((offset == LLONG_MIN || offset == LLONG_MAX) && errno == ERANGE)) { - fprintf(stderr, "error parsing starting offset '%s'\n", + ((block == LLONG_MIN || block == LLONG_MAX) && errno == ERANGE)) { + fprintf(stderr, "error parsing starting 4K block offset '%s'\n", argv[2]); ret = -EINVAL; goto out; @@ -173,7 +173,7 @@ static int release_cmd(int argc, char **argv) goto out; } - args.offset = offset; + args.block = block; args.count = count; args.data_version = vers; @@ -190,6 +190,6 @@ out: static void __attribute__((constructor)) release_ctor(void) { - cmd_register("release", " ", + cmd_register("release", " <4K block offset> ", "mark file region offline and free extents", release_cmd); }