mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	Btrfs: add mount -o inode_cache
This makes the inode map cache default to off until we fix the overflow problem when the free space crcs don't fit inside a single page. Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
		
							parent
							
								
									e7786c3ae5
								
							
						
					
					
						commit
						4b9465cb9e
					
				
					 4 changed files with 34 additions and 1 deletions
				
			
		| 
						 | 
					@ -1340,6 +1340,7 @@ struct btrfs_ioctl_defrag_range_args {
 | 
				
			||||||
#define BTRFS_MOUNT_USER_SUBVOL_RM_ALLOWED (1 << 14)
 | 
					#define BTRFS_MOUNT_USER_SUBVOL_RM_ALLOWED (1 << 14)
 | 
				
			||||||
#define BTRFS_MOUNT_ENOSPC_DEBUG	 (1 << 15)
 | 
					#define BTRFS_MOUNT_ENOSPC_DEBUG	 (1 << 15)
 | 
				
			||||||
#define BTRFS_MOUNT_AUTO_DEFRAG		(1 << 16)
 | 
					#define BTRFS_MOUNT_AUTO_DEFRAG		(1 << 16)
 | 
				
			||||||
 | 
					#define BTRFS_MOUNT_INODE_MAP_CACHE	(1 << 17)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define btrfs_clear_opt(o, opt)		((o) &= ~BTRFS_MOUNT_##opt)
 | 
					#define btrfs_clear_opt(o, opt)		((o) &= ~BTRFS_MOUNT_##opt)
 | 
				
			||||||
#define btrfs_set_opt(o, opt)		((o) |= BTRFS_MOUNT_##opt)
 | 
					#define btrfs_set_opt(o, opt)		((o) |= BTRFS_MOUNT_##opt)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2536,6 +2536,9 @@ int load_free_ino_cache(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
 | 
				
			||||||
	int ret = 0;
 | 
						int ret = 0;
 | 
				
			||||||
	u64 root_gen = btrfs_root_generation(&root->root_item);
 | 
						u64 root_gen = btrfs_root_generation(&root->root_item);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!btrfs_test_opt(root, INODE_MAP_CACHE))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * If we're unmounting then just return, since this does a search on the
 | 
						 * If we're unmounting then just return, since this does a search on the
 | 
				
			||||||
	 * normal root and not the commit root and we could deadlock.
 | 
						 * normal root and not the commit root and we could deadlock.
 | 
				
			||||||
| 
						 | 
					@ -2575,6 +2578,9 @@ int btrfs_write_out_ino_cache(struct btrfs_root *root,
 | 
				
			||||||
	struct inode *inode;
 | 
						struct inode *inode;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!btrfs_test_opt(root, INODE_MAP_CACHE))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inode = lookup_free_ino_inode(root, path);
 | 
						inode = lookup_free_ino_inode(root, path);
 | 
				
			||||||
	if (IS_ERR(inode))
 | 
						if (IS_ERR(inode))
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,6 +38,9 @@ static int caching_kthread(void *data)
 | 
				
			||||||
	int slot;
 | 
						int slot;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!btrfs_test_opt(root, INODE_MAP_CACHE))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	path = btrfs_alloc_path();
 | 
						path = btrfs_alloc_path();
 | 
				
			||||||
	if (!path)
 | 
						if (!path)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
| 
						 | 
					@ -141,6 +144,9 @@ static void start_caching(struct btrfs_root *root)
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
	u64 objectid;
 | 
						u64 objectid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!btrfs_test_opt(root, INODE_MAP_CACHE))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spin_lock(&root->cache_lock);
 | 
						spin_lock(&root->cache_lock);
 | 
				
			||||||
	if (root->cached != BTRFS_CACHE_NO) {
 | 
						if (root->cached != BTRFS_CACHE_NO) {
 | 
				
			||||||
		spin_unlock(&root->cache_lock);
 | 
							spin_unlock(&root->cache_lock);
 | 
				
			||||||
| 
						 | 
					@ -178,6 +184,9 @@ static void start_caching(struct btrfs_root *root)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid)
 | 
					int btrfs_find_free_ino(struct btrfs_root *root, u64 *objectid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						if (!btrfs_test_opt(root, INODE_MAP_CACHE))
 | 
				
			||||||
 | 
							return btrfs_find_free_objectid(root, objectid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
again:
 | 
					again:
 | 
				
			||||||
	*objectid = btrfs_find_ino_for_alloc(root);
 | 
						*objectid = btrfs_find_ino_for_alloc(root);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -201,6 +210,10 @@ void btrfs_return_ino(struct btrfs_root *root, u64 objectid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct btrfs_free_space_ctl *ctl = root->free_ino_ctl;
 | 
						struct btrfs_free_space_ctl *ctl = root->free_ino_ctl;
 | 
				
			||||||
	struct btrfs_free_space_ctl *pinned = root->free_ino_pinned;
 | 
						struct btrfs_free_space_ctl *pinned = root->free_ino_pinned;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!btrfs_test_opt(root, INODE_MAP_CACHE))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
again:
 | 
					again:
 | 
				
			||||||
	if (root->cached == BTRFS_CACHE_FINISHED) {
 | 
						if (root->cached == BTRFS_CACHE_FINISHED) {
 | 
				
			||||||
		__btrfs_add_free_space(ctl, objectid, 1);
 | 
							__btrfs_add_free_space(ctl, objectid, 1);
 | 
				
			||||||
| 
						 | 
					@ -250,6 +263,9 @@ void btrfs_unpin_free_ino(struct btrfs_root *root)
 | 
				
			||||||
	struct rb_node *n;
 | 
						struct rb_node *n;
 | 
				
			||||||
	u64 count;
 | 
						u64 count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!btrfs_test_opt(root, INODE_MAP_CACHE))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while (1) {
 | 
						while (1) {
 | 
				
			||||||
		n = rb_first(rbroot);
 | 
							n = rb_first(rbroot);
 | 
				
			||||||
		if (!n)
 | 
							if (!n)
 | 
				
			||||||
| 
						 | 
					@ -399,9 +415,13 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
 | 
				
			||||||
	    root != root->fs_info->tree_root)
 | 
						    root != root->fs_info->tree_root)
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!btrfs_test_opt(root, INODE_MAP_CACHE))
 | 
				
			||||||
 | 
							return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	path = btrfs_alloc_path();
 | 
						path = btrfs_alloc_path();
 | 
				
			||||||
	if (!path)
 | 
						if (!path)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
again:
 | 
					again:
 | 
				
			||||||
	inode = lookup_free_ino_inode(root, path);
 | 
						inode = lookup_free_ino_inode(root, path);
 | 
				
			||||||
	if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) {
 | 
						if (IS_ERR(inode) && PTR_ERR(inode) != -ENOENT) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -160,7 +160,8 @@ enum {
 | 
				
			||||||
	Opt_compress_type, Opt_compress_force, Opt_compress_force_type,
 | 
						Opt_compress_type, Opt_compress_force, Opt_compress_force_type,
 | 
				
			||||||
	Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard,
 | 
						Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard,
 | 
				
			||||||
	Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed,
 | 
						Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed,
 | 
				
			||||||
	Opt_enospc_debug, Opt_subvolrootid, Opt_defrag, Opt_err,
 | 
						Opt_enospc_debug, Opt_subvolrootid, Opt_defrag,
 | 
				
			||||||
 | 
						Opt_inode_cache, Opt_err,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static match_table_t tokens = {
 | 
					static match_table_t tokens = {
 | 
				
			||||||
| 
						 | 
					@ -192,6 +193,7 @@ static match_table_t tokens = {
 | 
				
			||||||
	{Opt_enospc_debug, "enospc_debug"},
 | 
						{Opt_enospc_debug, "enospc_debug"},
 | 
				
			||||||
	{Opt_subvolrootid, "subvolrootid=%d"},
 | 
						{Opt_subvolrootid, "subvolrootid=%d"},
 | 
				
			||||||
	{Opt_defrag, "autodefrag"},
 | 
						{Opt_defrag, "autodefrag"},
 | 
				
			||||||
 | 
						{Opt_inode_cache, "inode_cache"},
 | 
				
			||||||
	{Opt_err, NULL},
 | 
						{Opt_err, NULL},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -360,6 +362,10 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
 | 
				
			||||||
			printk(KERN_INFO "btrfs: enabling disk space caching\n");
 | 
								printk(KERN_INFO "btrfs: enabling disk space caching\n");
 | 
				
			||||||
			btrfs_set_opt(info->mount_opt, SPACE_CACHE);
 | 
								btrfs_set_opt(info->mount_opt, SPACE_CACHE);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
							case Opt_inode_cache:
 | 
				
			||||||
 | 
								printk(KERN_INFO "btrfs: enabling inode map caching\n");
 | 
				
			||||||
 | 
								btrfs_set_opt(info->mount_opt, INODE_MAP_CACHE);
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
		case Opt_clear_cache:
 | 
							case Opt_clear_cache:
 | 
				
			||||||
			printk(KERN_INFO "btrfs: force clearing of disk cache\n");
 | 
								printk(KERN_INFO "btrfs: force clearing of disk cache\n");
 | 
				
			||||||
			btrfs_set_opt(info->mount_opt, CLEAR_CACHE);
 | 
								btrfs_set_opt(info->mount_opt, CLEAR_CACHE);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue