⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 layout.h

📁 linux 内核源代码
💻 H
📖 第 1 页 / 共 5 页
字号:
/* * Attribute compression. * * Only the data attribute is ever compressed in the current ntfs driver in * Windows. Further, compression is only applied when the data attribute is * non-resident. Finally, to use compression, the maximum allowed cluster size * on a volume is 4kib. * * The compression method is based on independently compressing blocks of X * clusters, where X is determined from the compression_unit value found in the * non-resident attribute record header (more precisely: X = 2^compression_unit * clusters). On Windows NT/2k, X always is 16 clusters (compression_unit = 4). * * There are three different cases of how a compression block of X clusters * can be stored: * *   1) The data in the block is all zero (a sparse block): *	  This is stored as a sparse block in the runlist, i.e. the runlist *	  entry has length = X and lcn = -1. The mapping pairs array actually *	  uses a delta_lcn value length of 0, i.e. delta_lcn is not present at *	  all, which is then interpreted by the driver as lcn = -1. *	  NOTE: Even uncompressed files can be sparse on NTFS 3.0 volumes, then *	  the same principles apply as above, except that the length is not *	  restricted to being any particular value. * *   2) The data in the block is not compressed: *	  This happens when compression doesn't reduce the size of the block *	  in clusters. I.e. if compression has a small effect so that the *	  compressed data still occupies X clusters, then the uncompressed data *	  is stored in the block. *	  This case is recognised by the fact that the runlist entry has *	  length = X and lcn >= 0. The mapping pairs array stores this as *	  normal with a run length of X and some specific delta_lcn, i.e. *	  delta_lcn has to be present. * *   3) The data in the block is compressed: *	  The common case. This case is recognised by the fact that the run *	  list entry has length L < X and lcn >= 0. The mapping pairs array *	  stores this as normal with a run length of X and some specific *	  delta_lcn, i.e. delta_lcn has to be present. This runlist entry is *	  immediately followed by a sparse entry with length = X - L and *	  lcn = -1. The latter entry is to make up the vcn counting to the *	  full compression block size X. * * In fact, life is more complicated because adjacent entries of the same type * can be coalesced. This means that one has to keep track of the number of * clusters handled and work on a basis of X clusters at a time being one * block. An example: if length L > X this means that this particular runlist * entry contains a block of length X and part of one or more blocks of length * L - X. Another example: if length L < X, this does not necessarily mean that * the block is compressed as it might be that the lcn changes inside the block * and hence the following runlist entry describes the continuation of the * potentially compressed block. The block would be compressed if the * following runlist entry describes at least X - L sparse clusters, thus * making up the compression block length as described in point 3 above. (Of * course, there can be several runlist entries with small lengths so that the * sparse entry does not follow the first data containing entry with * length < X.) * * NOTE: At the end of the compressed attribute value, there most likely is not * just the right amount of data to make up a compression block, thus this data * is not even attempted to be compressed. It is just stored as is, unless * the number of clusters it occupies is reduced when compressed in which case * it is stored as a compressed compression block, complete with sparse * clusters at the end. *//* * Flags of resident attributes (8-bit). */enum {	RESIDENT_ATTR_IS_INDEXED = 0x01, /* Attribute is referenced in an index					    (has implications for deleting and					    modifying the attribute). */} __attribute__ ((__packed__));typedef u8 RESIDENT_ATTR_FLAGS;/* * Attribute record header. Always aligned to 8-byte boundary. */typedef struct {/*Ofs*//*  0*/	ATTR_TYPE type;		/* The (32-bit) type of the attribute. *//*  4*/	le32 length;		/* Byte size of the resident part of the				   attribute (aligned to 8-byte boundary).				   Used to get to the next attribute. *//*  8*/	u8 non_resident;	/* If 0, attribute is resident.				   If 1, attribute is non-resident. *//*  9*/	u8 name_length;		/* Unicode character size of name of attribute.				   0 if unnamed. *//* 10*/	le16 name_offset;	/* If name_length != 0, the byte offset to the				   beginning of the name from the attribute				   record. Note that the name is stored as a				   Unicode string. When creating, place offset				   just at the end of the record header. Then,				   follow with attribute value or mapping pairs				   array, resident and non-resident attributes				   respectively, aligning to an 8-byte				   boundary. *//* 12*/	ATTR_FLAGS flags;	/* Flags describing the attribute. *//* 14*/	le16 instance;		/* The instance of this attribute record. This				   number is unique within this mft record (see				   MFT_RECORD/next_attribute_instance notes in				   in mft.h for more details). *//* 16*/	union {		/* Resident attributes. */		struct {/* 16 */		le32 value_length;/* Byte size of attribute value. *//* 20 */		le16 value_offset;/* Byte offset of the attribute					     value from the start of the					     attribute record. When creating,					     align to 8-byte boundary if we					     have a name present as this might					     not have a length of a multiple					     of 8-bytes. *//* 22 */		RESIDENT_ATTR_FLAGS flags; /* See above. *//* 23 */		s8 reserved;	  /* Reserved/alignment to 8-byte					     boundary. */		} __attribute__ ((__packed__)) resident;		/* Non-resident attributes. */		struct {/* 16*/			leVCN lowest_vcn;/* Lowest valid virtual cluster number				for this portion of the attribute value or				0 if this is the only extent (usually the				case). - Only when an attribute list is used				does lowest_vcn != 0 ever occur. *//* 24*/			leVCN highest_vcn;/* Highest valid vcn of this extent of				the attribute value. - Usually there is only one				portion, so this usually equals the attribute				value size in clusters minus 1. Can be -1 for				zero length files. Can be 0 for "single extent"				attributes. *//* 32*/			le16 mapping_pairs_offset; /* Byte offset from the				beginning of the structure to the mapping pairs				array which contains the mappings between the				vcns and the logical cluster numbers (lcns).				When creating, place this at the end of this				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				compression unit size to be a power of two				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.*//* 40*/			sle64 allocated_size;	/* Byte size of disk space				allocated to hold the attribute value. Always				is a multiple of the cluster size. When a file				is compressed, this field is a multiple of the				compression block size (2^compression_unit) and				it represents the logically allocated space				rather than the actual on disk usage. For this				use the compressed_size (see below). *//* 48*/			sle64 data_size;	/* Byte size of the attribute				value. Can be larger than allocated_size if				attribute value is compressed or sparse. *//* 56*/			sle64 initialized_size;	/* Byte size of initialized				portion of the attribute value. Usually equals				data_size. *//* sizeof(uncompressed attr) = 64*//* 64*/			sle64 compressed_size;	/* Byte size of the attribute				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;} __attribute__ ((__packed__)) ATTR_RECORD;typedef ATTR_RECORD ATTR_REC;/* * 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 {	FILE_ATTR_READONLY		= const_cpu_to_le32(0x00000001),	FILE_ATTR_HIDDEN		= const_cpu_to_le32(0x00000002),	FILE_ATTR_SYSTEM		= const_cpu_to_le32(0x00000004),	/* Old DOS volid. Unused in NT.	= const_cpu_to_le32(0x00000008), */	FILE_ATTR_DIRECTORY		= const_cpu_to_le32(0x00000010),	/* Note, FILE_ATTR_DIRECTORY is not considered valid in NT.  It is	   reserved for the DOS SUBDIRECTORY flag. */	FILE_ATTR_ARCHIVE		= const_cpu_to_le32(0x00000020),	FILE_ATTR_DEVICE		= const_cpu_to_le32(0x00000040),	FILE_ATTR_NORMAL		= const_cpu_to_le32(0x00000080),	FILE_ATTR_TEMPORARY		= const_cpu_to_le32(0x00000100),	FILE_ATTR_SPARSE_FILE		= const_cpu_to_le32(0x00000200),	FILE_ATTR_REPARSE_POINT		= const_cpu_to_le32(0x00000400),	FILE_ATTR_COMPRESSED		= const_cpu_to_le32(0x00000800),	FILE_ATTR_OFFLINE		= const_cpu_to_le32(0x00001000),	FILE_ATTR_NOT_CONTENT_INDEXED	= const_cpu_to_le32(0x00002000),	FILE_ATTR_ENCRYPTED		= const_cpu_to_le32(0x00004000),	FILE_ATTR_VALID_FLAGS		= const_cpu_to_le32(0x00007fb7),	/* Note, FILE_ATTR_VALID_FLAGS masks out the old DOS VolId and the	   FILE_ATTR_DEVICE and preserves everything else.  This mask is used	   to obtain all flags that are valid for reading. */	FILE_ATTR_VALID_SET_FLAGS	= const_cpu_to_le32(0x000031a7),	/* Note, FILE_ATTR_VALID_SET_FLAGS masks out the old DOS VolId, the	   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 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,	   telling us whether this is a directory or not, i.e. whether it has	   an index root attribute or not. */	FILE_ATTR_DUP_VIEW_INDEX_PRESENT	= const_cpu_to_le32(0x20000000),	/* 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	   filesystem related indexes). */};typedef le32 FILE_ATTR_FLAGS;/* * NOTE on times in NTFS: All times are in MS standard time format, i.e. they * are the number of 100-nanosecond intervals since 1st January 1601, 00:00:00 * universal coordinated time (UTC). (In Linux time starts 1st January 1970, * 00:00:00 UTC and is stored as the number of 1-second intervals since then.) *//* * Attribute: Standard information (0x10). * * NOTE: Always resident. * NOTE: Present in all base file records on a volume. * NOTE: There is conflicting information about the meaning of each of the time *	 fields but the meaning as defined below has been verified to be *	 correct by practical experimentation on Windows NT4 SP6a and is hence *	 assumed to be the one and only correct interpretation. */typedef struct {/*Ofs*//*  0*/	sle64 creation_time;		/* Time file was created. Updated when					   a filename is changed(?). *//*  8*/	sle64 last_data_change_time;	/* Time the data attribute was last					   modified. *//* 16*/	sle64 last_mft_change_time;	/* Time this mft record was last					   modified. *//* 24*/	sle64 last_access_time;		/* Approximate time when the file was					   last accessed (obviously this is not					   updated on read-only volumes). In					   Windows this is only updated when					   accessed if some time delta has					   passed since the last update. Also,					   last access time updates can be					   disabled altogether for speed. *//* 32*/	FILE_ATTR_FLAGS file_attributes; /* Flags describing the file. *//* 36*/	union {	/* NTFS 1.2 */		struct {		/* 36*/	u8 reserved12[12];	/* Reserved/alignment to 8-byte						   boundary. */		} __attribute__ ((__packed__)) v1;	/* sizeof() = 48 bytes */	/* NTFS 3.x */		struct {/* * If a volume has been upgraded from a previous NTFS version, then these * fields are present only if the file has been accessed since the upgrade. * Recognize the difference by comparing the length of the resident attribute * value. If it is 48, then the following fields are missing. If it is 72 then * the fields are present. Maybe just check like this: *	if (resident.ValueLength < sizeof(STANDARD_INFORMATION)) { *		Assume NTFS 1.2- format. *		If (volume version is 3.x) *			Upgrade attribute to NTFS 3.x format. *		else *			Use NTFS 1.2- format for access. *	} else *		Use NTFS 3.x format for access. * Only problem is that it might be legal to set the length of the value to * arbitrarily large values thus spoiling this check. - But chkdsk probably * views that as a corruption, assuming that it behaves like this for all * attributes. */		/* 36*/	le32 maximum_versions;	/* Maximum allowed versions for				file. Zero if version numbering is disabled. */		/* 40*/	le32 version_number;	/* This file's version (if any).				Set to zero if maximum_versions is zero. */		/* 44*/	le32 class_id;		/* Class id from bidirectional				class id index (?). */		/* 48*/	le32 owner_id;		/* Owner_id of the user owning				the file. Translate via $Q index in FILE_Extend				/$Quota to the quota control entry for the user				owning the file. Zero if quotas are disabled. */		/* 52*/	le32 security_id;	/* Security_id for the file.				Translate via $SII index and $SDS data stream				in FILE_Secure to the security descriptor. */		/* 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. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -