aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2013-02-07 16:06:02 -0500
committerJosef Bacik <jbacik@fusionio.com>2013-02-20 12:59:42 -0500
commit5d80366e9b5e56b3ffc1923b4995e83bbbf605e3 (patch)
treeabf60c6bb2534f17bb40fd60819b02e7cfa64bb8
parent8696c53304f16fde9368b9d5c89a5acb4a815d4c (diff)
Btrfs: steal from global reserve if we are cleaning up orphans
Sometimes xfstest 83 will fail to remount the scratch device because we've gotten ourselves so full that we cannot cleanup the orphan items. In this case check to see if we're doing the orphan cleanup and if we are allow us to steal our reservation from the global block rsv. With this patch I've not been able to reproduce the failed mount problem. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com>
-rw-r--r--fs/btrfs/ctree.h5
-rw-r--r--fs/btrfs/extent-tree.c11
-rw-r--r--fs/btrfs/inode.c5
3 files changed, 16 insertions, 5 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 7e2cffd2a5d8..f1cc247f3178 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1237,6 +1237,11 @@ struct seq_list {
1237 u64 seq; 1237 u64 seq;
1238}; 1238};
1239 1239
1240enum btrfs_orphan_cleanup_state {
1241 ORPHAN_CLEANUP_STARTED = 1,
1242 ORPHAN_CLEANUP_DONE = 2,
1243};
1244
1240/* fs_info */ 1245/* fs_info */
1241struct reloc_control; 1246struct reloc_control;
1242struct btrfs_device; 1247struct btrfs_device;
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 81aa7cf3ae86..1818dd90c27e 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -102,6 +102,8 @@ static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
102 int dump_block_groups); 102 int dump_block_groups);
103static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, 103static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
104 u64 num_bytes, int reserve); 104 u64 num_bytes, int reserve);
105static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv,
106 u64 num_bytes);
105 107
106static noinline int 108static noinline int
107block_group_cache_done(struct btrfs_block_group_cache *cache) 109block_group_cache_done(struct btrfs_block_group_cache *cache)
@@ -4099,6 +4101,15 @@ again:
4099 goto again; 4101 goto again;
4100 4102
4101out: 4103out:
4104 if (ret == -ENOSPC &&
4105 unlikely(root->orphan_cleanup_state == ORPHAN_CLEANUP_STARTED)) {
4106 struct btrfs_block_rsv *global_rsv =
4107 &root->fs_info->global_block_rsv;
4108
4109 if (block_rsv != global_rsv &&
4110 !block_rsv_use_bytes(global_rsv, orig_bytes))
4111 ret = 0;
4112 }
4102 if (flushing) { 4113 if (flushing) {
4103 spin_lock(&space_info->lock); 4114 spin_lock(&space_info->lock);
4104 space_info->flush = 0; 4115 space_info->flush = 0;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 348b7bb920ef..cf26778085e0 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2218,11 +2218,6 @@ void btrfs_run_delayed_iputs(struct btrfs_root *root)
2218 } 2218 }
2219} 2219}
2220 2220
2221enum btrfs_orphan_cleanup_state {
2222 ORPHAN_CLEANUP_STARTED = 1,
2223 ORPHAN_CLEANUP_DONE = 2,
2224};
2225
2226/* 2221/*
2227 * This is called in transaction commit time. If there are no orphan 2222 * This is called in transaction commit time. If there are no orphan
2228 * files in the subvolume, it removes orphan item and frees block_rsv 2223 * files in the subvolume, it removes orphan item and frees block_rsv