xref: /OK3568_Linux_fs/kernel/fs/ntfs/logfile.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-or-later */
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * logfile.h - Defines for NTFS kernel journal ($LogFile) handling.  Part of
4*4882a593Smuzhiyun  *	       the Linux-NTFS project.
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Copyright (c) 2000-2005 Anton Altaparmakov
7*4882a593Smuzhiyun  */
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #ifndef _LINUX_NTFS_LOGFILE_H
10*4882a593Smuzhiyun #define _LINUX_NTFS_LOGFILE_H
11*4882a593Smuzhiyun 
12*4882a593Smuzhiyun #ifdef NTFS_RW
13*4882a593Smuzhiyun 
14*4882a593Smuzhiyun #include <linux/fs.h>
15*4882a593Smuzhiyun 
16*4882a593Smuzhiyun #include "types.h"
17*4882a593Smuzhiyun #include "endian.h"
18*4882a593Smuzhiyun #include "layout.h"
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun /*
21*4882a593Smuzhiyun  * Journal ($LogFile) organization:
22*4882a593Smuzhiyun  *
23*4882a593Smuzhiyun  * Two restart areas present in the first two pages (restart pages, one restart
24*4882a593Smuzhiyun  * area in each page).  When the volume is dismounted they should be identical,
25*4882a593Smuzhiyun  * except for the update sequence array which usually has a different update
26*4882a593Smuzhiyun  * sequence number.
27*4882a593Smuzhiyun  *
28*4882a593Smuzhiyun  * These are followed by log records organized in pages headed by a log record
29*4882a593Smuzhiyun  * header going up to log file size.  Not all pages contain log records when a
30*4882a593Smuzhiyun  * volume is first formatted, but as the volume ages, all records will be used.
31*4882a593Smuzhiyun  * When the log file fills up, the records at the beginning are purged (by
32*4882a593Smuzhiyun  * modifying the oldest_lsn to a higher value presumably) and writing begins
33*4882a593Smuzhiyun  * at the beginning of the file.  Effectively, the log file is viewed as a
34*4882a593Smuzhiyun  * circular entity.
35*4882a593Smuzhiyun  *
36*4882a593Smuzhiyun  * NOTE: Windows NT, 2000, and XP all use log file version 1.1 but they accept
37*4882a593Smuzhiyun  * versions <= 1.x, including 0.-1.  (Yes, that is a minus one in there!)  We
38*4882a593Smuzhiyun  * probably only want to support 1.1 as this seems to be the current version
39*4882a593Smuzhiyun  * and we don't know how that differs from the older versions.  The only
40*4882a593Smuzhiyun  * exception is if the journal is clean as marked by the two restart pages
41*4882a593Smuzhiyun  * then it doesn't matter whether we are on an earlier version.  We can just
42*4882a593Smuzhiyun  * reinitialize the logfile and start again with version 1.1.
43*4882a593Smuzhiyun  */
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun /* Some $LogFile related constants. */
46*4882a593Smuzhiyun #define MaxLogFileSize		0x100000000ULL
47*4882a593Smuzhiyun #define DefaultLogPageSize	4096
48*4882a593Smuzhiyun #define MinLogRecordPages	48
49*4882a593Smuzhiyun 
50*4882a593Smuzhiyun /*
51*4882a593Smuzhiyun  * Log file restart page header (begins the restart area).
52*4882a593Smuzhiyun  */
53*4882a593Smuzhiyun typedef struct {
54*4882a593Smuzhiyun /*Ofs*/
55*4882a593Smuzhiyun /*  0	NTFS_RECORD; -- Unfolded here as gcc doesn't like unnamed structs. */
56*4882a593Smuzhiyun /*  0*/	NTFS_RECORD_TYPE magic;	/* The magic is "RSTR". */
57*4882a593Smuzhiyun /*  4*/	le16 usa_ofs;		/* See NTFS_RECORD definition in layout.h.
58*4882a593Smuzhiyun 				   When creating, set this to be immediately
59*4882a593Smuzhiyun 				   after this header structure (without any
60*4882a593Smuzhiyun 				   alignment). */
61*4882a593Smuzhiyun /*  6*/	le16 usa_count;		/* See NTFS_RECORD definition in layout.h. */
62*4882a593Smuzhiyun 
63*4882a593Smuzhiyun /*  8*/	leLSN chkdsk_lsn;	/* The last log file sequence number found by
64*4882a593Smuzhiyun 				   chkdsk.  Only used when the magic is changed
65*4882a593Smuzhiyun 				   to "CHKD".  Otherwise this is zero. */
66*4882a593Smuzhiyun /* 16*/	le32 system_page_size;	/* Byte size of system pages when the log file
67*4882a593Smuzhiyun 				   was created, has to be >= 512 and a power of
68*4882a593Smuzhiyun 				   2.  Use this to calculate the required size
69*4882a593Smuzhiyun 				   of the usa (usa_count) and add it to usa_ofs.
70*4882a593Smuzhiyun 				   Then verify that the result is less than the
71*4882a593Smuzhiyun 				   value of the restart_area_offset. */
72*4882a593Smuzhiyun /* 20*/	le32 log_page_size;	/* Byte size of log file pages, has to be >=
73*4882a593Smuzhiyun 				   512 and a power of 2.  The default is 4096
74*4882a593Smuzhiyun 				   and is used when the system page size is
75*4882a593Smuzhiyun 				   between 4096 and 8192.  Otherwise this is
76*4882a593Smuzhiyun 				   set to the system page size instead. */
77*4882a593Smuzhiyun /* 24*/	le16 restart_area_offset;/* Byte offset from the start of this header to
78*4882a593Smuzhiyun 				   the RESTART_AREA.  Value has to be aligned
79*4882a593Smuzhiyun 				   to 8-byte boundary.  When creating, set this
80*4882a593Smuzhiyun 				   to be after the usa. */
81*4882a593Smuzhiyun /* 26*/	sle16 minor_ver;	/* Log file minor version.  Only check if major
82*4882a593Smuzhiyun 				   version is 1. */
83*4882a593Smuzhiyun /* 28*/	sle16 major_ver;	/* Log file major version.  We only support
84*4882a593Smuzhiyun 				   version 1.1. */
85*4882a593Smuzhiyun /* sizeof() = 30 (0x1e) bytes */
86*4882a593Smuzhiyun } __attribute__ ((__packed__)) RESTART_PAGE_HEADER;
87*4882a593Smuzhiyun 
88*4882a593Smuzhiyun /*
89*4882a593Smuzhiyun  * Constant for the log client indices meaning that there are no client records
90*4882a593Smuzhiyun  * in this particular client array.  Also inside the client records themselves,
91*4882a593Smuzhiyun  * this means that there are no client records preceding or following this one.
92*4882a593Smuzhiyun  */
93*4882a593Smuzhiyun #define LOGFILE_NO_CLIENT	cpu_to_le16(0xffff)
94*4882a593Smuzhiyun #define LOGFILE_NO_CLIENT_CPU	0xffff
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun /*
97*4882a593Smuzhiyun  * These are the so far known RESTART_AREA_* flags (16-bit) which contain
98*4882a593Smuzhiyun  * information about the log file in which they are present.
99*4882a593Smuzhiyun  */
100*4882a593Smuzhiyun enum {
101*4882a593Smuzhiyun 	RESTART_VOLUME_IS_CLEAN	= cpu_to_le16(0x0002),
102*4882a593Smuzhiyun 	RESTART_SPACE_FILLER	= cpu_to_le16(0xffff), /* gcc: Force enum bit width to 16. */
103*4882a593Smuzhiyun } __attribute__ ((__packed__));
104*4882a593Smuzhiyun 
105*4882a593Smuzhiyun typedef le16 RESTART_AREA_FLAGS;
106*4882a593Smuzhiyun 
107*4882a593Smuzhiyun /*
108*4882a593Smuzhiyun  * Log file restart area record.  The offset of this record is found by adding
109*4882a593Smuzhiyun  * the offset of the RESTART_PAGE_HEADER to the restart_area_offset value found
110*4882a593Smuzhiyun  * in it.  See notes at restart_area_offset above.
111*4882a593Smuzhiyun  */
112*4882a593Smuzhiyun typedef struct {
113*4882a593Smuzhiyun /*Ofs*/
114*4882a593Smuzhiyun /*  0*/	leLSN current_lsn;	/* The current, i.e. last LSN inside the log
115*4882a593Smuzhiyun 				   when the restart area was last written.
116*4882a593Smuzhiyun 				   This happens often but what is the interval?
117*4882a593Smuzhiyun 				   Is it just fixed time or is it every time a
118*4882a593Smuzhiyun 				   check point is written or somethine else?
119*4882a593Smuzhiyun 				   On create set to 0. */
120*4882a593Smuzhiyun /*  8*/	le16 log_clients;	/* Number of log client records in the array of
121*4882a593Smuzhiyun 				   log client records which follows this
122*4882a593Smuzhiyun 				   restart area.  Must be 1.  */
123*4882a593Smuzhiyun /* 10*/	le16 client_free_list;	/* The index of the first free log client record
124*4882a593Smuzhiyun 				   in the array of log client records.
125*4882a593Smuzhiyun 				   LOGFILE_NO_CLIENT means that there are no
126*4882a593Smuzhiyun 				   free log client records in the array.
127*4882a593Smuzhiyun 				   If != LOGFILE_NO_CLIENT, check that
128*4882a593Smuzhiyun 				   log_clients > client_free_list.  On Win2k
129*4882a593Smuzhiyun 				   and presumably earlier, on a clean volume
130*4882a593Smuzhiyun 				   this is != LOGFILE_NO_CLIENT, and it should
131*4882a593Smuzhiyun 				   be 0, i.e. the first (and only) client
132*4882a593Smuzhiyun 				   record is free and thus the logfile is
133*4882a593Smuzhiyun 				   closed and hence clean.  A dirty volume
134*4882a593Smuzhiyun 				   would have left the logfile open and hence
135*4882a593Smuzhiyun 				   this would be LOGFILE_NO_CLIENT.  On WinXP
136*4882a593Smuzhiyun 				   and presumably later, the logfile is always
137*4882a593Smuzhiyun 				   open, even on clean shutdown so this should
138*4882a593Smuzhiyun 				   always be LOGFILE_NO_CLIENT. */
139*4882a593Smuzhiyun /* 12*/	le16 client_in_use_list;/* The index of the first in-use log client
140*4882a593Smuzhiyun 				   record in the array of log client records.
141*4882a593Smuzhiyun 				   LOGFILE_NO_CLIENT means that there are no
142*4882a593Smuzhiyun 				   in-use log client records in the array.  If
143*4882a593Smuzhiyun 				   != LOGFILE_NO_CLIENT check that log_clients
144*4882a593Smuzhiyun 				   > client_in_use_list.  On Win2k and
145*4882a593Smuzhiyun 				   presumably earlier, on a clean volume this
146*4882a593Smuzhiyun 				   is LOGFILE_NO_CLIENT, i.e. there are no
147*4882a593Smuzhiyun 				   client records in use and thus the logfile
148*4882a593Smuzhiyun 				   is closed and hence clean.  A dirty volume
149*4882a593Smuzhiyun 				   would have left the logfile open and hence
150*4882a593Smuzhiyun 				   this would be != LOGFILE_NO_CLIENT, and it
151*4882a593Smuzhiyun 				   should be 0, i.e. the first (and only)
152*4882a593Smuzhiyun 				   client record is in use.  On WinXP and
153*4882a593Smuzhiyun 				   presumably later, the logfile is always
154*4882a593Smuzhiyun 				   open, even on clean shutdown so this should
155*4882a593Smuzhiyun 				   always be 0. */
156*4882a593Smuzhiyun /* 14*/	RESTART_AREA_FLAGS flags;/* Flags modifying LFS behaviour.  On Win2k
157*4882a593Smuzhiyun 				   and presumably earlier this is always 0.  On
158*4882a593Smuzhiyun 				   WinXP and presumably later, if the logfile
159*4882a593Smuzhiyun 				   was shutdown cleanly, the second bit,
160*4882a593Smuzhiyun 				   RESTART_VOLUME_IS_CLEAN, is set.  This bit
161*4882a593Smuzhiyun 				   is cleared when the volume is mounted by
162*4882a593Smuzhiyun 				   WinXP and set when the volume is dismounted,
163*4882a593Smuzhiyun 				   thus if the logfile is dirty, this bit is
164*4882a593Smuzhiyun 				   clear.  Thus we don't need to check the
165*4882a593Smuzhiyun 				   Windows version to determine if the logfile
166*4882a593Smuzhiyun 				   is clean.  Instead if the logfile is closed,
167*4882a593Smuzhiyun 				   we know it must be clean.  If it is open and
168*4882a593Smuzhiyun 				   this bit is set, we also know it must be
169*4882a593Smuzhiyun 				   clean.  If on the other hand the logfile is
170*4882a593Smuzhiyun 				   open and this bit is clear, we can be almost
171*4882a593Smuzhiyun 				   certain that the logfile is dirty. */
172*4882a593Smuzhiyun /* 16*/	le32 seq_number_bits;	/* How many bits to use for the sequence
173*4882a593Smuzhiyun 				   number.  This is calculated as 67 - the
174*4882a593Smuzhiyun 				   number of bits required to store the logfile
175*4882a593Smuzhiyun 				   size in bytes and this can be used in with
176*4882a593Smuzhiyun 				   the specified file_size as a consistency
177*4882a593Smuzhiyun 				   check. */
178*4882a593Smuzhiyun /* 20*/	le16 restart_area_length;/* Length of the restart area including the
179*4882a593Smuzhiyun 				   client array.  Following checks required if
180*4882a593Smuzhiyun 				   version matches.  Otherwise, skip them.
181*4882a593Smuzhiyun 				   restart_area_offset + restart_area_length
182*4882a593Smuzhiyun 				   has to be <= system_page_size.  Also,
183*4882a593Smuzhiyun 				   restart_area_length has to be >=
184*4882a593Smuzhiyun 				   client_array_offset + (log_clients *
185*4882a593Smuzhiyun 				   sizeof(log client record)). */
186*4882a593Smuzhiyun /* 22*/	le16 client_array_offset;/* Offset from the start of this record to
187*4882a593Smuzhiyun 				   the first log client record if versions are
188*4882a593Smuzhiyun 				   matched.  When creating, set this to be
189*4882a593Smuzhiyun 				   after this restart area structure, aligned
190*4882a593Smuzhiyun 				   to 8-bytes boundary.  If the versions do not
191*4882a593Smuzhiyun 				   match, this is ignored and the offset is
192*4882a593Smuzhiyun 				   assumed to be (sizeof(RESTART_AREA) + 7) &
193*4882a593Smuzhiyun 				   ~7, i.e. rounded up to first 8-byte
194*4882a593Smuzhiyun 				   boundary.  Either way, client_array_offset
195*4882a593Smuzhiyun 				   has to be aligned to an 8-byte boundary.
196*4882a593Smuzhiyun 				   Also, restart_area_offset +
197*4882a593Smuzhiyun 				   client_array_offset has to be <= 510.
198*4882a593Smuzhiyun 				   Finally, client_array_offset + (log_clients
199*4882a593Smuzhiyun 				   * sizeof(log client record)) has to be <=
200*4882a593Smuzhiyun 				   system_page_size.  On Win2k and presumably
201*4882a593Smuzhiyun 				   earlier, this is 0x30, i.e. immediately
202*4882a593Smuzhiyun 				   following this record.  On WinXP and
203*4882a593Smuzhiyun 				   presumably later, this is 0x40, i.e. there
204*4882a593Smuzhiyun 				   are 16 extra bytes between this record and
205*4882a593Smuzhiyun 				   the client array.  This probably means that
206*4882a593Smuzhiyun 				   the RESTART_AREA record is actually bigger
207*4882a593Smuzhiyun 				   in WinXP and later. */
208*4882a593Smuzhiyun /* 24*/	sle64 file_size;	/* Usable byte size of the log file.  If the
209*4882a593Smuzhiyun 				   restart_area_offset + the offset of the
210*4882a593Smuzhiyun 				   file_size are > 510 then corruption has
211*4882a593Smuzhiyun 				   occurred.  This is the very first check when
212*4882a593Smuzhiyun 				   starting with the restart_area as if it
213*4882a593Smuzhiyun 				   fails it means that some of the above values
214*4882a593Smuzhiyun 				   will be corrupted by the multi sector
215*4882a593Smuzhiyun 				   transfer protection.  The file_size has to
216*4882a593Smuzhiyun 				   be rounded down to be a multiple of the
217*4882a593Smuzhiyun 				   log_page_size in the RESTART_PAGE_HEADER and
218*4882a593Smuzhiyun 				   then it has to be at least big enough to
219*4882a593Smuzhiyun 				   store the two restart pages and 48 (0x30)
220*4882a593Smuzhiyun 				   log record pages. */
221*4882a593Smuzhiyun /* 32*/	le32 last_lsn_data_length;/* Length of data of last LSN, not including
222*4882a593Smuzhiyun 				   the log record header.  On create set to
223*4882a593Smuzhiyun 				   0. */
224*4882a593Smuzhiyun /* 36*/	le16 log_record_header_length;/* Byte size of the log record header.
225*4882a593Smuzhiyun 				   If the version matches then check that the
226*4882a593Smuzhiyun 				   value of log_record_header_length is a
227*4882a593Smuzhiyun 				   multiple of 8, i.e.
228*4882a593Smuzhiyun 				   (log_record_header_length + 7) & ~7 ==
229*4882a593Smuzhiyun 				   log_record_header_length.  When creating set
230*4882a593Smuzhiyun 				   it to sizeof(LOG_RECORD_HEADER), aligned to
231*4882a593Smuzhiyun 				   8 bytes. */
232*4882a593Smuzhiyun /* 38*/	le16 log_page_data_offset;/* Offset to the start of data in a log record
233*4882a593Smuzhiyun 				   page.  Must be a multiple of 8.  On create
234*4882a593Smuzhiyun 				   set it to immediately after the update
235*4882a593Smuzhiyun 				   sequence array of the log record page. */
236*4882a593Smuzhiyun /* 40*/	le32 restart_log_open_count;/* A counter that gets incremented every
237*4882a593Smuzhiyun 				   time the logfile is restarted which happens
238*4882a593Smuzhiyun 				   at mount time when the logfile is opened.
239*4882a593Smuzhiyun 				   When creating set to a random value.  Win2k
240*4882a593Smuzhiyun 				   sets it to the low 32 bits of the current
241*4882a593Smuzhiyun 				   system time in NTFS format (see time.h). */
242*4882a593Smuzhiyun /* 44*/	le32 reserved;		/* Reserved/alignment to 8-byte boundary. */
243*4882a593Smuzhiyun /* sizeof() = 48 (0x30) bytes */
244*4882a593Smuzhiyun } __attribute__ ((__packed__)) RESTART_AREA;
245*4882a593Smuzhiyun 
246*4882a593Smuzhiyun /*
247*4882a593Smuzhiyun  * Log client record.  The offset of this record is found by adding the offset
248*4882a593Smuzhiyun  * of the RESTART_AREA to the client_array_offset value found in it.
249*4882a593Smuzhiyun  */
250*4882a593Smuzhiyun typedef struct {
251*4882a593Smuzhiyun /*Ofs*/
252*4882a593Smuzhiyun /*  0*/	leLSN oldest_lsn;	/* Oldest LSN needed by this client.  On create
253*4882a593Smuzhiyun 				   set to 0. */
254*4882a593Smuzhiyun /*  8*/	leLSN client_restart_lsn;/* LSN at which this client needs to restart
255*4882a593Smuzhiyun 				   the volume, i.e. the current position within
256*4882a593Smuzhiyun 				   the log file.  At present, if clean this
257*4882a593Smuzhiyun 				   should = current_lsn in restart area but it
258*4882a593Smuzhiyun 				   probably also = current_lsn when dirty most
259*4882a593Smuzhiyun 				   of the time.  At create set to 0. */
260*4882a593Smuzhiyun /* 16*/	le16 prev_client;	/* The offset to the previous log client record
261*4882a593Smuzhiyun 				   in the array of log client records.
262*4882a593Smuzhiyun 				   LOGFILE_NO_CLIENT means there is no previous
263*4882a593Smuzhiyun 				   client record, i.e. this is the first one.
264*4882a593Smuzhiyun 				   This is always LOGFILE_NO_CLIENT. */
265*4882a593Smuzhiyun /* 18*/	le16 next_client;	/* The offset to the next log client record in
266*4882a593Smuzhiyun 				   the array of log client records.
267*4882a593Smuzhiyun 				   LOGFILE_NO_CLIENT means there are no next
268*4882a593Smuzhiyun 				   client records, i.e. this is the last one.
269*4882a593Smuzhiyun 				   This is always LOGFILE_NO_CLIENT. */
270*4882a593Smuzhiyun /* 20*/	le16 seq_number;	/* On Win2k and presumably earlier, this is set
271*4882a593Smuzhiyun 				   to zero every time the logfile is restarted
272*4882a593Smuzhiyun 				   and it is incremented when the logfile is
273*4882a593Smuzhiyun 				   closed at dismount time.  Thus it is 0 when
274*4882a593Smuzhiyun 				   dirty and 1 when clean.  On WinXP and
275*4882a593Smuzhiyun 				   presumably later, this is always 0. */
276*4882a593Smuzhiyun /* 22*/	u8 reserved[6];		/* Reserved/alignment. */
277*4882a593Smuzhiyun /* 28*/	le32 client_name_length;/* Length of client name in bytes.  Should
278*4882a593Smuzhiyun 				   always be 8. */
279*4882a593Smuzhiyun /* 32*/	ntfschar client_name[64];/* Name of the client in Unicode.  Should
280*4882a593Smuzhiyun 				   always be "NTFS" with the remaining bytes
281*4882a593Smuzhiyun 				   set to 0. */
282*4882a593Smuzhiyun /* sizeof() = 160 (0xa0) bytes */
283*4882a593Smuzhiyun } __attribute__ ((__packed__)) LOG_CLIENT_RECORD;
284*4882a593Smuzhiyun 
285*4882a593Smuzhiyun extern bool ntfs_check_logfile(struct inode *log_vi,
286*4882a593Smuzhiyun 		RESTART_PAGE_HEADER **rp);
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun extern bool ntfs_is_logfile_clean(struct inode *log_vi,
289*4882a593Smuzhiyun 		const RESTART_PAGE_HEADER *rp);
290*4882a593Smuzhiyun 
291*4882a593Smuzhiyun extern bool ntfs_empty_logfile(struct inode *log_vi);
292*4882a593Smuzhiyun 
293*4882a593Smuzhiyun #endif /* NTFS_RW */
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun #endif /* _LINUX_NTFS_LOGFILE_H */
296