提交 c59f8951 编写于 作者: C Chris Mason

Btrfs: Add mount option to enforce a max extent size

Signed-off-by: NChris Mason <chris.mason@oracle.com>
上级 d10c5f31
...@@ -322,6 +322,7 @@ struct btrfs_fs_info { ...@@ -322,6 +322,7 @@ struct btrfs_fs_info {
u64 generation; u64 generation;
u64 last_trans_committed; u64 last_trans_committed;
unsigned long mount_opt; unsigned long mount_opt;
u64 max_extent;
struct btrfs_transaction *running_transaction; struct btrfs_transaction *running_transaction;
struct btrfs_super_block super_copy; struct btrfs_super_block super_copy;
struct extent_buffer *sb_buffer; struct extent_buffer *sb_buffer;
......
...@@ -569,6 +569,7 @@ struct btrfs_root *open_ctree(struct super_block *sb) ...@@ -569,6 +569,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
fs_info->extent_root = extent_root; fs_info->extent_root = extent_root;
fs_info->sb = sb; fs_info->sb = sb;
fs_info->mount_opt = 0; fs_info->mount_opt = 0;
fs_info->max_extent = (u64)-1;
fs_info->btree_inode = new_inode(sb); fs_info->btree_inode = new_inode(sb);
fs_info->btree_inode->i_ino = 1; fs_info->btree_inode->i_ino = 1;
fs_info->btree_inode->i_nlink = 1; fs_info->btree_inode->i_nlink = 1;
......
...@@ -78,6 +78,7 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end) ...@@ -78,6 +78,7 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end)
struct btrfs_trans_handle *trans; struct btrfs_trans_handle *trans;
u64 alloc_hint = 0; u64 alloc_hint = 0;
u64 num_bytes; u64 num_bytes;
u64 cur_alloc_size;
u64 blocksize = root->sectorsize; u64 blocksize = root->sectorsize;
struct btrfs_key ins; struct btrfs_key ins;
int ret; int ret;
...@@ -94,17 +95,24 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end) ...@@ -94,17 +95,24 @@ static int cow_file_range(struct inode *inode, u64 start, u64 end)
if (alloc_hint == EXTENT_MAP_INLINE) if (alloc_hint == EXTENT_MAP_INLINE)
goto out; goto out;
ret = btrfs_alloc_extent(trans, root, num_bytes, while(num_bytes > 0) {
root->root_key.objectid, trans->transid, cur_alloc_size = min(num_bytes, root->fs_info->max_extent);
inode->i_ino, start, 0, ret = btrfs_alloc_extent(trans, root, cur_alloc_size,
alloc_hint, (u64)-1, &ins, 1); root->root_key.objectid,
if (ret) { trans->transid,
WARN_ON(1); inode->i_ino, start, 0,
goto out; alloc_hint, (u64)-1, &ins, 1);
if (ret) {
WARN_ON(1);
goto out;
}
ret = btrfs_insert_file_extent(trans, root, inode->i_ino,
start, ins.objectid, ins.offset,
ins.offset);
num_bytes -= cur_alloc_size;
alloc_hint = ins.objectid + ins.offset;
start += cur_alloc_size;
} }
ret = btrfs_insert_file_extent(trans, root, inode->i_ino,
start, ins.objectid, ins.offset,
ins.offset);
out: out:
btrfs_end_transaction(trans, root); btrfs_end_transaction(trans, root);
return ret; return ret;
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <linux/statfs.h> #include <linux/statfs.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/parser.h> #include <linux/parser.h>
#include <linux/ctype.h>
#include "ctree.h" #include "ctree.h"
#include "disk-io.h" #include "disk-io.h"
#include "transaction.h" #include "transaction.h"
...@@ -61,16 +62,42 @@ static void btrfs_put_super (struct super_block * sb) ...@@ -61,16 +62,42 @@ static void btrfs_put_super (struct super_block * sb)
} }
enum { enum {
Opt_subvol, Opt_nodatasum, Opt_nodatacow, Opt_err, Opt_subvol, Opt_nodatasum, Opt_nodatacow, Opt_max_extent, Opt_err,
}; };
static match_table_t tokens = { static match_table_t tokens = {
{Opt_subvol, "subvol=%s"}, {Opt_subvol, "subvol=%s"},
{Opt_nodatasum, "nodatasum"}, {Opt_nodatasum, "nodatasum"},
{Opt_nodatacow, "nodatacow"}, {Opt_nodatacow, "nodatacow"},
{Opt_max_extent, "max_extent=%s"},
{Opt_err, NULL} {Opt_err, NULL}
}; };
static unsigned long parse_size(char *str)
{
unsigned long res;
int mult = 1;
char *end;
char last;
res = simple_strtoul(str, &end, 10);
last = end[0];
if (isalpha(last)) {
last = tolower(last);
switch (last) {
case 'g':
mult *= 1024;
case 'm':
mult *= 1024;
case 'k':
mult *= 1024;
}
res = res * mult;
}
return res;
}
static int parse_options (char * options, static int parse_options (char * options,
struct btrfs_root *root, struct btrfs_root *root,
char **subvol_name) char **subvol_name)
...@@ -118,6 +145,21 @@ static int parse_options (char * options, ...@@ -118,6 +145,21 @@ static int parse_options (char * options,
btrfs_set_opt(info->mount_opt, NODATASUM); btrfs_set_opt(info->mount_opt, NODATASUM);
} }
break; break;
case Opt_max_extent:
if (info) {
char *num = match_strdup(&args[0]);
if (num) {
info->max_extent = parse_size(num);
kfree(num);
info->max_extent = max_t(u64,
info->max_extent,
root->sectorsize);
printk("btrfs: max_extent at %Lu\n",
info->max_extent);
}
}
break;
default: default:
break; break;
} }
...@@ -329,6 +371,8 @@ static int btrfs_get_sb(struct file_system_type *fs_type, ...@@ -329,6 +371,8 @@ static int btrfs_get_sb(struct file_system_type *fs_type,
ret = btrfs_get_sb_bdev(fs_type, flags, dev_name, data, ret = btrfs_get_sb_bdev(fs_type, flags, dev_name, data,
btrfs_fill_super, mnt, btrfs_fill_super, mnt,
subvol_name ? subvol_name : "default"); subvol_name ? subvol_name : "default");
if (subvol_name)
kfree(subvol_name);
return ret; return ret;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册