aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h8
-rw-r--r--fs/btrfs/extent_io.c2
-rw-r--r--fs/btrfs/extent_io.h1
-rw-r--r--fs/btrfs/file-item.c50
-rw-r--r--fs/btrfs/inode.c32
5 files changed, 75 insertions, 18 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 086cb0525cd1..92d892f92075 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -1142,11 +1142,9 @@ int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
1142 struct btrfs_root *root, 1142 struct btrfs_root *root,
1143 struct btrfs_path *path, u64 objectid, 1143 struct btrfs_path *path, u64 objectid,
1144 u64 bytenr, int mod); 1144 u64 bytenr, int mod);
1145int btrfs_csum_file_block(struct btrfs_trans_handle *trans, 1145int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
1146 struct btrfs_root *root, 1146 struct btrfs_root *root, struct inode *inode,
1147 struct inode *inode, 1147 struct bio *bio);
1148 u64 objectid, u64 offset,
1149 char *data, size_t len);
1150struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans, 1148struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans,
1151 struct btrfs_root *root, 1149 struct btrfs_root *root,
1152 struct btrfs_path *path, 1150 struct btrfs_path *path,
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index fb6400895ed6..e8130c876330 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -1705,6 +1705,8 @@ static int submit_one_bio(int rw, struct bio *bio)
1705 (unsigned long long)bio->bi_sector); 1705 (unsigned long long)bio->bi_sector);
1706 WARN_ON(1); 1706 WARN_ON(1);
1707 } 1707 }
1708 if (tree->ops && tree->ops->submit_bio_hook)
1709 tree->ops->submit_bio_hook(rw, bio);
1708 1710
1709 submit_bio(rw, bio); 1711 submit_bio(rw, bio);
1710 if (bio_flagged(bio, BIO_EOPNOTSUPP)) 1712 if (bio_flagged(bio, BIO_EOPNOTSUPP))
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index fcc4bb078c24..9d6654667089 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -28,6 +28,7 @@ struct extent_state;
28struct extent_io_ops { 28struct extent_io_ops {
29 int (*fill_delalloc)(struct inode *inode, u64 start, u64 end); 29 int (*fill_delalloc)(struct inode *inode, u64 start, u64 end);
30 int (*writepage_io_hook)(struct page *page, u64 start, u64 end); 30 int (*writepage_io_hook)(struct page *page, u64 start, u64 end);
31 int (*submit_bio_hook)(int rw, struct bio *bio);
31 int (*readpage_io_hook)(struct page *page, u64 start, u64 end); 32 int (*readpage_io_hook)(struct page *page, u64 start, u64 end);
32 int (*readpage_end_io_hook)(struct page *page, u64 start, u64 end, 33 int (*readpage_end_io_hook)(struct page *page, u64 start, u64 end,
33 struct extent_state *state); 34 struct extent_state *state);
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index 3ebbc058d082..3f0e71b0e5d9 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -16,6 +16,9 @@
16 * Boston, MA 021110-1307, USA. 16 * Boston, MA 021110-1307, USA.
17 */ 17 */
18 18
19#include <linux/bio.h>
20#include <linux/pagemap.h>
21#include <linux/highmem.h>
19#include "ctree.h" 22#include "ctree.h"
20#include "disk-io.h" 23#include "disk-io.h"
21#include "transaction.h" 24#include "transaction.h"
@@ -131,28 +134,35 @@ int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
131 return ret; 134 return ret;
132} 135}
133 136
134int btrfs_csum_file_block(struct btrfs_trans_handle *trans, 137int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
135 struct btrfs_root *root, 138 struct btrfs_root *root, struct inode *inode,
136 struct inode *inode, 139 struct bio *bio)
137 u64 objectid, u64 offset,
138 char *data, size_t len)
139{ 140{
141 u64 objectid = inode->i_ino;
142 u64 offset;
140 int ret; 143 int ret;
141 struct btrfs_key file_key; 144 struct btrfs_key file_key;
142 struct btrfs_key found_key; 145 struct btrfs_key found_key;
143 u64 next_offset = (u64)-1; 146 u64 next_offset;
144 int found_next = 0; 147 int found_next;
145 struct btrfs_path *path; 148 struct btrfs_path *path;
146 struct btrfs_csum_item *item; 149 struct btrfs_csum_item *item;
150 struct btrfs_csum_item *item_end;
147 struct extent_buffer *leaf = NULL; 151 struct extent_buffer *leaf = NULL;
148 u64 csum_offset; 152 u64 csum_offset;
149 u32 csum_result = ~(u32)0; 153 u32 csum_result;
150 u32 nritems; 154 u32 nritems;
151 u32 ins_size; 155 u32 ins_size;
156 int bio_index = 0;
157 struct bio_vec *bvec = bio->bi_io_vec;
158 char *data;
152 159
153 path = btrfs_alloc_path(); 160 path = btrfs_alloc_path();
154 BUG_ON(!path); 161 BUG_ON(!path);
155 162again:
163 next_offset = (u64)-1;
164 found_next = 0;
165 offset = page_offset(bvec->bv_page) + bvec->bv_offset;
156 file_key.objectid = objectid; 166 file_key.objectid = objectid;
157 file_key.offset = offset; 167 file_key.offset = offset;
158 btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); 168 btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY);
@@ -259,7 +269,15 @@ csum:
259 item = (struct btrfs_csum_item *)((unsigned char *)item + 269 item = (struct btrfs_csum_item *)((unsigned char *)item +
260 csum_offset * BTRFS_CRC32_SIZE); 270 csum_offset * BTRFS_CRC32_SIZE);
261found: 271found:
262 csum_result = btrfs_csum_data(root, data, csum_result, len); 272 item_end = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_csum_item);
273 item_end = (struct btrfs_csum_item *)((unsigned char *)item_end +
274 btrfs_item_size_nr(leaf, path->slots[0]));
275next_bvec:
276 data = kmap_atomic(bvec->bv_page, KM_IRQ0);
277 csum_result = ~(u32)0;
278 csum_result = btrfs_csum_data(root, data + bvec->bv_offset,
279 csum_result, bvec->bv_len);
280 kunmap_atomic(data, KM_IRQ0);
263 btrfs_csum_final(csum_result, (char *)&csum_result); 281 btrfs_csum_final(csum_result, (char *)&csum_result);
264 if (csum_result == 0) { 282 if (csum_result == 0) {
265 printk("csum result is 0 for inode %lu offset %Lu\n", inode->i_ino, offset); 283 printk("csum result is 0 for inode %lu offset %Lu\n", inode->i_ino, offset);
@@ -267,9 +285,19 @@ found:
267 285
268 write_extent_buffer(leaf, &csum_result, (unsigned long)item, 286 write_extent_buffer(leaf, &csum_result, (unsigned long)item,
269 BTRFS_CRC32_SIZE); 287 BTRFS_CRC32_SIZE);
288 bio_index++;
289 bvec++;
290 if (bio_index < bio->bi_vcnt) {
291 item = (struct btrfs_csum_item *)((char *)item + BTRFS_CRC32_SIZE);
292 if (item < item_end)
293 goto next_bvec;
294 }
270 btrfs_mark_buffer_dirty(path->nodes[0]); 295 btrfs_mark_buffer_dirty(path->nodes[0]);
296 if (bio_index < bio->bi_vcnt) {
297 btrfs_release_path(root, path);
298 goto again;
299 }
271fail: 300fail:
272 btrfs_release_path(root, path);
273 btrfs_free_path(path); 301 btrfs_free_path(path);
274 return ret; 302 return ret;
275} 303}
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 3e79572a5cb1..bbb71fad861a 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -16,6 +16,7 @@
16 * Boston, MA 021110-1307, USA. 16 * Boston, MA 021110-1307, USA.
17 */ 17 */
18 18
19#include <linux/bio.h>
19#include <linux/buffer_head.h> 20#include <linux/buffer_head.h>
20#include <linux/fs.h> 21#include <linux/fs.h>
21#include <linux/pagemap.h> 22#include <linux/pagemap.h>
@@ -294,6 +295,32 @@ int btrfs_clear_bit_hook(struct inode *inode, u64 start, u64 end,
294 return 0; 295 return 0;
295} 296}
296 297
298int btrfs_submit_bio_hook(int rw, struct bio *bio)
299{
300 // struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1;
301 struct bio_vec *bvec = bio->bi_io_vec;
302 struct inode *inode = bvec->bv_page->mapping->host;
303 struct btrfs_root *root = BTRFS_I(inode)->root;
304 struct btrfs_trans_handle *trans;
305 int ret = 0;
306
307 if (rw != WRITE)
308 return 0;
309
310 if (btrfs_test_opt(root, NODATASUM) ||
311 btrfs_test_flag(inode, NODATASUM))
312 return 0;
313
314 mutex_lock(&root->fs_info->fs_mutex);
315 trans = btrfs_start_transaction(root, 1);
316 btrfs_set_trans_block_group(trans, inode);
317 btrfs_csum_file_blocks(trans, root, inode, bio);
318 ret = btrfs_end_transaction(trans, root);
319 BUG_ON(ret);
320 mutex_unlock(&root->fs_info->fs_mutex);
321 return ret;
322}
323#if 0
297int btrfs_writepage_io_hook(struct page *page, u64 start, u64 end) 324int btrfs_writepage_io_hook(struct page *page, u64 start, u64 end)
298{ 325{
299 struct inode *inode = page->mapping->host; 326 struct inode *inode = page->mapping->host;
@@ -318,7 +345,7 @@ int btrfs_writepage_io_hook(struct page *page, u64 start, u64 end)
318 mutex_unlock(&root->fs_info->fs_mutex); 345 mutex_unlock(&root->fs_info->fs_mutex);
319 return ret; 346 return ret;
320} 347}
321 348#endif
322int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end) 349int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end)
323{ 350{
324 int ret = 0; 351 int ret = 0;
@@ -3022,7 +3049,8 @@ static struct file_operations btrfs_dir_file_operations = {
3022 3049
3023static struct extent_io_ops btrfs_extent_io_ops = { 3050static struct extent_io_ops btrfs_extent_io_ops = {
3024 .fill_delalloc = run_delalloc_range, 3051 .fill_delalloc = run_delalloc_range,
3025 .writepage_io_hook = btrfs_writepage_io_hook, 3052 // .writepage_io_hook = btrfs_writepage_io_hook,
3053 .submit_bio_hook = btrfs_submit_bio_hook,
3026 .readpage_io_hook = btrfs_readpage_io_hook, 3054 .readpage_io_hook = btrfs_readpage_io_hook,
3027 .readpage_end_io_hook = btrfs_readpage_end_io_hook, 3055 .readpage_end_io_hook = btrfs_readpage_end_io_hook,
3028 .set_bit_hook = btrfs_set_bit_hook, 3056 .set_bit_hook = btrfs_set_bit_hook,