On Fri, Jun 20, 2014 at 08:29:58AM -0700, Mark Fasheh wrote:
> +static int account_shared_subtree(struct btrfs_trans_handle *trans,
> +                               struct btrfs_root *root,
> +                               struct extent_buffer *root_eb,
> +                               u64 root_gen,
> +                               int root_level)
> +{
> +     int ret;
> +     int level;
> +     struct extent_buffer *eb = root_eb;
> +     struct btrfs_path *path = NULL;
> +
> +     BUG_ON(root_level < 0 || root_level > BTRFS_MAX_LEVEL);
> +     BUG_ON(root_eb == NULL);

The caller is ready for errors, can you please turn these to ane EIO?
(Separate patch is fine)

> +static int qgroup_subtree_accounting(struct btrfs_trans_handle *trans,
> +                                  struct btrfs_fs_info *fs_info,
> +                                  struct btrfs_qgroup_operation *oper)
> +{
> +     struct ulist *roots = NULL;
> +     struct ulist_node *unode;
> +     struct ulist_iterator uiter;
> +     struct btrfs_qgroup_list *glist;
> +     struct ulist *parents;
> +     int ret = 0;
> +     struct btrfs_qgroup *qg;
> +     u64 root_obj = 0;
> +     struct seq_list elem = {};
> +
> +     parents = ulist_alloc(GFP_NOFS);
> +     if (!parents)
> +             return -ENOMEM;
> +
> +     btrfs_get_tree_mod_seq(fs_info, &elem);
> +     ret = btrfs_find_all_roots(trans, fs_info, oper->bytenr,
> +                                elem.seq, &roots);
> +     btrfs_put_tree_mod_seq(fs_info, &elem);
> +     if (ret < 0)
> +             return ret;
> +
> +     if (roots->nnodes != 1)
> +             goto out;
> +
> +     ULIST_ITER_INIT(&uiter);
> +     unode = ulist_next(roots, &uiter); /* Only want 1 so no need to loop */
> +     /*
> +      * If we find our ref root then that means all refs
> +      * this extent has to the root have not yet been
> +      * deleted. In that case, we do nothing and let the
> +      * last ref for this bytenr drive our update.
> +      *
> +      * This can happen for example if an extent is
> +      * referenced multiple times in a snapshot (clone,
> +      * etc). If we are in the middle of snapshot removal,
> +      * queued updates for such an extent will find the
> +      * root if we have not yet finished removing the
> +      * snapshot.
> +      */
> +     if (unode->val == oper->ref_root)
> +             goto out;
> +
> +     root_obj = unode->val;
> +     BUG_ON(!root_obj);

Same here, although when called through btrfs_qgroup_account, the error
code is not properly checked in btrfs_delayed_qgroup_accounting, line 1944:

1933 int btrfs_delayed_qgroup_accounting(struct btrfs_trans_handle *trans,
1934                                     struct btrfs_fs_info *fs_info)
1935 {
1936         struct btrfs_qgroup_operation *oper;
1937         int ret = 0;
1938
1939         while (!list_empty(&trans->qgroup_ref_list)) {
1940                 oper = list_first_entry(&trans->qgroup_ref_list,
1941                                         struct btrfs_qgroup_operation, 
list);
1942                 list_del_init(&oper->list);
1943                 if (!ret || !trans->aborted)
1944                         ret = btrfs_qgroup_account(trans, fs_info, oper);
1945                 spin_lock(&fs_info->qgroup_op_lock);
1946                 rb_erase(&oper->n, &fs_info->qgroup_op_tree);
1947                 spin_unlock(&fs_info->qgroup_op_lock);
1948                 btrfs_put_tree_mod_seq(fs_info, &oper->elem);
1949                 kfree(oper);
1950         }
1951         return ret;
1952 }
--
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