diff options
-rw-r--r-- | fs/btrfs/ctree.h | 8 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 2 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 1 | ||||
-rw-r--r-- | fs/btrfs/file-item.c | 50 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 32 |
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); |
1145 | int btrfs_csum_file_block(struct btrfs_trans_handle *trans, | 1145 | int 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); | ||
1150 | struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans, | 1148 | struct 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; | |||
28 | struct extent_io_ops { | 28 | struct 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 | ||
134 | int btrfs_csum_file_block(struct btrfs_trans_handle *trans, | 137 | int 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 | 162 | again: | |
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); |
261 | found: | 271 | found: |
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])); | ||
275 | next_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 | } | ||
271 | fail: | 300 | fail: |
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 | ||
298 | int 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 | ||
297 | int btrfs_writepage_io_hook(struct page *page, u64 start, u64 end) | 324 | int 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 | |
322 | int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end) | 349 | int 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 | ||
3023 | static struct extent_io_ops btrfs_extent_io_ops = { | 3050 | static 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, |