Btrfs: steal from global reserve if we are cleaning up orphans
authorJosef Bacik <jbacik@fusionio.com>
Thu, 7 Feb 2013 21:06:02 +0000 (16:06 -0500)
committerJosef Bacik <jbacik@fusionio.com>
Wed, 20 Feb 2013 17:59:42 +0000 (12:59 -0500)
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>
fs/btrfs/ctree.h
fs/btrfs/extent-tree.c
fs/btrfs/inode.c

index 7e2cffd2a5d8f439b2b0165a404134c4b63c0d7f..f1cc247f31786588c17ee8defa3a03436776b3df 100644 (file)
@@ -1237,6 +1237,11 @@ struct seq_list {
        u64 seq;
 };
 
+enum btrfs_orphan_cleanup_state {
+       ORPHAN_CLEANUP_STARTED  = 1,
+       ORPHAN_CLEANUP_DONE     = 2,
+};
+
 /* fs_info */
 struct reloc_control;
 struct btrfs_device;
index 81aa7cf3ae86e8c20139669587a8ac0caef1cf60..1818dd90c27ea00583ebc76919c2de59d19b72f3 100644 (file)
@@ -102,6 +102,8 @@ static void dump_space_info(struct btrfs_space_info *info, u64 bytes,
                            int dump_block_groups);
 static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache,
                                       u64 num_bytes, int reserve);
+static int block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv,
+                              u64 num_bytes);
 
 static noinline int
 block_group_cache_done(struct btrfs_block_group_cache *cache)
@@ -4099,6 +4101,15 @@ again:
                goto again;
 
 out:
+       if (ret == -ENOSPC &&
+           unlikely(root->orphan_cleanup_state == ORPHAN_CLEANUP_STARTED)) {
+               struct btrfs_block_rsv *global_rsv =
+                       &root->fs_info->global_block_rsv;
+
+               if (block_rsv != global_rsv &&
+                   !block_rsv_use_bytes(global_rsv, orig_bytes))
+                       ret = 0;
+       }
        if (flushing) {
                spin_lock(&space_info->lock);
                space_info->flush = 0;
index 348b7bb920ef655cb89d61826c0f64a255f46538..cf26778085e08185a7c7c03e0fd6f7a34bc7c7e4 100644 (file)
@@ -2218,11 +2218,6 @@ void btrfs_run_delayed_iputs(struct btrfs_root *root)
        }
 }
 
-enum btrfs_orphan_cleanup_state {
-       ORPHAN_CLEANUP_STARTED  = 1,
-       ORPHAN_CLEANUP_DONE     = 2,
-};
-
 /*
  * This is called in transaction commit time. If there are no orphan
  * files in the subvolume, it removes orphan item and frees block_rsv