Skip to content

Commit 5b8d453

Browse files
Ming LinDongsu Park
authored andcommitted
btrfs: allow read-/writing an extent to handle arbitrarily sized bios
Fix bugs in end_bio_extent_{read,write}page(), upon reading or writing biovec that has length of multiple pages. The condition "bvec.bv_len != PAGE_CACHE_SIZE" would not be always valid any more, because now biovec is able to handle arbitrary size of bio. Without this patch, read/write IO stalls with the following log: BTRFS error (device sdb1): partial page write in btrfs with offset 0 and length 8192 BTRFS critical (device sdb1): bad ordered accounting left 0 size 4096 Signed-off-by: Ming Lin <[email protected]> Signed-off-by: Dongsu Park <[email protected]>
1 parent 7708786 commit 5b8d453

File tree

1 file changed

+6
-4
lines changed

1 file changed

+6
-4
lines changed

fs/btrfs/extent_io.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2495,7 +2495,7 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
24952495
* advance bv_offset and adjust bv_len to compensate.
24962496
* Print a warning for nonzero offsets, and an error
24972497
* if they don't add up to a full page. */
2498-
if (bvec.bv_offset || bvec.bv_len != PAGE_CACHE_SIZE) {
2498+
if (bvec.bv_offset) {
24992499
if (bvec.bv_offset + bvec.bv_len != PAGE_CACHE_SIZE)
25002500
btrfs_err(BTRFS_I(page->mapping->host)->root->fs_info,
25012501
"partial page write in btrfs with offset %u and length %u",
@@ -2508,7 +2508,8 @@ static void end_bio_extent_writepage(struct bio *bio, int err)
25082508
}
25092509

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

25132514
if (end_extent_writepage(page, err, start, end))
25142515
continue;
@@ -2575,7 +2576,7 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
25752576
* advance bv_offset and adjust bv_len to compensate.
25762577
* Print a warning for nonzero offsets, and an error
25772578
* if they don't add up to a full page. */
2578-
if (bvec.bv_offset || bvec.bv_len != PAGE_CACHE_SIZE) {
2579+
if (bvec.bv_offset) {
25792580
if (bvec.bv_offset + bvec.bv_len != PAGE_CACHE_SIZE)
25802581
btrfs_err(BTRFS_I(page->mapping->host)->root->fs_info,
25812582
"partial page read in btrfs with offset %u and length %u",
@@ -2588,7 +2589,8 @@ static void end_bio_extent_readpage(struct bio *bio, int err)
25882589
}
25892590

25902591
start = page_offset(page);
2591-
end = start + bvec.bv_offset + bvec.bv_len - 1;
2592+
end = start + bvec.bv_offset
2593+
+ min_t(unsigned int, bvec.bv_len, PAGE_CACHE_SIZE) - 1;
25922594
len = bvec.bv_len;
25932595

25942596
mirror = io_bio->mirror_num;

0 commit comments

Comments
 (0)