xref: /linux/fs/ntfs/aops.c (revision cdd4dc3aebeab43a72ce0bc2b5bab6f0a80b97a5)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * NTFS kernel address space operations and page cache handling.
4  *
5  * Copyright (c) 2001-2014 Anton Altaparmakov and Tuxera Inc.
6  * Copyright (c) 2002 Richard Russon
7  * Copyright (c) 2025 LG Electronics Co., Ltd.
8  */
9 
10 #include <linux/writeback.h>
11 
12 #include "attrib.h"
13 #include "mft.h"
14 #include "ntfs.h"
15 #include "debug.h"
16 #include "iomap.h"
17 
18 /*
19  * ntfs_read_folio - Read data for a folio from the device
20  * @file:	open file to which the folio @folio belongs or NULL
21  * @folio:	page cache folio to fill with data
22  *
23  * This function handles reading data into the page cache. It first checks
24  * for specific ntfs attribute type like encryption and compression.
25  *
26  * - If the attribute is encrypted, access is denied (-EACCES) because
27  *   decryption is not supported in this path.
28  * - If the attribute is non-resident and compressed, the read operation is
29  *   delegated to ntfs_read_compressed_block().
30  * - For normal resident or non-resident attribute, it utilizes the generic
31  *   iomap infrastructure via iomap_bio_read_folio() to perform the I/O.
32  *
33  * Return: 0 on success, or -errno on error.
34  */
35 static int ntfs_read_folio(struct file *file, struct folio *folio)
36 {
37 	struct ntfs_inode *ni = NTFS_I(folio->mapping->host);
38 
39 	/*
40 	 * Only $DATA attributes can be encrypted and only unnamed $DATA
41 	 * attributes can be compressed.  Index root can have the flags set but
42 	 * this means to create compressed/encrypted files, not that the
43 	 * attribute is compressed/encrypted.  Note we need to check for
44 	 * AT_INDEX_ALLOCATION since this is the type of both directory and
45 	 * index inodes.
46 	 */
47 	if (ni->type != AT_INDEX_ALLOCATION) {
48 		/*
49 		 * EFS-encrypted files are not supported.
50 		 * (decryption/encryption is not implemented yet)
51 		 */
52 		if (NInoEncrypted(ni)) {
53 			folio_unlock(folio);
54 			return -EOPNOTSUPP;
55 		}
56 		/* Compressed data streams are handled in compress.c. */
57 		if (NInoNonResident(ni) && NInoCompressed(ni))
58 			return ntfs_read_compressed_block(folio);
59 	}
60 
61 	iomap_bio_read_folio(folio, &ntfs_read_iomap_ops);
62 	return 0;
63 }
64 
65 /*
66  * ntfs_bmap - map logical file block to physical device block
67  * @mapping:	address space mapping to which the block to be mapped belongs
68  * @block:	logical block to map to its physical device block
69  *
70  * For regular, non-resident files (i.e. not compressed and not encrypted), map
71  * the logical @block belonging to the file described by the address space
72  * mapping @mapping to its physical device block.
73  *
74  * The size of the block is equal to the @s_blocksize field of the super block
75  * of the mounted file system which is guaranteed to be smaller than or equal
76  * to the cluster size thus the block is guaranteed to fit entirely inside the
77  * cluster which means we do not need to care how many contiguous bytes are
78  * available after the beginning of the block.
79  *
80  * Return the physical device block if the mapping succeeded or 0 if the block
81  * is sparse or there was an error.
82  *
83  * Note: This is a problem if someone tries to run bmap() on $Boot system file
84  * as that really is in block zero but there is nothing we can do.  bmap() is
85  * just broken in that respect (just like it cannot distinguish sparse from
86  * not available or error).
87  */
88 static sector_t ntfs_bmap(struct address_space *mapping, sector_t block)
89 {
90 	s64 ofs, size;
91 	loff_t i_size;
92 	s64 lcn;
93 	unsigned long blocksize, flags;
94 	struct ntfs_inode *ni = NTFS_I(mapping->host);
95 	struct ntfs_volume *vol = ni->vol;
96 	unsigned int delta;
97 	unsigned char blocksize_bits;
98 
99 	ntfs_debug("Entering for mft_no 0x%llx, logical block 0x%llx.",
100 			ni->mft_no, (unsigned long long)block);
101 	if (ni->type != AT_DATA || !NInoNonResident(ni) || NInoEncrypted(ni) ||
102 	    NInoMstProtected(ni)) {
103 		ntfs_error(vol->sb, "BMAP does not make sense for %s attributes, returning 0.",
104 				(ni->type != AT_DATA) ? "non-data" :
105 				(!NInoNonResident(ni) ? "resident" :
106 				"encrypted"));
107 		return 0;
108 	}
109 	/* None of these can happen. */
110 	blocksize = vol->sb->s_blocksize;
111 	blocksize_bits = vol->sb->s_blocksize_bits;
112 	ofs = (s64)block << blocksize_bits;
113 	read_lock_irqsave(&ni->size_lock, flags);
114 	size = ni->initialized_size;
115 	i_size = i_size_read(VFS_I(ni));
116 	read_unlock_irqrestore(&ni->size_lock, flags);
117 	/*
118 	 * If the offset is outside the initialized size or the block straddles
119 	 * the initialized size then pretend it is a hole unless the
120 	 * initialized size equals the file size.
121 	 */
122 	if (unlikely(ofs >= size || (ofs + blocksize > size && size < i_size)))
123 		goto hole;
124 	down_read(&ni->runlist.lock);
125 	lcn = ntfs_attr_vcn_to_lcn_nolock(ni, ntfs_bytes_to_cluster(vol, ofs),
126 			false);
127 	up_read(&ni->runlist.lock);
128 	if (unlikely(lcn < LCN_HOLE)) {
129 		/*
130 		 * Step down to an integer to avoid gcc doing a long long
131 		 * comparision in the switch when we know @lcn is between
132 		 * LCN_HOLE and LCN_EIO (i.e. -1 to -5).
133 		 *
134 		 * Otherwise older gcc (at least on some architectures) will
135 		 * try to use __cmpdi2() which is of course not available in
136 		 * the kernel.
137 		 */
138 		switch ((int)lcn) {
139 		case LCN_ENOENT:
140 			/*
141 			 * If the offset is out of bounds then pretend it is a
142 			 * hole.
143 			 */
144 			goto hole;
145 		case LCN_ENOMEM:
146 			ntfs_error(vol->sb,
147 				"Not enough memory to complete mapping for inode 0x%llx. Returning 0.",
148 				ni->mft_no);
149 			break;
150 		default:
151 			ntfs_error(vol->sb,
152 				"Failed to complete mapping for inode 0x%llx.  Run chkdsk. Returning 0.",
153 				ni->mft_no);
154 			break;
155 		}
156 		return 0;
157 	}
158 	if (lcn < 0) {
159 		/* It is a hole. */
160 hole:
161 		ntfs_debug("Done (returning hole).");
162 		return 0;
163 	}
164 	/*
165 	 * The block is really allocated and fullfils all our criteria.
166 	 * Convert the cluster to units of block size and return the result.
167 	 */
168 	delta = ofs & vol->cluster_size_mask;
169 	if (unlikely(sizeof(block) < sizeof(lcn))) {
170 		block = lcn = (ntfs_cluster_to_bytes(vol, lcn) + delta) >>
171 				blocksize_bits;
172 		/* If the block number was truncated return 0. */
173 		if (unlikely(block != lcn)) {
174 			ntfs_error(vol->sb,
175 				"Physical block 0x%llx is too large to be returned, returning 0.",
176 				(long long)lcn);
177 			return 0;
178 		}
179 	} else
180 		block = (ntfs_cluster_to_bytes(vol, lcn) + delta) >>
181 				blocksize_bits;
182 	ntfs_debug("Done (returning block 0x%llx).", (unsigned long long)lcn);
183 	return block;
184 }
185 
186 static void ntfs_readahead(struct readahead_control *rac)
187 {
188 	struct address_space *mapping = rac->mapping;
189 	struct inode *inode = mapping->host;
190 	struct ntfs_inode *ni = NTFS_I(inode);
191 
192 	/*
193 	 * Resident files are not cached in the page cache,
194 	 * and readahead is not implemented for compressed files.
195 	 */
196 	if (!NInoNonResident(ni) || NInoCompressed(ni))
197 		return;
198 	iomap_bio_readahead(rac, &ntfs_read_iomap_ops);
199 }
200 
201 static int ntfs_writepages(struct address_space *mapping,
202 		struct writeback_control *wbc)
203 {
204 	struct inode *inode = mapping->host;
205 	struct ntfs_inode *ni = NTFS_I(inode);
206 	struct iomap_writepage_ctx wpc = {
207 		.inode		= mapping->host,
208 		.wbc		= wbc,
209 		.ops		= &ntfs_writeback_ops,
210 	};
211 
212 	if (NVolShutdown(ni->vol))
213 		return -EIO;
214 
215 	if (!NInoNonResident(ni))
216 		return 0;
217 
218 	/*
219 	 * EFS-encrypted files are not supported.
220 	 * (decryption/encryption is not implemented yet)
221 	 */
222 	if (NInoEncrypted(ni)) {
223 		ntfs_debug("Encrypted I/O not supported");
224 		return -EOPNOTSUPP;
225 	}
226 
227 	return iomap_writepages(&wpc);
228 }
229 
230 static int ntfs_swap_activate(struct swap_info_struct *sis,
231 		struct file *swap_file, sector_t *span)
232 {
233 	return iomap_swapfile_activate(sis, swap_file, span,
234 			&ntfs_read_iomap_ops);
235 }
236 
237 const struct address_space_operations ntfs_aops = {
238 	.read_folio		= ntfs_read_folio,
239 	.readahead		= ntfs_readahead,
240 	.writepages		= ntfs_writepages,
241 	.direct_IO		= noop_direct_IO,
242 	.dirty_folio		= iomap_dirty_folio,
243 	.bmap			= ntfs_bmap,
244 	.migrate_folio		= filemap_migrate_folio,
245 	.is_partially_uptodate	= iomap_is_partially_uptodate,
246 	.error_remove_folio	= generic_error_remove_folio,
247 	.release_folio		= iomap_release_folio,
248 	.invalidate_folio	= iomap_invalidate_folio,
249 	.swap_activate          = ntfs_swap_activate,
250 };
251 
252 const struct address_space_operations ntfs_mft_aops = {
253 	.read_folio		= ntfs_read_folio,
254 	.readahead		= ntfs_readahead,
255 	.writepages		= ntfs_mft_writepages,
256 	.dirty_folio		= iomap_dirty_folio,
257 	.bmap			= ntfs_bmap,
258 	.migrate_folio		= filemap_migrate_folio,
259 	.is_partially_uptodate	= iomap_is_partially_uptodate,
260 	.error_remove_folio	= generic_error_remove_folio,
261 	.release_folio		= iomap_release_folio,
262 	.invalidate_folio	= iomap_invalidate_folio,
263 };
264