Commit 34d73f54 authored by Alexander Block's avatar Alexander Block Committed by Chris Mason
Browse files

Btrfs: make aux field of ulist 64 bit



Btrfs send/receive uses the aux field to store inode numbers. On
32 bit machines this may become a problem.

Also fix all users of ulist_add and ulist_add_merged.

Reported-by: default avatarArne Jansen <sensille@gmx.net>
Signed-off-by: default avatarAlexander Block <ablock84@googlemail.com>
parent 7e0926fe
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -231,7 +231,7 @@ static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path,
			}
			if (!ret) {
				ret = ulist_add(parents, eb->start,
						(unsigned long)eie, GFP_NOFS);
						(u64)eie, GFP_NOFS);
				if (ret < 0)
					break;
				if (!extent_item_pos) {
@@ -914,8 +914,8 @@ again:
				free_extent_buffer(eb);
			}
			ret = ulist_add_merge(refs, ref->parent,
					      (unsigned long)ref->inode_list,
					      (unsigned long *)&eie, GFP_NOFS);
					      (u64)ref->inode_list,
					      (u64 *)&eie, GFP_NOFS);
			if (!ret && extent_item_pos) {
				/*
				 * we've recorded that parent, so we must extend
@@ -1404,7 +1404,7 @@ int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
		ULIST_ITER_INIT(&root_uiter);
		while (!ret && (root_node = ulist_next(roots, &root_uiter))) {
			pr_debug("root %llu references leaf %llu, data list "
				 "%#lx\n", root_node->val, ref_node->val,
				 "%#llx\n", root_node->val, ref_node->val,
				 ref_node->aux);
			ret = iterate_leaf_refs(
				(struct extent_inode_elem *)ref_node->aux,
+10 −10
Original line number Diff line number Diff line
@@ -1145,7 +1145,7 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,

		ulist_reinit(tmp);
						/* XXX id not needed */
		ulist_add(tmp, qg->qgroupid, (unsigned long)qg, GFP_ATOMIC);
		ulist_add(tmp, qg->qgroupid, (u64)qg, GFP_ATOMIC);
		ULIST_ITER_INIT(&tmp_uiter);
		while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) {
			struct btrfs_qgroup_list *glist;
@@ -1158,7 +1158,7 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,

			list_for_each_entry(glist, &qg->groups, next_group) {
				ulist_add(tmp, glist->group->qgroupid,
					  (unsigned long)glist->group,
					  (u64)glist->group,
					  GFP_ATOMIC);
			}
		}
@@ -1168,7 +1168,7 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,
	 * step 2: walk from the new root
	 */
	ulist_reinit(tmp);
	ulist_add(tmp, qgroup->qgroupid, (unsigned long)qgroup, GFP_ATOMIC);
	ulist_add(tmp, qgroup->qgroupid, (u64)qgroup, GFP_ATOMIC);
	ULIST_ITER_INIT(&uiter);
	while ((unode = ulist_next(tmp, &uiter))) {
		struct btrfs_qgroup *qg;
@@ -1190,7 +1190,7 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,

		list_for_each_entry(glist, &qg->groups, next_group) {
			ulist_add(tmp, glist->group->qgroupid,
				  (unsigned long)glist->group, GFP_ATOMIC);
				  (u64)glist->group, GFP_ATOMIC);
		}
	}

@@ -1208,7 +1208,7 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,
			continue;

		ulist_reinit(tmp);
		ulist_add(tmp, qg->qgroupid, (unsigned long)qg, GFP_ATOMIC);
		ulist_add(tmp, qg->qgroupid, (u64)qg, GFP_ATOMIC);
		ULIST_ITER_INIT(&tmp_uiter);
		while ((tmp_unode = ulist_next(tmp, &tmp_uiter))) {
			struct btrfs_qgroup_list *glist;
@@ -1225,7 +1225,7 @@ int btrfs_qgroup_account_ref(struct btrfs_trans_handle *trans,

			list_for_each_entry(glist, &qg->groups, next_group) {
				ulist_add(tmp, glist->group->qgroupid,
					  (unsigned long)glist->group,
					  (u64)glist->group,
					  GFP_ATOMIC);
			}
		}
@@ -1469,7 +1469,7 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes)
	 * be exceeded
	 */
	ulist = ulist_alloc(GFP_ATOMIC);
	ulist_add(ulist, qgroup->qgroupid, (unsigned long)qgroup, GFP_ATOMIC);
	ulist_add(ulist, qgroup->qgroupid, (u64)qgroup, GFP_ATOMIC);
	ULIST_ITER_INIT(&uiter);
	while ((unode = ulist_next(ulist, &uiter))) {
		struct btrfs_qgroup *qg;
@@ -1489,7 +1489,7 @@ int btrfs_qgroup_reserve(struct btrfs_root *root, u64 num_bytes)

		list_for_each_entry(glist, &qg->groups, next_group) {
			ulist_add(ulist, glist->group->qgroupid,
				  (unsigned long)glist->group, GFP_ATOMIC);
				  (u64)glist->group, GFP_ATOMIC);
		}
	}
	if (ret)
@@ -1541,7 +1541,7 @@ void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes)
		goto out;

	ulist = ulist_alloc(GFP_ATOMIC);
	ulist_add(ulist, qgroup->qgroupid, (unsigned long)qgroup, GFP_ATOMIC);
	ulist_add(ulist, qgroup->qgroupid, (u64)qgroup, GFP_ATOMIC);
	ULIST_ITER_INIT(&uiter);
	while ((unode = ulist_next(ulist, &uiter))) {
		struct btrfs_qgroup *qg;
@@ -1553,7 +1553,7 @@ void btrfs_qgroup_free(struct btrfs_root *root, u64 num_bytes)

		list_for_each_entry(glist, &qg->groups, next_group) {
			ulist_add(ulist, glist->group->qgroupid,
				  (unsigned long)glist->group, GFP_ATOMIC);
				  (u64)glist->group, GFP_ATOMIC);
		}
	}

+3 −4
Original line number Diff line number Diff line
@@ -143,14 +143,13 @@ EXPORT_SYMBOL(ulist_free);
 * In case of allocation failure -ENOMEM is returned and the ulist stays
 * unaltered.
 */
int ulist_add(struct ulist *ulist, u64 val, unsigned long aux,
	      gfp_t gfp_mask)
int ulist_add(struct ulist *ulist, u64 val, u64 aux, gfp_t gfp_mask)
{
	return ulist_add_merge(ulist, val, aux, NULL, gfp_mask);
}

int ulist_add_merge(struct ulist *ulist, u64 val, unsigned long aux,
		    unsigned long *old_aux, gfp_t gfp_mask)
int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux,
		    u64 *old_aux, gfp_t gfp_mask)
{
	int i;

+4 −5
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ struct ulist_iterator {
 */
struct ulist_node {
	u64 val;		/* value to store */
	unsigned long aux;	/* auxiliary value saved along with the val */
	u64 aux;		/* auxiliary value saved along with the val */
};

struct ulist {
@@ -65,10 +65,9 @@ void ulist_fini(struct ulist *ulist);
void ulist_reinit(struct ulist *ulist);
struct ulist *ulist_alloc(gfp_t gfp_mask);
void ulist_free(struct ulist *ulist);
int ulist_add(struct ulist *ulist, u64 val, unsigned long aux,
	      gfp_t gfp_mask);
int ulist_add_merge(struct ulist *ulist, u64 val, unsigned long aux,
		    unsigned long *old_aux, gfp_t gfp_mask);
int ulist_add(struct ulist *ulist, u64 val, u64 aux, gfp_t gfp_mask);
int ulist_add_merge(struct ulist *ulist, u64 val, u64 aux,
		    u64 *old_aux, gfp_t gfp_mask);
struct ulist_node *ulist_next(struct ulist *ulist,
			      struct ulist_iterator *uiter);