xref: /linux/fs/ntfs/volume.h (revision cdd4dc3aebeab43a72ce0bc2b5bab6f0a80b97a5)
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