xref: /linux/fs/ntfs/volume.h (revision bfda5a01aa99c5c363ac9967b81cbd5902d6c940)
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)
DEFINE_NVOL_BIT_OPS(ShowSystemFiles)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 
ntfs_dec_free_clusters(struct ntfs_volume * vol,s64 nr)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 
ntfs_inc_free_mft_records(struct ntfs_volume * vol,s64 nr)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 
ntfs_dec_free_mft_records(struct ntfs_volume * vol,s64 nr)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 
ntfs_set_lcn_empty_bits(struct ntfs_volume * vol,unsigned long index,u8 val,unsigned int count)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 
ntfs_hold_dirty_clusters(struct ntfs_volume * vol,s64 nr_clusters)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 
ntfs_release_dirty_clusters(struct ntfs_volume * vol,s64 nr_clusters)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