fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / fs / ntfs / layout.h
index 57f3a88..1e38332 100644 (file)
@@ -2,7 +2,7 @@
  * layout.h - All NTFS associated on-disk structures. Part of the Linux-NTFS
  *           project.
  *
- * Copyright (c) 2001-2004 Anton Altaparmakov
+ * Copyright (c) 2001-2005 Anton Altaparmakov
  * Copyright (c) 2002 Richard Russon
  *
  * This program/include file is free software; you can redistribute it and/or
@@ -123,7 +123,7 @@ enum {
        magic_RCRD = const_cpu_to_le32(0x44524352), /* Log record page. */
 
        /* Found in $LogFile/$DATA.  (May be found in $MFT/$DATA, also?) */
-       magic_CHKD = const_cpu_to_le32(0x424b4843), /* Modified by chkdsk. */
+       magic_CHKD = const_cpu_to_le32(0x444b4843), /* Modified by chkdsk. */
 
        /* Found in all ntfs record containing records. */
        magic_BAAD = const_cpu_to_le32(0x44414142), /* Failed multi sector
@@ -142,13 +142,13 @@ typedef le32 NTFS_RECORD_TYPE;
  * operator! (-8
  */
 
-static inline BOOL __ntfs_is_magic(le32 x, NTFS_RECORD_TYPE r)
+static inline bool __ntfs_is_magic(le32 x, NTFS_RECORD_TYPE r)
 {
        return (x == r);
 }
 #define ntfs_is_magic(x, m)    __ntfs_is_magic(x, magic_##m)
 
-static inline BOOL __ntfs_is_magicp(le32 *p, NTFS_RECORD_TYPE r)
+static inline bool __ntfs_is_magicp(le32 *p, NTFS_RECORD_TYPE r)
 {
        return (*p == r);
 }
@@ -260,7 +260,7 @@ typedef enum {
 enum {
        MFT_RECORD_IN_USE       = const_cpu_to_le16(0x0001),
        MFT_RECORD_IS_DIRECTORY = const_cpu_to_le16(0x0002),
-};
+} __attribute__ ((__packed__));
 
 typedef le16 MFT_RECORD_FLAGS;
 
@@ -308,20 +308,22 @@ typedef le16 MFT_RECORD_FLAGS;
  * The _LE versions are to be applied on little endian MFT_REFs.
  * Note: The _LE versions will return a CPU endian formatted value!
  */
-typedef enum {
-       MFT_REF_MASK_CPU        = 0x0000ffffffffffffULL,
-       MFT_REF_MASK_LE         = const_cpu_to_le64(0x0000ffffffffffffULL),
-} MFT_REF_CONSTS;
+#define MFT_REF_MASK_CPU 0x0000ffffffffffffULL
+#define MFT_REF_MASK_LE const_cpu_to_le64(MFT_REF_MASK_CPU)
 
 typedef u64 MFT_REF;
 typedef le64 leMFT_REF;
 
+#define MK_MREF(m, s)  ((MFT_REF)(((MFT_REF)(s) << 48) |               \
+                                       ((MFT_REF)(m) & MFT_REF_MASK_CPU)))
+#define MK_LE_MREF(m, s) cpu_to_le64(MK_MREF(m, s))
+
 #define MREF(x)                ((unsigned long)((x) & MFT_REF_MASK_CPU))
 #define MSEQNO(x)      ((u16)(((x) >> 48) & 0xffff))
 #define MREF_LE(x)     ((unsigned long)(le64_to_cpu(x) & MFT_REF_MASK_CPU))
 #define MSEQNO_LE(x)   ((u16)((le64_to_cpu(x) >> 48) & 0xffff))
 
-#define IS_ERR_MREF(x) (((x) & 0x0000800000000000ULL) ? 1 : 0)
+#define IS_ERR_MREF(x) (((x) & 0x0000800000000000ULL) ? true : false)
 #define ERR_MREF(x)    ((u64)((s64)(x)))
 #define MREF_ERR(x)    ((int)((s64)(x)))
 
@@ -385,22 +387,87 @@ typedef struct {
                                   NOTE: Every time the mft record is reused
                                   this number is set to zero.  NOTE: The first
                                   instance number is always 0. */
-/* sizeof() = 42 bytes */
-/* NTFS 3.1+ (Windows XP and above) introduce the following additions. */
-/* 42*/ //le16 reserved;       /* Reserved/alignment. */
-/* 44*/ //le32 mft_record_number;/* Number of this mft record. */
+/* The below fields are specific to NTFS 3.1+ (Windows XP and above): */
+/* 42*/ le16 reserved;         /* Reserved/alignment. */
+/* 44*/ le32 mft_record_number;        /* Number of this mft record. */
 /* sizeof() = 48 bytes */
 /*
  * When (re)using the mft record, we place the update sequence array at this
- * offset, i.e. before we start with the attributes. This also makes sense,
+ * offset, i.e. before we start with the attributes.  This also makes sense,
  * otherwise we could run into problems with the update sequence array
  * containing in itself the last two bytes of a sector which would mean that
- * multi sector transfer protection wouldn't work. As you can't protect data
+ * multi sector transfer protection wouldn't work.  As you can't protect data
  * by overwriting it since you then can't get it back...
  * When reading we obviously use the data from the ntfs record header.
  */
 } __attribute__ ((__packed__)) MFT_RECORD;
 
+/* This is the version without the NTFS 3.1+ specific fields. */
+typedef struct {
+/*Ofs*/
+/*  0  NTFS_RECORD; -- Unfolded here as gcc doesn't like unnamed structs. */
+       NTFS_RECORD_TYPE magic; /* Usually the magic is "FILE". */
+       le16 usa_ofs;           /* See NTFS_RECORD definition above. */
+       le16 usa_count;         /* See NTFS_RECORD definition above. */
+
+/*  8*/        le64 lsn;               /* $LogFile sequence number for this record.
+                                  Changed every time the record is modified. */
+/* 16*/        le16 sequence_number;   /* Number of times this mft record has been
+                                  reused. (See description for MFT_REF
+                                  above.) NOTE: The increment (skipping zero)
+                                  is done when the file is deleted. NOTE: If
+                                  this is zero it is left zero. */
+/* 18*/        le16 link_count;        /* Number of hard links, i.e. the number of
+                                  directory entries referencing this record.
+                                  NOTE: Only used in mft base records.
+                                  NOTE: When deleting a directory entry we
+                                  check the link_count and if it is 1 we
+                                  delete the file. Otherwise we delete the
+                                  FILE_NAME_ATTR being referenced by the
+                                  directory entry from the mft record and
+                                  decrement the link_count.
+                                  FIXME: Careful with Win32 + DOS names! */
+/* 20*/        le16 attrs_offset;      /* Byte offset to the first attribute in this
+                                  mft record from the start of the mft record.
+                                  NOTE: Must be aligned to 8-byte boundary. */
+/* 22*/        MFT_RECORD_FLAGS flags; /* Bit array of MFT_RECORD_FLAGS. When a file
+                                  is deleted, the MFT_RECORD_IN_USE flag is
+                                  set to zero. */
+/* 24*/        le32 bytes_in_use;      /* Number of bytes used in this mft record.
+                                  NOTE: Must be aligned to 8-byte boundary. */
+/* 28*/        le32 bytes_allocated;   /* Number of bytes allocated for this mft
+                                  record. This should be equal to the mft
+                                  record size. */
+/* 32*/        leMFT_REF base_mft_record;/* This is zero for base mft records.
+                                  When it is not zero it is a mft reference
+                                  pointing to the base mft record to which
+                                  this record belongs (this is then used to
+                                  locate the attribute list attribute present
+                                  in the base record which describes this
+                                  extension record and hence might need
+                                  modification when the extension record
+                                  itself is modified, also locating the
+                                  attribute list also means finding the other
+                                  potential extents, belonging to the non-base
+                                  mft record). */
+/* 40*/        le16 next_attr_instance;/* The instance number that will be assigned to
+                                  the next attribute added to this mft record.
+                                  NOTE: Incremented each time after it is used.
+                                  NOTE: Every time the mft record is reused
+                                  this number is set to zero.  NOTE: The first
+                                  instance number is always 0. */
+/* sizeof() = 42 bytes */
+/*
+ * When (re)using the mft record, we place the update sequence array at this
+ * offset, i.e. before we start with the attributes.  This also makes sense,
+ * otherwise we could run into problems with the update sequence array
+ * containing in itself the last two bytes of a sector which would mean that
+ * multi sector transfer protection wouldn't work.  As you can't protect data
+ * by overwriting it since you then can't get it back...
+ * When reading we obviously use the data from the ntfs record header.
+ */
+} __attribute__ ((__packed__)) MFT_RECORD_OLD;
+
 /*
  * System defined attributes (32-bit).  Each attribute type has a corresponding
  * attribute name (Unicode string of maximum 64 character length) as described
@@ -478,26 +545,44 @@ enum {
        COLLATION_NTOFS_ULONG           = const_cpu_to_le32(0x10),
        COLLATION_NTOFS_SID             = const_cpu_to_le32(0x11),
        COLLATION_NTOFS_SECURITY_HASH   = const_cpu_to_le32(0x12),
-       COLLATION_NTOFS_ULONGS          = const_cpu_to_le32(0x13)
+       COLLATION_NTOFS_ULONGS          = const_cpu_to_le32(0x13),
 };
 
 typedef le32 COLLATION_RULE;
 
 /*
  * The flags (32-bit) describing attribute properties in the attribute
- * definition structure.  FIXME: This information is from Regis's information
- * and, according to him, it is not certain and probably incomplete.
- * The INDEXABLE flag is fairly certainly correct as only the file name
- * attribute has this flag set and this is the only attribute indexed in NT4.
+ * definition structure.  FIXME: This information is based on Regis's
+ * information and, according to him, it is not certain and probably
+ * incomplete.  The INDEXABLE flag is fairly certainly correct as only the file
+ * name attribute has this flag set and this is the only attribute indexed in
+ * NT4.
  */
 enum {
-       INDEXABLE           = const_cpu_to_le32(0x02), /* Attribute can be
-                                                         indexed. */
-       NEED_TO_REGENERATE  = const_cpu_to_le32(0x40), /* Need to regenerate
-                                                         during regeneration
-                                                         phase. */
-       CAN_BE_NON_RESIDENT = const_cpu_to_le32(0x80), /* Attribute can be
-                                                         non-resident. */
+       ATTR_DEF_INDEXABLE      = const_cpu_to_le32(0x02), /* Attribute can be
+                                       indexed. */
+       ATTR_DEF_MULTIPLE       = const_cpu_to_le32(0x04), /* Attribute type
+                                       can be present multiple times in the
+                                       mft records of an inode. */
+       ATTR_DEF_NOT_ZERO       = const_cpu_to_le32(0x08), /* Attribute value
+                                       must contain at least one non-zero
+                                       byte. */
+       ATTR_DEF_INDEXED_UNIQUE = const_cpu_to_le32(0x10), /* Attribute must be
+                                       indexed and the attribute value must be
+                                       unique for the attribute type in all of
+                                       the mft records of an inode. */
+       ATTR_DEF_NAMED_UNIQUE   = const_cpu_to_le32(0x20), /* Attribute must be
+                                       named and the name must be unique for
+                                       the attribute type in all of the mft
+                                       records of an inode. */
+       ATTR_DEF_RESIDENT       = const_cpu_to_le32(0x40), /* Attribute must be
+                                       resident. */
+       ATTR_DEF_ALWAYS_LOG     = const_cpu_to_le32(0x80), /* Always log
+                                       modifications to this attribute,
+                                       regardless of whether it is resident or
+                                       non-resident.  Without this, only log
+                                       modifications if the attribute is
+                                       resident. */
 };
 
 typedef le32 ATTR_DEF_FLAGS;
@@ -520,8 +605,8 @@ typedef struct {
                                           FIXME: What does it mean? (AIA) */
 /* 88*/ COLLATION_RULE collation_rule; /* Default collation rule. */
 /* 8c*/        ATTR_DEF_FLAGS flags;           /* Flags describing the attribute. */
-/* 90*/        le64 min_size;                  /* Optional minimum attribute size. */
-/* 98*/        le64 max_size;                  /* Maximum size of attribute. */
+/* 90*/        sle64 min_size;                 /* Optional minimum attribute size. */
+/* 98*/        sle64 max_size;                 /* Maximum size of attribute. */
 /* sizeof() = 0xa0 or 160 bytes */
 } __attribute__ ((__packed__)) ATTR_DEF;
 
@@ -680,10 +765,11 @@ typedef struct {
                                record header aligned to 8-byte boundary. */
 /* 34*/                        u8 compression_unit; /* The compression unit expressed
                                as the log to the base 2 of the number of
-                               clusters in a compression unit. 0 means not
-                               compressed. (This effectively limits the
+                               clusters in a compression unit.  0 means not
+                               compressed.  (This effectively limits the
                                compression unit size to be a power of two
-                               clusters.) WinNT4 only uses a value of 4. */
+                               clusters.)  WinNT4 only uses a value of 4.
+                               Sparse files have this set to 0 on XPSP2. */
 /* 35*/                        u8 reserved[5];         /* Align to 8-byte boundary. */
 /* The sizes below are only used when lowest_vcn is zero, as otherwise it would
    be difficult to keep them up-to-date.*/
@@ -703,10 +789,10 @@ typedef struct {
                                data_size. */
 /* sizeof(uncompressed attr) = 64*/
 /* 64*/                        sle64 compressed_size;  /* Byte size of the attribute
-                               value after compression. Only present when
-                               compressed. Always is a multiple of the
-                               cluster size. Represents the actual amount of
-                               disk space being used on the disk. */
+                               value after compression.  Only present when
+                               compressed or sparse.  Always is a multiple of
+                               the cluster size.  Represents the actual amount
+                               of disk space being used on the disk. */
 /* sizeof(compressed attr) = 72*/
                } __attribute__ ((__packed__)) non_resident;
        } __attribute__ ((__packed__)) data;
@@ -715,13 +801,16 @@ typedef struct {
 typedef ATTR_RECORD ATTR_REC;
 
 /*
- * File attribute flags (32-bit).
+ * File attribute flags (32-bit) appearing in the file_attributes fields of the
+ * STANDARD_INFORMATION attribute of MFT_RECORDs and the FILENAME_ATTR
+ * attributes of MFT_RECORDs and directory index entries.
+ *
+ * All of the below flags appear in the directory index entries but only some
+ * appear in the STANDARD_INFORMATION attribute whilst only some others appear
+ * in the FILENAME_ATTR attribute of MFT_RECORDs.  Unless otherwise stated the
+ * flags appear in all of the above.
  */
 enum {
-       /*
-        * The following flags are only present in the STANDARD_INFORMATION
-        * attribute (in the field file_attributes).
-        */
        FILE_ATTR_READONLY              = const_cpu_to_le32(0x00000001),
        FILE_ATTR_HIDDEN                = const_cpu_to_le32(0x00000002),
        FILE_ATTR_SYSTEM                = const_cpu_to_le32(0x00000004),
@@ -752,10 +841,10 @@ enum {
           F_A_DEVICE, F_A_DIRECTORY, F_A_SPARSE_FILE, F_A_REPARSE_POINT,
           F_A_COMPRESSED, and F_A_ENCRYPTED and preserves the rest.  This mask
           is used to to obtain all flags that are valid for setting. */
-
        /*
-        * The following flags are only present in the FILE_NAME attribute (in
-        * the field file_attributes).
+        * The flag FILE_ATTR_DUP_FILENAME_INDEX_PRESENT is present in all
+        * FILENAME_ATTR attributes but not in the STANDARD_INFORMATION
+        * attribute of an mft record.
         */
        FILE_ATTR_DUP_FILE_NAME_INDEX_PRESENT   = const_cpu_to_le32(0x10000000),
        /* Note, this is a copy of the corresponding bit from the mft record,
@@ -765,7 +854,7 @@ enum {
        /* Note, this is a copy of the corresponding bit from the mft record,
           telling us whether this file has a view index present (eg. object id
           index, quota index, one of the security indexes or the encrypting
-          file system related indexes). */
+          filesystem related indexes). */
 };
 
 typedef le32 FILE_ATTR_FLAGS;
@@ -801,7 +890,7 @@ typedef struct {
                                           Windows this is only updated when
                                           accessed if some time delta has
                                           passed since the last update. Also,
-                                          last access times updates can be
+                                          last access time updates can be
                                           disabled altogether for speed. */
 /* 32*/        FILE_ATTR_FLAGS file_attributes; /* Flags describing the file. */
 /* 36*/        union {
@@ -848,20 +937,12 @@ typedef struct {
                /* 56*/ le64 quota_charged;     /* Byte size of the charge to
                                the quota for all streams of the file. Note: Is
                                zero if quotas are disabled. */
-               /* 64*/ le64 usn;               /* Last update sequence number
-                               of the file. This is a direct index into the
-                               change (aka usn) journal file. It is zero if
-                               the usn journal is disabled.
-                               NOTE: To disable the journal need to delete
-                               the journal file itself and to then walk the
-                               whole mft and set all Usn entries in all mft
-                               records to zero! (This can take a while!)
-                               The journal is FILE_Extend/$UsnJrnl. Win2k
-                               will recreate the journal and initiate
-                               logging if necessary when mounting the
-                               partition. This, in contrast to disabling the
-                               journal is a very fast process, so the user
-                               won't even notice it. */
+               /* 64*/ leUSN usn;              /* Last update sequence number
+                               of the file.  This is a direct index into the
+                               transaction log file ($UsnJrnl).  It is zero if
+                               the usn journal is disabled or this file has
+                               not been subject to logging yet.  See usnjrnl.h
+                               for details. */
                } __attribute__ ((__packed__)) v3;
        /* sizeof() = 72 bytes (NTFS 3.x) */
        } __attribute__ ((__packed__)) ver;
@@ -943,10 +1024,17 @@ enum {
        FILE_NAME_POSIX         = 0x00,
        /* This is the largest namespace. It is case sensitive and allows all
           Unicode characters except for: '\0' and '/'.  Beware that in
-          WinNT/2k files which eg have the same name except for their case
-          will not be distinguished by the standard utilities and thus a "del
-          filename" will delete both "filename" and "fileName" without
-          warning. */
+          WinNT/2k/2003 by default files which eg have the same name except
+          for their case will not be distinguished by the standard utilities
+          and thus a "del filename" will delete both "filename" and "fileName"
+          without warning.  However if for example Services For Unix (SFU) are
+          installed and the case sensitive option was enabled at installation
+          time, then you can create/access/delete such files.
+          Note that even SFU places restrictions on the filenames beyond the
+          '\0' and '/' and in particular the following set of characters is
+          not allowed: '"', '/', '<', '>', '\'.  All other characters,
+          including the ones no allowed in WIN32 namespace are allowed.
+          Tested with SFU 3.5 (this is now free) running on Windows XP. */
        FILE_NAME_WIN32         = 0x01,
        /* The standard WinNT/2k NTFS long filenames. Case insensitive.  All
           Unicode chars except: '\0', '"', '*', '/', ':', '<', '>', '?', '\',
@@ -986,11 +1074,22 @@ typedef struct {
                                           modified. */
 /* 20*/        sle64 last_access_time;         /* Time this mft record was last
                                           accessed. */
-/* 28*/        sle64 allocated_size;           /* Byte size of allocated space for the
-                                          data attribute. NOTE: Is a multiple
-                                          of the cluster size. */
-/* 30*/        sle64 data_size;                /* Byte size of actual data in data
-                                          attribute. */
+/* 28*/        sle64 allocated_size;           /* Byte size of on-disk allocated space
+                                          for the unnamed data attribute.  So
+                                          for normal $DATA, this is the
+                                          allocated_size from the unnamed
+                                          $DATA attribute and for compressed
+                                          and/or sparse $DATA, this is the
+                                          compressed_size from the unnamed
+                                          $DATA attribute.  For a directory or
+                                          other inode without an unnamed $DATA
+                                          attribute, this is always 0.  NOTE:
+                                          This is a multiple of the cluster
+                                          size. */
+/* 30*/        sle64 data_size;                /* Byte size of actual data in unnamed
+                                          data attribute.  For a directory or
+                                          other inode without an unnamed $DATA
+                                          attribute, this is always 0. */
 /* 38*/        FILE_ATTR_FLAGS file_attributes;        /* Flags describing the file. */
 /* 3c*/        union {
        /* 3c*/ struct {
@@ -1819,12 +1918,13 @@ enum {
        VOLUME_DELETE_USN_UNDERWAY      = const_cpu_to_le16(0x0010),
        VOLUME_REPAIR_OBJECT_ID         = const_cpu_to_le16(0x0020),
 
+       VOLUME_CHKDSK_UNDERWAY          = const_cpu_to_le16(0x4000),
        VOLUME_MODIFIED_BY_CHKDSK       = const_cpu_to_le16(0x8000),
 
-       VOLUME_FLAGS_MASK               = const_cpu_to_le16(0x803f),
+       VOLUME_FLAGS_MASK               = const_cpu_to_le16(0xc03f),
 
        /* To make our life easier when checking if we must mount read-only. */
-       VOLUME_MUST_MOUNT_RO_MASK       = const_cpu_to_le16(0x8037),
+       VOLUME_MUST_MOUNT_RO_MASK       = const_cpu_to_le16(0xc027),
 } __attribute__ ((__packed__));
 
 typedef le16 VOLUME_FLAGS;
@@ -2289,7 +2389,9 @@ typedef struct {
  * Extended attribute flags (8-bit).
  */
 enum {
-       NEED_EA = 0x80
+       NEED_EA = 0x80          /* If set the file to which the EA belongs
+                                  cannot be interpreted without understanding
+                                  the associates extended attributes. */
 } __attribute__ ((__packed__));
 
 typedef u8 EA_FLAGS;
@@ -2297,20 +2399,20 @@ typedef u8 EA_FLAGS;
 /*
  * Attribute: Extended attribute (EA) (0xe0).
  *
- * NOTE: Always non-resident. (Is this true?)
+ * NOTE: Can be resident or non-resident.
  *
  * Like the attribute list and the index buffer list, the EA attribute value is
  * a sequence of EA_ATTR variable length records.
- *
- * FIXME: It appears weird that the EA name is not unicode. Is it true?
  */
 typedef struct {
        le32 next_entry_offset; /* Offset to the next EA_ATTR. */
        EA_FLAGS flags;         /* Flags describing the EA. */
-       u8 ea_name_length;      /* Length of the name of the EA in bytes. */
+       u8 ea_name_length;      /* Length of the name of the EA in bytes
+                                  excluding the '\0' byte terminator. */
        le16 ea_value_length;   /* Byte size of the EA's value. */
-       u8 ea_name[0];          /* Name of the EA. */
-       u8 ea_value[0];         /* The value of the EA. Immediately follows
+       u8 ea_name[0];          /* Name of the EA.  Note this is ASCII, not
+                                  Unicode and it is zero terminated. */
+       u8 ea_value[0];         /* The value of the EA.  Immediately follows
                                   the name. */
 } __attribute__ ((__packed__)) EA_ATTR;