btrfs: Ignore errors from btrfs_qgroup_trace_extent_post
authorNikolay Borisov <nborisov@suse.com>
Mon, 29 Jan 2018 13:53:01 +0000 (15:53 +0200)
committerDavid Sterba <dsterba@suse.com>
Fri, 2 Feb 2018 15:25:14 +0000 (16:25 +0100)
Running generic/019 with qgroups on the scratch device enabled is almost
guaranteed to trigger the BUG_ON in btrfs_free_tree_block. It's supposed
to trigger only on -ENOMEM, in reality, however, it's possible to get
-EIO from btrfs_qgroup_trace_extent_post. This function just finds the
roots of the extent being tracked and sets the qrecord->old_roots list.
If this operation fails nothing critical happens except the quota
accounting can be considered wrong. In such case just set the
INCONSISTENT flag for the quota and print a warning, rather than killing
off the system. Additionally, it's possible to trigger a BUG_ON in
btrfs_truncate_inode_items as well.

Signed-off-by: Nikolay Borisov <nborisov@suse.com>
Reviewed-by: Qu Wenruo <wqu@suse.com>
[ error message adjustments ]
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/delayed-ref.c
fs/btrfs/qgroup.c

index a1a40cf382e39c1da97dcd3d8fd3a0a9eda537e2..7ab5e0128f0ce823101f5623a0664c01208f89a7 100644 (file)
@@ -821,7 +821,8 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
        spin_unlock(&delayed_refs->lock);
 
        if (qrecord_inserted)
-               return btrfs_qgroup_trace_extent_post(fs_info, record);
+               btrfs_qgroup_trace_extent_post(fs_info, record);
+
        return 0;
 
 free_head_ref:
index 9e61dd624f7b5b4e8dde13c47d6e24a8eb8138d5..aa259d6986e1c24049c8f500184b2393d99b0549 100644 (file)
@@ -1442,8 +1442,13 @@ int btrfs_qgroup_trace_extent_post(struct btrfs_fs_info *fs_info,
        int ret;
 
        ret = btrfs_find_all_roots(NULL, fs_info, bytenr, 0, &old_root, false);
-       if (ret < 0)
-               return ret;
+       if (ret < 0) {
+               fs_info->qgroup_flags |= BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT;
+               btrfs_warn(fs_info,
+"error accounting new delayed refs extent (err code: %d), quota inconsistent",
+                       ret);
+               return 0;
+       }
 
        /*
         * Here we don't need to get the lock of