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