From 71ad6f2f530df936acbec456ea03a5e79f09e0ea Mon Sep 17 00:00:00 2001 From: David Sterba Date: Thu, 7 Dec 2023 17:21:56 +0100 Subject: [PATCH] btrfs-progs: subvol sync: check if the filesystem is writable The subvolume cleaning is done by polling but it's possible that the filesystem turns to read-only (as reported), either due to an error intentionally. In that case the waiting would be indefinite without an obvious reason. To fix that check if the filesystem is still writable in each iteration. Issue: #535 Link: https://github.com/btrfs/fstests/issues/40 Signed-off-by: David Sterba --- Documentation/btrfs-subvolume.rst | 2 ++ cmds/subvolume.c | 13 +++++++++++++ 2 files changed, 15 insertions(+) diff --git a/Documentation/btrfs-subvolume.rst b/Documentation/btrfs-subvolume.rst index 9c808ccc..0f46db3d 100644 --- a/Documentation/btrfs-subvolume.rst +++ b/Documentation/btrfs-subvolume.rst @@ -272,6 +272,8 @@ sync [subvolid...] deletion. If no subvolume id is given, wait until all current deletion requests are completed, but do not wait for subvolumes deleted in the meantime. + If the filesystem status changes to read-only then the waiting is interrupted. + ``Options`` -s diff --git a/cmds/subvolume.c b/cmds/subvolume.c index 0c34c30d..57be9eac 100644 --- a/cmds/subvolume.c +++ b/cmds/subvolume.c @@ -17,6 +17,7 @@ #include "kerncompat.h" #include #include +#include #include #include #include @@ -78,10 +79,13 @@ static int wait_for_subvolume_cleaning(int fd, size_t count, uint64_t *ids, size_t i; enum btrfs_util_error err; size_t done = 0; + bool statvfs_warned = false; pr_verbose(LOG_DEFAULT, "Waiting for %zu subvolume%s\n", count, (count > 1 ? "s" : "")); while (1) { + struct statvfs st; + int ret; bool clean = true; for (i = 0; i < count; i++) { @@ -102,6 +106,15 @@ static int wait_for_subvolume_cleaning(int fd, size_t count, uint64_t *ids, } if (clean) break; + + ret = fstatvfs(fd, &st); + if (ret < 0 && !statvfs_warned) { + statvfs_warned = true; + warning("cannot check read-only status of the filesystem: %m"); + } else if (st.f_flag & ST_RDONLY) { + warning("filesystem is now read-only"); + return 1; + } sleep(sleep_interval); }