From nobody Mon Feb 9 01:01:50 2026 Received: from relayaws-01.paragon-software.com (relayaws-01.paragon-software.com [35.157.23.187]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3D5CD328B70; Fri, 31 Oct 2025 07:15:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=35.157.23.187 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761894937; cv=none; b=V2ds0xqdDqRta9KaqtQ/NQixaMhISfXB9+LwUb8vh575UrkYi3rpMvAieUt4JACR/B0pkLLkW/eM2sXc2pjoMuWO4c026m5tLxqlddy1dGS3dvEpwMciCwWBGpE1qCbEVCNYW8FnXPLUTHz4KSCwleZH7oDtfJPt086XK5LSuaI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1761894937; c=relaxed/simple; bh=9gjK2wHVEI2cwyP19ZSa7HGwPtmu5ioiCQrU6rWBP2g=; h=From:To:CC:Subject:Date:Message-ID:MIME-Version:Content-Type; b=aiGXuTwxL8zaRA9HTsU7tjvGm9PW4bAzGD8pBQinW5SvczJ8vClNv4GtSkI3SXy7lyE/kWfTAuw8eDoHgjOMhXII/XwpTUe+EMNTM3ZA5nJETKhaB4vyE/R+1MdL/VqJlosA2wMLxqUTnKSJ0KI55K9s/T+IMmAjna2KgQ/uxbQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=paragon-software.com; spf=pass smtp.mailfrom=paragon-software.com; dkim=pass (1024-bit key) header.d=paragon-software.com header.i=@paragon-software.com header.b=YUKnFl1b; arc=none smtp.client-ip=35.157.23.187 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=paragon-software.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=paragon-software.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=paragon-software.com header.i=@paragon-software.com header.b="YUKnFl1b" Received: from relayfre-01.paragon-software.com (unknown [176.12.100.13]) by relayaws-01.paragon-software.com (Postfix) with ESMTPS id 1930C1E39; Fri, 31 Oct 2025 07:12:17 +0000 (UTC) Authentication-Results: relayaws-01.paragon-software.com; dkim=pass (1024-bit key; unprotected) header.d=paragon-software.com header.i=@paragon-software.com header.b=YUKnFl1b; dkim-atps=neutral Received: from dlg2.mail.paragon-software.com (vdlg-exch-02.paragon-software.com [172.30.1.105]) by relayfre-01.paragon-software.com (Postfix) with ESMTPS id 4ABE731; Fri, 31 Oct 2025 07:15:26 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=paragon-software.com; s=mail; t=1761894926; bh=OpCFc2u6CH7glT0gDsjbR3AmVOrBe58fnilqPfGxNr8=; h=From:To:CC:Subject:Date; b=YUKnFl1b5TDAt+3QqxQrOc9/kPMtIiwf/qQl6BIoX1oNdbMJtcpFgaC7phHzXuUrb XQB37UKTkaO17R7pfv/hxt5lTKOVzjjthrIzxUP14h+Ugge1pBwr9aGfSR010yZqlv YYukDhQ4PUjs6VssO79T/jXD5cgo2Zp/brQUOHNo= Received: from localhost.localdomain (172.30.20.190) by vdlg-exch-02.paragon-software.com (172.30.1.105) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2375.7; Fri, 31 Oct 2025 10:15:25 +0300 From: Konstantin Komarov To: CC: , , Konstantin Komarov Subject: [PATCH] fs/ntfs3: remove ntfs_bio_pages and use page cache for compressed I/O Date: Fri, 31 Oct 2025 08:15:16 +0100 Message-ID: <20251031071516.3604-1-almaz.alexandrovich@paragon-software.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: vdlg-exch-02.paragon-software.com (172.30.1.105) To vdlg-exch-02.paragon-software.com (172.30.1.105) Content-Type: text/plain; charset="utf-8" Replace the use of ntfs_bio_pages with the disk page cache for reading and writing compressed files. This slightly improves performance when reading compressed data and simplifies the I/O logic. When an XPRESS or LZX compressed file is opened for writing, it is now decompressed into a normal file before modification. A new argument (`int c= opy`) is added to ni_read_frame() to handle writing of decompressed and mapped da= ta. Signed-off-by: Konstantin Komarov --- fs/ntfs3/attrib.c | 4 +- fs/ntfs3/file.c | 6 +- fs/ntfs3/frecord.c | 151 ++++++++++++--------------------------------- fs/ntfs3/fsntfs.c | 123 +++++++++++++++++------------------- fs/ntfs3/inode.c | 1 - fs/ntfs3/ntfs_fs.h | 20 ++++-- 6 files changed, 114 insertions(+), 191 deletions(-) diff --git a/fs/ntfs3/attrib.c b/fs/ntfs3/attrib.c index eced9013a881..d0373254f82a 100644 --- a/fs/ntfs3/attrib.c +++ b/fs/ntfs3/attrib.c @@ -1457,7 +1457,6 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct= ATTRIB *attr, pgoff_t index =3D vbo[i] >> PAGE_SHIFT; =20 if (index !=3D folio->index) { - struct page *page =3D &folio->page; u64 from =3D vbo[i] & ~(u64)(PAGE_SIZE - 1); u64 to =3D min(from + PAGE_SIZE, wof_size); =20 @@ -1467,8 +1466,7 @@ int attr_wof_frame_info(struct ntfs_inode *ni, struct= ATTRIB *attr, if (err) goto out1; =20 - err =3D ntfs_bio_pages(sbi, run, &page, 1, from, - to - from, REQ_OP_READ); + err =3D ntfs_read_run(sbi, run, addr, from, to - from); if (err) { folio->index =3D -1; goto out1; diff --git a/fs/ntfs3/file.c b/fs/ntfs3/file.c index 7471a4bbb438..60eb90bff955 100644 --- a/fs/ntfs3/file.c +++ b/fs/ntfs3/file.c @@ -59,7 +59,7 @@ static int ntfs_ioctl_get_volume_label(struct ntfs_sb_inf= o *sbi, u8 __user *buf) =20 static int ntfs_ioctl_set_volume_label(struct ntfs_sb_info *sbi, u8 __user= *buf) { - u8 user[FSLABEL_MAX] =3D {0}; + u8 user[FSLABEL_MAX] =3D { 0 }; int len; =20 if (!capable(CAP_SYS_ADMIN)) @@ -1039,7 +1039,7 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb= , struct iov_iter *from) =20 if (!frame_uptodate && off) { err =3D ni_read_frame(ni, frame_vbo, pages, - pages_per_frame); + pages_per_frame, 0); if (err) { for (ip =3D 0; ip < pages_per_frame; ip++) { folio =3D page_folio(pages[ip]); @@ -1104,7 +1104,7 @@ static ssize_t ntfs_compress_write(struct kiocb *iocb= , struct iov_iter *from) =20 if (off || (to < i_size && (to & (frame_size - 1)))) { err =3D ni_read_frame(ni, frame_vbo, pages, - pages_per_frame); + pages_per_frame, 0); if (err) { for (ip =3D 0; ip < pages_per_frame; ip++) { diff --git a/fs/ntfs3/frecord.c b/fs/ntfs3/frecord.c index e44181185526..4a7d56c06dcb 100644 --- a/fs/ntfs3/frecord.c +++ b/fs/ntfs3/frecord.c @@ -2105,7 +2105,7 @@ int ni_readpage_cmpr(struct ntfs_inode *ni, struct fo= lio *folio) pages[i] =3D pg; } =20 - err =3D ni_read_frame(ni, frame_vbo, pages, pages_per_frame); + err =3D ni_read_frame(ni, frame_vbo, pages, pages_per_frame, 0); =20 out1: for (i =3D 0; i < pages_per_frame; i++) { @@ -2175,17 +2175,9 @@ int ni_decompress_file(struct ntfs_inode *ni) */ index =3D 0; for (vbo =3D 0; vbo < i_size; vbo +=3D bytes) { - u32 nr_pages; bool new; =20 - if (vbo + frame_size > i_size) { - bytes =3D i_size - vbo; - nr_pages =3D (bytes + PAGE_SIZE - 1) >> PAGE_SHIFT; - } else { - nr_pages =3D pages_per_frame; - bytes =3D frame_size; - } - + bytes =3D vbo + frame_size > i_size ? (i_size - vbo) : frame_size; end =3D bytes_to_cluster(sbi, vbo + bytes); =20 for (vcn =3D vbo >> sbi->cluster_bits; vcn < end; vcn +=3D clen) { @@ -2210,15 +2202,7 @@ int ni_decompress_file(struct ntfs_inode *ni) pages[i] =3D pg; } =20 - err =3D ni_read_frame(ni, vbo, pages, pages_per_frame); - - if (!err) { - down_read(&ni->file.run_lock); - err =3D ntfs_bio_pages(sbi, &ni->file.run, pages, - nr_pages, vbo, bytes, - REQ_OP_WRITE); - up_read(&ni->file.run_lock); - } + err =3D ni_read_frame(ni, vbo, pages, pages_per_frame, 1); =20 for (i =3D 0; i < pages_per_frame; i++) { unlock_page(pages[i]); @@ -2408,20 +2392,19 @@ static int decompress_lzx_xpress(struct ntfs_sb_inf= o *sbi, const char *cmpr, * Pages - Array of locked pages. */ int ni_read_frame(struct ntfs_inode *ni, u64 frame_vbo, struct page **page= s, - u32 pages_per_frame) + u32 pages_per_frame, int copy) { int err; struct ntfs_sb_info *sbi =3D ni->mi.sbi; u8 cluster_bits =3D sbi->cluster_bits; char *frame_ondisk =3D NULL; char *frame_mem =3D NULL; - struct page **pages_disk =3D NULL; struct ATTR_LIST_ENTRY *le =3D NULL; struct runs_tree *run =3D &ni->file.run; u64 valid_size =3D ni->i_valid; u64 vbo_disk; size_t unc_size; - u32 frame_size, i, npages_disk, ondisk_size; + u32 frame_size, i, ondisk_size; struct page *pg; struct ATTRIB *attr; CLST frame, clst_data; @@ -2513,7 +2496,7 @@ int ni_read_frame(struct ntfs_inode *ni, u64 frame_vb= o, struct page **pages, err =3D attr_wof_frame_info(ni, attr, run, frame64, frames, frame_bits, &ondisk_size, &vbo_data); if (err) - goto out2; + goto out1; =20 if (frame64 =3D=3D frames) { unc_size =3D 1 + ((i_size - 1) & (frame_size - 1)); @@ -2524,7 +2507,7 @@ int ni_read_frame(struct ntfs_inode *ni, u64 frame_vb= o, struct page **pages, =20 if (ondisk_size > frame_size) { err =3D -EINVAL; - goto out2; + goto out1; } =20 if (!attr->non_res) { @@ -2545,10 +2528,7 @@ int ni_read_frame(struct ntfs_inode *ni, u64 frame_v= bo, struct page **pages, ARRAY_SIZE(WOF_NAME), run, vbo_disk, vbo_data + ondisk_size); if (err) - goto out2; - npages_disk =3D (ondisk_size + (vbo_disk & (PAGE_SIZE - 1)) + - PAGE_SIZE - 1) >> - PAGE_SHIFT; + goto out1; #endif } else if (is_attr_compressed(attr)) { /* LZNT compression. */ @@ -2582,60 +2562,37 @@ int ni_read_frame(struct ntfs_inode *ni, u64 frame_= vbo, struct page **pages, if (clst_data >=3D NTFS_LZNT_CLUSTERS) { /* Frame is not compressed. */ down_read(&ni->file.run_lock); - err =3D ntfs_bio_pages(sbi, run, pages, pages_per_frame, - frame_vbo, ondisk_size, - REQ_OP_READ); + err =3D ntfs_read_run(sbi, run, frame_mem, frame_vbo, + ondisk_size); up_read(&ni->file.run_lock); goto out1; } vbo_disk =3D frame_vbo; - npages_disk =3D (ondisk_size + PAGE_SIZE - 1) >> PAGE_SHIFT; } else { __builtin_unreachable(); err =3D -EINVAL; goto out1; } =20 - pages_disk =3D kcalloc(npages_disk, sizeof(*pages_disk), GFP_NOFS); - if (!pages_disk) { + /* Allocate memory to read compressed data to. */ + frame_ondisk =3D kvmalloc(ondisk_size, GFP_KERNEL); + if (!frame_ondisk) { err =3D -ENOMEM; - goto out2; - } - - for (i =3D 0; i < npages_disk; i++) { - pg =3D alloc_page(GFP_KERNEL); - if (!pg) { - err =3D -ENOMEM; - goto out3; - } - pages_disk[i] =3D pg; - lock_page(pg); + goto out1; } =20 /* Read 'ondisk_size' bytes from disk. */ down_read(&ni->file.run_lock); - err =3D ntfs_bio_pages(sbi, run, pages_disk, npages_disk, vbo_disk, - ondisk_size, REQ_OP_READ); + err =3D ntfs_read_run(sbi, run, frame_ondisk, vbo_disk, ondisk_size); up_read(&ni->file.run_lock); if (err) - goto out3; - - /* - * To simplify decompress algorithm do vmap for source and target pages. - */ - frame_ondisk =3D vmap(pages_disk, npages_disk, VM_MAP, PAGE_KERNEL_RO); - if (!frame_ondisk) { - err =3D -ENOMEM; - goto out3; - } + goto out2; =20 - /* Decompress: Frame_ondisk -> frame_mem. */ #ifdef CONFIG_NTFS3_LZX_XPRESS if (run !=3D &ni->file.run) { /* LZX or XPRESS */ - err =3D decompress_lzx_xpress( - sbi, frame_ondisk + (vbo_disk & (PAGE_SIZE - 1)), - ondisk_size, frame_mem, unc_size, frame_size); + err =3D decompress_lzx_xpress(sbi, frame_ondisk, ondisk_size, + frame_mem, unc_size, frame_size); } else #endif { @@ -2653,24 +2610,21 @@ int ni_read_frame(struct ntfs_inode *ni, u64 frame_= vbo, struct page **pages, memset(frame_mem + ok, 0, frame_size - ok); } =20 - vunmap(frame_ondisk); - -out3: - for (i =3D 0; i < npages_disk; i++) { - pg =3D pages_disk[i]; - if (pg) { - unlock_page(pg); - put_page(pg); - } - } - kfree(pages_disk); - out2: + kvfree(frame_ondisk); +out1: #ifdef CONFIG_NTFS3_LZX_XPRESS if (run !=3D &ni->file.run) run_free(run); + if (!err && copy) { + /* We are called from 'ni_decompress_file' */ + /* Copy decompressed LZX or XPRESS data into new place. */ + down_read(&ni->file.run_lock); + err =3D ntfs_write_run(sbi, &ni->file.run, frame_mem, frame_vbo, + frame_size); + up_read(&ni->file.run_lock); + } #endif -out1: vunmap(frame_mem); out: for (i =3D 0; i < pages_per_frame; i++) { @@ -2697,13 +2651,11 @@ int ni_write_frame(struct ntfs_inode *ni, struct pa= ge **pages, u64 frame_vbo =3D folio_pos(folio); CLST frame =3D frame_vbo >> frame_bits; char *frame_ondisk =3D NULL; - struct page **pages_disk =3D NULL; struct ATTR_LIST_ENTRY *le =3D NULL; char *frame_mem; struct ATTRIB *attr; struct mft_inode *mi; u32 i; - struct page *pg; size_t compr_size, ondisk_size; struct lznt *lznt; =20 @@ -2738,34 +2690,18 @@ int ni_write_frame(struct ntfs_inode *ni, struct pa= ge **pages, goto out; } =20 - pages_disk =3D kcalloc(pages_per_frame, sizeof(struct page *), GFP_NOFS); - if (!pages_disk) { - err =3D -ENOMEM; - goto out; - } - - for (i =3D 0; i < pages_per_frame; i++) { - pg =3D alloc_page(GFP_KERNEL); - if (!pg) { - err =3D -ENOMEM; - goto out1; - } - pages_disk[i] =3D pg; - lock_page(pg); - } - - /* To simplify compress algorithm do vmap for source and target pages. */ - frame_ondisk =3D vmap(pages_disk, pages_per_frame, VM_MAP, PAGE_KERNEL); + /* Allocate memory to write compressed data to. */ + frame_ondisk =3D kvmalloc(frame_size, GFP_KERNEL); if (!frame_ondisk) { err =3D -ENOMEM; - goto out1; + goto out; } =20 /* Map in-memory frame for read-only. */ frame_mem =3D vmap(pages, pages_per_frame, VM_MAP, PAGE_KERNEL_RO); if (!frame_mem) { err =3D -ENOMEM; - goto out2; + goto out1; } =20 mutex_lock(&sbi->compress.mtx_lznt); @@ -2781,7 +2717,7 @@ int ni_write_frame(struct ntfs_inode *ni, struct page= **pages, if (!lznt) { mutex_unlock(&sbi->compress.mtx_lznt); err =3D -ENOMEM; - goto out3; + goto out2; } =20 sbi->compress.lznt =3D lznt; @@ -2818,25 +2754,16 @@ int ni_write_frame(struct ntfs_inode *ni, struct pa= ge **pages, goto out2; =20 down_read(&ni->file.run_lock); - err =3D ntfs_bio_pages(sbi, &ni->file.run, - ondisk_size < frame_size ? pages_disk : pages, - pages_per_frame, frame_vbo, ondisk_size, - REQ_OP_WRITE); + err =3D ntfs_write_run(sbi, &ni->file.run, + ondisk_size < frame_size ? frame_ondisk : + frame_mem, + frame_vbo, ondisk_size); up_read(&ni->file.run_lock); =20 -out3: - vunmap(frame_mem); out2: - vunmap(frame_ondisk); + vunmap(frame_mem); out1: - for (i =3D 0; i < pages_per_frame; i++) { - pg =3D pages_disk[i]; - if (pg) { - unlock_page(pg); - put_page(pg); - } - } - kfree(pages_disk); + kvfree(frame_ondisk); out: return err; } diff --git a/fs/ntfs3/fsntfs.c b/fs/ntfs3/fsntfs.c index 5ae910e9ecbd..a65b66c349e8 100644 --- a/fs/ntfs3/fsntfs.c +++ b/fs/ntfs3/fsntfs.c @@ -1479,99 +1479,86 @@ int ntfs_write_bh(struct ntfs_sb_info *sbi, struct = NTFS_RECORD_HEADER *rhdr, } =20 /* - * ntfs_bio_pages - Read/write pages from/to disk. + * ntfs_read_write_run - Read/Write disk's page cache. */ -int ntfs_bio_pages(struct ntfs_sb_info *sbi, const struct runs_tree *run, - struct page **pages, u32 nr_pages, u64 vbo, u32 bytes, - enum req_op op) +int ntfs_read_write_run(struct ntfs_sb_info *sbi, const struct runs_tree *= run, + void *buf, u64 vbo, size_t bytes, int wr) { - int err =3D 0; - struct bio *new, *bio =3D NULL; struct super_block *sb =3D sbi->sb; - struct block_device *bdev =3D sb->s_bdev; - struct page *page; + struct address_space *mapping =3D sb->s_bdev->bd_mapping; u8 cluster_bits =3D sbi->cluster_bits; - CLST lcn, clen, vcn, vcn_next; - u32 add, off, page_idx; + CLST vcn_next, vcn =3D vbo >> cluster_bits; + CLST lcn, clen; u64 lbo, len; - size_t run_idx; - struct blk_plug plug; + size_t idx; + u32 off, op; + struct page *page; + char *kaddr; =20 if (!bytes) return 0; =20 - blk_start_plug(&plug); + if (!run_lookup_entry(run, vcn, &lcn, &clen, &idx)) + return -ENOENT; =20 - /* Align vbo and bytes to be 512 bytes aligned. */ - lbo =3D (vbo + bytes + 511) & ~511ull; - vbo =3D vbo & ~511ull; - bytes =3D lbo - vbo; + if (lcn =3D=3D SPARSE_LCN) + return -EINVAL; =20 - vcn =3D vbo >> cluster_bits; - if (!run_lookup_entry(run, vcn, &lcn, &clen, &run_idx)) { - err =3D -ENOENT; - goto out; - } off =3D vbo & sbi->cluster_mask; - page_idx =3D 0; - page =3D pages[0]; + lbo =3D ((u64)lcn << cluster_bits) + off; + len =3D ((u64)clen << cluster_bits) - off; =20 for (;;) { - lbo =3D ((u64)lcn << cluster_bits) + off; - len =3D ((u64)clen << cluster_bits) - off; -new_bio: - new =3D bio_alloc(bdev, nr_pages - page_idx, op, GFP_NOFS); - if (bio) { - bio_chain(bio, new); - submit_bio(bio); - } - bio =3D new; - bio->bi_iter.bi_sector =3D lbo >> 9; + /* Read range [lbo, lbo+len). */ + page =3D read_mapping_page(mapping, lbo >> PAGE_SHIFT, NULL); =20 - while (len) { - off =3D vbo & (PAGE_SIZE - 1); - add =3D off + len > PAGE_SIZE ? (PAGE_SIZE - off) : len; + if (IS_ERR(page)) + return PTR_ERR(page); =20 - if (bio_add_page(bio, page, add, off) < add) - goto new_bio; + off =3D offset_in_page(lbo); + op =3D PAGE_SIZE - off; =20 - if (bytes <=3D add) - goto out; - bytes -=3D add; - vbo +=3D add; + if (op > len) + op =3D len; + if (op > bytes) + op =3D bytes; =20 - if (add + off =3D=3D PAGE_SIZE) { - page_idx +=3D 1; - if (WARN_ON(page_idx >=3D nr_pages)) { - err =3D -EINVAL; - goto out; - } - page =3D pages[page_idx]; - } + kaddr =3D kmap_local_page(page); + if (wr) { + memcpy(kaddr + off, buf, op); + set_page_dirty(page); + } else { + memcpy(buf, kaddr + off, op); + flush_dcache_page(page); + } + kunmap_local(kaddr); + put_page(page); =20 - if (len <=3D add) - break; - len -=3D add; - lbo +=3D add; + bytes -=3D op; + if (!bytes) + return 0; + + buf +=3D op; + len -=3D op; + if (len) { + /* next volume's page. */ + lbo +=3D op; + continue; } =20 + /* get next range. */ vcn_next =3D vcn + clen; - if (!run_get_entry(run, ++run_idx, &vcn, &lcn, &clen) || + if (!run_get_entry(run, ++idx, &vcn, &lcn, &clen) || vcn !=3D vcn_next) { - err =3D -ENOENT; - goto out; + return -ENOENT; } - off =3D 0; - } -out: - if (bio) { - if (!err) - err =3D submit_bio_wait(bio); - bio_put(bio); - } - blk_finish_plug(&plug); =20 - return err; + if (lcn =3D=3D SPARSE_LCN) + return -EINVAL; + + lbo =3D ((u64)lcn << cluster_bits); + len =3D ((u64)clen << cluster_bits); + } } =20 /* diff --git a/fs/ntfs3/inode.c b/fs/ntfs3/inode.c index 439078106cc6..53b51659b3a4 100644 --- a/fs/ntfs3/inode.c +++ b/fs/ntfs3/inode.c @@ -2106,7 +2106,6 @@ const struct address_space_operations ntfs_aops =3D { =20 const struct address_space_operations ntfs_aops_cmpr =3D { .read_folio =3D ntfs_read_folio, - .readahead =3D ntfs_readahead, .dirty_folio =3D block_dirty_folio, .direct_IO =3D ntfs_direct_IO, }; diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h index 6a7594d3f3eb..86f825cf1c29 100644 --- a/fs/ntfs3/ntfs_fs.h +++ b/fs/ntfs3/ntfs_fs.h @@ -570,7 +570,7 @@ int ni_fiemap(struct ntfs_inode *ni, struct fiemap_exte= nt_info *fieinfo, int ni_readpage_cmpr(struct ntfs_inode *ni, struct folio *folio); int ni_decompress_file(struct ntfs_inode *ni); int ni_read_frame(struct ntfs_inode *ni, u64 frame_vbo, struct page **page= s, - u32 pages_per_frame); + u32 pages_per_frame, int copy); int ni_write_frame(struct ntfs_inode *ni, struct page **pages, u32 pages_per_frame); int ni_remove_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni, @@ -633,9 +633,21 @@ int ntfs_get_bh(struct ntfs_sb_info *sbi, const struct= runs_tree *run, u64 vbo, u32 bytes, struct ntfs_buffers *nb); int ntfs_write_bh(struct ntfs_sb_info *sbi, struct NTFS_RECORD_HEADER *rhd= r, struct ntfs_buffers *nb, int sync); -int ntfs_bio_pages(struct ntfs_sb_info *sbi, const struct runs_tree *run, - struct page **pages, u32 nr_pages, u64 vbo, u32 bytes, - enum req_op op); +int ntfs_read_write_run(struct ntfs_sb_info *sbi, const struct runs_tree *= run, + void *buf, u64 vbo, size_t bytes, int wr); +static inline int ntfs_read_run(struct ntfs_sb_info *sbi, + const struct runs_tree *run, void *buf, u64 vbo, + size_t bytes) +{ + return ntfs_read_write_run(sbi, run, buf, vbo, bytes, 0); +} +static inline int ntfs_write_run(struct ntfs_sb_info *sbi, + const struct runs_tree *run, void *buf, + u64 vbo, size_t bytes) +{ + return ntfs_read_write_run(sbi, run, buf, vbo, bytes, 1); +} + int ntfs_bio_fill_1(struct ntfs_sb_info *sbi, const struct runs_tree *run); int ntfs_vbo_to_lbo(struct ntfs_sb_info *sbi, const struct runs_tree *run, u64 vbo, u64 *lbo, u64 *bytes); --=20 2.43.0