From 9d5d3de01cee10c53f74528e4f3dabd7d137ac8e Mon Sep 17 00:00:00 2001 From: Qu Wenruo Date: Mon, 28 Jun 2021 18:26:28 +0800 Subject: [PATCH] btrfs-progs: subvol delete: try to delete subvolume by id when its path can't be resolved There is a recent report of ghost subvolumes where such subvolumes has no ROOT_REF/BACKREF, and 0 root ref. But without an orphan item, thus kernel won't queue them for cleanup. Such ghost subvolumes are just here to take up space, and no way to delete them except by btrfs check, which will try to fix the problem by adding orphan item. There is a kernel patch submitted to allow btrfs to detect such ghost subvolumes and queue them for cleanup. But btrfs-progs will not continue to call the ioctl if it can't find the full subvolume path. Thus this patch will loose the restriction by allowing btrfs-progs to continue to call the ioctl even if it can't grab the subvolume path. Signed-off-by: Qu Wenruo Signed-off-by: David Sterba --- cmds/subvolume.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/cmds/subvolume.c b/cmds/subvolume.c index 9bd17808..f10a19f1 100644 --- a/cmds/subvolume.c +++ b/cmds/subvolume.c @@ -258,6 +258,7 @@ static int cmd_subvol_delete(const struct cmd_struct *cmd, char *path = NULL; DIR *dirstream = NULL; int commit_mode = 0; + bool subvol_path_not_found = false; u8 fsid[BTRFS_FSID_SIZE]; u64 subvolid = 0; char uuidbuf[BTRFS_UUID_UNPARSED_SIZE]; @@ -319,6 +320,18 @@ static int cmd_subvol_delete(const struct cmd_struct *cmd, path = argv[cnt]; err = btrfs_util_subvolume_path(path, subvolid, &subvol); + /* + * If the subvolume is really not referred by anyone, and refs + * is 0, newer kernel can handle it by just adding an orphan + * item and queue it for cleanup. + * + * In this case, just let kernel to handle it, we do no extra + * handling. + */ + if (err == BTRFS_UTIL_ERROR_SUBVOLUME_NOT_FOUND) { + subvol_path_not_found = true; + goto again; + } if (err) { error_btrfs_util(err); ret = 1; @@ -395,8 +408,10 @@ again: if (subvolid == 0) pr_verbose(MUST_LOG, "'%s/%s'\n", dname, vname); - else + else if (!subvol_path_not_found) pr_verbose(MUST_LOG, "'%s'\n", full_subvolpath); + else + pr_verbose(MUST_LOG, "subvolid=%llu\n", subvolid); if (subvolid == 0) err = btrfs_util_delete_subvolume_fd(fd, vname, 0);