[PATCH 09/11] ntfs: skip reads for full compression unit overwrites

Namjae Jeon <[email protected]> Tue, 21 Jul 2026 18:54:29 +0900
Newsgroups dev.linux.lists.ntfs
Message-ID <[email protected]>
ntfs_compress_write() reads every page in a compression unit before copying
new data into it. The read is unnecessary when an aligned write replaces
every byte covered by the page-cache folios.

Detect full page-aligned compression unit overwrites and grab locked cache
folios without reading them. Keep the read-modify-write path for partial
units and units that cover only part of a large page.

Signed-off-by: Namjae Jeon <[email protected]>
---
 fs/ntfs/compress.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/fs/ntfs/compress.c b/fs/ntfs/compress.c
index a3af669b1008..ea29fade9b9b 100644
--- a/fs/ntfs/compress.c
+++ b/fs/ntfs/compress.c
@@ -1501,6 +1501,7 @@ int ntfs_compress_write(struct ntfs_inode *ni, loff_t pos, size_t count,
 		pgoff_t index;
 		size_t copied, bytes;
 		unsigned int page_offset;
+		bool full_cb;
 		int off;
 
 		off = pos & (cb_size - 1);
@@ -1512,6 +1513,8 @@ int ntfs_compress_write(struct ntfs_inode *ni, loff_t pos, size_t count,
 		page_offset = offset_in_page(cb_off);
 		pages_per_cb = DIV_ROUND_UP(page_offset + cb_size, PAGE_SIZE);
 		index = cb_off >> PAGE_SHIFT;
+		full_cb = !off && bytes == cb_size && !page_offset &&
+				!(cb_size & (PAGE_SIZE - 1));
 
 		if (unlikely(fault_in_iov_iter_readable(from, bytes))) {
 			err = -EFAULT;
@@ -1519,7 +1522,10 @@ int ntfs_compress_write(struct ntfs_inode *ni, loff_t pos, size_t count,
 		}
 
 		for (i = 0; i < pages_per_cb; i++) {
-			folio = read_mapping_folio(mapping, index + i, NULL);
+			if (full_cb)
+				folio = filemap_grab_folio(mapping, index + i);
+			else
+				folio = read_mapping_folio(mapping, index + i, NULL);
 			if (IS_ERR(folio)) {
 				for (ip = 0; ip < i; ip++) {
 					folio_unlock(page_folio(pages[ip]));
@@ -1529,7 +1535,8 @@ int ntfs_compress_write(struct ntfs_inode *ni, loff_t pos, size_t count,
 				goto out;
 			}
 
-			folio_lock(folio);
+			if (!full_cb)
+				folio_lock(folio);
 			pages[i] = folio_page(folio, 0);
 		}
 
-- 
2.34.1