Btrfs: Add mount option to enforce a max extent size
Signed-off-by: Chris Mason <chris.mason@oracle.com>
This commit is contained in:
parent
d10c5f31c7
commit
c59f8951d4
|
@ -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)
|
||||||
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)
|
||||||
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)
|
||||||
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 @@
|
||||||
#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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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,
|
||||||
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,
|
||||||
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue