diff --git a/doc/attributes.txt b/doc/attributes.txt index e69de29b..7469dd7e 100644 --- a/doc/attributes.txt +++ b/doc/attributes.txt @@ -0,0 +1,113 @@ +$Id$ + +Notes on the storage of attributes. +=================================== + +Resident attributes +=================== + +Resident attributes are small enough to be stored in the mft record itself. + +When an attribute becomes too big to fit in the mft record or when the number +of attributes grows so large that there is no more space in the mft record, the +largest attribute(s) is(are) made non-resident. (Note, that some attributes +cannot be non-resident.) + +Non-resident attributes +======================= + +Non-resident attributes contain only their non-resident attribute header in the +mft record and the actual attribute value is stored anywhere on the volume +(but not in other mft records). + +The value of the attribute is saved as a sequence of clusters, named virtual +clusters, beginning at virtual cluster number (vcn) zero. Each vcn corresponds +to a cluster on the volume, or a logical cluster number (lcn). The lcns on the +volume begin with lcn zero for the very first cluster on the volume. + +The location of the attribute value is described by the mapping pairs array +present in the non-resident attribute header structure. The mapping pairs array +contains, in compressed form, the mapping between the attribute's vcns and the +corresponding lcns on the volume. + +When the mapping pairs array of a non-resident attribute becomes too large to +fit in the mft record or when there are so many attributes in the mft record +that, even though all attributes that can be non-resident have been made +non-resident, they still do not fit in the mft record, the larger non-resident +attributes are moved away from the mft record to make space. + +This is done by moving whole non-resident attribute header structures to other +mft records and/or by splitting the mapping pairs array of attributes into +several non-resident attribute headers, each containing a chunk of the +original mapping pairs array. These non-resident attribute headers each +describing the same attribute value (but different parts of it) are called +extents. + +Attribute list attribute +======================== + +The attribute list attribute is then added to the base mft record to describe +the location of each attribute. + +The attribute list attribute lists all attributes that belong to this mft +record (with the exception of itself). Each entry in the attribute list +describes the attribute listed and in which mft record it's attribute header can +be found. For resident attributes this will be the same number as the base mft +record in which the attribute list attribute is located itself. For non-resident +attributes, this will be another mft record, called an extension mft record. +Naturally, all extension mft records point back to their base mft record. + +Only one attribute is stored in an extension mft record, even if the attribute +is very small. At least this is the case with Windows NT4 SP6a driver. + +Should the mapping pairs array of an attribute become so large as to not fit +into an extenstion mft record, even though it's attribute is the only attribute +in this extension record, then the attribute is splitt into several extents. +The first extent starts at vcn 0 and has it's lowest vcn value set to zero and +continues up to it's highest vcn value. This is determined by splitting up the +mapping pairs array into chunks which just fit into an extension mft record +each. Thus the first mapping pairs array chunk will determine the value of +the highest vcn for the first extent. The attribute list will contain an entry +for this extent. Then, a second extent is created which has it's lowest vcn +value set to the highest vcn of the previous extent + 1 and the next chunk of +the mapping pairs array is inserted into this extent. Again, an entry for this +extent is placed into the attribute list, and so on, until the whole +non-resident attribute's mapping pairs array has been accomodated. + +Should the attribute list become too big to fit inside the base mft record it +is made non-resident. However, it's maximum value size is determined by the +Windows cache manager to be 256kb (the size of a VACB). Also, the mapping pairs +array of the attribute list has to fit inside the base mft record, as an +attribute list can't be described by itself and attribute lists are not allowed to be nested. + +Compressed attributes +===================== + +The attribute value of each $DATA attribute can be compressed to save space. +If this is the case, the ATTR_IS_COMPRESSED flag is set. + +See the discussion on compression in include/attrib.h for more details. +FIXME: The discussion belongs here! (AIA) + +Sparse attributes (NTFS 3.0+) +============================= + +The attribute value of each $DATA attribute can be sparse to save space. +If this is the case, the ATTR_IS_SPARSE flag is set. Note, that compressed +attributes are by definition sparse, as well as compressed, without having the +ATTR_IS_SPARSE flag set. + +See the discussion on compression in include/attrib.h for more details. +FIXME: The discussion belongs here! (AIA) + +Encrypted attributes (NTFS 3.0+) +================================ + +Since NTFS 3.0, the attribute value of each $DATA attribute can be encrypted, +to protect the contents from spying eyes. If this is the case, the +ATTR_IS_ENCRYPTED flag is set. + +FIXME: Write notes on attribute encryption. The descussions from the articles +"Inside the Encrypting File System" in Windows NT magazine (?) are very good +starting points. (AIA) +