Skip to content

Commit bf9be4d

Browse files
Ming LinDongsu Park
authored andcommitted
btrfs: fix wrong bvec_len in btrfs_csum_one_bio()
Fixed below WARNING. WARNING: CPU: 0 PID: 511 at /home/mlin/linux/fs/btrfs/ordered-data.c:288 btrfs_add_ordered_sum+0x5e/0x8e() Modules linked in: CPU: 0 PID: 511 Comm: kworker/u2:4 Not tainted 3.18.0-00029-g30fd029 torvalds#68 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 Workqueue: btrfs-worker btrfs_worker_helper 0000000000000009 ffff88001e357c58 ffffffff81488839 0000000000000002 0000000000000000 ffff88001e357c98 ffffffff8103b8a3 ffff88001e357c88 ffffffff8124ec83 ffff88001ddd4000 ffff88001d8e8000 ffff88001df248a0 Call Trace: [<ffffffff81488839>] dump_stack+0x4f/0x7c [<ffffffff8103b8a3>] warn_slowpath_common+0x81/0x9b [<ffffffff8124ec83>] ? btrfs_add_ordered_sum+0x5e/0x8e [<ffffffff8103b8d7>] warn_slowpath_null+0x1a/0x1c [<ffffffff8124ec83>] btrfs_add_ordered_sum+0x5e/0x8e [<ffffffff8122e895>] btrfs_csum_one_bio+0x16a/0x3de [<ffffffff81232929>] ? btrfs_async_submit_limit+0x28/0x28 [<ffffffff8123bebb>] __btrfs_submit_bio_start+0x1d/0x27 [<ffffffff81230d37>] run_one_async_start+0x27/0x32 [<ffffffff81261932>] normal_work_helper+0xf9/0x2fd [<ffffffff81261b48>] btrfs_worker_helper+0x12/0x14 [<ffffffff8104ded7>] process_one_work+0x1ca/0x376 [<ffffffff8104e319>] worker_thread+0x267/0x366 [<ffffffff8104e0b2>] ? process_scheduled_works+0x2f/0x2f [<ffffffff81051e7c>] kthread+0xd2/0xda [<ffffffff81480000>] ? br_multicast_set_hash_max+0x4d/0xcd [<ffffffff81051daa>] ? kthread_freezable_should_stop+0x48/0x48 [<ffffffff8148da6c>] ret_from_fork+0x7c/0xb0 [<ffffffff81051daa>] ? kthread_freezable_should_stop+0x48/0x48 Signed-off-by: Ming Lin <minggr.net>
1 parent 5b8d453 commit bf9be4d

File tree

2 files changed

+16
-14
lines changed

2 files changed

+16
-14
lines changed

fs/btrfs/extent_io.c

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2489,27 +2489,27 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
24892489

24902490
bio_for_each_page_all(bvec, bio, iter) {
24912491
struct page *page = bvec.bv_page;
2492+
unsigned int bv_len = min_t(unsigned int, bvec.bv_len, PAGE_CACHE_SIZE);
24922493

24932494
/* We always issue full-page reads, but if some block
24942495
* in a page fails to read, blk_update_request() will
24952496
* advance bv_offset and adjust bv_len to compensate.
24962497
* Print a warning for nonzero offsets, and an error
24972498
* if they don't add up to a full page. */
24982499
if (bvec.bv_offset) {
2499-
if (bvec.bv_offset + bvec.bv_len != PAGE_CACHE_SIZE)
2500+
if (bvec.bv_offset + bv_len != PAGE_CACHE_SIZE)
25002501
btrfs_err(BTRFS_I(page->mapping->host)->root->fs_info,
25012502
"partial page write in btrfs with offset %u and length %u",
2502-
bvec.bv_offset, bvec.bv_len);
2503+
bvec.bv_offset, bv_len);
25032504
else
25042505
btrfs_info(BTRFS_I(page->mapping->host)->root->fs_info,
25052506
"incomplete page write in btrfs with offset %u and "
25062507
"length %u",
2507-
bvec.bv_offset, bvec.bv_len);
2508+
bvec.bv_offset, bv_len);
25082509
}
25092510

25102511
start = page_offset(page);
2511-
end = start + bvec.bv_offset
2512-
+ min_t(unsigned int, bvec.bv_len, PAGE_CACHE_SIZE) - 1;
2512+
end = start + bvec.bv_offset + bv_len - 1;
25132513

25142514
if (end_extent_writepage(page, err, start, end))
25152515
continue;
@@ -2565,6 +2565,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
25652565
bio_for_each_page_all(bvec, bio, iter) {
25662566
struct page *page = bvec.bv_page;
25672567
struct inode *inode = page->mapping->host;
2568+
unsigned int bv_len = min_t(unsigned int, bvec.bv_len, PAGE_CACHE_SIZE);
25682569

25692570
pr_debug("end_bio_extent_readpage: bi_sector=%llu, err=%d, "
25702571
"mirror=%u\n", (u64)bio->bi_iter.bi_sector, err,
@@ -2577,21 +2578,20 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
25772578
* Print a warning for nonzero offsets, and an error
25782579
* if they don't add up to a full page. */
25792580
if (bvec.bv_offset) {
2580-
if (bvec.bv_offset + bvec.bv_len != PAGE_CACHE_SIZE)
2581+
if (bvec.bv_offset + bv_len != PAGE_CACHE_SIZE)
25812582
btrfs_err(BTRFS_I(page->mapping->host)->root->fs_info,
25822583
"partial page read in btrfs with offset %u and length %u",
2583-
bvec.bv_offset, bvec.bv_len);
2584+
bvec.bv_offset, bv_len);
25842585
else
25852586
btrfs_info(BTRFS_I(page->mapping->host)->root->fs_info,
25862587
"incomplete page read in btrfs with offset %u and "
25872588
"length %u",
2588-
bvec.bv_offset, bvec.bv_len);
2589+
bvec.bv_offset, bv_len);
25892590
}
25902591

25912592
start = page_offset(page);
2592-
end = start + bvec.bv_offset
2593-
+ min_t(unsigned int, bvec.bv_len, PAGE_CACHE_SIZE) - 1;
2594-
len = bvec.bv_len;
2593+
end = start + bvec.bv_offset + bv_len - 1;
2594+
len = bv_len;
25952595

25962596
mirror = io_bio->mirror_num;
25972597
if (likely(uptodate && tree->ops &&

fs/btrfs/file-item.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,8 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
448448
index = 0;
449449

450450
bio_for_each_page(bvec, bio, iter) {
451+
unsigned int bv_len = min_t(unsigned int, bvec.bv_len, PAGE_CACHE_SIZE);
452+
451453
if (!contig)
452454
offset = page_offset(bvec.bv_page) + bvec.bv_offset;
453455

@@ -472,14 +474,14 @@ int btrfs_csum_one_bio(struct btrfs_root *root, struct inode *inode,
472474
sums->sums[index] = ~(u32)0;
473475
sums->sums[index] = btrfs_csum_data(data + bvec.bv_offset,
474476
sums->sums[index],
475-
bvec.bv_len);
477+
bv_len);
476478
kunmap_atomic(data);
477479
btrfs_csum_final(sums->sums[index],
478480
(char *)(sums->sums + index));
479481

480482
index++;
481-
offset += bvec.bv_len;
482-
this_sum_bytes += bvec.bv_len;
483+
offset += bv_len;
484+
this_sum_bytes += bv_len;
483485
}
484486
this_sum_bytes = 0;
485487
btrfs_add_ordered_sum(inode, ordered, sums);

0 commit comments

Comments
 (0)