Commit 4b9465cb authored by Chris Mason's avatar Chris Mason

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: default avatarChris Mason <chris.mason@oracle.com>
parent e7786c3a
...@@ -1340,6 +1340,7 @@ struct btrfs_ioctl_defrag_range_args { ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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 { ...@@ -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 = { ...@@ -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) ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment