aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-12-14 15:30:32 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:58 -0400
commitb6cda9bcb4df7544c67fc3548a53bc1607d59f46 (patch)
tree2bae71b1c9eca52bf1e37ca1b3bdd4525e0a43fd /fs/btrfs
parente9906a98497c26a3c1a7532b51b81cc1fbdf9e1d (diff)
Btrfs: Add mount -o nodatasum to turn of file data checksumming
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.h14
-rw-r--r--fs/btrfs/disk-io.c1
-rw-r--r--fs/btrfs/inode.c11
-rw-r--r--fs/btrfs/super.c17
4 files changed, 34 insertions, 9 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 052555ced44d..5e255cabfd10 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -321,6 +321,7 @@ struct btrfs_fs_info {
321 321
322 u64 generation; 322 u64 generation;
323 u64 last_trans_committed; 323 u64 last_trans_committed;
324 unsigned long mount_opt;
324 struct btrfs_transaction *running_transaction; 325 struct btrfs_transaction *running_transaction;
325 struct btrfs_super_block super_copy; 326 struct btrfs_super_block super_copy;
326 struct extent_buffer *sb_buffer; 327 struct extent_buffer *sb_buffer;
@@ -429,6 +430,13 @@ struct btrfs_root {
429 */ 430 */
430#define BTRFS_STRING_ITEM_KEY 253 431#define BTRFS_STRING_ITEM_KEY 253
431 432
433#define BTRFS_MOUNT_NODATASUM 0x1
434
435#define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt)
436#define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt)
437#define btrfs_test_opt(root, opt) ((root)->fs_info->mount_opt & \
438 BTRFS_MOUNT_##opt)
439
432/* some macros to generate set/get funcs for the struct fields. This 440/* some macros to generate set/get funcs for the struct fields. This
433 * assumes there is a lefoo_to_cpu for every type, so lets make a simple 441 * assumes there is a lefoo_to_cpu for every type, so lets make a simple
434 * one for u8: 442 * one for u8:
@@ -906,12 +914,6 @@ static inline u32 btrfs_level_size(struct btrfs_root *root, int level) {
906 ((unsigned long)(btrfs_leaf_data(leaf) + \ 914 ((unsigned long)(btrfs_leaf_data(leaf) + \
907 btrfs_item_offset_nr(leaf, slot))) 915 btrfs_item_offset_nr(leaf, slot)))
908 916
909/* mount option defines and helpers */
910#define BTRFS_MOUNT_SUBVOL 0x000001
911#define btrfs_clear_opt(o, opt) o &= ~BTRFS_MOUNT_##opt
912#define btrfs_set_opt(o, opt) o |= BTRFS_MOUNT_##opt
913#define btrfs_test_opt(sb, opt) (BTRFS_SB(sb)->s_mount_opt & \
914 BTRFS_MOUNT_##opt)
915/* extent-tree.c */ 917/* extent-tree.c */
916int btrfs_extent_post_op(struct btrfs_trans_handle *trans, 918int btrfs_extent_post_op(struct btrfs_trans_handle *trans,
917 struct btrfs_root *root); 919 struct btrfs_root *root);
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 60a30da6af00..4338b00c2a25 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -568,6 +568,7 @@ struct btrfs_root *open_ctree(struct super_block *sb)
568 fs_info->tree_root = tree_root; 568 fs_info->tree_root = tree_root;
569 fs_info->extent_root = extent_root; 569 fs_info->extent_root = extent_root;
570 fs_info->sb = sb; 570 fs_info->sb = sb;
571 fs_info->mount_opt = 0;
571 fs_info->btree_inode = new_inode(sb); 572 fs_info->btree_inode = new_inode(sb);
572 fs_info->btree_inode->i_ino = 1; 573 fs_info->btree_inode->i_ino = 1;
573 fs_info->btree_inode->i_nlink = 1; 574 fs_info->btree_inode->i_nlink = 1;
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index e535c50e669b..11885cb114e2 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -116,10 +116,13 @@ int btrfs_writepage_io_hook(struct page *page, u64 start, u64 end)
116 struct btrfs_root *root = BTRFS_I(inode)->root; 116 struct btrfs_root *root = BTRFS_I(inode)->root;
117 struct btrfs_trans_handle *trans; 117 struct btrfs_trans_handle *trans;
118 char *kaddr; 118 char *kaddr;
119 int ret; 119 int ret = 0;
120 u64 page_start = (u64)page->index << PAGE_CACHE_SHIFT; 120 u64 page_start = (u64)page->index << PAGE_CACHE_SHIFT;
121 size_t offset = start - page_start; 121 size_t offset = start - page_start;
122 122
123 if (btrfs_test_opt(root, NODATASUM))
124 return 0;
125
123 mutex_lock(&root->fs_info->fs_mutex); 126 mutex_lock(&root->fs_info->fs_mutex);
124 trans = btrfs_start_transaction(root, 1); 127 trans = btrfs_start_transaction(root, 1);
125 btrfs_set_trans_block_group(trans, inode); 128 btrfs_set_trans_block_group(trans, inode);
@@ -143,6 +146,9 @@ int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end)
143 struct btrfs_path *path = NULL; 146 struct btrfs_path *path = NULL;
144 u32 csum; 147 u32 csum;
145 148
149 if (btrfs_test_opt(root, NODATASUM))
150 return 0;
151
146 mutex_lock(&root->fs_info->fs_mutex); 152 mutex_lock(&root->fs_info->fs_mutex);
147 path = btrfs_alloc_path(); 153 path = btrfs_alloc_path();
148 item = btrfs_lookup_csum(NULL, root, path, inode->i_ino, start, 0); 154 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 u32 csum = ~(u32)0; 182 u32 csum = ~(u32)0;
177 unsigned long flags; 183 unsigned long flags;
178 184
185 if (btrfs_test_opt(root, NODATASUM))
186 return 0;
187
179 ret = get_state_private(em_tree, start, &private); 188 ret = get_state_private(em_tree, start, &private);
180 local_irq_save(flags); 189 local_irq_save(flags);
181 kaddr = kmap_atomic(page, KM_IRQ0); 190 kaddr = kmap_atomic(page, KM_IRQ0);
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index ffa02872c4d6..ad4f280ec777 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -61,11 +61,12 @@ static void btrfs_put_super (struct super_block * sb)
61} 61}
62 62
63enum { 63enum {
64 Opt_subvol, Opt_err, 64 Opt_subvol, Opt_nodatasum, Opt_err,
65}; 65};
66 66
67static match_table_t tokens = { 67static match_table_t tokens = {
68 {Opt_subvol, "subvol=%s"}, 68 {Opt_subvol, "subvol=%s"},
69 {Opt_nodatasum, "nodatasum"},
69 {Opt_err, NULL} 70 {Opt_err, NULL}
70}; 71};
71 72
@@ -74,7 +75,12 @@ static int parse_options (char * options,
74 char **subvol_name) 75 char **subvol_name)
75{ 76{
76 char * p; 77 char * p;
78 struct btrfs_fs_info *info = NULL;
77 substring_t args[MAX_OPT_ARGS]; 79 substring_t args[MAX_OPT_ARGS];
80
81 if (root)
82 info = root->fs_info;
83
78 if (!options) 84 if (!options)
79 return 1; 85 return 1;
80 86
@@ -86,7 +92,12 @@ static int parse_options (char * options,
86 token = match_token(p, tokens, args); 92 token = match_token(p, tokens, args);
87 switch (token) { 93 switch (token) {
88 case Opt_subvol: 94 case Opt_subvol:
89 *subvol_name = match_strdup(&args[0]); 95 if (subvol_name)
96 *subvol_name = match_strdup(&args[0]);
97 break;
98 case Opt_nodatasum:
99 if (root)
100 btrfs_set_opt(info->mount_opt, NODATASUM);
90 break; 101 break;
91 default: 102 default:
92 return 0; 103 return 0;
@@ -143,6 +154,8 @@ static int btrfs_fill_super(struct super_block * sb, void * data, int silent)
143 goto fail_close; 154 goto fail_close;
144 } 155 }
145 156
157 parse_options((char *)data, tree_root, NULL);
158
146 /* this does the super kobj at the same time */ 159 /* this does the super kobj at the same time */
147 err = btrfs_sysfs_add_super(tree_root->fs_info); 160 err = btrfs_sysfs_add_super(tree_root->fs_info);
148 if (err) 161 if (err)