Re: WARNING: lock held when returning to user space in ovl_write_iter

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



#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;

[Index of Archives]     [Linux Filesystems Devel]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux