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

Btrfs: Add mount -o nodatasum to turn of file data checksumming

Signed-off-by: NChris Mason <chris.mason@oracle.com>
上级 e9906a98
...@@ -321,6 +321,7 @@ struct btrfs_fs_info { ...@@ -321,6 +321,7 @@ struct btrfs_fs_info {
u64 generation; u64 generation;
u64 last_trans_committed; u64 last_trans_committed;
unsigned long mount_opt;
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;
...@@ -429,6 +430,13 @@ struct btrfs_root { ...@@ -429,6 +430,13 @@ struct btrfs_root {
*/ */
#define BTRFS_STRING_ITEM_KEY 253 #define BTRFS_STRING_ITEM_KEY 253
#define BTRFS_MOUNT_NODATASUM 0x1
#define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt)
#define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt)
#define btrfs_test_opt(root, opt) ((root)->fs_info->mount_opt & \
BTRFS_MOUNT_##opt)
/* some macros to generate set/get funcs for the struct fields. This /* some macros to generate set/get funcs for the struct fields. This
* assumes there is a lefoo_to_cpu for every type, so lets make a simple * assumes there is a lefoo_to_cpu for every type, so lets make a simple
* one for u8: * one for u8:
...@@ -906,12 +914,6 @@ static inline u32 btrfs_level_size(struct btrfs_root *root, int level) { ...@@ -906,12 +914,6 @@ static inline u32 btrfs_level_size(struct btrfs_root *root, int level) {
((unsigned long)(btrfs_leaf_data(leaf) + \ ((unsigned long)(btrfs_leaf_data(leaf) + \
btrfs_item_offset_nr(leaf, slot))) btrfs_item_offset_nr(leaf, slot)))
/* mount option defines and helpers */
#define BTRFS_MOUNT_SUBVOL 0x000001
#define btrfs_clear_opt(o, opt) o &= ~BTRFS_MOUNT_##opt
#define btrfs_set_opt(o, opt) o |= BTRFS_MOUNT_##opt
#define btrfs_test_opt(sb, opt) (BTRFS_SB(sb)->s_mount_opt & \
BTRFS_MOUNT_##opt)
/* extent-tree.c */ /* extent-tree.c */
int btrfs_extent_post_op(struct btrfs_trans_handle *trans, int btrfs_extent_post_op(struct btrfs_trans_handle *trans,
struct btrfs_root *root); struct btrfs_root *root);
......
...@@ -568,6 +568,7 @@ struct btrfs_root *open_ctree(struct super_block *sb) ...@@ -568,6 +568,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
fs_info->tree_root = tree_root; fs_info->tree_root = tree_root;
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->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;
......
...@@ -116,10 +116,13 @@ int btrfs_writepage_io_hook(struct page *page, u64 start, u64 end) ...@@ -116,10 +116,13 @@ int btrfs_writepage_io_hook(struct page *page, u64 start, u64 end)
struct btrfs_root *root = BTRFS_I(inode)->root; struct btrfs_root *root = BTRFS_I(inode)->root;
struct btrfs_trans_handle *trans; struct btrfs_trans_handle *trans;
char *kaddr; char *kaddr;
int ret; int ret = 0;
u64 page_start = (u64)page->index << PAGE_CACHE_SHIFT; u64 page_start = (u64)page->index << PAGE_CACHE_SHIFT;
size_t offset = start - page_start; size_t offset = start - page_start;
if (btrfs_test_opt(root, NODATASUM))
return 0;
mutex_lock(&root->fs_info->fs_mutex); mutex_lock(&root->fs_info->fs_mutex);
trans = btrfs_start_transaction(root, 1); trans = btrfs_start_transaction(root, 1);
btrfs_set_trans_block_group(trans, inode); btrfs_set_trans_block_group(trans, inode);
...@@ -143,6 +146,9 @@ int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end) ...@@ -143,6 +146,9 @@ int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end)
struct btrfs_path *path = NULL; struct btrfs_path *path = NULL;
u32 csum; u32 csum;
if (btrfs_test_opt(root, NODATASUM))
return 0;
mutex_lock(&root->fs_info->fs_mutex); mutex_lock(&root->fs_info->fs_mutex);
path = btrfs_alloc_path(); path = btrfs_alloc_path();
item = btrfs_lookup_csum(NULL, root, path, inode->i_ino, start, 0); item = btrfs_lookup_csum(NULL, root, path, inode->i_ino, start, 0);
...@@ -176,6 +182,9 @@ int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end) ...@@ -176,6 +182,9 @@ int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end)
u32 csum = ~(u32)0; u32 csum = ~(u32)0;
unsigned long flags; unsigned long flags;
if (btrfs_test_opt(root, NODATASUM))
return 0;
ret = get_state_private(em_tree, start, &private); ret = get_state_private(em_tree, start, &private);
local_irq_save(flags); local_irq_save(flags);
kaddr = kmap_atomic(page, KM_IRQ0); kaddr = kmap_atomic(page, KM_IRQ0);
......
...@@ -61,11 +61,12 @@ static void btrfs_put_super (struct super_block * sb) ...@@ -61,11 +61,12 @@ static void btrfs_put_super (struct super_block * sb)
} }
enum { enum {
Opt_subvol, Opt_err, Opt_subvol, Opt_nodatasum, Opt_err,
}; };
static match_table_t tokens = { static match_table_t tokens = {
{Opt_subvol, "subvol=%s"}, {Opt_subvol, "subvol=%s"},
{Opt_nodatasum, "nodatasum"},
{Opt_err, NULL} {Opt_err, NULL}
}; };
...@@ -74,7 +75,12 @@ static int parse_options (char * options, ...@@ -74,7 +75,12 @@ static int parse_options (char * options,
char **subvol_name) char **subvol_name)
{ {
char * p; char * p;
struct btrfs_fs_info *info = NULL;
substring_t args[MAX_OPT_ARGS]; substring_t args[MAX_OPT_ARGS];
if (root)
info = root->fs_info;
if (!options) if (!options)
return 1; return 1;
...@@ -86,7 +92,12 @@ static int parse_options (char * options, ...@@ -86,7 +92,12 @@ static int parse_options (char * options,
token = match_token(p, tokens, args); token = match_token(p, tokens, args);
switch (token) { switch (token) {
case Opt_subvol: case Opt_subvol:
*subvol_name = match_strdup(&args[0]); if (subvol_name)
*subvol_name = match_strdup(&args[0]);
break;
case Opt_nodatasum:
if (root)
btrfs_set_opt(info->mount_opt, NODATASUM);
break; break;
default: default:
return 0; return 0;
...@@ -143,6 +154,8 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent) ...@@ -143,6 +154,8 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent)
goto fail_close; goto fail_close;
} }
parse_options((char *)data, tree_root, NULL);
/* this does the super kobj at the same time */ /* this does the super kobj at the same time */
err = btrfs_sysfs_add_super(tree_root->fs_info); err = btrfs_sysfs_add_super(tree_root->fs_info);
if (err) if (err)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册