NTFS_MFT_RECORD_ALLOC

Section: (9)
Updated: 09 October 2005
Index Return to Main Contents

 

NAME

ntfs_mft_record_alloc - allocate an mft record on an ntfs volume  

SYNOPSIS

"SYNOPSIS"

ntfs_inode * ntfs_mft_record_alloc (ntfs_volume * vol, const int mode, ntfs_inode * base_ni, MFT_RECORD ** mrec);  

ARGUMENTS

vol
[IN] volume on which to allocate the mft record
mode
[IN] mode if want a file or directory, i.e. base inode or 0
base_ni
[IN] open base inode if allocating an extent mft record or NULL
mrec
[OUT] on successful return this is the mapped mft record
 

DESCRIPTION

Allocate an mft record in $MFT/$DATA of an open ntfs volume vol.

If base_ni is NULL make the mft record a base mft record, i.e. a file or direvctory inode, and allocate it at the default allocator position. In this case mode is the file mode as given to us by the caller. We in particular use mode to distinguish whether a file or a directory is being created (S_IFDIR(mode) and S_IFREG(mode), respectively).

If base_ni is not NULL make the allocated mft record an extent record, allocate it starting at the mft record after the base mft record and attach the allocated and opened ntfs inode to the base inode base_ni. In this case mode must be 0 as it is meaningless for extent inodes.

You need to check the return value with IS_ERR. If false, the function was successful and the return value is the now opened ntfs inode of the allocated mft record. *mrec is then set to the allocated, mapped, pinned, and locked mft record. If IS_ERR is true, the function failed and the error code is obtained from PTR_ERR(return value). *mrec is undefined in this case.  

ALLOCATION STRATEGY

To find a free mft record, we scan the mft bitmap for a zero bit. To optimize this we start scanning at the place specified by base_ni or if base_ni is NULL we start where we last stopped and we perform wrap around when we reach the end. Note, we do not try to allocate mft records below number 24 because numbers 0 to 15 are the defined system files anyway and 16 to 24 are special in that they are used for storing extension mft records for the $DATA attribute of $MFT. This is required to avoid the possibility of creating a runlist with a circular dependency which once written to disk can never be read in again. Windows will only use records 16 to 24 for normal files if the volume is completely out of space. We never use them which means that when the volume is really out of space we cannot create any more files while Windows can still create up to 8 small files. We can start doing this at some later time, it does not matter much for now.

When scanning the mft bitmap, we only search up to the last allocated mft record. If there are no free records left in the range 24 to number of allocated mft records, then we extend the $MFT/$DATA attribute in order to create free mft records. We extend the allocated size of $MFT/$DATA by 16 records at a time or one cluster, if cluster size is above 16kiB. If there is not sufficient space to do this, we try to extend by a single mft record or one cluster, if cluster size is above the mft record size.

No matter how many mft records we allocate, we initialize only the first allocated mft record, incrementing mft data size and initialized size accordingly, open an ntfs_inode for it and return it to the caller, unless there are less than 24 mft records, in which case we allocate and initialize mft records until we reach record 24 which we consider as the first free mft record for use by normal files.

If during any stage we overflow the initialized data in the mft bitmap, we extend the initialized size (and data size) by 8 bytes, allocating another cluster if required. The bitmap data size has to be at least equal to the number of mft records in the mft, but it can be bigger, in which case the superflous bits are padded with zeroes.

Thus, when we return successfully (IS_ERR is false), we will have: - initialized / extended the mft bitmap if necessary, - initialized / extended the mft data if necessary, - set the bit corresponding to the mft record being allocated in the mft bitmap, - opened an ntfs_inode for the allocated mft record, and we will have - returned the ntfs_inode as well as the allocated mapped, pinned, and locked mft record.

On error, the volume will be left in a consistent state and no record will be allocated. If rolling back a partial operation fails, we may leave some inconsistent metadata in which case we set NVolErrors so the volume is left dirty when unmounted.

Note, this function cannot make use of most of the normal functions, like for example for attribute resizing, etc, because when the run list overflows the base mft record and an attribute list is used, it is very important that the extension mft records used to store the $DATA attribute of $MFT can be reached without having to read the information contained inside them, as this would make it impossible to find them in the first place after the volume is unmounted. $MFT/$BITMAP probably does not need to follow this rule because the bitmap is not essential for finding the mft records, but on the other hand, handling the bitmap in this special way would make life easier because otherwise there might be circular invocations of functions when reading the bitmap.


 

Index

NAME
SYNOPSIS
ARGUMENTS
DESCRIPTION
ALLOCATION STRATEGY

This document was created by man2html, using the manual pages.
Time: 00:02:34 GMT, October 09, 2005