Jiri Slaby ef7db2
From: Jan Kara <jack@suse.cz>
Jiri Slaby ef7db2
Date: Mon, 2 Jan 2023 20:14:47 +0100
Jiri Slaby ef7db2
Subject: [PATCH] udf: Do not update file length for failed writes to inline
Jiri Slaby ef7db2
 files
Jiri Slaby ef7db2
References: bsc#1012628
Jiri Slaby ef7db2
Patch-mainline: 6.2.3
Jiri Slaby ef7db2
Git-commit: 256fe4162f8b5a1625b8603ca5f7ff79725bfb47
Jiri Slaby ef7db2
Jiri Slaby ef7db2
commit 256fe4162f8b5a1625b8603ca5f7ff79725bfb47 upstream.
Jiri Slaby ef7db2
Jiri Slaby ef7db2
When write to inline file fails (or happens only partly), we still
Jiri Slaby ef7db2
updated length of inline data as if the whole write succeeded. Fix the
Jiri Slaby ef7db2
update of length of inline data to happen only if the write succeeds.
Jiri Slaby ef7db2
Jiri Slaby ef7db2
Reported-by: syzbot+0937935b993956ba28ab@syzkaller.appspotmail.com
Jiri Slaby ef7db2
CC: stable@vger.kernel.org
Jiri Slaby ef7db2
Signed-off-by: Jan Kara <jack@suse.cz>
Jiri Slaby ef7db2
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Jiri Slaby ef7db2
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
Jiri Slaby ef7db2
---
Jiri Slaby ef7db2
 fs/udf/file.c | 26 ++++++++++++--------------
Jiri Slaby ef7db2
 1 file changed, 12 insertions(+), 14 deletions(-)
Jiri Slaby ef7db2
Jiri Slaby ef7db2
diff --git a/fs/udf/file.c b/fs/udf/file.c
Jiri Slaby ef7db2
index 5c659e23..8be51161 100644
Jiri Slaby ef7db2
--- a/fs/udf/file.c
Jiri Slaby ef7db2
+++ b/fs/udf/file.c
Jiri Slaby ef7db2
@@ -149,26 +149,24 @@ static ssize_t udf_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
Jiri Slaby ef7db2
 		goto out;
Jiri Slaby ef7db2
 
Jiri Slaby ef7db2
 	down_write(&iinfo->i_data_sem);
Jiri Slaby ef7db2
-	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) {
Jiri Slaby ef7db2
-		loff_t end = iocb->ki_pos + iov_iter_count(from);
Jiri Slaby ef7db2
-
Jiri Slaby ef7db2
-		if (inode->i_sb->s_blocksize <
Jiri Slaby ef7db2
-				(udf_file_entry_alloc_offset(inode) + end)) {
Jiri Slaby ef7db2
-			err = udf_expand_file_adinicb(inode);
Jiri Slaby ef7db2
-			if (err) {
Jiri Slaby ef7db2
-				inode_unlock(inode);
Jiri Slaby ef7db2
-				udf_debug("udf_expand_adinicb: err=%d\n", err);
Jiri Slaby ef7db2
-				return err;
Jiri Slaby ef7db2
-			}
Jiri Slaby ef7db2
-		} else {
Jiri Slaby ef7db2
-			iinfo->i_lenAlloc = max(end, inode->i_size);
Jiri Slaby ef7db2
-			up_write(&iinfo->i_data_sem);
Jiri Slaby ef7db2
+	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB &&
Jiri Slaby ef7db2
+	    inode->i_sb->s_blocksize < (udf_file_entry_alloc_offset(inode) +
Jiri Slaby ef7db2
+				 iocb->ki_pos + iov_iter_count(from))) {
Jiri Slaby ef7db2
+		err = udf_expand_file_adinicb(inode);
Jiri Slaby ef7db2
+		if (err) {
Jiri Slaby ef7db2
+			inode_unlock(inode);
Jiri Slaby ef7db2
+			udf_debug("udf_expand_adinicb: err=%d\n", err);
Jiri Slaby ef7db2
+			return err;
Jiri Slaby ef7db2
 		}
Jiri Slaby ef7db2
 	} else
Jiri Slaby ef7db2
 		up_write(&iinfo->i_data_sem);
Jiri Slaby ef7db2
 
Jiri Slaby ef7db2
 	retval = __generic_file_write_iter(iocb, from);
Jiri Slaby ef7db2
 out:
Jiri Slaby ef7db2
+	down_write(&iinfo->i_data_sem);
Jiri Slaby ef7db2
+	if (iinfo->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB && retval > 0)
Jiri Slaby ef7db2
+		iinfo->i_lenAlloc = inode->i_size;
Jiri Slaby ef7db2
+	up_write(&iinfo->i_data_sem);
Jiri Slaby ef7db2
 	inode_unlock(inode);
Jiri Slaby ef7db2
 
Jiri Slaby ef7db2
 	if (retval > 0) {
Jiri Slaby ef7db2
-- 
Jiri Slaby ef7db2
2.35.3
Jiri Slaby ef7db2