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: volume label. 76 * @root_ino: The VFS inode of the root directory. 77 * @secure_ino: The VFS inode of $Secure (NTFS3.0+ only, otherwise NULL). 78 * @extend_ino: The VFS inode of $Extend (NTFS3.0+ only, otherwise NULL). 79 * @quota_ino: The VFS inode of $Quota. 80 * @quota_q_ino: Attribute inode for $Quota/$Q. 81 * @nls_map: NLS (National Language Support) table. 82 * @nls_utf8: NLS table for UTF-8. 83 * @free_waitq: Wait queue for threads waiting for free clusters or MFT records. 84 * @free_clusters: Track the number of free clusters. 85 * @free_mft_records: Track the free mft records. 86 * @dirty_clusters: Number of clusters that are dirty. 87 * @sparse_compression_unit: Size of compression/sparse unit in clusters. 88 * @lcn_empty_bits_per_page: Number of empty bits per page in the LCN bitmap. 89 * @precalc_work: Work structure for background pre-calculation tasks. 90 * @preallocated_size: reallocation size (in bytes). 91 */ 92 struct ntfs_volume { 93 struct super_block *sb; 94 s64 nr_blocks; 95 unsigned long flags; 96 kuid_t uid; 97 kgid_t gid; 98 umode_t fmask; 99 umode_t dmask; 100 u8 mft_zone_multiplier; 101 u8 on_errors; 102 errseq_t wb_err; 103 u16 sector_size; 104 u8 sector_size_bits; 105 u32 cluster_size; 106 u32 cluster_size_mask; 107 u8 cluster_size_bits; 108 u32 mft_record_size; 109 u32 mft_record_size_mask; 110 u8 mft_record_size_bits; 111 u32 index_record_size; 112 u32 index_record_size_mask; 113 u8 index_record_size_bits; 114 s64 nr_clusters; 115 s64 mft_lcn; 116 s64 mftmirr_lcn; 117 u64 serial_no; 118 u32 upcase_len; 119 __le16 *upcase; 120 s32 attrdef_size; 121 struct attr_def *attrdef; 122 s64 mft_data_pos; 123 s64 mft_zone_start; 124 s64 mft_zone_end; 125 s64 mft_zone_pos; 126 s64 data1_zone_pos; 127 s64 data2_zone_pos; 128 struct inode *mft_ino; 129 struct inode *mftbmp_ino; 130 struct rw_semaphore mftbmp_lock; 131 struct inode *mftmirr_ino; 132 int mftmirr_size; 133 struct inode *logfile_ino; 134 struct inode *lcnbmp_ino; 135 struct rw_semaphore lcnbmp_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 inode *quota_ino; 145 struct inode *quota_q_ino; 146 struct nls_table *nls_map; 147 bool nls_utf8; 148 wait_queue_head_t free_waitq; 149 atomic64_t free_clusters; 150 atomic64_t free_mft_records; 151 atomic64_t dirty_clusters; 152 u8 sparse_compression_unit; 153 unsigned int *lcn_empty_bits_per_page; 154 struct work_struct precalc_work; 155 loff_t preallocated_size; 156 }; 157 158 /* 159 * Defined bits for the flags field in the ntfs_volume structure. 160 * 161 * NV_Errors Volume has errors, prevent remount rw. 162 * NV_ShowSystemFiles Return system files in ntfs_readdir(). 163 * NV_CaseSensitive Treat file names as case sensitive and 164 * create filenames in the POSIX namespace. 165 * Otherwise be case insensitive but still 166 * create file names in POSIX namespace. 167 * NV_LogFileEmpty LogFile journal is empty. 168 * NV_QuotaOutOfDate Quota is out of date. 169 * NV_UsnJrnlStamped UsnJrnl has been stamped. 170 * NV_ReadOnly Volume is mounted read-only. 171 * NV_Compression Volume supports compression. 172 * NV_FreeClusterKnown Free cluster count is known and up-to-date. 173 * NV_Shutdown Volume is in shutdown state 174 * NV_SysImmutable Protect system files from deletion. 175 * NV_ShowHiddenFiles Return hidden files in ntfs_readdir(). 176 * NV_HideDotFiles Hide names beginning with a dot ("."). 177 * NV_CheckWindowsNames Refuse creation/rename of files with 178 * Windows-reserved names (CON, AUX, NUL, COM1, 179 * LPT1, etc.) or invalid characters. 180 * 181 * NV_Discard Issue discard/TRIM commands for freed clusters. 182 * NV_DisableSparse Disable creation of sparse regions. 183 */ 184 enum { 185 NV_Errors, 186 NV_ShowSystemFiles, 187 NV_CaseSensitive, 188 NV_LogFileEmpty, 189 NV_QuotaOutOfDate, 190 NV_UsnJrnlStamped, 191 NV_ReadOnly, 192 NV_Compression, 193 NV_FreeClusterKnown, 194 NV_Shutdown, 195 NV_SysImmutable, 196 NV_ShowHiddenFiles, 197 NV_HideDotFiles, 198 NV_CheckWindowsNames, 199 NV_Discard, 200 NV_DisableSparse, 201 }; 202 203 /* 204 * Macro tricks to expand the NVolFoo(), NVolSetFoo(), and NVolClearFoo() 205 * functions. 206 */ 207 #define DEFINE_NVOL_BIT_OPS(flag) \ 208 static inline int NVol##flag(struct ntfs_volume *vol) \ 209 { \ 210 return test_bit(NV_##flag, &(vol)->flags); \ 211 } \ 212 static inline void NVolSet##flag(struct ntfs_volume *vol) \ 213 { \ 214 set_bit(NV_##flag, &(vol)->flags); \ 215 } \ 216 static inline void NVolClear##flag(struct ntfs_volume *vol) \ 217 { \ 218 clear_bit(NV_##flag, &(vol)->flags); \ 219 } 220 221 /* Emit the ntfs volume bitops functions. */ 222 DEFINE_NVOL_BIT_OPS(Errors) 223 DEFINE_NVOL_BIT_OPS(ShowSystemFiles) 224 DEFINE_NVOL_BIT_OPS(CaseSensitive) 225 DEFINE_NVOL_BIT_OPS(LogFileEmpty) 226 DEFINE_NVOL_BIT_OPS(QuotaOutOfDate) 227 DEFINE_NVOL_BIT_OPS(UsnJrnlStamped) 228 DEFINE_NVOL_BIT_OPS(ReadOnly) 229 DEFINE_NVOL_BIT_OPS(Compression) 230 DEFINE_NVOL_BIT_OPS(FreeClusterKnown) 231 DEFINE_NVOL_BIT_OPS(Shutdown) 232 DEFINE_NVOL_BIT_OPS(SysImmutable) 233 DEFINE_NVOL_BIT_OPS(ShowHiddenFiles) 234 DEFINE_NVOL_BIT_OPS(HideDotFiles) 235 DEFINE_NVOL_BIT_OPS(CheckWindowsNames) 236 DEFINE_NVOL_BIT_OPS(Discard) 237 DEFINE_NVOL_BIT_OPS(DisableSparse) 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