Skip to content

Commit be48bcf

Browse files
committed
Merge tag 'for-6.17-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "Several zoned mode fixes, mount option printing fixups, folio state handling fixes and one log replay fix. - zoned mode: - zone activation and finish fixes - block group reservation fixes - mount option fixes: - bring back printing of mount options with key=value that got accidentally dropped during mount option parsing in 6.8 - fix inverse logic or typos when printing nodatasum/nodatacow - folio status fixes: - writeback fixes in zoned mode - properly reset dirty/writeback if submission fails - properly handle TOWRITE xarray mark/tag - do not set mtime/ctime to current time when unlinking for log replay" * tag 'for-6.17-rc2-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: fix printing of mount info messages for NODATACOW/NODATASUM btrfs: restore mount option info messages during mount btrfs: fix incorrect log message for nobarrier mount option btrfs: fix buffer index in wait_eb_writebacks() btrfs: subpage: keep TOWRITE tag until folio is cleaned btrfs: clear TAG_TOWRITE from buffer tree when submitting a tree block btrfs: do not set mtime/ctime to current time when unlinking for log replay btrfs: clear block dirty if btrfs_writepage_cow_fixup() failed btrfs: clear block dirty if submit_one_sector() failed btrfs: zoned: limit active zones to max_open_zones btrfs: zoned: fix write time activation failure for metadata block group btrfs: zoned: fix data relocation block group reservation btrfs: zoned: skip ZONE FINISH of conventional zones
2 parents 074e461 + 74857fd commit be48bcf

File tree

5 files changed

+163
-55
lines changed

5 files changed

+163
-55
lines changed

fs/btrfs/extent_io.c

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,7 +1512,7 @@ static noinline_for_stack int writepage_delalloc(struct btrfs_inode *inode,
15121512

15131513
/*
15141514
* Return 0 if we have submitted or queued the sector for submission.
1515-
* Return <0 for critical errors.
1515+
* Return <0 for critical errors, and the sector will have its dirty flag cleared.
15161516
*
15171517
* Caller should make sure filepos < i_size and handle filepos >= i_size case.
15181518
*/
@@ -1535,8 +1535,17 @@ static int submit_one_sector(struct btrfs_inode *inode,
15351535
ASSERT(filepos < i_size);
15361536

15371537
em = btrfs_get_extent(inode, NULL, filepos, sectorsize);
1538-
if (IS_ERR(em))
1538+
if (IS_ERR(em)) {
1539+
/*
1540+
* When submission failed, we should still clear the folio dirty.
1541+
* Or the folio will be written back again but without any
1542+
* ordered extent.
1543+
*/
1544+
btrfs_folio_clear_dirty(fs_info, folio, filepos, sectorsize);
1545+
btrfs_folio_set_writeback(fs_info, folio, filepos, sectorsize);
1546+
btrfs_folio_clear_writeback(fs_info, folio, filepos, sectorsize);
15391547
return PTR_ERR(em);
1548+
}
15401549

15411550
extent_offset = filepos - em->start;
15421551
em_end = btrfs_extent_map_end(em);
@@ -1609,8 +1618,12 @@ static noinline_for_stack int extent_writepage_io(struct btrfs_inode *inode,
16091618
folio_unlock(folio);
16101619
return 1;
16111620
}
1612-
if (ret < 0)
1621+
if (ret < 0) {
1622+
btrfs_folio_clear_dirty(fs_info, folio, start, len);
1623+
btrfs_folio_set_writeback(fs_info, folio, start, len);
1624+
btrfs_folio_clear_writeback(fs_info, folio, start, len);
16131625
return ret;
1626+
}
16141627

16151628
for (cur = start; cur < start + len; cur += fs_info->sectorsize)
16161629
set_bit((cur - folio_start) >> fs_info->sectorsize_bits, &range_bitmap);
@@ -1666,8 +1679,8 @@ static noinline_for_stack int extent_writepage_io(struct btrfs_inode *inode,
16661679
* Here we set writeback and clear for the range. If the full folio
16671680
* is no longer dirty then we clear the PAGECACHE_TAG_DIRTY tag.
16681681
*
1669-
* If we hit any error, the corresponding sector will still be dirty
1670-
* thus no need to clear PAGECACHE_TAG_DIRTY.
1682+
* If we hit any error, the corresponding sector will have its dirty
1683+
* flag cleared and writeback finished, thus no need to handle the error case.
16711684
*/
16721685
if (!submitted_io && !error) {
16731686
btrfs_folio_set_writeback(fs_info, folio, start, len);
@@ -1813,6 +1826,7 @@ static noinline_for_stack bool lock_extent_buffer_for_io(struct extent_buffer *e
18131826
xas_load(&xas);
18141827
xas_set_mark(&xas, PAGECACHE_TAG_WRITEBACK);
18151828
xas_clear_mark(&xas, PAGECACHE_TAG_DIRTY);
1829+
xas_clear_mark(&xas, PAGECACHE_TAG_TOWRITE);
18161830
xas_unlock_irqrestore(&xas, flags);
18171831

18181832
btrfs_set_header_flag(eb, BTRFS_HEADER_FLAG_WRITTEN);

fs/btrfs/inode.c

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4189,6 +4189,23 @@ int btrfs_update_inode_fallback(struct btrfs_trans_handle *trans,
41894189
return ret;
41904190
}
41914191

4192+
static void update_time_after_link_or_unlink(struct btrfs_inode *dir)
4193+
{
4194+
struct timespec64 now;
4195+
4196+
/*
4197+
* If we are replaying a log tree, we do not want to update the mtime
4198+
* and ctime of the parent directory with the current time, since the
4199+
* log replay procedure is responsible for setting them to their correct
4200+
* values (the ones it had when the fsync was done).
4201+
*/
4202+
if (test_bit(BTRFS_FS_LOG_RECOVERING, &dir->root->fs_info->flags))
4203+
return;
4204+
4205+
now = inode_set_ctime_current(&dir->vfs_inode);
4206+
inode_set_mtime_to_ts(&dir->vfs_inode, now);
4207+
}
4208+
41924209
/*
41934210
* unlink helper that gets used here in inode.c and in the tree logging
41944211
* recovery code. It remove a link in a directory with a given name, and
@@ -4289,7 +4306,7 @@ static int __btrfs_unlink_inode(struct btrfs_trans_handle *trans,
42894306
inode_inc_iversion(&inode->vfs_inode);
42904307
inode_set_ctime_current(&inode->vfs_inode);
42914308
inode_inc_iversion(&dir->vfs_inode);
4292-
inode_set_mtime_to_ts(&dir->vfs_inode, inode_set_ctime_current(&dir->vfs_inode));
4309+
update_time_after_link_or_unlink(dir);
42934310

42944311
return btrfs_update_inode(trans, dir);
42954312
}
@@ -6683,15 +6700,7 @@ int btrfs_add_link(struct btrfs_trans_handle *trans,
66836700
btrfs_i_size_write(parent_inode, parent_inode->vfs_inode.i_size +
66846701
name->len * 2);
66856702
inode_inc_iversion(&parent_inode->vfs_inode);
6686-
/*
6687-
* If we are replaying a log tree, we do not want to update the mtime
6688-
* and ctime of the parent directory with the current time, since the
6689-
* log replay procedure is responsible for setting them to their correct
6690-
* values (the ones it had when the fsync was done).
6691-
*/
6692-
if (!test_bit(BTRFS_FS_LOG_RECOVERING, &root->fs_info->flags))
6693-
inode_set_mtime_to_ts(&parent_inode->vfs_inode,
6694-
inode_set_ctime_current(&parent_inode->vfs_inode));
6703+
update_time_after_link_or_unlink(parent_inode);
66956704

66966705
ret = btrfs_update_inode(trans, parent_inode);
66976706
if (ret)

fs/btrfs/subpage.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,25 @@ void btrfs_subpage_set_writeback(const struct btrfs_fs_info *fs_info,
448448

449449
spin_lock_irqsave(&bfs->lock, flags);
450450
bitmap_set(bfs->bitmaps, start_bit, len >> fs_info->sectorsize_bits);
451+
452+
/*
453+
* Don't clear the TOWRITE tag when starting writeback on a still-dirty
454+
* folio. Doing so can cause WB_SYNC_ALL writepages() to overlook it,
455+
* assume writeback is complete, and exit too early — violating sync
456+
* ordering guarantees.
457+
*/
451458
if (!folio_test_writeback(folio))
452-
folio_start_writeback(folio);
459+
__folio_start_writeback(folio, true);
460+
if (!folio_test_dirty(folio)) {
461+
struct address_space *mapping = folio_mapping(folio);
462+
XA_STATE(xas, &mapping->i_pages, folio->index);
463+
unsigned long flags;
464+
465+
xas_lock_irqsave(&xas, flags);
466+
xas_load(&xas);
467+
xas_clear_mark(&xas, PAGECACHE_TAG_TOWRITE);
468+
xas_unlock_irqrestore(&xas, flags);
469+
}
453470
spin_unlock_irqrestore(&bfs->lock, flags);
454471
}
455472

fs/btrfs/super.c

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ struct btrfs_fs_context {
8888
refcount_t refs;
8989
};
9090

91+
static void btrfs_emit_options(struct btrfs_fs_info *info,
92+
struct btrfs_fs_context *old);
93+
9194
enum {
9295
Opt_acl,
9396
Opt_clear_cache,
@@ -698,12 +701,9 @@ bool btrfs_check_options(const struct btrfs_fs_info *info,
698701

699702
if (!test_bit(BTRFS_FS_STATE_REMOUNTING, &info->fs_state)) {
700703
if (btrfs_raw_test_opt(*mount_opt, SPACE_CACHE)) {
701-
btrfs_info(info, "disk space caching is enabled");
702704
btrfs_warn(info,
703705
"space cache v1 is being deprecated and will be removed in a future release, please use -o space_cache=v2");
704706
}
705-
if (btrfs_raw_test_opt(*mount_opt, FREE_SPACE_TREE))
706-
btrfs_info(info, "using free-space-tree");
707707
}
708708

709709
return ret;
@@ -980,6 +980,8 @@ static int btrfs_fill_super(struct super_block *sb,
980980
return ret;
981981
}
982982

983+
btrfs_emit_options(fs_info, NULL);
984+
983985
inode = btrfs_iget(BTRFS_FIRST_FREE_OBJECTID, fs_info->fs_root);
984986
if (IS_ERR(inode)) {
985987
ret = PTR_ERR(inode);
@@ -1437,7 +1439,7 @@ static void btrfs_emit_options(struct btrfs_fs_info *info,
14371439
{
14381440
btrfs_info_if_set(info, old, NODATASUM, "setting nodatasum");
14391441
btrfs_info_if_set(info, old, DEGRADED, "allowing degraded mounts");
1440-
btrfs_info_if_set(info, old, NODATASUM, "setting nodatasum");
1442+
btrfs_info_if_set(info, old, NODATACOW, "setting nodatacow");
14411443
btrfs_info_if_set(info, old, SSD, "enabling ssd optimizations");
14421444
btrfs_info_if_set(info, old, SSD_SPREAD, "using spread ssd allocation scheme");
14431445
btrfs_info_if_set(info, old, NOBARRIER, "turning off barriers");
@@ -1459,10 +1461,11 @@ static void btrfs_emit_options(struct btrfs_fs_info *info,
14591461
btrfs_info_if_set(info, old, IGNOREMETACSUMS, "ignoring meta csums");
14601462
btrfs_info_if_set(info, old, IGNORESUPERFLAGS, "ignoring unknown super block flags");
14611463

1464+
btrfs_info_if_unset(info, old, NODATASUM, "setting datasum");
14621465
btrfs_info_if_unset(info, old, NODATACOW, "setting datacow");
14631466
btrfs_info_if_unset(info, old, SSD, "not using ssd optimizations");
14641467
btrfs_info_if_unset(info, old, SSD_SPREAD, "not using spread ssd allocation scheme");
1465-
btrfs_info_if_unset(info, old, NOBARRIER, "turning off barriers");
1468+
btrfs_info_if_unset(info, old, NOBARRIER, "turning on barriers");
14661469
btrfs_info_if_unset(info, old, NOTREELOG, "enabling tree log");
14671470
btrfs_info_if_unset(info, old, SPACE_CACHE, "disabling disk space caching");
14681471
btrfs_info_if_unset(info, old, FREE_SPACE_TREE, "disabling free space tree");

0 commit comments

Comments
 (0)