mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
nilfs2: ignore non-fatal signals during synchronous log write wait
Based on a syzbot report, Wang Jianjian pointed out that following a
successful directory operation in nilfs_rename(), a synchronous write
requested within nilfs_transaction_commit(), triggered by a sync flag
set by nilfs_commit_chunk(), could be interrupted by a user signal.
This interruption leaves in-memory metadata updates intact while
returning an error, causing inconsistency with the VFS dentry cache and
ultimately triggering a kernel warning.
According to "signal(7)", local disks are not classified as "slow
devices" (such as terminals, FIFOs, or pipes) and their I/O operations
on disk devices are not interrupted by signals. In kernel space,
waiting for such disk I/O should therefore not be aborted by ordinary
(non-fatal) signals.
Suppress this issue by modifying nilfs_segctor_sync(), which waits for
the log writer thread to complete synchronous writes, to catch only
fatal signals via fatal_signal_pending() and return -EINTR rather than
-ERESTARTSYS. To complement this change and prevent the wait loop from
busy-looping when schedule() returns immediately due to a pending
non-fatal signal, switch the wait state from TASK_INTERRUPTIBLE to
TASK_KILLABLE.
This serves as an effective interim stabilization measure without
structural changes until a comprehensive fix for metadata consistency
is implemented.
Reported-by: syzbot+f6c7e1f1809f235eeb90@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=f6c7e1f1809f235eeb90
Fixes: 9ff05123e3 ("nilfs2: segment constructor")
Tested-by: syzbot+f6c7e1f1809f235eeb90@syzkaller.appspotmail.com
Cc: Wang Jianjian <wangjianjian3@huawei.com>
Cc: stable@vger.kernel.org
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@gmail.com>
Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
This commit is contained in:
parent
6faad04a00
commit
7131aaa74b
|
|
@ -965,10 +965,10 @@ static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
|
|||
* Return: 0 on success, or one of the following negative error codes on
|
||||
* failure:
|
||||
* * %-EFAULT - Failure during execution of requested operation.
|
||||
* * %-EINTR - Interrupted.
|
||||
* * %-EIO - I/O error.
|
||||
* * %-ENOMEM - Insufficient memory available.
|
||||
* * %-ENOSPC - No space left on device (only in a panic state).
|
||||
* * %-ERESTARTSYS - Interrupted.
|
||||
* * %-EROFS - Read only filesystem.
|
||||
*/
|
||||
static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
|
||||
|
|
|
|||
|
|
@ -790,11 +790,11 @@ static void nilfs_abort_roll_forward(struct the_nilfs *nilfs)
|
|||
*
|
||||
* Return: 0 on success, or one of the following negative error codes on
|
||||
* failure:
|
||||
* * %-EINTR - Interrupted.
|
||||
* * %-EINVAL - Inconsistent filesystem state.
|
||||
* * %-EIO - I/O error.
|
||||
* * %-ENOMEM - Insufficient memory available.
|
||||
* * %-ENOSPC - No space left on device (only in a panic state).
|
||||
* * %-ERESTARTSYS - Interrupted.
|
||||
*/
|
||||
int nilfs_salvage_orphan_logs(struct the_nilfs *nilfs,
|
||||
struct super_block *sb,
|
||||
|
|
|
|||
|
|
@ -2259,7 +2259,7 @@ static int nilfs_segctor_sync(struct nilfs_sc_info *sci)
|
|||
wake_up(&sci->sc_wait_daemon);
|
||||
|
||||
for (;;) {
|
||||
set_current_state(TASK_INTERRUPTIBLE);
|
||||
set_current_state(TASK_KILLABLE);
|
||||
|
||||
/*
|
||||
* Synchronize only while the log writer thread is alive.
|
||||
|
|
@ -2273,11 +2273,11 @@ static int nilfs_segctor_sync(struct nilfs_sc_info *sci)
|
|||
err = wait_req.err;
|
||||
break;
|
||||
}
|
||||
if (!signal_pending(current)) {
|
||||
if (!fatal_signal_pending(current)) {
|
||||
schedule();
|
||||
continue;
|
||||
}
|
||||
err = -ERESTARTSYS;
|
||||
err = -EINTR;
|
||||
break;
|
||||
}
|
||||
finish_wait(&sci->sc_wait_request, &wait_req.wq);
|
||||
|
|
@ -2311,10 +2311,10 @@ static void nilfs_segctor_wakeup(struct nilfs_sc_info *sci, int err, bool force)
|
|||
*
|
||||
* Return: 0 on success, or one of the following negative error codes on
|
||||
* failure:
|
||||
* * %-EINTR - Interrupted.
|
||||
* * %-EIO - I/O error (including metadata corruption).
|
||||
* * %-ENOMEM - Insufficient memory available.
|
||||
* * %-ENOSPC - No space left on device (only in a panic state).
|
||||
* * %-ERESTARTSYS - Interrupted.
|
||||
* * %-EROFS - Read only filesystem.
|
||||
*/
|
||||
int nilfs_construct_segment(struct super_block *sb)
|
||||
|
|
@ -2341,10 +2341,10 @@ int nilfs_construct_segment(struct super_block *sb)
|
|||
*
|
||||
* Return: 0 on success, or one of the following negative error codes on
|
||||
* failure:
|
||||
* * %-EINTR - Interrupted.
|
||||
* * %-EIO - I/O error (including metadata corruption).
|
||||
* * %-ENOMEM - Insufficient memory available.
|
||||
* * %-ENOSPC - No space left on device (only in a panic state).
|
||||
* * %-ERESTARTSYS - Interrupted.
|
||||
* * %-EROFS - Read only filesystem.
|
||||
*/
|
||||
int nilfs_construct_dsync_segment(struct super_block *sb, struct inode *inode,
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user