#syz test: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 63623fd4
--- fs/overlayfs/file.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -243,7 +243,11 @@ static void ovl_aio_cleanup_handler(stru if (iocb->ki_flags & IOCB_WRITE) { struct inode *inode = file_inode(orig_iocb->ki_filp); + struct inode *real_inode = ovl_inode_real(inode); + WARN_ON(real_inode != file_inode(iocb->ki_filp)); + /* See aio_complete_rw() */ + __sb_writers_acquired(real_inode->i_sb, SB_FREEZE_WRITE); file_end_write(iocb->ki_filp); ovl_copyattr(ovl_inode_real(inode), inode); } @@ -311,6 +315,7 @@ static ssize_t ovl_write_iter(struct kio { struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); + struct inode *real_inode = ovl_inode_real(inode); struct fd real; const struct cred *old_cred; ssize_t ret; @@ -320,7 +325,7 @@ static ssize_t ovl_write_iter(struct kio inode_lock(inode); /* Update mode */ - ovl_copyattr(ovl_inode_real(inode), inode); + ovl_copyattr(real_inode, inode); ret = file_remove_privs(file); if (ret) goto out_unlock; @@ -346,6 +351,9 @@ static ssize_t ovl_write_iter(struct kio goto out; file_start_write(real.file); + WARN_ON(real_inode != file_inode(real.file)); + /* See aio_write() */ + __sb_writers_release(real_inode->i_sb, SB_FREEZE_WRITE); aio_req->fd = real; real.flags = 0; aio_req->orig_iocb = iocb;