In the case of large folio buffered write, if we pre-allocate partial
blocks after acquiring the folio lock, it may call f2fs_balance_fs and
need to unlock the folio during write.

Re-locking after unlocking can be troublesome because a large folio
carries additional f2fs_folio_state metadata, and partial truncate can
cause the large folio to be split.
At this point, the large folio is still in the inode->mapping.

Prellocate partial blocks in advance to avoid handling this.
Signed-off-by: Nanzhe Zhao <[email protected]>
---
 fs/f2fs/file.c | 17 ++++++++++++++---
 1 file changed, 14 insertions(+), 3 deletions(-)

diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
index abcf6f486dd7..18a9feccb1f9 100644
--- a/fs/f2fs/file.c
+++ b/fs/f2fs/file.c
@@ -4995,9 +4995,20 @@ static int f2fs_preallocate_blocks(struct kiocb *iocb, 
struct iov_iter *iter,
                        return ret;
        }
 
-       /* Do not preallocate blocks that will be written partially in 4KB. */
-       map.m_lblk = F2FS_BLK_ALIGN(pos);
-       map.m_len = F2FS_BYTES_TO_BLK(pos + count);
+       if (mapping_large_folio_support(inode->i_mapping)) {
+               /* preallocate all blocks for large folio inode before write to 
avoid
+                * unlocking large folios by balance_fs during write. 
Rechecking the
+                * large-folio state is unreliable since partial truncation may 
split
+                * the folio.
+                */
+               map.m_lblk = F2FS_BYTES_TO_BLK(pos);
+               map.m_len = F2FS_BLK_ALIGN(pos + count);
+       } else {
+               /* Do not preallocate blocks that will be written partially in 
4KB. */
+               map.m_lblk = F2FS_BLK_ALIGN(pos);
+               map.m_len = F2FS_BYTES_TO_BLK(pos + count);
+       }
+
        if (map.m_len > map.m_lblk)
                map.m_len -= map.m_lblk;
        else
-- 
2.34.1



_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel

Reply via email to