1*a1d312deSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 21da177e4SLinus Torvalds /* 31da177e4SLinus Torvalds * logfile.h - Defines for NTFS kernel journal ($LogFile) handling. Part of 41da177e4SLinus Torvalds * the Linux-NTFS project. 51da177e4SLinus Torvalds * 6e7a1033bSAnton Altaparmakov * Copyright (c) 2000-2005 Anton Altaparmakov 71da177e4SLinus Torvalds */ 81da177e4SLinus Torvalds 91da177e4SLinus Torvalds #ifndef _LINUX_NTFS_LOGFILE_H 101da177e4SLinus Torvalds #define _LINUX_NTFS_LOGFILE_H 111da177e4SLinus Torvalds 121da177e4SLinus Torvalds #ifdef NTFS_RW 131da177e4SLinus Torvalds 141da177e4SLinus Torvalds #include <linux/fs.h> 151da177e4SLinus Torvalds 161da177e4SLinus Torvalds #include "types.h" 171da177e4SLinus Torvalds #include "endian.h" 181da177e4SLinus Torvalds #include "layout.h" 191da177e4SLinus Torvalds 201da177e4SLinus Torvalds /* 211da177e4SLinus Torvalds * Journal ($LogFile) organization: 221da177e4SLinus Torvalds * 231da177e4SLinus Torvalds * Two restart areas present in the first two pages (restart pages, one restart 241da177e4SLinus Torvalds * area in each page). When the volume is dismounted they should be identical, 251da177e4SLinus Torvalds * except for the update sequence array which usually has a different update 261da177e4SLinus Torvalds * sequence number. 271da177e4SLinus Torvalds * 281da177e4SLinus Torvalds * These are followed by log records organized in pages headed by a log record 291da177e4SLinus Torvalds * header going up to log file size. Not all pages contain log records when a 301da177e4SLinus Torvalds * volume is first formatted, but as the volume ages, all records will be used. 311da177e4SLinus Torvalds * When the log file fills up, the records at the beginning are purged (by 321da177e4SLinus Torvalds * modifying the oldest_lsn to a higher value presumably) and writing begins 331da177e4SLinus Torvalds * at the beginning of the file. Effectively, the log file is viewed as a 341da177e4SLinus Torvalds * circular entity. 351da177e4SLinus Torvalds * 361da177e4SLinus Torvalds * NOTE: Windows NT, 2000, and XP all use log file version 1.1 but they accept 371da177e4SLinus Torvalds * versions <= 1.x, including 0.-1. (Yes, that is a minus one in there!) We 381da177e4SLinus Torvalds * probably only want to support 1.1 as this seems to be the current version 391da177e4SLinus Torvalds * and we don't know how that differs from the older versions. The only 401da177e4SLinus Torvalds * exception is if the journal is clean as marked by the two restart pages 411da177e4SLinus Torvalds * then it doesn't matter whether we are on an earlier version. We can just 421da177e4SLinus Torvalds * reinitialize the logfile and start again with version 1.1. 431da177e4SLinus Torvalds */ 441da177e4SLinus Torvalds 451da177e4SLinus Torvalds /* Some $LogFile related constants. */ 461da177e4SLinus Torvalds #define MaxLogFileSize 0x100000000ULL 471da177e4SLinus Torvalds #define DefaultLogPageSize 4096 481da177e4SLinus Torvalds #define MinLogRecordPages 48 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds /* 511da177e4SLinus Torvalds * Log file restart page header (begins the restart area). 521da177e4SLinus Torvalds */ 531da177e4SLinus Torvalds typedef struct { 541da177e4SLinus Torvalds /*Ofs*/ 551da177e4SLinus Torvalds /* 0 NTFS_RECORD; -- Unfolded here as gcc doesn't like unnamed structs. */ 561da177e4SLinus Torvalds /* 0*/ NTFS_RECORD_TYPE magic; /* The magic is "RSTR". */ 571da177e4SLinus Torvalds /* 4*/ le16 usa_ofs; /* See NTFS_RECORD definition in layout.h. 581da177e4SLinus Torvalds When creating, set this to be immediately 591da177e4SLinus Torvalds after this header structure (without any 601da177e4SLinus Torvalds alignment). */ 611da177e4SLinus Torvalds /* 6*/ le16 usa_count; /* See NTFS_RECORD definition in layout.h. */ 621da177e4SLinus Torvalds 631da177e4SLinus Torvalds /* 8*/ leLSN chkdsk_lsn; /* The last log file sequence number found by 641da177e4SLinus Torvalds chkdsk. Only used when the magic is changed 651da177e4SLinus Torvalds to "CHKD". Otherwise this is zero. */ 661da177e4SLinus Torvalds /* 16*/ le32 system_page_size; /* Byte size of system pages when the log file 671da177e4SLinus Torvalds was created, has to be >= 512 and a power of 681da177e4SLinus Torvalds 2. Use this to calculate the required size 691da177e4SLinus Torvalds of the usa (usa_count) and add it to usa_ofs. 701da177e4SLinus Torvalds Then verify that the result is less than the 711da177e4SLinus Torvalds value of the restart_area_offset. */ 721da177e4SLinus Torvalds /* 20*/ le32 log_page_size; /* Byte size of log file pages, has to be >= 731da177e4SLinus Torvalds 512 and a power of 2. The default is 4096 741da177e4SLinus Torvalds and is used when the system page size is 751da177e4SLinus Torvalds between 4096 and 8192. Otherwise this is 761da177e4SLinus Torvalds set to the system page size instead. */ 771da177e4SLinus Torvalds /* 24*/ le16 restart_area_offset;/* Byte offset from the start of this header to 781da177e4SLinus Torvalds the RESTART_AREA. Value has to be aligned 791da177e4SLinus Torvalds to 8-byte boundary. When creating, set this 801da177e4SLinus Torvalds to be after the usa. */ 811da177e4SLinus Torvalds /* 26*/ sle16 minor_ver; /* Log file minor version. Only check if major 821da177e4SLinus Torvalds version is 1. */ 831da177e4SLinus Torvalds /* 28*/ sle16 major_ver; /* Log file major version. We only support 841da177e4SLinus Torvalds version 1.1. */ 851da177e4SLinus Torvalds /* sizeof() = 30 (0x1e) bytes */ 861da177e4SLinus Torvalds } __attribute__ ((__packed__)) RESTART_PAGE_HEADER; 871da177e4SLinus Torvalds 881da177e4SLinus Torvalds /* 891da177e4SLinus Torvalds * Constant for the log client indices meaning that there are no client records 901da177e4SLinus Torvalds * in this particular client array. Also inside the client records themselves, 911da177e4SLinus Torvalds * this means that there are no client records preceding or following this one. 921da177e4SLinus Torvalds */ 9363cd8854SHarvey Harrison #define LOGFILE_NO_CLIENT cpu_to_le16(0xffff) 941da177e4SLinus Torvalds #define LOGFILE_NO_CLIENT_CPU 0xffff 951da177e4SLinus Torvalds 961da177e4SLinus Torvalds /* 971da177e4SLinus Torvalds * These are the so far known RESTART_AREA_* flags (16-bit) which contain 981da177e4SLinus Torvalds * information about the log file in which they are present. 991da177e4SLinus Torvalds */ 1001da177e4SLinus Torvalds enum { 10163cd8854SHarvey Harrison RESTART_VOLUME_IS_CLEAN = cpu_to_le16(0x0002), 10263cd8854SHarvey Harrison RESTART_SPACE_FILLER = cpu_to_le16(0xffff), /* gcc: Force enum bit width to 16. */ 1031da177e4SLinus Torvalds } __attribute__ ((__packed__)); 1041da177e4SLinus Torvalds 1051da177e4SLinus Torvalds typedef le16 RESTART_AREA_FLAGS; 1061da177e4SLinus Torvalds 1071da177e4SLinus Torvalds /* 1081da177e4SLinus Torvalds * Log file restart area record. The offset of this record is found by adding 1091da177e4SLinus Torvalds * the offset of the RESTART_PAGE_HEADER to the restart_area_offset value found 1101da177e4SLinus Torvalds * in it. See notes at restart_area_offset above. 1111da177e4SLinus Torvalds */ 1121da177e4SLinus Torvalds typedef struct { 1131da177e4SLinus Torvalds /*Ofs*/ 1141da177e4SLinus Torvalds /* 0*/ leLSN current_lsn; /* The current, i.e. last LSN inside the log 1151da177e4SLinus Torvalds when the restart area was last written. 1161da177e4SLinus Torvalds This happens often but what is the interval? 1171da177e4SLinus Torvalds Is it just fixed time or is it every time a 1181da177e4SLinus Torvalds check point is written or somethine else? 1191da177e4SLinus Torvalds On create set to 0. */ 1201da177e4SLinus Torvalds /* 8*/ le16 log_clients; /* Number of log client records in the array of 1211da177e4SLinus Torvalds log client records which follows this 1221da177e4SLinus Torvalds restart area. Must be 1. */ 1231da177e4SLinus Torvalds /* 10*/ le16 client_free_list; /* The index of the first free log client record 1241da177e4SLinus Torvalds in the array of log client records. 1251da177e4SLinus Torvalds LOGFILE_NO_CLIENT means that there are no 1261da177e4SLinus Torvalds free log client records in the array. 1271da177e4SLinus Torvalds If != LOGFILE_NO_CLIENT, check that 1281da177e4SLinus Torvalds log_clients > client_free_list. On Win2k 1291da177e4SLinus Torvalds and presumably earlier, on a clean volume 1301da177e4SLinus Torvalds this is != LOGFILE_NO_CLIENT, and it should 1311da177e4SLinus Torvalds be 0, i.e. the first (and only) client 1321da177e4SLinus Torvalds record is free and thus the logfile is 1331da177e4SLinus Torvalds closed and hence clean. A dirty volume 1341da177e4SLinus Torvalds would have left the logfile open and hence 1351da177e4SLinus Torvalds this would be LOGFILE_NO_CLIENT. On WinXP 1361da177e4SLinus Torvalds and presumably later, the logfile is always 1371da177e4SLinus Torvalds open, even on clean shutdown so this should 1381da177e4SLinus Torvalds always be LOGFILE_NO_CLIENT. */ 1391da177e4SLinus Torvalds /* 12*/ le16 client_in_use_list;/* The index of the first in-use log client 1401da177e4SLinus Torvalds record in the array of log client records. 1411da177e4SLinus Torvalds LOGFILE_NO_CLIENT means that there are no 1421da177e4SLinus Torvalds in-use log client records in the array. If 1431da177e4SLinus Torvalds != LOGFILE_NO_CLIENT check that log_clients 1441da177e4SLinus Torvalds > client_in_use_list. On Win2k and 1451da177e4SLinus Torvalds presumably earlier, on a clean volume this 1461da177e4SLinus Torvalds is LOGFILE_NO_CLIENT, i.e. there are no 1471da177e4SLinus Torvalds client records in use and thus the logfile 1481da177e4SLinus Torvalds is closed and hence clean. A dirty volume 1491da177e4SLinus Torvalds would have left the logfile open and hence 1501da177e4SLinus Torvalds this would be != LOGFILE_NO_CLIENT, and it 1511da177e4SLinus Torvalds should be 0, i.e. the first (and only) 1521da177e4SLinus Torvalds client record is in use. On WinXP and 1531da177e4SLinus Torvalds presumably later, the logfile is always 1541da177e4SLinus Torvalds open, even on clean shutdown so this should 1551da177e4SLinus Torvalds always be 0. */ 1561da177e4SLinus Torvalds /* 14*/ RESTART_AREA_FLAGS flags;/* Flags modifying LFS behaviour. On Win2k 1571da177e4SLinus Torvalds and presumably earlier this is always 0. On 1581da177e4SLinus Torvalds WinXP and presumably later, if the logfile 1591da177e4SLinus Torvalds was shutdown cleanly, the second bit, 1601da177e4SLinus Torvalds RESTART_VOLUME_IS_CLEAN, is set. This bit 1611da177e4SLinus Torvalds is cleared when the volume is mounted by 1621da177e4SLinus Torvalds WinXP and set when the volume is dismounted, 1631da177e4SLinus Torvalds thus if the logfile is dirty, this bit is 1641da177e4SLinus Torvalds clear. Thus we don't need to check the 1651da177e4SLinus Torvalds Windows version to determine if the logfile 1661da177e4SLinus Torvalds is clean. Instead if the logfile is closed, 1671da177e4SLinus Torvalds we know it must be clean. If it is open and 1681da177e4SLinus Torvalds this bit is set, we also know it must be 1691da177e4SLinus Torvalds clean. If on the other hand the logfile is 1701da177e4SLinus Torvalds open and this bit is clear, we can be almost 1711da177e4SLinus Torvalds certain that the logfile is dirty. */ 1721da177e4SLinus Torvalds /* 16*/ le32 seq_number_bits; /* How many bits to use for the sequence 1731da177e4SLinus Torvalds number. This is calculated as 67 - the 1741da177e4SLinus Torvalds number of bits required to store the logfile 1751da177e4SLinus Torvalds size in bytes and this can be used in with 1761da177e4SLinus Torvalds the specified file_size as a consistency 1771da177e4SLinus Torvalds check. */ 1781da177e4SLinus Torvalds /* 20*/ le16 restart_area_length;/* Length of the restart area including the 1791da177e4SLinus Torvalds client array. Following checks required if 1801da177e4SLinus Torvalds version matches. Otherwise, skip them. 1811da177e4SLinus Torvalds restart_area_offset + restart_area_length 1821da177e4SLinus Torvalds has to be <= system_page_size. Also, 1831da177e4SLinus Torvalds restart_area_length has to be >= 1841da177e4SLinus Torvalds client_array_offset + (log_clients * 1851da177e4SLinus Torvalds sizeof(log client record)). */ 1861da177e4SLinus Torvalds /* 22*/ le16 client_array_offset;/* Offset from the start of this record to 1871da177e4SLinus Torvalds the first log client record if versions are 1881da177e4SLinus Torvalds matched. When creating, set this to be 1891da177e4SLinus Torvalds after this restart area structure, aligned 1901da177e4SLinus Torvalds to 8-bytes boundary. If the versions do not 1911da177e4SLinus Torvalds match, this is ignored and the offset is 1921da177e4SLinus Torvalds assumed to be (sizeof(RESTART_AREA) + 7) & 1931da177e4SLinus Torvalds ~7, i.e. rounded up to first 8-byte 1941da177e4SLinus Torvalds boundary. Either way, client_array_offset 1951da177e4SLinus Torvalds has to be aligned to an 8-byte boundary. 1961da177e4SLinus Torvalds Also, restart_area_offset + 1971da177e4SLinus Torvalds client_array_offset has to be <= 510. 1981da177e4SLinus Torvalds Finally, client_array_offset + (log_clients 1991da177e4SLinus Torvalds * sizeof(log client record)) has to be <= 2001da177e4SLinus Torvalds system_page_size. On Win2k and presumably 2011da177e4SLinus Torvalds earlier, this is 0x30, i.e. immediately 2021da177e4SLinus Torvalds following this record. On WinXP and 2031da177e4SLinus Torvalds presumably later, this is 0x40, i.e. there 2041da177e4SLinus Torvalds are 16 extra bytes between this record and 2051da177e4SLinus Torvalds the client array. This probably means that 2061da177e4SLinus Torvalds the RESTART_AREA record is actually bigger 2071da177e4SLinus Torvalds in WinXP and later. */ 2081da177e4SLinus Torvalds /* 24*/ sle64 file_size; /* Usable byte size of the log file. If the 2091da177e4SLinus Torvalds restart_area_offset + the offset of the 2101da177e4SLinus Torvalds file_size are > 510 then corruption has 21125985edcSLucas De Marchi occurred. This is the very first check when 2121da177e4SLinus Torvalds starting with the restart_area as if it 2131da177e4SLinus Torvalds fails it means that some of the above values 2141da177e4SLinus Torvalds will be corrupted by the multi sector 2151da177e4SLinus Torvalds transfer protection. The file_size has to 2161da177e4SLinus Torvalds be rounded down to be a multiple of the 2171da177e4SLinus Torvalds log_page_size in the RESTART_PAGE_HEADER and 2181da177e4SLinus Torvalds then it has to be at least big enough to 2191da177e4SLinus Torvalds store the two restart pages and 48 (0x30) 2201da177e4SLinus Torvalds log record pages. */ 2211da177e4SLinus Torvalds /* 32*/ le32 last_lsn_data_length;/* Length of data of last LSN, not including 2221da177e4SLinus Torvalds the log record header. On create set to 2231da177e4SLinus Torvalds 0. */ 2241da177e4SLinus Torvalds /* 36*/ le16 log_record_header_length;/* Byte size of the log record header. 2251da177e4SLinus Torvalds If the version matches then check that the 2261da177e4SLinus Torvalds value of log_record_header_length is a 2271da177e4SLinus Torvalds multiple of 8, i.e. 2281da177e4SLinus Torvalds (log_record_header_length + 7) & ~7 == 2291da177e4SLinus Torvalds log_record_header_length. When creating set 2301da177e4SLinus Torvalds it to sizeof(LOG_RECORD_HEADER), aligned to 2311da177e4SLinus Torvalds 8 bytes. */ 2321da177e4SLinus Torvalds /* 38*/ le16 log_page_data_offset;/* Offset to the start of data in a log record 2331da177e4SLinus Torvalds page. Must be a multiple of 8. On create 2341da177e4SLinus Torvalds set it to immediately after the update 2351da177e4SLinus Torvalds sequence array of the log record page. */ 2361da177e4SLinus Torvalds /* 40*/ le32 restart_log_open_count;/* A counter that gets incremented every 2371da177e4SLinus Torvalds time the logfile is restarted which happens 2381da177e4SLinus Torvalds at mount time when the logfile is opened. 2391da177e4SLinus Torvalds When creating set to a random value. Win2k 2401da177e4SLinus Torvalds sets it to the low 32 bits of the current 2411da177e4SLinus Torvalds system time in NTFS format (see time.h). */ 2421da177e4SLinus Torvalds /* 44*/ le32 reserved; /* Reserved/alignment to 8-byte boundary. */ 2431da177e4SLinus Torvalds /* sizeof() = 48 (0x30) bytes */ 2441da177e4SLinus Torvalds } __attribute__ ((__packed__)) RESTART_AREA; 2451da177e4SLinus Torvalds 2461da177e4SLinus Torvalds /* 2471da177e4SLinus Torvalds * Log client record. The offset of this record is found by adding the offset 2481da177e4SLinus Torvalds * of the RESTART_AREA to the client_array_offset value found in it. 2491da177e4SLinus Torvalds */ 2501da177e4SLinus Torvalds typedef struct { 2511da177e4SLinus Torvalds /*Ofs*/ 2521da177e4SLinus Torvalds /* 0*/ leLSN oldest_lsn; /* Oldest LSN needed by this client. On create 2531da177e4SLinus Torvalds set to 0. */ 2541da177e4SLinus Torvalds /* 8*/ leLSN client_restart_lsn;/* LSN at which this client needs to restart 2551da177e4SLinus Torvalds the volume, i.e. the current position within 2561da177e4SLinus Torvalds the log file. At present, if clean this 2571da177e4SLinus Torvalds should = current_lsn in restart area but it 2581da177e4SLinus Torvalds probably also = current_lsn when dirty most 2591da177e4SLinus Torvalds of the time. At create set to 0. */ 2601da177e4SLinus Torvalds /* 16*/ le16 prev_client; /* The offset to the previous log client record 2611da177e4SLinus Torvalds in the array of log client records. 2621da177e4SLinus Torvalds LOGFILE_NO_CLIENT means there is no previous 2631da177e4SLinus Torvalds client record, i.e. this is the first one. 2641da177e4SLinus Torvalds This is always LOGFILE_NO_CLIENT. */ 2651da177e4SLinus Torvalds /* 18*/ le16 next_client; /* The offset to the next log client record in 2661da177e4SLinus Torvalds the array of log client records. 2671da177e4SLinus Torvalds LOGFILE_NO_CLIENT means there are no next 2681da177e4SLinus Torvalds client records, i.e. this is the last one. 2691da177e4SLinus Torvalds This is always LOGFILE_NO_CLIENT. */ 2701da177e4SLinus Torvalds /* 20*/ le16 seq_number; /* On Win2k and presumably earlier, this is set 2711da177e4SLinus Torvalds to zero every time the logfile is restarted 2721da177e4SLinus Torvalds and it is incremented when the logfile is 2731da177e4SLinus Torvalds closed at dismount time. Thus it is 0 when 2741da177e4SLinus Torvalds dirty and 1 when clean. On WinXP and 2751da177e4SLinus Torvalds presumably later, this is always 0. */ 2761da177e4SLinus Torvalds /* 22*/ u8 reserved[6]; /* Reserved/alignment. */ 2771da177e4SLinus Torvalds /* 28*/ le32 client_name_length;/* Length of client name in bytes. Should 2781da177e4SLinus Torvalds always be 8. */ 2791da177e4SLinus Torvalds /* 32*/ ntfschar client_name[64];/* Name of the client in Unicode. Should 2801da177e4SLinus Torvalds always be "NTFS" with the remaining bytes 2811da177e4SLinus Torvalds set to 0. */ 2821da177e4SLinus Torvalds /* sizeof() = 160 (0xa0) bytes */ 2831da177e4SLinus Torvalds } __attribute__ ((__packed__)) LOG_CLIENT_RECORD; 2841da177e4SLinus Torvalds 285c49c3111SRichard Knutsson extern bool ntfs_check_logfile(struct inode *log_vi, 286e7a1033bSAnton Altaparmakov RESTART_PAGE_HEADER **rp); 2871da177e4SLinus Torvalds 288c49c3111SRichard Knutsson extern bool ntfs_is_logfile_clean(struct inode *log_vi, 289e7a1033bSAnton Altaparmakov const RESTART_PAGE_HEADER *rp); 2901da177e4SLinus Torvalds 291c49c3111SRichard Knutsson extern bool ntfs_empty_logfile(struct inode *log_vi); 2921da177e4SLinus Torvalds 2931da177e4SLinus Torvalds #endif /* NTFS_RW */ 2941da177e4SLinus Torvalds 2951da177e4SLinus Torvalds #endif /* _LINUX_NTFS_LOGFILE_H */ 296