]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Drop ext4-properly-sync-file-size-update-after-o_sync-dir.patch
authorSasha Levin <sashal@kernel.org>
Mon, 4 Dec 2023 19:46:05 +0000 (14:46 -0500)
committerSasha Levin <sashal@kernel.org>
Mon, 4 Dec 2023 19:46:05 +0000 (14:46 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-5.10/ext4-properly-sync-file-size-update-after-o_sync-dir.patch [deleted file]
queue-5.10/series
queue-5.15/ext4-properly-sync-file-size-update-after-o_sync-dir.patch [deleted file]
queue-5.15/series

diff --git a/queue-5.10/ext4-properly-sync-file-size-update-after-o_sync-dir.patch b/queue-5.10/ext4-properly-sync-file-size-update-after-o_sync-dir.patch
deleted file mode 100644 (file)
index dc74dce..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-From 84133ca398f3d3a0563b2b47a0c0d86191848b2b Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 13 Oct 2023 14:13:50 +0200
-Subject: ext4: properly sync file size update after O_SYNC direct IO
-
-From: Jan Kara <jack@suse.cz>
-
-[ Upstream commit 91562895f8030cb9a0470b1db49de79346a69f91 ]
-
-Gao Xiang has reported that on ext4 O_SYNC direct IO does not properly
-sync file size update and thus if we crash at unfortunate moment, the
-file can have smaller size although O_SYNC IO has reported successful
-completion. The problem happens because update of on-disk inode size is
-handled in ext4_dio_write_iter() *after* iomap_dio_rw() (and thus
-dio_complete() in particular) has returned and generic_file_sync() gets
-called by dio_complete(). Fix the problem by handling on-disk inode size
-update directly in our ->end_io completion handler.
-
-References: https://lore.kernel.org/all/02d18236-26ef-09b0-90ad-030c4fe3ee20@linux.alibaba.com
-Reported-by: Gao Xiang <hsiangkao@linux.alibaba.com>
-CC: stable@vger.kernel.org
-Fixes: 378f32bab371 ("ext4: introduce direct I/O write using iomap infrastructure")
-Signed-off-by: Jan Kara <jack@suse.cz>
-Tested-by: Joseph Qi <joseph.qi@linux.alibaba.com>
-Reviewed-by: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
-Link: https://lore.kernel.org/r/20231013121350.26872-1-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/ext4/file.c | 153 +++++++++++++++++++++----------------------------
- 1 file changed, 65 insertions(+), 88 deletions(-)
-
-diff --git a/fs/ext4/file.c b/fs/ext4/file.c
-index f42cc1fe0ba1d..15f45499f491a 100644
---- a/fs/ext4/file.c
-+++ b/fs/ext4/file.c
-@@ -280,80 +280,38 @@ static ssize_t ext4_buffered_write_iter(struct kiocb *iocb,
- }
- static ssize_t ext4_handle_inode_extension(struct inode *inode, loff_t offset,
--                                         ssize_t written, size_t count)
-+                                         ssize_t count)
- {
-       handle_t *handle;
--      bool truncate = false;
--      u8 blkbits = inode->i_blkbits;
--      ext4_lblk_t written_blk, end_blk;
--      int ret;
--
--      /*
--       * Note that EXT4_I(inode)->i_disksize can get extended up to
--       * inode->i_size while the I/O was running due to writeback of delalloc
--       * blocks. But, the code in ext4_iomap_alloc() is careful to use
--       * zeroed/unwritten extents if this is possible; thus we won't leave
--       * uninitialized blocks in a file even if we didn't succeed in writing
--       * as much as we intended.
--       */
--      WARN_ON_ONCE(i_size_read(inode) < EXT4_I(inode)->i_disksize);
--      if (offset + count <= EXT4_I(inode)->i_disksize) {
--              /*
--               * We need to ensure that the inode is removed from the orphan
--               * list if it has been added prematurely, due to writeback of
--               * delalloc blocks.
--               */
--              if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) {
--                      handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
--
--                      if (IS_ERR(handle)) {
--                              ext4_orphan_del(NULL, inode);
--                              return PTR_ERR(handle);
--                      }
--
--                      ext4_orphan_del(handle, inode);
--                      ext4_journal_stop(handle);
--              }
--
--              return written;
--      }
--
--      if (written < 0)
--              goto truncate;
-+      lockdep_assert_held_write(&inode->i_rwsem);
-       handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
--      if (IS_ERR(handle)) {
--              written = PTR_ERR(handle);
--              goto truncate;
--      }
-+      if (IS_ERR(handle))
-+              return PTR_ERR(handle);
--      if (ext4_update_inode_size(inode, offset + written)) {
--              ret = ext4_mark_inode_dirty(handle, inode);
-+      if (ext4_update_inode_size(inode, offset + count)) {
-+              int ret = ext4_mark_inode_dirty(handle, inode);
-               if (unlikely(ret)) {
--                      written = ret;
-                       ext4_journal_stop(handle);
--                      goto truncate;
-+                      return ret;
-               }
-       }
--      /*
--       * We may need to truncate allocated but not written blocks beyond EOF.
--       */
--      written_blk = ALIGN(offset + written, 1 << blkbits);
--      end_blk = ALIGN(offset + count, 1 << blkbits);
--      if (written_blk < end_blk && ext4_can_truncate(inode))
--              truncate = true;
--
--      /*
--       * Remove the inode from the orphan list if it has been extended and
--       * everything went OK.
--       */
--      if (!truncate && inode->i_nlink)
-+      if (inode->i_nlink)
-               ext4_orphan_del(handle, inode);
-       ext4_journal_stop(handle);
--      if (truncate) {
--truncate:
-+      return count;
-+}
-+
-+/*
-+ * Clean up the inode after DIO or DAX extending write has completed and the
-+ * inode size has been updated using ext4_handle_inode_extension().
-+ */
-+static void ext4_inode_extension_cleanup(struct inode *inode, ssize_t count)
-+{
-+      lockdep_assert_held_write(&inode->i_rwsem);
-+      if (count < 0) {
-               ext4_truncate_failed_write(inode);
-               /*
-                * If the truncate operation failed early, then the inode may
-@@ -362,9 +320,28 @@ static ssize_t ext4_handle_inode_extension(struct inode *inode, loff_t offset,
-                */
-               if (inode->i_nlink)
-                       ext4_orphan_del(NULL, inode);
-+              return;
-       }
-+      /*
-+       * If i_disksize got extended due to writeback of delalloc blocks while
-+       * the DIO was running we could fail to cleanup the orphan list in
-+       * ext4_handle_inode_extension(). Do it now.
-+       */
-+      if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) {
-+              handle_t *handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
--      return written;
-+              if (IS_ERR(handle)) {
-+                      /*
-+                       * The write has successfully completed. Not much to
-+                       * do with the error here so just cleanup the orphan
-+                       * list and hope for the best.
-+                       */
-+                      ext4_orphan_del(NULL, inode);
-+                      return;
-+              }
-+              ext4_orphan_del(handle, inode);
-+              ext4_journal_stop(handle);
-+      }
- }
- static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size,
-@@ -373,31 +350,22 @@ static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size,
-       loff_t pos = iocb->ki_pos;
-       struct inode *inode = file_inode(iocb->ki_filp);
-+      if (!error && size && flags & IOMAP_DIO_UNWRITTEN)
-+              error = ext4_convert_unwritten_extents(NULL, inode, pos, size);
-       if (error)
-               return error;
--
--      if (size && flags & IOMAP_DIO_UNWRITTEN) {
--              error = ext4_convert_unwritten_extents(NULL, inode, pos, size);
--              if (error < 0)
--                      return error;
--      }
-       /*
--       * If we are extending the file, we have to update i_size here before
--       * page cache gets invalidated in iomap_dio_rw(). Otherwise racing
--       * buffered reads could zero out too much from page cache pages. Update
--       * of on-disk size will happen later in ext4_dio_write_iter() where
--       * we have enough information to also perform orphan list handling etc.
--       * Note that we perform all extending writes synchronously under
--       * i_rwsem held exclusively so i_size update is safe here in that case.
--       * If the write was not extending, we cannot see pos > i_size here
--       * because operations reducing i_size like truncate wait for all
--       * outstanding DIO before updating i_size.
-+       * Note that EXT4_I(inode)->i_disksize can get extended up to
-+       * inode->i_size while the I/O was running due to writeback of delalloc
-+       * blocks. But the code in ext4_iomap_alloc() is careful to use
-+       * zeroed/unwritten extents if this is possible; thus we won't leave
-+       * uninitialized blocks in a file even if we didn't succeed in writing
-+       * as much as we intended.
-        */
--      pos += size;
--      if (pos > i_size_read(inode))
--              i_size_write(inode, pos);
--
--      return 0;
-+      WARN_ON_ONCE(i_size_read(inode) < READ_ONCE(EXT4_I(inode)->i_disksize));
-+      if (pos + size <= READ_ONCE(EXT4_I(inode)->i_disksize))
-+              return size;
-+      return ext4_handle_inode_extension(inode, pos, size);
- }
- static const struct iomap_dio_ops ext4_dio_write_ops = {
-@@ -572,9 +540,16 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)
-                          is_sync_kiocb(iocb) || unaligned_io || extend);
-       if (ret == -ENOTBLK)
-               ret = 0;
--
--      if (extend)
--              ret = ext4_handle_inode_extension(inode, offset, ret, count);
-+      if (extend) {
-+              /*
-+               * We always perform extending DIO write synchronously so by
-+               * now the IO is completed and ext4_handle_inode_extension()
-+               * was called. Cleanup the inode in case of error or race with
-+               * writeback of delalloc blocks.
-+               */
-+              WARN_ON_ONCE(ret == -EIOCBQUEUED);
-+              ext4_inode_extension_cleanup(inode, ret);
-+      }
- out:
-       if (ilock_shared)
-@@ -655,8 +630,10 @@ ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter *from)
-       ret = dax_iomap_rw(iocb, from, &ext4_iomap_ops);
--      if (extend)
--              ret = ext4_handle_inode_extension(inode, offset, ret, count);
-+      if (extend) {
-+              ret = ext4_handle_inode_extension(inode, offset, ret);
-+              ext4_inode_extension_cleanup(inode, ret);
-+      }
- out:
-       inode_unlock(inode);
-       if (ret > 0)
--- 
-2.42.0
-
index a812cb7a6720468b7b89044507da2c1430dbac84..7052f4ef836153a75a5203ef91b7ad7d5d821ba0 100644 (file)
@@ -114,7 +114,6 @@ misc-pci_endpoint_test-add-deviceid-for-am64-and-j72.patch
 misc-pci_endpoint_test-add-deviceid-for-j721s2-pcie-.patch
 fbdev-stifb-make-the-sti-next-font-pointer-a-32-bit-.patch
 ima-annotate-iint-mutex-to-avoid-lockdep-false-posit.patch
-ext4-properly-sync-file-size-update-after-o_sync-dir.patch
 driver-core-move-the-removable-attribute-from-usb-to.patch
 drm-amdgpu-don-t-use-atrm-for-external-devices.patch
 fs-add-ctime-accessors-infrastructure.patch
diff --git a/queue-5.15/ext4-properly-sync-file-size-update-after-o_sync-dir.patch b/queue-5.15/ext4-properly-sync-file-size-update-after-o_sync-dir.patch
deleted file mode 100644 (file)
index 7f35f1d..0000000
+++ /dev/null
@@ -1,246 +0,0 @@
-From 91d014706a567575472e4872abeac522965cbe1f Mon Sep 17 00:00:00 2001
-From: Sasha Levin <sashal@kernel.org>
-Date: Fri, 13 Oct 2023 14:13:50 +0200
-Subject: ext4: properly sync file size update after O_SYNC direct IO
-
-From: Jan Kara <jack@suse.cz>
-
-[ Upstream commit 91562895f8030cb9a0470b1db49de79346a69f91 ]
-
-Gao Xiang has reported that on ext4 O_SYNC direct IO does not properly
-sync file size update and thus if we crash at unfortunate moment, the
-file can have smaller size although O_SYNC IO has reported successful
-completion. The problem happens because update of on-disk inode size is
-handled in ext4_dio_write_iter() *after* iomap_dio_rw() (and thus
-dio_complete() in particular) has returned and generic_file_sync() gets
-called by dio_complete(). Fix the problem by handling on-disk inode size
-update directly in our ->end_io completion handler.
-
-References: https://lore.kernel.org/all/02d18236-26ef-09b0-90ad-030c4fe3ee20@linux.alibaba.com
-Reported-by: Gao Xiang <hsiangkao@linux.alibaba.com>
-CC: stable@vger.kernel.org
-Fixes: 378f32bab371 ("ext4: introduce direct I/O write using iomap infrastructure")
-Signed-off-by: Jan Kara <jack@suse.cz>
-Tested-by: Joseph Qi <joseph.qi@linux.alibaba.com>
-Reviewed-by: "Ritesh Harjani (IBM)" <ritesh.list@gmail.com>
-Link: https://lore.kernel.org/r/20231013121350.26872-1-jack@suse.cz
-Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-Signed-off-by: Sasha Levin <sashal@kernel.org>
----
- fs/ext4/file.c | 153 +++++++++++++++++++++----------------------------
- 1 file changed, 65 insertions(+), 88 deletions(-)
-
-diff --git a/fs/ext4/file.c b/fs/ext4/file.c
-index 4704fe627c4e2..94ce73fadcba6 100644
---- a/fs/ext4/file.c
-+++ b/fs/ext4/file.c
-@@ -279,80 +279,38 @@ static ssize_t ext4_buffered_write_iter(struct kiocb *iocb,
- }
- static ssize_t ext4_handle_inode_extension(struct inode *inode, loff_t offset,
--                                         ssize_t written, size_t count)
-+                                         ssize_t count)
- {
-       handle_t *handle;
--      bool truncate = false;
--      u8 blkbits = inode->i_blkbits;
--      ext4_lblk_t written_blk, end_blk;
--      int ret;
--
--      /*
--       * Note that EXT4_I(inode)->i_disksize can get extended up to
--       * inode->i_size while the I/O was running due to writeback of delalloc
--       * blocks. But, the code in ext4_iomap_alloc() is careful to use
--       * zeroed/unwritten extents if this is possible; thus we won't leave
--       * uninitialized blocks in a file even if we didn't succeed in writing
--       * as much as we intended.
--       */
--      WARN_ON_ONCE(i_size_read(inode) < EXT4_I(inode)->i_disksize);
--      if (offset + count <= EXT4_I(inode)->i_disksize) {
--              /*
--               * We need to ensure that the inode is removed from the orphan
--               * list if it has been added prematurely, due to writeback of
--               * delalloc blocks.
--               */
--              if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) {
--                      handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
--
--                      if (IS_ERR(handle)) {
--                              ext4_orphan_del(NULL, inode);
--                              return PTR_ERR(handle);
--                      }
--
--                      ext4_orphan_del(handle, inode);
--                      ext4_journal_stop(handle);
--              }
--
--              return written;
--      }
--
--      if (written < 0)
--              goto truncate;
-+      lockdep_assert_held_write(&inode->i_rwsem);
-       handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
--      if (IS_ERR(handle)) {
--              written = PTR_ERR(handle);
--              goto truncate;
--      }
-+      if (IS_ERR(handle))
-+              return PTR_ERR(handle);
--      if (ext4_update_inode_size(inode, offset + written)) {
--              ret = ext4_mark_inode_dirty(handle, inode);
-+      if (ext4_update_inode_size(inode, offset + count)) {
-+              int ret = ext4_mark_inode_dirty(handle, inode);
-               if (unlikely(ret)) {
--                      written = ret;
-                       ext4_journal_stop(handle);
--                      goto truncate;
-+                      return ret;
-               }
-       }
--      /*
--       * We may need to truncate allocated but not written blocks beyond EOF.
--       */
--      written_blk = ALIGN(offset + written, 1 << blkbits);
--      end_blk = ALIGN(offset + count, 1 << blkbits);
--      if (written_blk < end_blk && ext4_can_truncate(inode))
--              truncate = true;
--
--      /*
--       * Remove the inode from the orphan list if it has been extended and
--       * everything went OK.
--       */
--      if (!truncate && inode->i_nlink)
-+      if (inode->i_nlink)
-               ext4_orphan_del(handle, inode);
-       ext4_journal_stop(handle);
--      if (truncate) {
--truncate:
-+      return count;
-+}
-+
-+/*
-+ * Clean up the inode after DIO or DAX extending write has completed and the
-+ * inode size has been updated using ext4_handle_inode_extension().
-+ */
-+static void ext4_inode_extension_cleanup(struct inode *inode, ssize_t count)
-+{
-+      lockdep_assert_held_write(&inode->i_rwsem);
-+      if (count < 0) {
-               ext4_truncate_failed_write(inode);
-               /*
-                * If the truncate operation failed early, then the inode may
-@@ -361,9 +319,28 @@ static ssize_t ext4_handle_inode_extension(struct inode *inode, loff_t offset,
-                */
-               if (inode->i_nlink)
-                       ext4_orphan_del(NULL, inode);
-+              return;
-       }
-+      /*
-+       * If i_disksize got extended due to writeback of delalloc blocks while
-+       * the DIO was running we could fail to cleanup the orphan list in
-+       * ext4_handle_inode_extension(). Do it now.
-+       */
-+      if (!list_empty(&EXT4_I(inode)->i_orphan) && inode->i_nlink) {
-+              handle_t *handle = ext4_journal_start(inode, EXT4_HT_INODE, 2);
--      return written;
-+              if (IS_ERR(handle)) {
-+                      /*
-+                       * The write has successfully completed. Not much to
-+                       * do with the error here so just cleanup the orphan
-+                       * list and hope for the best.
-+                       */
-+                      ext4_orphan_del(NULL, inode);
-+                      return;
-+              }
-+              ext4_orphan_del(handle, inode);
-+              ext4_journal_stop(handle);
-+      }
- }
- static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size,
-@@ -372,31 +349,22 @@ static int ext4_dio_write_end_io(struct kiocb *iocb, ssize_t size,
-       loff_t pos = iocb->ki_pos;
-       struct inode *inode = file_inode(iocb->ki_filp);
-+      if (!error && size && flags & IOMAP_DIO_UNWRITTEN)
-+              error = ext4_convert_unwritten_extents(NULL, inode, pos, size);
-       if (error)
-               return error;
--
--      if (size && flags & IOMAP_DIO_UNWRITTEN) {
--              error = ext4_convert_unwritten_extents(NULL, inode, pos, size);
--              if (error < 0)
--                      return error;
--      }
-       /*
--       * If we are extending the file, we have to update i_size here before
--       * page cache gets invalidated in iomap_dio_rw(). Otherwise racing
--       * buffered reads could zero out too much from page cache pages. Update
--       * of on-disk size will happen later in ext4_dio_write_iter() where
--       * we have enough information to also perform orphan list handling etc.
--       * Note that we perform all extending writes synchronously under
--       * i_rwsem held exclusively so i_size update is safe here in that case.
--       * If the write was not extending, we cannot see pos > i_size here
--       * because operations reducing i_size like truncate wait for all
--       * outstanding DIO before updating i_size.
-+       * Note that EXT4_I(inode)->i_disksize can get extended up to
-+       * inode->i_size while the I/O was running due to writeback of delalloc
-+       * blocks. But the code in ext4_iomap_alloc() is careful to use
-+       * zeroed/unwritten extents if this is possible; thus we won't leave
-+       * uninitialized blocks in a file even if we didn't succeed in writing
-+       * as much as we intended.
-        */
--      pos += size;
--      if (pos > i_size_read(inode))
--              i_size_write(inode, pos);
--
--      return 0;
-+      WARN_ON_ONCE(i_size_read(inode) < READ_ONCE(EXT4_I(inode)->i_disksize));
-+      if (pos + size <= READ_ONCE(EXT4_I(inode)->i_disksize))
-+              return size;
-+      return ext4_handle_inode_extension(inode, pos, size);
- }
- static const struct iomap_dio_ops ext4_dio_write_ops = {
-@@ -572,9 +540,16 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from)
-                          0);
-       if (ret == -ENOTBLK)
-               ret = 0;
--
--      if (extend)
--              ret = ext4_handle_inode_extension(inode, offset, ret, count);
-+      if (extend) {
-+              /*
-+               * We always perform extending DIO write synchronously so by
-+               * now the IO is completed and ext4_handle_inode_extension()
-+               * was called. Cleanup the inode in case of error or race with
-+               * writeback of delalloc blocks.
-+               */
-+              WARN_ON_ONCE(ret == -EIOCBQUEUED);
-+              ext4_inode_extension_cleanup(inode, ret);
-+      }
- out:
-       if (ilock_shared)
-@@ -655,8 +630,10 @@ ext4_dax_write_iter(struct kiocb *iocb, struct iov_iter *from)
-       ret = dax_iomap_rw(iocb, from, &ext4_iomap_ops);
--      if (extend)
--              ret = ext4_handle_inode_extension(inode, offset, ret, count);
-+      if (extend) {
-+              ret = ext4_handle_inode_extension(inode, offset, ret);
-+              ext4_inode_extension_cleanup(inode, ret);
-+      }
- out:
-       inode_unlock(inode);
-       if (ret > 0)
--- 
-2.42.0
-
index 58f56434d603928b0f33c5be621db58c0af855be..879495ef4a3ba09432579ae2000866a6e885408d 100644 (file)
@@ -55,7 +55,6 @@ asoc-sof-sof-pci-dev-add-parameter-to-override-topol.patch
 asoc-sof-sof-pci-dev-don-t-use-the-community-key-on-.patch
 asoc-sof-sof-pci-dev-fix-community-key-quirk-detecti.patch
 fbdev-stifb-make-the-sti-next-font-pointer-a-32-bit-.patch
-ext4-properly-sync-file-size-update-after-o_sync-dir.patch
 fs-add-ctime-accessors-infrastructure.patch
 smb3-fix-caching-of-ctime-on-setxattr.patch
 cpufreq-imx6q-don-t-warn-for-disabling-a-non-existin.patch
@@ -69,7 +68,6 @@ asoc-sof-sof-pci-dev-add-parameter-to-override-topol.patch-4431
 asoc-sof-sof-pci-dev-don-t-use-the-community-key-on-.patch-15789
 asoc-sof-sof-pci-dev-fix-community-key-quirk-detecti.patch-6356
 fbdev-stifb-make-the-sti-next-font-pointer-a-32-bit-.patch-17578
-ext4-properly-sync-file-size-update-after-o_sync-dir.patch-12628
 fs-add-ctime-accessors-infrastructure.patch-279
 smb3-fix-caching-of-ctime-on-setxattr.patch-25511
 cpufreq-imx6q-don-t-warn-for-disabling-a-non-existin.patch-28374