btrfs: fall back to global reservation when removing subvolumes
PATCH 1/1 btrfs: fall back to global reservation when removing subvolumes
I recently did some ENOSPC testing that involved filling the disk while create and removing snapshots in a loop. During the test cycle, I ran into an ENOSPC when trying to remove a snapshot, leaving the fs stuck in ENOSPC even after a umount/mount cycle.
This patch allow subvolume removal to fall back onto the global block reservation in order to succeed when it would have failed otherwise.
Signed-off-by Jeff Mahoney <[email protected]>
--- fs/btrfs/ctree.h | 2 +- fs/btrfs/extent-tree.c | 8 +++++++- fs/btrfs/ioctl.c | 7 ++++--- 3 files changed, 12 insertions(+), 5 deletions(-)
fs/btrfs/ctree.h +1 -1
@@ -3186,7 +3186,7 @@ void btrfs_orphan_release_metadata(strucint btrfs_subvolume_reserve_metadata (struct btrfs_root *root,struct btrfs_block_rsv *rsv,int nitems, -u64 *qgroup_reserved); +u64 *qgroup_reserved,bool use_global_rsv);void btrfs_subvolume_release_metadata (struct btrfs_root *root,struct btrfs_block_rsv *rsv,u64 qgroup_reserved);
fs/btrfs/extent-tree.c +7 -1
@@ -4735,10 +4735,12 @@ void btrfs_orphan_release_metadata(strucint btrfs_subvolume_reserve_metadata (struct btrfs_root *root,struct btrfs_block_rsv *rsv,int items, -u64 *qgroup_reserved) +u64 *qgroup_reserved, +bool use_global_rsv) {u64 num_bytes;int ret; +struct btrfs_block_rsv *global_rsv = &root->fs_info->global_block_rsv;if (root->fs_info->quota_enabled) {/* One for parent inode, two for dir entries */
@@ -4757,6 +4759,10 @@ int btrfs_subvolume_reserve_metadata(str BTRFS_BLOCK_GROUP_METADATA); ret =btrfs_block_rsv_add (root, rsv, num_bytes,BTRFS_RESERVE_FLUSH_ALL ); + +if (ret == -ENOSPC && use_global_rsv) + ret =btrfs_block_rsv_migrate (global_rsv, rsv, num_bytes); +if (ret) {if (*qgroup_reserved)btrfs_qgroup_free (root, *qgroup_reserved);
fs/btrfs/ioctl.c +4 -3
@@ -396,7 +396,7 @@ static noinline int create_subvol(struct* of create_snapshot(). */ ret =btrfs_subvolume_reserve_metadata (root, &block_rsv, -7 , &qgroup_reserved); +7 , &qgroup_reserved, false);if (ret)return ret;
@@ -576,7 +576,8 @@ static int create_snapshot(struct btrfs_*/ ret =btrfs_subvolume_reserve_metadata (BTRFS_I (dir)->root, &pending_snapshot->block_rsv,7 , - &pending_snapshot->qgroup_reserved); + &pending_snapshot->qgroup_reserved, + false);if (ret) goto out;
@@ -2174,7 +2175,7 @@ static noinline int btrfs_ioctl_snap_des* ref/backref. */ err =btrfs_subvolume_reserve_metadata (root, &block_rsv, -5 , &qgroup_reserved); +5 , &qgroup_reserved, true);if (err) goto out_up_write;
Signature · 2 lines
Jeff Mahoney SUSE Labs