1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * Defines for volume structures in NTFS Linux kernel driver. 4 * 5 * Copyright (c) 2001-2006 Anton Altaparmakov 6 * Copyright (c) 2002 Richard Russon 7 * Copyright (c) 2025 LG Electronics Co., Ltd. 8 */ 9 10 #ifndef _LINUX_NTFS_VOLUME_H 11 #define _LINUX_NTFS_VOLUME_H 12 13 #include <linux/rwsem.h> 14 #include <linux/sched.h> 15 #include <linux/wait.h> 16 #include <linux/uidgid.h> 17 #include <linux/workqueue.h> 18 #include <linux/errseq.h> 19 20 #include "layout.h" 21 22 #define NTFS_VOL_UID BIT(1) 23 #define NTFS_VOL_GID BIT(2) 24 25 /* 26 * The NTFS in memory super block structure. 27 * 28 * @sb: Pointer back to the super_block. 29 * @nr_blocks: Number of sb->s_blocksize bytes sized blocks on the device. 30 * @flags: Miscellaneous flags, see below. 31 * @uid: uid that files will be mounted as. 32 * @gid: gid that files will be mounted as. 33 * @fmask: The mask for file permissions. 34 * @dmask: The mask for directory permissions. 35 * @mft_zone_multiplier: Initial mft zone multiplier. 36 * @on_errors: What to do on filesystem errors. 37 * @wb_err: Writeback error tracking. 38 * @sector_size: in bytes 39 * @sector_size_bits: log2(sector_size) 40 * @cluster_size: in bytes 41 * @cluster_size_mask: cluster_size - 1 42 * @cluster_size_bits: log2(cluster_size) 43 * @mft_record_size: in bytes 44 * @mft_record_size_mask: mft_record_size - 1 45 * @mft_record_size_bits: log2(mft_record_size) 46 * @index_record_size: in bytes 47 * @index_record_size_mask: index_record_size - 1 48 * @index_record_size_bits: log2(index_record_size) 49 * @nr_clusters: Volume size in clusters == number of bits in lcn bitmap. 50 * @mft_lcn: Cluster location of mft data. 51 * @mftmirr_lcn: Cluster location of copy of mft. 52 * @serial_no: The volume serial number. 53 * @upcase_len: Number of entries in upcase[]. 54 * @upcase: The upcase table. 55 * @attrdef_size: Size of the attribute definition table in bytes. 56 * @attrdef: Table of attribute definitions. Obtained from FILE_AttrDef. 57 * @mft_data_pos: Mft record number at which to allocate the next mft record. 58 * @mft_record_reserve_pos: First record in the in-memory MFT metadata reserve 59 * (protected by mftbmp_lock). 60 * @mft_record_reserve_end: First record beyond the MFT metadata reserve 61 * (protected by mftbmp_lock). 62 * @mft_zone_start: First cluster of the mft zone. 63 * @mft_zone_end: First cluster beyond the mft zone. 64 * @mft_zone_pos: Current position in the mft zone. 65 * @data1_zone_pos: Current position in the first data zone. 66 * @data2_zone_pos: Current position in the second data zone. 67 * @mft_ino: The VFS inode of $MFT. 68 * @mftbmp_ino: Attribute inode for $MFT/$BITMAP. 69 * @mftbmp_lock: Lock for serializing accesses to the mft record bitmap. 70 * @mftmirr_ino: The VFS inode of $MFTMirr. 71 * @mftmirr_size: Size of mft mirror in mft records. 72 * @logfile_ino: The VFS inode of LogFile. 73 * @lcnbmp_ino: The VFS inode of $Bitmap. 74 * @lcnbmp_lock: Lock for serializing accesses to the cluster bitmap 75 * @vol_ino: The VFS inode of $Volume. 76 * @vol_flags: Volume flags. 77 * @major_ver: Ntfs major version of volume. 78 * @minor_ver: Ntfs minor version of volume. 79 * @volume_label_lock: protects @volume_label. 80 * @volume_label: volume label. 81 * @root_ino: The VFS inode of the root directory. 82 * @secure_ino: The VFS inode of $Secure (NTFS3.0+ only, otherwise NULL). 83 * @extend_ino: The VFS inode of $Extend (NTFS3.0+ only, otherwise NULL). 84 * @nls_map: NLS (National Language Support) table. 85 * @nls_utf8: NLS table for UTF-8. 86 * @free_waitq: Wait queue for threads waiting for free clusters or MFT records. 87 * @free_clusters: Track the number of free clusters. 88 * @free_mft_records: Track the free mft records. 89 * @dirty_clusters: Number of clusters that are dirty. 90 * @sparse_compression_unit: Size of compression/sparse unit in clusters. 91 * @lcn_empty_bits_per_page: Number of empty bits per page in the LCN bitmap. 92 * @precalc_work: Work structure for background pre-calculation tasks. 93 * @preallocated_size: reallocation size (in bytes). 94 */ 95 struct ntfs_volume { 96 struct super_block *sb; 97 s64 nr_blocks; 98 unsigned long flags; 99 kuid_t uid; 100 kgid_t gid; 101 umode_t fmask; 102 umode_t dmask; 103 u8 mft_zone_multiplier; 104 u8 on_errors; 105 errseq_t wb_err; 106 u16 sector_size; 107 u8 sector_size_bits; 108 u32 cluster_size; 109 u32 cluster_size_mask; 110 u8 cluster_size_bits; 111 u32 mft_record_size; 112 u32 mft_record_size_mask; 113 u8 mft_record_size_bits; 114 u32 index_record_size; 115 u32 index_record_size_mask; 116 u8 index_record_size_bits; 117 s64 nr_clusters; 118 s64 mft_lcn; 119 s64 mftmirr_lcn; 120 u64 serial_no; 121 u32 upcase_len; 122 __le16 *upcase; 123 s32 attrdef_size; 124 struct attr_def *attrdef; 125 s64 mft_data_pos; 126 s64 mft_record_reserve_pos; 127 s64 mft_record_reserve_end; 128 s64 mft_zone_start; 129 s64 mft_zone_end; 130 s64 mft_zone_pos; 131 s64 data1_zone_pos; 132 s64 data2_zone_pos; 133 struct inode *mft_ino; 134 struct inode *mftbmp_ino; 135 struct rw_semaphore mftbmp_lock; 136 struct inode *mftmirr_ino; 137 int mftmirr_size; 138 struct inode *logfile_ino; 139 struct inode *lcnbmp_ino; 140 struct rw_semaphore lcnbmp_lock; 141 struct mutex volume_label_lock; 142 struct inode *vol_ino; 143 __le16 vol_flags; 144 u8 major_ver; 145 u8 minor_ver; 146 unsigned char *volume_label; 147 struct inode *root_ino; 148 struct inode *secure_ino; 149 struct inode *extend_ino; 150 struct nls_table *nls_map; 151 bool nls_utf8; 152 wait_queue_head_t free_waitq; 153 atomic64_t free_clusters; 154 atomic64_t free_mft_records; 155 atomic64_t dirty_clusters; 156 u8 sparse_compression_unit; 157 unsigned int *lcn_empty_bits_per_page; 158 struct work_struct precalc_work; 159 loff_t preallocated_size; 160 }; 161 162 /* 163 * Defined bits for the flags field in the ntfs_volume structure. 164 * 165 * NV_Errors Volume has errors, prevent remount rw. 166 * NV_ShowSystemFiles Return system files in ntfs_readdir(). 167 * NV_CaseSensitive Treat file names as case sensitive and 168 * create filenames in the POSIX namespace. 169 * Otherwise be case insensitive but still 170 * create file names in POSIX namespace. 171 * NV_LogFileEmpty LogFile journal is empty. 172 * NV_UsnJrnlStamped UsnJrnl has been stamped. 173 * NV_ReadOnly Volume is mounted read-only. 174 * NV_Compression Volume supports compression. 175 * NV_FreeClusterKnown Free cluster count is known and up-to-date. 176 * NV_Shutdown Volume is in shutdown state 177 * NV_SysImmutable Protect system files from deletion. 178 * NV_ShowHiddenFiles Return hidden files in ntfs_readdir(). 179 * NV_HideDotFiles Hide names beginning with a dot ("."). 180 * NV_CheckWindowsNames Refuse creation/rename of files with 181 * Windows-reserved names (CON, AUX, NUL, COM1, 182 * LPT1, etc.) or invalid characters. 183 * 184 * NV_Discard Issue discard/TRIM commands for freed clusters. 185 * NV_DisableSparse Disable creation of sparse regions. 186 * NV_NativeSymlinkRel Translate absolute Windows reparse targets (native_symlink=rel). 187 */ 188 enum { 189 NV_Errors, 190 NV_ShowSystemFiles, 191 NV_CaseSensitive, 192 NV_LogFileEmpty, 193 NV_UsnJrnlStamped, 194 NV_ReadOnly, 195 NV_Compression, 196 NV_FreeClusterKnown, 197 NV_Shutdown, 198 NV_SysImmutable, 199 NV_ShowHiddenFiles, 200 NV_HideDotFiles, 201 NV_CheckWindowsNames, 202 NV_Discard, 203 NV_DisableSparse, 204 NV_NativeSymlinkRel, 205 NV_SymlinkNative, 206 }; 207 208 /* 209 * Macro tricks to expand the NVolFoo(), NVolSetFoo(), and NVolClearFoo() 210 * functions. 211 */ 212 #define DEFINE_NVOL_BIT_OPS(flag) \ 213 static inline int NVol##flag(struct ntfs_volume *vol) \ 214 { \ 215 return test_bit(NV_##flag, &(vol)->flags); \ 216 } \ 217 static inline void NVolSet##flag(struct ntfs_volume *vol) \ 218 { \ 219 set_bit(NV_##flag, &(vol)->flags); \ 220 } \ 221 static inline void NVolClear##flag(struct ntfs_volume *vol) \ 222 { \ 223 clear_bit(NV_##flag, &(vol)->flags); \ 224 } 225 226 /* Emit the ntfs volume bitops functions. */ 227 DEFINE_NVOL_BIT_OPS(Errors) 228 DEFINE_NVOL_BIT_OPS(ShowSystemFiles) 229 DEFINE_NVOL_BIT_OPS(CaseSensitive) 230 DEFINE_NVOL_BIT_OPS(LogFileEmpty) 231 DEFINE_NVOL_BIT_OPS(UsnJrnlStamped) 232 DEFINE_NVOL_BIT_OPS(ReadOnly) 233 DEFINE_NVOL_BIT_OPS(Compression) 234 DEFINE_NVOL_BIT_OPS(FreeClusterKnown) 235 DEFINE_NVOL_BIT_OPS(Shutdown) 236 DEFINE_NVOL_BIT_OPS(SysImmutable) 237 DEFINE_NVOL_BIT_OPS(ShowHiddenFiles) 238 DEFINE_NVOL_BIT_OPS(HideDotFiles) 239 DEFINE_NVOL_BIT_OPS(CheckWindowsNames) 240 DEFINE_NVOL_BIT_OPS(Discard) 241 DEFINE_NVOL_BIT_OPS(DisableSparse) 242 DEFINE_NVOL_BIT_OPS(NativeSymlinkRel) 243 DEFINE_NVOL_BIT_OPS(SymlinkNative) 244 245 static inline void ntfs_inc_free_clusters(struct ntfs_volume *vol, s64 nr) 246 { 247 if (!NVolFreeClusterKnown(vol)) 248 wait_event(vol->free_waitq, NVolFreeClusterKnown(vol)); 249 atomic64_add(nr, &vol->free_clusters); 250 } 251 252 static inline void ntfs_dec_free_clusters(struct ntfs_volume *vol, s64 nr) 253 { 254 if (!NVolFreeClusterKnown(vol)) 255 wait_event(vol->free_waitq, NVolFreeClusterKnown(vol)); 256 atomic64_sub(nr, &vol->free_clusters); 257 } 258 259 static inline void ntfs_inc_free_mft_records(struct ntfs_volume *vol, s64 nr) 260 { 261 atomic64_add(nr, &vol->free_mft_records); 262 } 263 264 static inline void ntfs_dec_free_mft_records(struct ntfs_volume *vol, s64 nr) 265 { 266 atomic64_sub(nr, &vol->free_mft_records); 267 } 268 269 static inline void ntfs_set_lcn_empty_bits(struct ntfs_volume *vol, unsigned long index, 270 u8 val, unsigned int count) 271 { 272 if (!NVolFreeClusterKnown(vol)) 273 wait_event(vol->free_waitq, NVolFreeClusterKnown(vol)); 274 275 if (val) 276 vol->lcn_empty_bits_per_page[index] -= count; 277 else 278 vol->lcn_empty_bits_per_page[index] += count; 279 } 280 281 static __always_inline void ntfs_hold_dirty_clusters(struct ntfs_volume *vol, s64 nr_clusters) 282 { 283 atomic64_add(nr_clusters, &vol->dirty_clusters); 284 } 285 286 static __always_inline void ntfs_release_dirty_clusters(struct ntfs_volume *vol, s64 nr_clusters) 287 { 288 if (atomic64_read(&vol->dirty_clusters) < nr_clusters) 289 atomic64_set(&vol->dirty_clusters, 0); 290 else 291 atomic64_sub(nr_clusters, &vol->dirty_clusters); 292 } 293 294 s64 ntfs_available_clusters_count(struct ntfs_volume *vol, s64 nr_clusters); 295 s64 get_nr_free_clusters(struct ntfs_volume *vol); 296 #endif /* _LINUX_NTFS_VOLUME_H */ 297