lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20230504105624.9789-1-idryomov@gmail.com>
Date:   Thu,  4 May 2023 12:56:24 +0200
From:   Ilya Dryomov <idryomov@...il.com>
To:     Christoph Hellwig <hch@....de>
Cc:     Jan Kara <jack@...e.cz>,
        Johannes Thumshirn <johannes.thumshirn@....com>,
        Jens Axboe <axboe@...nel.dk>, linux-block@...r.kernel.org,
        linux-fsdevel@...r.kernel.org, linux-mm@...ck.org,
        linux-kernel@...r.kernel.org
Subject: [PATCH] mm: always respect QUEUE_FLAG_STABLE_WRITES on the block device

Commit 1cb039f3dc16 ("bdi: replace BDI_CAP_STABLE_WRITES with a queue
and a sb flag") introduced a regression for the raw block device use
case.  Capturing QUEUE_FLAG_STABLE_WRITES flag in set_bdev_super() has
the effect of respecting it only when there is a filesystem mounted on
top of the block device.  If a filesystem is not mounted, block devices
that do integrity checking return sporadic checksum errors.

Additionally, this commit made the corresponding sysfs knob writeable
for debugging purposes.  However, because QUEUE_FLAG_STABLE_WRITES flag
is captured when the filesystem is mounted and isn't consulted after
that anywhere outside of swap code, changing it doesn't take immediate
effect even though dumping the knob shows the new value.  With no way
to dump SB_I_STABLE_WRITES flag, this is needlessly confusing.

Resurrect the original stable writes behavior by changing
folio_wait_stable() to account for the case of a raw block device and
also:

- for the case of a filesystem, test QUEUE_FLAG_STABLE_WRITES flag
  each time instead of capturing it in the superblock so that changes
  are reflected immediately (thus aligning with the case of a raw block
  device)
- retain SB_I_STABLE_WRITES flag for filesystems that need stable
  writes independent of the underlying block device (currently just
  NFS)

Cc: stable@...r.kernel.org
Fixes: 1cb039f3dc16 ("bdi: replace BDI_CAP_STABLE_WRITES with a queue and a sb flag")
Signed-off-by: Ilya Dryomov <idryomov@...il.com>
---
 fs/super.c          |  2 --
 mm/page-writeback.c | 12 +++++++++++-
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/fs/super.c b/fs/super.c
index 04bc62ab7dfe..6705b3506ae8 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1213,8 +1213,6 @@ static int set_bdev_super(struct super_block *s, void *data)
 	s->s_dev = s->s_bdev->bd_dev;
 	s->s_bdi = bdi_get(s->s_bdev->bd_disk->bdi);
 
-	if (bdev_stable_writes(s->s_bdev))
-		s->s_iflags |= SB_I_STABLE_WRITES;
 	return 0;
 }
 
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 516b1aa247e8..469bc57add8c 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -3169,7 +3169,17 @@ EXPORT_SYMBOL_GPL(folio_wait_writeback_killable);
  */
 void folio_wait_stable(struct folio *folio)
 {
-	if (folio_inode(folio)->i_sb->s_iflags & SB_I_STABLE_WRITES)
+	struct inode *inode = folio_inode(folio);
+	struct super_block *sb = inode->i_sb;
+	bool stable_writes;
+
+	if (sb_is_blkdev_sb(sb))
+		stable_writes = bdev_stable_writes(I_BDEV(inode));
+	else
+		stable_writes = bdev_stable_writes(sb->s_bdev) ||
+				(sb->s_iflags & SB_I_STABLE_WRITES);
+
+	if (stable_writes)
 		folio_wait_writeback(folio);
 }
 EXPORT_SYMBOL_GPL(folio_wait_stable);
-- 
2.39.2

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ