From: Mark Fasheh <mfas...@suse.com>

In btrfs_add_root_ref() we BUG if an error is encountered during
REF/BACKREF insertion. This does not look like a logic error, thus the BUG
is not called for. However, I don't think there's a simple way to recover
from such an error at that point, so we mark the fs readonly instead.

At the same time, we can update the following caller of
btrfs_add_root_ref() which BUG_ON from an error:

- create_subvol: now passes the return code back to userspace

- create_pending_snapshot: goes readonly on any error from
  btrfs_add_root_ref().

Signed-off-by: Mark Fasheh <mfas...@suse.de>
---
 fs/btrfs/ioctl.c       |    4 ++--
 fs/btrfs/root-tree.c   |    8 ++++++--
 fs/btrfs/transaction.c |    2 +-
 3 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c
index 7cf0133..8adb220 100644
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -430,8 +430,8 @@ static noinline int create_subvol(struct btrfs_root *root,
        ret = btrfs_add_root_ref(trans, root->fs_info->tree_root,
                                 objectid, root->root_key.objectid,
                                 btrfs_ino(dir), index, name, namelen);
-
-       BUG_ON(ret);
+       if (ret)
+               goto fail;
 
        d_instantiate(dentry, btrfs_lookup_dentry(dir, dentry));
 fail:
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
index f409990..02f2bf3 100644
--- a/fs/btrfs/root-tree.c
+++ b/fs/btrfs/root-tree.c
@@ -407,7 +407,10 @@ int btrfs_add_root_ref(struct btrfs_trans_handle *trans,
 again:
        ret = btrfs_insert_empty_item(trans, tree_root, path, &key,
                                      sizeof(*ref) + name_len);
-       BUG_ON(ret);
+       if (ret) {
+               btrfs_std_error(tree_root->fs_info, ret);
+               goto out_free;
+       }
 
        leaf = path->nodes[0];
        ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref);
@@ -426,8 +429,9 @@ again:
                goto again;
        }
 
+out_free:
        btrfs_free_path(path);
-       return 0;
+       return ret;
 }
 
 /*
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 7dc36fa..7c46ece 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -991,7 +991,7 @@ static noinline int create_pending_snapshot(struct 
btrfs_trans_handle *trans,
                                 parent_root->root_key.objectid,
                                 btrfs_ino(parent_inode), index,
                                 dentry->d_name.name, dentry->d_name.len);
-       BUG_ON(ret);
+       btrfs_std_error(fs_info, ret);
        dput(parent);
 
        key.offset = (u64)-1;
-- 
1.7.6

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to