Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bcc63abb authored by Yan's avatar Yan Committed by Chris Mason
Browse files

Btrfs: implement memory reclaim for leaf reference cache



The memory reclaiming issue happens when snapshot exists. In that
case, some cache entries may not be used during old snapshot dropping,
so they will remain in the cache until umount.

The patch adds a field to struct btrfs_leaf_ref to record create time. Besides,
the patch makes all dead roots of a given snapshot linked together in order of
create time. After a old snapshot was completely dropped, we check the dead
root list and remove all cache entries created before the oldest dead root in
the list.

Signed-off-by: default avatarChris Mason <chris.mason@oracle.com>
parent 33958dc6
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -3275,4 +3275,3 @@ int btrfs_previous_item(struct btrfs_root *root,
	}
	return 1;
}
+2 −1
Original line number Diff line number Diff line
@@ -666,7 +666,8 @@ struct btrfs_root {
	/* the dirty list is only used by non-reference counted roots */
	struct list_head dirty_list;

	spinlock_t orphan_lock;
	spinlock_t list_lock;
	struct list_head dead_list;
	struct list_head orphan_list;
};

+0 −1
Original line number Diff line number Diff line
@@ -340,4 +340,3 @@ int btrfs_delete_one_dir_name(struct btrfs_trans_handle *trans,
	}
	return 0;
}
+3 −2
Original line number Diff line number Diff line
@@ -735,8 +735,9 @@ static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,

	INIT_LIST_HEAD(&root->dirty_list);
	INIT_LIST_HEAD(&root->orphan_list);
	INIT_LIST_HEAD(&root->dead_list);
	spin_lock_init(&root->node_lock);
	spin_lock_init(&root->orphan_lock);
	spin_lock_init(&root->list_lock);
	mutex_init(&root->objectid_mutex);

	btrfs_leaf_ref_tree_init(&root->ref_tree_struct);
+9 −9
Original line number Diff line number Diff line
@@ -1048,7 +1048,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		struct btrfs_leaf_ref *ref;
		struct btrfs_extent_info *info;

		ref = btrfs_alloc_leaf_ref(nr_file_extents);
		ref = btrfs_alloc_leaf_ref(root, nr_file_extents);
		if (!ref) {
			WARN_ON(1);
			goto out;
@@ -1085,7 +1085,7 @@ int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root,
		BUG_ON(!root->ref_tree);
		ret = btrfs_add_leaf_ref(root, ref);
		WARN_ON(ret);
		btrfs_free_leaf_ref(ref);
		btrfs_free_leaf_ref(root, ref);
	}
out:
	return 0;
@@ -2521,7 +2521,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans,
				ret = drop_leaf_ref(trans, root, ref);
				BUG_ON(ret);
				btrfs_remove_leaf_ref(root, ref);
				btrfs_free_leaf_ref(ref);
				btrfs_free_leaf_ref(root, ref);
				*level = 0;
				break;
			}
Loading