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