@@ -818,8 +818,13 @@ static void rbio_orig_end_io(struct btrfs_raid_bio *rbio, blk_status_t err)
if (rbio->generic_bio_cnt)
btrfs_bio_counter_sub(rbio->bioc->fs_info, rbio->generic_bio_cnt);
- /* Clear the write-intent bitmap range for write operation. */
- if (rbio->operation == BTRFS_RBIO_WRITE)
+ /*
+ * Clear the write-intent bitmap range for write operation.
+ * For full stripe write we didn't record it into write-intent thus no
+ * need to clear the bits for full stripe write.
+ */
+ if (rbio->operation == BTRFS_RBIO_WRITE &&
+ rbio->bio_list_bytes < rbio->nr_data * BTRFS_STRIPE_LEN)
btrfs_write_intent_clear_dirty(rbio->bioc->fs_info,
rbio->bioc->raid_map[0],
rbio->nr_data * BTRFS_STRIPE_LEN);
@@ -1342,13 +1347,19 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
atomic_set(&rbio->stripes_pending, bio_list_size(&bio_list));
BUG_ON(atomic_read(&rbio->stripes_pending) == 0);
- /* Update the write intent bitmap before we start submitting bios. */
- btrfs_write_intent_mark_dirty(bioc->fs_info, rbio->bioc->raid_map[0],
- rbio->nr_data * BTRFS_STRIPE_LEN, &event);
- ret = btrfs_write_intent_writeback(bioc->fs_info, event);
+ /*
+ * Update the write intent bitmap if it's a sub-stripe write,
+ * before we start submitting bios.
+ */
+ if (rbio->bio_list_bytes < rbio->nr_data * BTRFS_STRIPE_LEN) {
+ btrfs_write_intent_mark_dirty(bioc->fs_info,
+ rbio->bioc->raid_map[0],
+ rbio->nr_data * BTRFS_STRIPE_LEN, &event);
+ ret = btrfs_write_intent_writeback(bioc->fs_info, event);
+ if (ret < 0)
+ goto cleanup;
+ }
- if (ret < 0)
- goto cleanup;
while ((bio = bio_list_pop(&bio_list))) {
bio->bi_end_io = raid_write_end_io;
Full stripe write can happen in the following cases: - Writing into a completely new stripe In this case, even if powerloss happened, we won't have any committed metadata referring the new full stripe. Thus we don't need to recover. - Writing into a NODATACOW range In this case, although in theory we should recovery after power loss, but NODATACOW implies NODATASUM, thus we have no way to determine which data is correct. Thus we don't need to and can't recover either. So just avoid recording full stripe write into write-intent bitmaps. Signed-off-by: Qu Wenruo <wqu@suse.com> --- fs/btrfs/raid56.c | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-)