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_zone_start: First cluster of the mft zone. 59 * @mft_zone_end: First cluster beyond the mft zone. 60 * @mft_zone_pos: Current position in the mft zone. 61 * @data1_zone_pos: Current position in the first data zone. 62 * @data2_zone_pos: Current position in the second data zone. 63 * @mft_ino: The VFS inode of $MFT. 64 * @mftbmp_ino: Attribute inode for $MFT/$BITMAP. 65 * @mftbmp_lock: Lock for serializing accesses to the mft record bitmap. 66 * @mftmirr_ino: The VFS inode of $MFTMirr. 67 * @mftmirr_size: Size of mft mirror in mft records. 68 * @logfile_ino: The VFS inode of LogFile. 69 * @lcnbmp_ino: The VFS inode of $Bitmap. 70 * @lcnbmp_lock: Lock for serializing accesses to the cluster bitmap 71 * @vol_ino: The VFS inode of $Volume. 72 * @vol_flags: Volume flags. 73 * @major_ver: Ntfs major version of volume. 74 * @minor_ver: Ntfs minor version of volume. 75 * @volume_label_lock: protects @volume_label. 76 * @volume_label: volume label. 77 * @root_ino: The VFS inode of the root directory. 78 * @secure_ino: The VFS inode of $Secure (NTFS3.0+ only, otherwise NULL). 79 * @extend_ino: The VFS inode of $Extend (NTFS3.0+ only, otherwise NULL). 80 * @nls_map: NLS (National Language Support) table. 81 * @nls_utf8: NLS table for UTF-8. 82 * @free_waitq: Wait queue for threads waiting for free clusters or MFT records. 83 * @free_clusters: Track the number of free clusters. 84 * @free_mft_records: Track the free mft records. 85 * @dirty_clusters: Number of clusters that are dirty. 86 * @sparse_compression_unit: Size of compression/sparse unit in clusters. 87 * @lcn_empty_bits_per_page: Number of empty bits per page in the LCN bitmap. 88 * @precalc_work: Work structure for background pre-calculation tasks. 89 * @preallocated_size: reallocation size (in bytes). 90 */ 91 struct ntfs_volume { 92 struct super_block *sb; 93 s64 nr_blocks; 94 unsigned long flags; 95 kuid_t uid; 96 kgid_t gid; 97 umode_t fmask; 98 umode_t dmask; 99 u8 mft_zone_multiplier; 100 u8 on_errors; 101 errseq_t wb_err; 102 u16 sector_size; 103 u8 sector_size_bits; 104 u32 cluster_size; 105 u32 cluster_size_mask; 106 u8 cluster_size_bits; 107 u32 mft_record_size; 108 u32 mft_record_size_mask; 109 u8 mft_record_size_bits; 110 u32 index_record_size; 111 u32 index_record_size_mask; 112 u8 index_record_size_bits; 113 s64 nr_clusters; 114 s64 mft_lcn; 115 s64 mftmirr_lcn; 116 u64 serial_no; 117 u32 upcase_len; 118 __le16 *upcase; 119 s32 attrdef_size; 120 struct attr_def *attrdef; 121 s64 mft_data_pos; 122 s64 mft_zone_start; 123 s64 mft_zone_end; 124 s64 mft_zone_pos; 125 s64 data1_zone_pos; 126 s64 data2_zone_pos; 127 struct inode *mft_ino; 128 struct inode *mftbmp_ino; 129 struct rw_semaphore mftbmp_lock; 130 struct inode *mftmirr_ino; 131 int mftmirr_size; 132 struct inode *logfile_ino; 133 struct inode *lcnbmp_ino; 134 struct rw_semaphore lcnbmp_lock; 135 struct mutex volume_label_lock; 136 struct inode *vol_ino; 137 __le16 vol_flags; 138 u8 major_ver; 139 u8 minor_ver; 140 unsigned char *volume_label; 141 struct inode *root_ino; 142 struct inode *secure_ino; 143 struct inode *extend_ino; 144 struct nls_table *nls_map; 145 bool nls_utf8; 146 wait_queue_head_t free_waitq; 147 atomic64_t free_clusters; 148 atomic64_t free_mft_records; 149 atomic64_t dirty_clusters; 150 u8 sparse_compression_unit; 151 unsigned int *lcn_empty_bits_per_page; 152 struct work_struct precalc_work; 153 loff_t preallocated_size; 154 }; 155 156 /* 157 * Defined bits for the flags field in the ntfs_volume structure. 158 * 159 * NV_Errors Volume has errors, prevent remount rw. 160 * NV_ShowSystemFiles Return system files in ntfs_readdir(). 161 * NV_CaseSensitive Treat file names as case sensitive and 162 * create filenames in the POSIX namespace. 163 * Otherwise be case insensitive but still 164 * create file names in POSIX namespace. 165 * NV_LogFileEmpty LogFile journal is empty. 166 * NV_UsnJrnlStamped UsnJrnl has been stamped. 167 * NV_ReadOnly Volume is mounted read-only. 168 * NV_Compression Volume supports compression. 169 * NV_FreeClusterKnown Free cluster count is known and up-to-date. 170 * NV_Shutdown Volume is in shutdown state 171 * NV_SysImmutable Protect system files from deletion. 172 * NV_ShowHiddenFiles Return hidden files in ntfs_readdir(). 173 * NV_HideDotFiles Hide names beginning with a dot ("."). 174 * NV_CheckWindowsNames Refuse creation/rename of files with 175 * Windows-reserved names (CON, AUX, NUL, COM1, 176 * LPT1, etc.) or invalid characters. 177 * 178 * NV_Discard Issue discard/TRIM commands for freed clusters. 179 * NV_DisableSparse Disable creation of sparse regions. 180 * NV_NativeSymlinkRel Translate absolute Windows reparse targets (native_symlink=rel). 181 */ 182 enum { 183 NV_Errors, 184 NV_ShowSystemFiles, 185 NV_CaseSensitive, 186 NV_LogFileEmpty, 187 NV_UsnJrnlStamped, 188 NV_ReadOnly, 189 NV_Compression, 190 NV_FreeClusterKnown, 191 NV_Shutdown, 192 NV_SysImmutable, 193 NV_ShowHiddenFiles, 194 NV_HideDotFiles, 195 NV_CheckWindowsNames, 196 NV_Discard, 197 NV_DisableSparse, 198 NV_NativeSymlinkRel, 199 NV_SymlinkNative, 200 }; 201 202 /* 203 * Macro tricks to expand the NVolFoo(), NVolSetFoo(), and NVolClearFoo() 204 * functions. 205 */ 206 #define DEFINE_NVOL_BIT_OPS(flag) \ 207 static inline int NVol##flag(struct ntfs_volume *vol) \ 208 { \ 209 return test_bit(NV_##flag, &(vol)->flags); \ 210 } \ 211 static inline void NVolSet##flag(struct ntfs_volume *vol) \ 212 { \ 213 set_bit(NV_##flag, &(vol)->flags); \ 214 } \ 215 static inline void NVolClear##flag(struct ntfs_volume *vol) \ 216 { \ 217 clear_bit(NV_##flag, &(vol)->flags); \ 218 } 219 220 /* Emit the ntfs volume bitops functions. */ 221 DEFINE_NVOL_BIT_OPS(Errors) 222 DEFINE_NVOL_BIT_OPS(ShowSystemFiles) 223 DEFINE_NVOL_BIT_OPS(CaseSensitive) 224 DEFINE_NVOL_BIT_OPS(LogFileEmpty) 225 DEFINE_NVOL_BIT_OPS(UsnJrnlStamped) 226 DEFINE_NVOL_BIT_OPS(ReadOnly) 227 DEFINE_NVOL_BIT_OPS(Compression) 228 DEFINE_NVOL_BIT_OPS(FreeClusterKnown) 229 DEFINE_NVOL_BIT_OPS(Shutdown) 230 DEFINE_NVOL_BIT_OPS(SysImmutable) 231 DEFINE_NVOL_BIT_OPS(ShowHiddenFiles) 232 DEFINE_NVOL_BIT_OPS(HideDotFiles) 233 DEFINE_NVOL_BIT_OPS(CheckWindowsNames) 234 DEFINE_NVOL_BIT_OPS(Discard) 235 DEFINE_NVOL_BIT_OPS(DisableSparse) 236 DEFINE_NVOL_BIT_OPS(NativeSymlinkRel) 237 DEFINE_NVOL_BIT_OPS(SymlinkNative) 238 239 static inline void ntfs_inc_free_clusters(struct ntfs_volume *vol, s64 nr) 240 { 241 if (!NVolFreeClusterKnown(vol)) 242 wait_event(vol->free_waitq, NVolFreeClusterKnown(vol)); 243 atomic64_add(nr, &vol->free_clusters); 244 } 245 246 static inline void ntfs_dec_free_clusters(struct ntfs_volume *vol, s64 nr) 247 { 248 if (!NVolFreeClusterKnown(vol)) 249 wait_event(vol->free_waitq, NVolFreeClusterKnown(vol)); 250 atomic64_sub(nr, &vol->free_clusters); 251 } 252 253 static inline void ntfs_inc_free_mft_records(struct ntfs_volume *vol, s64 nr) 254 { 255 if (!NVolFreeClusterKnown(vol)) 256 return; 257 258 atomic64_add(nr, &vol->free_mft_records); 259 } 260 261 static inline void ntfs_dec_free_mft_records(struct ntfs_volume *vol, s64 nr) 262 { 263 if (!NVolFreeClusterKnown(vol)) 264 return; 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