Skip to content

Commit eabcdba

Browse files
committed
Merge tag 'for-6.13-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: - tree-checker catches invalid number of inline extent references - zoned mode fixes: - enhance zone append IO command so it also detects emulated writes - handle bio splitting at sectorsize boundary - when deleting a snapshot, fix a condition for visiting nodes in reloc trees * tag 'for-6.13-rc3-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: tree-checker: reject inline extent items with 0 ref count btrfs: split bios to the fs sector size boundary btrfs: use bio_is_zone_append() in the completion handler btrfs: fix improper generation check in snapshot delete
2 parents b69810f + dfb9268 commit eabcdba

File tree

4 files changed

+59
-9
lines changed

4 files changed

+59
-9
lines changed

fs/btrfs/bio.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ static void btrfs_simple_end_io(struct bio *bio)
358358
INIT_WORK(&bbio->end_io_work, btrfs_end_bio_work);
359359
queue_work(btrfs_end_io_wq(fs_info, bio), &bbio->end_io_work);
360360
} else {
361-
if (bio_op(bio) == REQ_OP_ZONE_APPEND && !bio->bi_status)
361+
if (bio_is_zone_append(bio) && !bio->bi_status)
362362
btrfs_record_physical_zoned(bbio);
363363
btrfs_bio_end_io(bbio, bbio->bio.bi_status);
364364
}
@@ -401,7 +401,7 @@ static void btrfs_orig_write_end_io(struct bio *bio)
401401
else
402402
bio->bi_status = BLK_STS_OK;
403403

404-
if (bio_op(bio) == REQ_OP_ZONE_APPEND && !bio->bi_status)
404+
if (bio_is_zone_append(bio) && !bio->bi_status)
405405
stripe->physical = bio->bi_iter.bi_sector << SECTOR_SHIFT;
406406

407407
btrfs_bio_end_io(bbio, bbio->bio.bi_status);
@@ -415,7 +415,7 @@ static void btrfs_clone_write_end_io(struct bio *bio)
415415
if (bio->bi_status) {
416416
atomic_inc(&stripe->bioc->error);
417417
btrfs_log_dev_io_error(bio, stripe->dev);
418-
} else if (bio_op(bio) == REQ_OP_ZONE_APPEND) {
418+
} else if (bio_is_zone_append(bio)) {
419419
stripe->physical = bio->bi_iter.bi_sector << SECTOR_SHIFT;
420420
}
421421

@@ -652,8 +652,14 @@ static u64 btrfs_append_map_length(struct btrfs_bio *bbio, u64 map_length)
652652
map_length = min(map_length, bbio->fs_info->max_zone_append_size);
653653
sector_offset = bio_split_rw_at(&bbio->bio, &bbio->fs_info->limits,
654654
&nr_segs, map_length);
655-
if (sector_offset)
656-
return sector_offset << SECTOR_SHIFT;
655+
if (sector_offset) {
656+
/*
657+
* bio_split_rw_at() could split at a size smaller than our
658+
* sectorsize and thus cause unaligned I/Os. Fix that by
659+
* always rounding down to the nearest boundary.
660+
*/
661+
return ALIGN_DOWN(sector_offset << SECTOR_SHIFT, bbio->fs_info->sectorsize);
662+
}
657663
return map_length;
658664
}
659665

fs/btrfs/ctree.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,25 @@ static inline void btrfs_set_root_last_trans(struct btrfs_root *root, u64 transi
370370
WRITE_ONCE(root->last_trans, transid);
371371
}
372372

373+
/*
374+
* Return the generation this root started with.
375+
*
376+
* Every normal root that is created with root->root_key.offset set to it's
377+
* originating generation. If it is a snapshot it is the generation when the
378+
* snapshot was created.
379+
*
380+
* However for TREE_RELOC roots root_key.offset is the objectid of the owning
381+
* tree root. Thankfully we copy the root item of the owning tree root, which
382+
* has it's last_snapshot set to what we would have root_key.offset set to, so
383+
* return that if this is a TREE_RELOC root.
384+
*/
385+
static inline u64 btrfs_root_origin_generation(const struct btrfs_root *root)
386+
{
387+
if (btrfs_root_id(root) == BTRFS_TREE_RELOC_OBJECTID)
388+
return btrfs_root_last_snapshot(&root->root_item);
389+
return root->root_key.offset;
390+
}
391+
373392
/*
374393
* Structure that conveys information about an extent that is going to replace
375394
* all the extents in a file range.

fs/btrfs/extent-tree.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5285,7 +5285,7 @@ static bool visit_node_for_delete(struct btrfs_root *root, struct walk_control *
52855285
* reference to it.
52865286
*/
52875287
generation = btrfs_node_ptr_generation(eb, slot);
5288-
if (!wc->update_ref || generation <= root->root_key.offset)
5288+
if (!wc->update_ref || generation <= btrfs_root_origin_generation(root))
52895289
return false;
52905290

52915291
/*
@@ -5340,7 +5340,7 @@ static noinline void reada_walk_down(struct btrfs_trans_handle *trans,
53405340
goto reada;
53415341

53425342
if (wc->stage == UPDATE_BACKREF &&
5343-
generation <= root->root_key.offset)
5343+
generation <= btrfs_root_origin_generation(root))
53445344
continue;
53455345

53465346
/* We don't lock the tree block, it's OK to be racy here */
@@ -5683,7 +5683,7 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans,
56835683
* for the subtree
56845684
*/
56855685
if (wc->stage == UPDATE_BACKREF &&
5686-
generation <= root->root_key.offset) {
5686+
generation <= btrfs_root_origin_generation(root)) {
56875687
wc->lookup_info = 1;
56885688
return 1;
56895689
}

fs/btrfs/tree-checker.c

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1527,6 +1527,11 @@ static int check_extent_item(struct extent_buffer *leaf,
15271527
dref_offset, fs_info->sectorsize);
15281528
return -EUCLEAN;
15291529
}
1530+
if (unlikely(btrfs_extent_data_ref_count(leaf, dref) == 0)) {
1531+
extent_err(leaf, slot,
1532+
"invalid data ref count, should have non-zero value");
1533+
return -EUCLEAN;
1534+
}
15301535
inline_refs += btrfs_extent_data_ref_count(leaf, dref);
15311536
break;
15321537
/* Contains parent bytenr and ref count */
@@ -1539,6 +1544,11 @@ static int check_extent_item(struct extent_buffer *leaf,
15391544
inline_offset, fs_info->sectorsize);
15401545
return -EUCLEAN;
15411546
}
1547+
if (unlikely(btrfs_shared_data_ref_count(leaf, sref) == 0)) {
1548+
extent_err(leaf, slot,
1549+
"invalid shared data ref count, should have non-zero value");
1550+
return -EUCLEAN;
1551+
}
15421552
inline_refs += btrfs_shared_data_ref_count(leaf, sref);
15431553
break;
15441554
case BTRFS_EXTENT_OWNER_REF_KEY:
@@ -1611,8 +1621,18 @@ static int check_simple_keyed_refs(struct extent_buffer *leaf,
16111621
{
16121622
u32 expect_item_size = 0;
16131623

1614-
if (key->type == BTRFS_SHARED_DATA_REF_KEY)
1624+
if (key->type == BTRFS_SHARED_DATA_REF_KEY) {
1625+
struct btrfs_shared_data_ref *sref;
1626+
1627+
sref = btrfs_item_ptr(leaf, slot, struct btrfs_shared_data_ref);
1628+
if (unlikely(btrfs_shared_data_ref_count(leaf, sref) == 0)) {
1629+
extent_err(leaf, slot,
1630+
"invalid shared data backref count, should have non-zero value");
1631+
return -EUCLEAN;
1632+
}
1633+
16151634
expect_item_size = sizeof(struct btrfs_shared_data_ref);
1635+
}
16161636

16171637
if (unlikely(btrfs_item_size(leaf, slot) != expect_item_size)) {
16181638
generic_err(leaf, slot,
@@ -1689,6 +1709,11 @@ static int check_extent_data_ref(struct extent_buffer *leaf,
16891709
offset, leaf->fs_info->sectorsize);
16901710
return -EUCLEAN;
16911711
}
1712+
if (unlikely(btrfs_extent_data_ref_count(leaf, dref) == 0)) {
1713+
extent_err(leaf, slot,
1714+
"invalid extent data backref count, should have non-zero value");
1715+
return -EUCLEAN;
1716+
}
16921717
}
16931718
return 0;
16941719
}

0 commit comments

Comments
 (0)