Btrfs: Add mount -o nodatasum to turn of file data checksumming
Signed-off-by: Chris Mason <chris.mason@oracle.com>
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 052555c..5e255ca 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -321,6 +321,7 @@
u64 generation;
u64 last_trans_committed;
+ unsigned long mount_opt;
struct btrfs_transaction *running_transaction;
struct btrfs_super_block super_copy;
struct extent_buffer *sb_buffer;
@@ -429,6 +430,13 @@
*/
#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
* assumes there is a lefoo_to_cpu for every type, so lets make a simple
* one for u8:
@@ -906,12 +914,6 @@
((unsigned long)(btrfs_leaf_data(leaf) + \
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 */
int btrfs_extent_post_op(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 60a30da..4338b00 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -568,6 +568,7 @@
fs_info->tree_root = tree_root;
fs_info->extent_root = extent_root;
fs_info->sb = sb;
+ fs_info->mount_opt = 0;
fs_info->btree_inode = new_inode(sb);
fs_info->btree_inode->i_ino = 1;
fs_info->btree_inode->i_nlink = 1;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index e535c50..11885cb 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -116,10 +116,13 @@
struct btrfs_root *root = BTRFS_I(inode)->root;
struct btrfs_trans_handle *trans;
char *kaddr;
- int ret;
+ int ret = 0;
u64 page_start = (u64)page->index << PAGE_CACHE_SHIFT;
size_t offset = start - page_start;
+ if (btrfs_test_opt(root, NODATASUM))
+ return 0;
+
mutex_lock(&root->fs_info->fs_mutex);
trans = btrfs_start_transaction(root, 1);
btrfs_set_trans_block_group(trans, inode);
@@ -143,6 +146,9 @@
struct btrfs_path *path = NULL;
u32 csum;
+ if (btrfs_test_opt(root, NODATASUM))
+ return 0;
+
mutex_lock(&root->fs_info->fs_mutex);
path = btrfs_alloc_path();
item = btrfs_lookup_csum(NULL, root, path, inode->i_ino, start, 0);
@@ -176,6 +182,9 @@
u32 csum = ~(u32)0;
unsigned long flags;
+ if (btrfs_test_opt(root, NODATASUM))
+ return 0;
+
ret = get_state_private(em_tree, start, &private);
local_irq_save(flags);
kaddr = kmap_atomic(page, KM_IRQ0);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index ffa0287..ad4f280 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -61,11 +61,12 @@
}
enum {
- Opt_subvol, Opt_err,
+ Opt_subvol, Opt_nodatasum, Opt_err,
};
static match_table_t tokens = {
{Opt_subvol, "subvol=%s"},
+ {Opt_nodatasum, "nodatasum"},
{Opt_err, NULL}
};
@@ -74,7 +75,12 @@
char **subvol_name)
{
char * p;
+ struct btrfs_fs_info *info = NULL;
substring_t args[MAX_OPT_ARGS];
+
+ if (root)
+ info = root->fs_info;
+
if (!options)
return 1;
@@ -86,7 +92,12 @@
token = match_token(p, tokens, args);
switch (token) {
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;
default:
return 0;
@@ -143,6 +154,8 @@
goto fail_close;
}
+ parse_options((char *)data, tree_root, NULL);
+
/* this does the super kobj at the same time */
err = btrfs_sysfs_add_super(tree_root->fs_info);
if (err)