1N/A * inode.c - Inode handling code. Part of the Linux-NTFS project. 1N/A * Copyright (c) 2002-2005 Anton Altaparmakov 1N/A * Copyright (c) 2004-2007 Yura Pakhuchiy 1N/A * Copyright (c) 2004-2005 Richard Russon 1N/A * modify it under the terms of the GNU General Public License as published 1N/A * by the Free Software Foundation; either version 2 of the License, or 1N/A * (at your option) any later version. 1N/A * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 1N/A * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1N/A * GNU General Public License for more details. 1N/A * You should have received a copy of the GNU General Public License 1N/A * along with this program (in the main directory of the Linux-NTFS 1N/A * distribution in the file COPYING); if not, write to the Free Software 1N/A * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 1N/A * __ntfs_inode_allocate - Create and initialise an NTFS inode object 1N/A * ntfs_inode_allocate - Create an NTFS inode object 1N/A * __ntfs_inode_release - Destroy an NTFS inode object 1N/A * __ntfs_inode_add_to_cache - do not use me! Only for internal library use. 1N/A * ntfs_inode_open - open an inode ready for access 1N/A * @vol: volume to get the inode from 1N/A * @mref: inode number / mft record number to open 1N/A * Allocate an ntfs_inode structure and initialize it for the given inode 1N/A * specified by @mref. @mref specifies the inode number / mft record to read, 1N/A * including the sequence number, which can be 0 if no sequence number checking 1N/A * is to be performed. 1N/A * Then, allocate a buffer for the mft record, read the mft record from the 1N/A * volume @vol, and attach it to the ntfs_inode structure (->mrec). The 1N/A * mft record is mst deprotected and sanity checked for validity and we abort 1N/A * if deprotection or checks fail. 1N/A * Finally, search for an attribute list attribute in the mft record and if one 1N/A * is found, load the attribute list attribute value and attach it to the 1N/A * ntfs_inode structure (->attr_list). Also set the NI_AttrList bit to indicate 1N/A * Return a pointer to the ntfs_inode structure on success or NULL on error, 1N/A * with errno set to the error code. 1N/A /* Check cache, maybe this inode already opened? */ 1N/A "reference count and return it.\n");
1N/A /* Search failed. Properly open inode. */ 1N/A /* Receive some basic information about inode. */ 1N/A /* Set attribute list information. */ 1N/A /* Attribute list attribute does not present. */ 1N/A /* Directory or special file. */ 1N/A * ntfs_inode_close - close an ntfs inode and free all associated memory 1N/A * @ni: ntfs inode to close 1N/A * Make sure the ntfs inode @ni is clean. 1N/A * If the ntfs inode @ni is a base inode, close all associated extent inodes, 1N/A * then deallocate all memory attached to it, and finally free the ntfs inode 1N/A * If it is an extent inode, we disconnect it from its base inode before we 1N/A * It is OK to pass NULL to this function, it is just noop in this case. 1N/A * Return 0 on success or -1 on error with errno set to the error code. On 1N/A * error, @ni has not been freed. The user should attempt to handle the error 1N/A * and call ntfs_inode_close() again. The following error codes are defined: 1N/A * EBUSY @ni and/or its attribute list runlist is/are dirty and the 1N/A * EINVAL @ni is invalid (probably it is an extent inode). 1N/A * EIO I/O error while trying to write inode to disk. 1N/A /* Decrement number of users. If there are left then just return. */ 1N/A /* Check whether all attributes of this inode are closed. */ 1N/A "We definitely have memory leak. " 1N/A "Continue anyway.\n",
"ntfs_inode_close");
1N/A /* If we have dirty metadata, write it out. */ 1N/A /* Is this a base inode with mapped extent inodes? */ 1N/A * If the inode is an extent inode, disconnect it from the 1N/A * base inode before destroying it. 1N/A /* Found it. Disconnect. */ 1N/A /* Buffer should be for multiple of four extents. */ 1N/A * ElectricFence is unhappy with realloc(x,0) as free(x) 1N/A * thus we explicitly separate these two cases. 1N/A /* Resize the memory buffer. */ 1N/A /* Ignore errors, they don't really matter. */ 1N/A /* Allow for error checking. */ 1N/A "inode! Continuing regardless.\n");
1N/A /* Remove inode from the list of opened inodes. */ 1N/A * ntfs_extent_inode_open - load an extent inode and attach it to its base 1N/A * @base_ni: base ntfs inode 1N/A * @mref: mft reference of the extent inode to load (in little endian) 1N/A * First check if the extent inode @mref is already attached to the base ntfs 1N/A * inode @base_ni, and if so, return a pointer to the attached extent inode. 1N/A * If the extent inode is not already attached to the base inode, allocate an 1N/A * ntfs_inode structure and initialize it for the given inode @mref. @mref 1N/A * specifies the inode number / mft record to read, including the sequence 1N/A * number, which can be 0 if no sequence number checking is to be performed. 1N/A * Then, allocate a buffer for the mft record, read the mft record from the 1N/A * volume @base_ni->vol, and attach it to the ntfs_inode structure (->mrec). 1N/A * The mft record is mst deprotected and sanity checked for validity and we 1N/A * abort if deprotection or checks fail. 1N/A * Finally attach the ntfs inode to its base inode @base_ni and return a 1N/A * pointer to the ntfs_inode structure on success or NULL on error, with errno 1N/A * set to the error code. 1N/A * Note, extent inodes are never closed directly. They are automatically 1N/A * disposed off by the closing of the base inode. 1N/A "(base MFT record 0x%llx).\n",
1N/A /* Is the extent inode already open and attached to the base inode? */ 1N/A /* Verify the sequence number if given. */ 1N/A "reference! Corrupt file " 1N/A "system. Run chkdsk.\n");
1N/A /* We are done, return the extent inode. */ 1N/A /* Wasn't there, we need to load the extent inode. */ 1N/A /* Attach extent inode to base inode, reallocating memory if needed. */ 1N/A * ntfs_inode_attach_all_extents - attach all extents for target inode 1N/A * @ni: opened ntfs inode for which perform attach 1N/A * Return 0 on success and -1 on error with errno set to the error code. 1N/A /* Inode haven't got attribute list, thus nothing to attach. */ 1N/A /* Walk through attribute list and attach all extents. */ 1N/A "inode (attr type 0x%x " 1N/A "references to it).\n",
1N/A * ntfs_inode_sync_standard_information - update standard information attribute 1N/A * @ni: ntfs inode to update standard information 1N/A * Return 0 on success or -1 on error with errno set to the error code. 1N/A * ntfs_inode_sync_file_name - update FILE_NAME attributes 1N/A * @ni: ntfs inode to update FILE_NAME attributes 1N/A * Update all FILE_NAME attributes for inode @ni in the index. 1N/A * Return 0 on success or -1 on error with errno set to the error code. 1N/A /* Walk through all FILE_NAME attributes and update them. */ 1N/A * WARNING: We cheater here and obtain 2 attribute 1N/A * search contexts for one inode (first we obtained 1N/A * above, second will be obtained inside 1N/A * ntfs_index_lookup), it's acceptable for library, 1N/A * but will lock kernel. 1N/A /* Update flags and file size. */ 1N/A /* Check for real error occurred. */ 1N/A * ntfs_inode_sync - write the inode (and its dirty extents) to disk 1N/A * @ni: ntfs inode to write 1N/A * Write the inode @ni to disk as well as its dirty extent inodes if such 1N/A * exist and @ni is a base inode. If @ni is an extent inode, only @ni is 1N/A * written completely disregarding its base inode and any other extent inodes. 1N/A * For a base inode with dirty extent inodes if any writes fail for whatever 1N/A * reason, the failing inode is skipped and the sync process is continued. At 1N/A * the end the error condition that brought about the failure is returned. Thus 1N/A * the smallest amount of data loss possible occurs. 1N/A * Return 0 on success or -1 on error with errno set to the error code. 1N/A * The following error codes are defined: 1N/A * EINVAL - Invalid arguments were passed to the function. 1N/A * EBUSY - Inode and/or one of its extents is busy, try again later. 1N/A * EIO - I/O error while writing the inode (or one of its extents). 1N/A /* Update FILE_NAME's in the index. */ 1N/A /* Write out attribute list from cache to disk. */ 1N/A "(open failed).\n");
1N/A "(invalid size).\n");
1N/A /* Write this inode out to the $MFT (and $MFTMirr if applicable). */ 1N/A /* Update STANDARD_INFORMATION. */ 1N/A /* Write MFT record. */ 1N/A /* If this is a base inode with extents write all dirty extents, too. */ 1N/A * ntfs_inode_add_attrlist - add attribute list to inode and fill it 1N/A * @ni: opened ntfs inode to which add attribute list 1N/A * Return 0 on success or -1 on error with errno set to the error code. 1N/A * The following error codes are defined: 1N/A * EINVAL - Invalid arguments were passed to the function. 1N/A * EEXIST - Attribute list already exist. 1N/A * ENOMEM - Not enough memory to perform add. 1N/A /* Form attribute list. */ 1N/A /* Walk through all attributes. */ 1N/A /* Calculate new length of attribute list. */ 1N/A /* Allocate more memory if needed. */ 1N/A 0x40));
/* Valgrind. */ 1N/A /* Add attribute to attribute list. */ 1N/A /* Check for real error occurred. */ 1N/A /* Deallocate trailing memory. */ 1N/A /* Set in-memory attribute list. */ 1N/A /* Free space if there is not enough it for $ATTRIBUTE_LIST. */ 1N/A /* Failed to free space. */ 1N/A "$ATTRIBUTE_LIST.\n");
1N/A /* Add $ATTRIBUTE_LIST to mft record. */ 1N/A /* Prevent ntfs_attr_recorm_rm from freeing attribute list. */ 1N/A /* Remove $ATTRIBUTE_LIST record. */ 1N/A /* Setup back in-memory runlist. */ 1N/A * Scan attribute list for attributes that placed not in the base MFT 1N/A * record and move them to it. 1N/A "back attribute to base MFT record.\n");
1N/A /* Remove in-memory attribute list. */ 1N/A * ntfs_inode_free_space - free space in the MFT record of inode 1N/A * @ni: ntfs inode in which MFT record free space 1N/A * @size: amount of space needed to free 1N/A * Return 0 on success or -1 on error with errno set to the error code. 1N/A * Chkdsk complain if $STANDARD_INFORMATION is not in the base MFT 1N/A * record. FIXME: I'm not sure in this, need to recheck. For now simply 1N/A * do not move $STANDARD_INFORMATION at all. 1N/A * Also we can't move $ATTRIBUTE_LIST from base MFT_RECORD, so position 1N/A * search context on first attribute after $STANDARD_INFORMATION and 1N/A * Why we reposition instead of simply skip this attributes during 1N/A * enumeration? Because in case we have got only in-memory attribute 1N/A * list ntfs_attr_lookup will fail when it will try to find 1N/A * Check whether attribute is from different MFT record. If so, 1N/A * find next, because we don't need such. 1N/A /* Move away attribute. */ 1N/A /* Check whether we done. */ 1N/A * Reposition to first attribute after $STANDARD_INFORMATION and 1N/A * $ATTRIBUTE_LIST (see comments upwards). 1N/A * ntfs_inode_update_times - update selected time fields for ntfs inode 1N/A * @ni: ntfs inode for which update time fields 1N/A * @mask: select which time fields should be updated 1N/A * This function updates time fields to current time. Fields to update are 1N/A * selected using @mask (see enum @ntfs_time_update_flags for posssible values). 1N/A * ntfs_inode_badclus_bad - check for $Badclus:$Bad data attribute 1N/A * @mft_no: mft record number where @attr is present 1N/A * @attr: attribute record used to check for the $Bad attribute 1N/A * Check if the mft record given by @mft_no and @attr contains the bad sector 1N/A * list. Please note that mft record numbers describing $Badclus extent inodes 1N/A * will not match the current $Badclus:$Bad check. 1N/A * On success return 1 if the file is $Badclus:$Bad, otherwise return 0. 1N/A * On error return -1 with errno set to the error code.