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: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Message-ID: <CAN2Y7hyi1HCrSiKsDT+KD8hBjQmsqzNp71Q9Z_RmBG0LLaZxCA@mail.gmail.com>
Date: Sun, 22 Jun 2025 20:32:18 +0800
From: ying chen <yc1082463@...il.com>
To: djwong@...nel.org, linux-xfs@...r.kernel.org, linux-kernel@...r.kernel.org
Subject: [PATCH] xfs: report a writeback error on a read() call

Normally, user space returns immediately after writing data to the
buffer cache. However, if an error occurs during the actual disk
write operation, data loss may ensue, and there is no way to report
this error back to user space immediately. Current kernels may report
writeback errors when fsync() is called, but frequent invocations of
fsync() can degrade performance. Therefore, a new sysctl
fs.xfs.report_writeback_error_on_read is introduced, which, when set
to 1, reports writeback errors when read() is called. This allows user
space to be notified of writeback errors more promptly.

Signed-off-by: fengchangqing <fengchangqing@...duoduo.com>
---
 fs/xfs/xfs_file.c    | 9 +++++++++
 fs/xfs/xfs_globals.c | 1 +
 fs/xfs/xfs_linux.h   | 1 +
 fs/xfs/xfs_sysctl.c  | 9 +++++++++
 fs/xfs/xfs_sysctl.h  | 1 +
 5 files changed, 21 insertions(+)

diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 595a5bc..8bf0a83 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -288,12 +288,21 @@
        struct inode            *inode = file_inode(iocb->ki_filp);
        struct xfs_mount        *mp = XFS_I(inode)->i_mount;
        ssize_t                 ret = 0;
+       int                     error = 0;
+       errseq_t                since;

        XFS_STATS_INC(mp, xs_read_calls);

        if (xfs_is_shutdown(mp))
                return -EIO;

+       if (xfs_report_writeback_error_on_read) {
+               since = READ_ONCE(iocb->ki_filp->f_wb_err);
+               error = filemap_check_wb_err(inode->i_mapping, since);
+               if (error)
+                       return  error;
+       }
+
        if (IS_DAX(inode))
                ret = xfs_file_dax_read(iocb, to);
        else if (iocb->ki_flags & IOCB_DIRECT)
diff --git a/fs/xfs/xfs_globals.c b/fs/xfs/xfs_globals.c
index 4d0a98f..9983a2f 100644
--- a/fs/xfs/xfs_globals.c
+++ b/fs/xfs/xfs_globals.c
@@ -29,6 +29,7 @@
        .inherit_nodfrg = {     0,              1,              1       },
        .fstrm_timer    = {     1,              30*100,         3600*100},
        .blockgc_timer  = {     1,              300,            3600*24},
+       .report_writeback_error_on_read = {     0,              0,
         1},
 };

 struct xfs_globals xfs_globals = {
diff --git a/fs/xfs/xfs_linux.h b/fs/xfs/xfs_linux.h
index f987802..bbe8bdb 100644
--- a/fs/xfs/xfs_linux.h
+++ b/fs/xfs/xfs_linux.h
@@ -100,6 +100,7 @@
 #define xfs_inherit_nodefrag   xfs_params.inherit_nodfrg.val
 #define xfs_fstrm_centisecs    xfs_params.fstrm_timer.val
 #define xfs_blockgc_secs       xfs_params.blockgc_timer.val
+#define xfs_report_writeback_error_on_read
xfs_params.report_writeback_error_on_read.val

 #define current_cpu()          (raw_smp_processor_id())
 #define current_set_flags_nested(sp, f)                \
diff --git a/fs/xfs/xfs_sysctl.c b/fs/xfs/xfs_sysctl.c
index 546a6cd..fbec214 100644
--- a/fs/xfs/xfs_sysctl.c
+++ b/fs/xfs/xfs_sysctl.c
@@ -194,6 +194,15 @@
                .extra1         = &xfs_params.blockgc_timer.min,
                .extra2         = &xfs_params.blockgc_timer.max,
        },
+       {
+               .procname       = "report_writeback_error_on_read",
+               .data           =
&xfs_params.report_writeback_error_on_read.val,
+               .maxlen         = sizeof(int),
+               .mode           = 0644,
+               .proc_handler   = xfs_deprecated_dointvec_minmax,
+               .extra1         =
&xfs_params.report_writeback_error_on_read.min,
+               .extra2         =
&xfs_params.report_writeback_error_on_read.max,
+       },
        /* please keep this the last entry */
 #ifdef CONFIG_PROC_FS
        {
diff --git a/fs/xfs/xfs_sysctl.h b/fs/xfs/xfs_sysctl.h
index f78ad6b..fa0688a 100644
--- a/fs/xfs/xfs_sysctl.h
+++ b/fs/xfs/xfs_sysctl.h
@@ -36,6 +36,7 @@
        xfs_sysctl_val_t inherit_nodfrg;/* Inherit the "nodefrag" inode flag. */
        xfs_sysctl_val_t fstrm_timer;   /* Filestream dir-AG assoc'n timeout. */
        xfs_sysctl_val_t blockgc_timer; /* Interval between blockgc scans */
+       xfs_sysctl_val_t report_writeback_error_on_read; /*  Report a
writeback error on a read() call. */
 } xfs_param_t;

 /*
--
1.8.3.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ