11e9ea7e0SNamjae Jeon // SPDX-License-Identifier: GPL-2.0-or-later 21e9ea7e0SNamjae Jeon /* 3b041ca56SNamjae Jeon * NTFS kernel address space operations and page cache handling. 41e9ea7e0SNamjae Jeon * 51e9ea7e0SNamjae Jeon * Copyright (c) 2001-2014 Anton Altaparmakov and Tuxera Inc. 61e9ea7e0SNamjae Jeon * Copyright (c) 2002 Richard Russon 7b041ca56SNamjae Jeon * Copyright (c) 2025 LG Electronics Co., Ltd. 81e9ea7e0SNamjae Jeon */ 91e9ea7e0SNamjae Jeon 101e9ea7e0SNamjae Jeon #include <linux/writeback.h> 111e9ea7e0SNamjae Jeon 121e9ea7e0SNamjae Jeon #include "attrib.h" 131e9ea7e0SNamjae Jeon #include "mft.h" 141e9ea7e0SNamjae Jeon #include "ntfs.h" 15b041ca56SNamjae Jeon #include "debug.h" 16b041ca56SNamjae Jeon #include "iomap.h" 171e9ea7e0SNamjae Jeon 181e9ea7e0SNamjae Jeon /* 19b041ca56SNamjae Jeon * ntfs_read_folio - Read data for a folio from the device 201e9ea7e0SNamjae Jeon * @file: open file to which the folio @folio belongs or NULL 211e9ea7e0SNamjae Jeon * @folio: page cache folio to fill with data 221e9ea7e0SNamjae Jeon * 23b041ca56SNamjae Jeon * This function handles reading data into the page cache. It first checks 24b041ca56SNamjae Jeon * for specific ntfs attribute type like encryption and compression. 251e9ea7e0SNamjae Jeon * 26b041ca56SNamjae Jeon * - If the attribute is encrypted, access is denied (-EACCES) because 27b041ca56SNamjae Jeon * decryption is not supported in this path. 28b041ca56SNamjae Jeon * - If the attribute is non-resident and compressed, the read operation is 29b041ca56SNamjae Jeon * delegated to ntfs_read_compressed_block(). 30b041ca56SNamjae Jeon * - For normal resident or non-resident attribute, it utilizes the generic 31b041ca56SNamjae Jeon * iomap infrastructure via iomap_bio_read_folio() to perform the I/O. 321e9ea7e0SNamjae Jeon * 33b041ca56SNamjae Jeon * Return: 0 on success, or -errno on error. 341e9ea7e0SNamjae Jeon */ 351e9ea7e0SNamjae Jeon static int ntfs_read_folio(struct file *file, struct folio *folio) 361e9ea7e0SNamjae Jeon { 37b041ca56SNamjae Jeon struct ntfs_inode *ni = NTFS_I(folio->mapping->host); 381e9ea7e0SNamjae Jeon 391e9ea7e0SNamjae Jeon /* 401e9ea7e0SNamjae Jeon * Only $DATA attributes can be encrypted and only unnamed $DATA 411e9ea7e0SNamjae Jeon * attributes can be compressed. Index root can have the flags set but 421e9ea7e0SNamjae Jeon * this means to create compressed/encrypted files, not that the 431e9ea7e0SNamjae Jeon * attribute is compressed/encrypted. Note we need to check for 441e9ea7e0SNamjae Jeon * AT_INDEX_ALLOCATION since this is the type of both directory and 451e9ea7e0SNamjae Jeon * index inodes. 461e9ea7e0SNamjae Jeon */ 471e9ea7e0SNamjae Jeon if (ni->type != AT_INDEX_ALLOCATION) { 481e9ea7e0SNamjae Jeon /* 49b041ca56SNamjae Jeon * EFS-encrypted files are not supported. 50b041ca56SNamjae Jeon * (decryption/encryption is not implemented yet) 511e9ea7e0SNamjae Jeon */ 521e9ea7e0SNamjae Jeon if (NInoEncrypted(ni)) { 531e9ea7e0SNamjae Jeon folio_unlock(folio); 54b041ca56SNamjae Jeon return -EOPNOTSUPP; 551e9ea7e0SNamjae Jeon } 561e9ea7e0SNamjae Jeon /* Compressed data streams are handled in compress.c. */ 57b041ca56SNamjae Jeon if (NInoNonResident(ni) && NInoCompressed(ni)) 58b041ca56SNamjae Jeon return ntfs_read_compressed_block(folio); 591e9ea7e0SNamjae Jeon } 60b041ca56SNamjae Jeon 61b041ca56SNamjae Jeon iomap_bio_read_folio(folio, &ntfs_read_iomap_ops); 621e9ea7e0SNamjae Jeon return 0; 63b041ca56SNamjae Jeon } 64b041ca56SNamjae Jeon 651e9ea7e0SNamjae Jeon /* 661e9ea7e0SNamjae Jeon * ntfs_bmap - map logical file block to physical device block 671e9ea7e0SNamjae Jeon * @mapping: address space mapping to which the block to be mapped belongs 681e9ea7e0SNamjae Jeon * @block: logical block to map to its physical device block 691e9ea7e0SNamjae Jeon * 701e9ea7e0SNamjae Jeon * For regular, non-resident files (i.e. not compressed and not encrypted), map 711e9ea7e0SNamjae Jeon * the logical @block belonging to the file described by the address space 721e9ea7e0SNamjae Jeon * mapping @mapping to its physical device block. 731e9ea7e0SNamjae Jeon * 741e9ea7e0SNamjae Jeon * The size of the block is equal to the @s_blocksize field of the super block 751e9ea7e0SNamjae Jeon * of the mounted file system which is guaranteed to be smaller than or equal 761e9ea7e0SNamjae Jeon * to the cluster size thus the block is guaranteed to fit entirely inside the 771e9ea7e0SNamjae Jeon * cluster which means we do not need to care how many contiguous bytes are 781e9ea7e0SNamjae Jeon * available after the beginning of the block. 791e9ea7e0SNamjae Jeon * 801e9ea7e0SNamjae Jeon * Return the physical device block if the mapping succeeded or 0 if the block 811e9ea7e0SNamjae Jeon * is sparse or there was an error. 821e9ea7e0SNamjae Jeon * 831e9ea7e0SNamjae Jeon * Note: This is a problem if someone tries to run bmap() on $Boot system file 841e9ea7e0SNamjae Jeon * as that really is in block zero but there is nothing we can do. bmap() is 851e9ea7e0SNamjae Jeon * just broken in that respect (just like it cannot distinguish sparse from 861e9ea7e0SNamjae Jeon * not available or error). 871e9ea7e0SNamjae Jeon */ 881e9ea7e0SNamjae Jeon static sector_t ntfs_bmap(struct address_space *mapping, sector_t block) 891e9ea7e0SNamjae Jeon { 901e9ea7e0SNamjae Jeon s64 ofs, size; 911e9ea7e0SNamjae Jeon loff_t i_size; 92b041ca56SNamjae Jeon s64 lcn; 931e9ea7e0SNamjae Jeon unsigned long blocksize, flags; 94b041ca56SNamjae Jeon struct ntfs_inode *ni = NTFS_I(mapping->host); 95b041ca56SNamjae Jeon struct ntfs_volume *vol = ni->vol; 96b041ca56SNamjae Jeon unsigned int delta; 97b041ca56SNamjae Jeon unsigned char blocksize_bits; 981e9ea7e0SNamjae Jeon 99*d9038d99SNamjae Jeon ntfs_debug("Entering for mft_no 0x%llx, logical block 0x%llx.", 1001e9ea7e0SNamjae Jeon ni->mft_no, (unsigned long long)block); 101b041ca56SNamjae Jeon if (ni->type != AT_DATA || !NInoNonResident(ni) || NInoEncrypted(ni) || 102b041ca56SNamjae Jeon NInoMstProtected(ni)) { 103b041ca56SNamjae Jeon ntfs_error(vol->sb, "BMAP does not make sense for %s attributes, returning 0.", 1041e9ea7e0SNamjae Jeon (ni->type != AT_DATA) ? "non-data" : 1051e9ea7e0SNamjae Jeon (!NInoNonResident(ni) ? "resident" : 1061e9ea7e0SNamjae Jeon "encrypted")); 1071e9ea7e0SNamjae Jeon return 0; 1081e9ea7e0SNamjae Jeon } 1091e9ea7e0SNamjae Jeon /* None of these can happen. */ 1101e9ea7e0SNamjae Jeon blocksize = vol->sb->s_blocksize; 1111e9ea7e0SNamjae Jeon blocksize_bits = vol->sb->s_blocksize_bits; 1121e9ea7e0SNamjae Jeon ofs = (s64)block << blocksize_bits; 1131e9ea7e0SNamjae Jeon read_lock_irqsave(&ni->size_lock, flags); 1141e9ea7e0SNamjae Jeon size = ni->initialized_size; 1151e9ea7e0SNamjae Jeon i_size = i_size_read(VFS_I(ni)); 1161e9ea7e0SNamjae Jeon read_unlock_irqrestore(&ni->size_lock, flags); 1171e9ea7e0SNamjae Jeon /* 1181e9ea7e0SNamjae Jeon * If the offset is outside the initialized size or the block straddles 1191e9ea7e0SNamjae Jeon * the initialized size then pretend it is a hole unless the 1201e9ea7e0SNamjae Jeon * initialized size equals the file size. 1211e9ea7e0SNamjae Jeon */ 1221e9ea7e0SNamjae Jeon if (unlikely(ofs >= size || (ofs + blocksize > size && size < i_size))) 1231e9ea7e0SNamjae Jeon goto hole; 1241e9ea7e0SNamjae Jeon down_read(&ni->runlist.lock); 125b041ca56SNamjae Jeon lcn = ntfs_attr_vcn_to_lcn_nolock(ni, ntfs_bytes_to_cluster(vol, ofs), 126b041ca56SNamjae Jeon false); 1271e9ea7e0SNamjae Jeon up_read(&ni->runlist.lock); 1281e9ea7e0SNamjae Jeon if (unlikely(lcn < LCN_HOLE)) { 1291e9ea7e0SNamjae Jeon /* 1301e9ea7e0SNamjae Jeon * Step down to an integer to avoid gcc doing a long long 1311e9ea7e0SNamjae Jeon * comparision in the switch when we know @lcn is between 1321e9ea7e0SNamjae Jeon * LCN_HOLE and LCN_EIO (i.e. -1 to -5). 1331e9ea7e0SNamjae Jeon * 1341e9ea7e0SNamjae Jeon * Otherwise older gcc (at least on some architectures) will 1351e9ea7e0SNamjae Jeon * try to use __cmpdi2() which is of course not available in 1361e9ea7e0SNamjae Jeon * the kernel. 1371e9ea7e0SNamjae Jeon */ 1381e9ea7e0SNamjae Jeon switch ((int)lcn) { 1391e9ea7e0SNamjae Jeon case LCN_ENOENT: 1401e9ea7e0SNamjae Jeon /* 1411e9ea7e0SNamjae Jeon * If the offset is out of bounds then pretend it is a 1421e9ea7e0SNamjae Jeon * hole. 1431e9ea7e0SNamjae Jeon */ 1441e9ea7e0SNamjae Jeon goto hole; 1451e9ea7e0SNamjae Jeon case LCN_ENOMEM: 146b041ca56SNamjae Jeon ntfs_error(vol->sb, 147*d9038d99SNamjae Jeon "Not enough memory to complete mapping for inode 0x%llx. Returning 0.", 148b041ca56SNamjae Jeon ni->mft_no); 1491e9ea7e0SNamjae Jeon break; 1501e9ea7e0SNamjae Jeon default: 151b041ca56SNamjae Jeon ntfs_error(vol->sb, 152*d9038d99SNamjae Jeon "Failed to complete mapping for inode 0x%llx. Run chkdsk. Returning 0.", 153b041ca56SNamjae Jeon ni->mft_no); 1541e9ea7e0SNamjae Jeon break; 1551e9ea7e0SNamjae Jeon } 1561e9ea7e0SNamjae Jeon return 0; 1571e9ea7e0SNamjae Jeon } 1581e9ea7e0SNamjae Jeon if (lcn < 0) { 1591e9ea7e0SNamjae Jeon /* It is a hole. */ 1601e9ea7e0SNamjae Jeon hole: 1611e9ea7e0SNamjae Jeon ntfs_debug("Done (returning hole)."); 1621e9ea7e0SNamjae Jeon return 0; 1631e9ea7e0SNamjae Jeon } 1641e9ea7e0SNamjae Jeon /* 1651e9ea7e0SNamjae Jeon * The block is really allocated and fullfils all our criteria. 1661e9ea7e0SNamjae Jeon * Convert the cluster to units of block size and return the result. 1671e9ea7e0SNamjae Jeon */ 1681e9ea7e0SNamjae Jeon delta = ofs & vol->cluster_size_mask; 1691e9ea7e0SNamjae Jeon if (unlikely(sizeof(block) < sizeof(lcn))) { 170b041ca56SNamjae Jeon block = lcn = (ntfs_cluster_to_bytes(vol, lcn) + delta) >> 1711e9ea7e0SNamjae Jeon blocksize_bits; 1721e9ea7e0SNamjae Jeon /* If the block number was truncated return 0. */ 1731e9ea7e0SNamjae Jeon if (unlikely(block != lcn)) { 174b041ca56SNamjae Jeon ntfs_error(vol->sb, 175b041ca56SNamjae Jeon "Physical block 0x%llx is too large to be returned, returning 0.", 1761e9ea7e0SNamjae Jeon (long long)lcn); 1771e9ea7e0SNamjae Jeon return 0; 1781e9ea7e0SNamjae Jeon } 1791e9ea7e0SNamjae Jeon } else 180b041ca56SNamjae Jeon block = (ntfs_cluster_to_bytes(vol, lcn) + delta) >> 1811e9ea7e0SNamjae Jeon blocksize_bits; 1821e9ea7e0SNamjae Jeon ntfs_debug("Done (returning block 0x%llx).", (unsigned long long)lcn); 1831e9ea7e0SNamjae Jeon return block; 1841e9ea7e0SNamjae Jeon } 1851e9ea7e0SNamjae Jeon 186b041ca56SNamjae Jeon static void ntfs_readahead(struct readahead_control *rac) 187b041ca56SNamjae Jeon { 188b041ca56SNamjae Jeon struct address_space *mapping = rac->mapping; 189b041ca56SNamjae Jeon struct inode *inode = mapping->host; 190b041ca56SNamjae Jeon struct ntfs_inode *ni = NTFS_I(inode); 191b041ca56SNamjae Jeon 1921e9ea7e0SNamjae Jeon /* 193b041ca56SNamjae Jeon * Resident files are not cached in the page cache, 194b041ca56SNamjae Jeon * and readahead is not implemented for compressed files. 1951e9ea7e0SNamjae Jeon */ 196b041ca56SNamjae Jeon if (!NInoNonResident(ni) || NInoCompressed(ni)) 197b041ca56SNamjae Jeon return; 198b041ca56SNamjae Jeon iomap_bio_readahead(rac, &ntfs_read_iomap_ops); 199b041ca56SNamjae Jeon } 200b041ca56SNamjae Jeon 201b041ca56SNamjae Jeon static int ntfs_writepages(struct address_space *mapping, 202b041ca56SNamjae Jeon struct writeback_control *wbc) 203b041ca56SNamjae Jeon { 204b041ca56SNamjae Jeon struct inode *inode = mapping->host; 205b041ca56SNamjae Jeon struct ntfs_inode *ni = NTFS_I(inode); 206b041ca56SNamjae Jeon struct iomap_writepage_ctx wpc = { 207b041ca56SNamjae Jeon .inode = mapping->host, 208b041ca56SNamjae Jeon .wbc = wbc, 209b041ca56SNamjae Jeon .ops = &ntfs_writeback_ops, 210b041ca56SNamjae Jeon }; 211b041ca56SNamjae Jeon 212b041ca56SNamjae Jeon if (NVolShutdown(ni->vol)) 213b041ca56SNamjae Jeon return -EIO; 214b041ca56SNamjae Jeon 215b041ca56SNamjae Jeon if (!NInoNonResident(ni)) 216b041ca56SNamjae Jeon return 0; 217b041ca56SNamjae Jeon 218b041ca56SNamjae Jeon /* 219b041ca56SNamjae Jeon * EFS-encrypted files are not supported. 220b041ca56SNamjae Jeon * (decryption/encryption is not implemented yet) 221b041ca56SNamjae Jeon */ 222b041ca56SNamjae Jeon if (NInoEncrypted(ni)) { 223b041ca56SNamjae Jeon ntfs_debug("Encrypted I/O not supported"); 224b041ca56SNamjae Jeon return -EOPNOTSUPP; 225b041ca56SNamjae Jeon } 226b041ca56SNamjae Jeon 227b041ca56SNamjae Jeon return iomap_writepages(&wpc); 228b041ca56SNamjae Jeon } 229b041ca56SNamjae Jeon 230b041ca56SNamjae Jeon static int ntfs_swap_activate(struct swap_info_struct *sis, 231b041ca56SNamjae Jeon struct file *swap_file, sector_t *span) 232b041ca56SNamjae Jeon { 233b041ca56SNamjae Jeon return iomap_swapfile_activate(sis, swap_file, span, 234b041ca56SNamjae Jeon &ntfs_read_iomap_ops); 235b041ca56SNamjae Jeon } 236b041ca56SNamjae Jeon 237b041ca56SNamjae Jeon const struct address_space_operations ntfs_aops = { 2381e9ea7e0SNamjae Jeon .read_folio = ntfs_read_folio, 239b041ca56SNamjae Jeon .readahead = ntfs_readahead, 240b041ca56SNamjae Jeon .writepages = ntfs_writepages, 241b041ca56SNamjae Jeon .direct_IO = noop_direct_IO, 242b041ca56SNamjae Jeon .dirty_folio = iomap_dirty_folio, 2431e9ea7e0SNamjae Jeon .bmap = ntfs_bmap, 244b041ca56SNamjae Jeon .migrate_folio = filemap_migrate_folio, 245b041ca56SNamjae Jeon .is_partially_uptodate = iomap_is_partially_uptodate, 2461e9ea7e0SNamjae Jeon .error_remove_folio = generic_error_remove_folio, 247b041ca56SNamjae Jeon .release_folio = iomap_release_folio, 248b041ca56SNamjae Jeon .invalidate_folio = iomap_invalidate_folio, 249b041ca56SNamjae Jeon .swap_activate = ntfs_swap_activate, 2501e9ea7e0SNamjae Jeon }; 2511e9ea7e0SNamjae Jeon 252b041ca56SNamjae Jeon const struct address_space_operations ntfs_mft_aops = { 2531e9ea7e0SNamjae Jeon .read_folio = ntfs_read_folio, 254b041ca56SNamjae Jeon .readahead = ntfs_readahead, 255b041ca56SNamjae Jeon .writepages = ntfs_mft_writepages, 256b041ca56SNamjae Jeon .dirty_folio = iomap_dirty_folio, 257b041ca56SNamjae Jeon .bmap = ntfs_bmap, 258b041ca56SNamjae Jeon .migrate_folio = filemap_migrate_folio, 259b041ca56SNamjae Jeon .is_partially_uptodate = iomap_is_partially_uptodate, 2601e9ea7e0SNamjae Jeon .error_remove_folio = generic_error_remove_folio, 261b041ca56SNamjae Jeon .release_folio = iomap_release_folio, 262b041ca56SNamjae Jeon .invalidate_folio = iomap_invalidate_folio, 2631e9ea7e0SNamjae Jeon }; 264