diff --git a/cmds/subvolume.c b/cmds/subvolume.c index 259f59616..116fe1b37 100644 --- a/cmds/subvolume.c +++ b/cmds/subvolume.c @@ -122,6 +122,22 @@ static int wait_for_subvolume_cleaning(int fd, size_t count, uint64_t *ids, return 0; } +static int wait_for_subvolume_sync(int fd, size_t count, uint64_t *ids) { + int i, ret; + struct btrfs_ioctl_subvol_wait arg; + + for (i=0; i ", NULL @@ -1726,9 +1742,12 @@ static const char * const cmd_subvolume_sync_usage[] = { "after deletion.", "If no subvolume id is given, wait until all current deletion requests", "are completed, but do not wait for subvolumes deleted meanwhile.", - "The status of subvolume ids is checked periodically.", + "The status of subvolume IDs is first checked by attempting to wait" + "via ioctl. If the ioctl is not supported or fails, the status is checked" + "periodically as a fallback.", "", OPTLINE("-s ", "sleep N seconds between checks (default: 1)"), + OPTLINE("-p", "use periodic checking instead of waiting via ioctl"), NULL }; @@ -1740,6 +1759,7 @@ static int cmd_subvolume_sync(const struct cmd_struct *cmd, int argc, char **arg size_t id_count, i; int sleep_interval = 1; enum btrfs_util_error err; + bool periodic = false; optind = 0; while (1) { @@ -1757,6 +1777,9 @@ static int cmd_subvolume_sync(const struct cmd_struct *cmd, int argc, char **arg goto out; } break; + case 'p': + periodic = true; + break; default: usage_unknown_option(cmd, argv); } @@ -1814,7 +1837,16 @@ static int cmd_subvolume_sync(const struct cmd_struct *cmd, int argc, char **arg } } - ret = wait_for_subvolume_cleaning(fd, id_count, ids, sleep_interval); + if (periodic) { + ret = wait_for_subvolume_cleaning(fd, id_count, ids, sleep_interval); + } else { + ret = wait_for_subvolume_sync(fd, id_count, ids); + if (ret) { + if (ret == -ENOTTY) + error("subvolume sync ioctl not supported in this kernel version, 6.13 and newer is required"); + ret = wait_for_subvolume_cleaning(fd, id_count, ids, sleep_interval); + } + } out: free(ids);