2 * inode.c - Inode handling code. Part of the Linux-NTFS project.
4 * Copyright (c) 2002 Anton Altaparmakov
6 * This program/include file is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as published
8 * by the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program/include file is distributed in the hope that it will be
12 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
13 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program (in the main directory of the Linux-NTFS
18 * distribution in the file COPYING); if not, write to the Free Software
19 * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
38 * __ntfs_inode_allocate - desc
40 static __inline__ ntfs_inode *__ntfs_inode_allocate(ntfs_volume *vol)
44 ni = (ntfs_inode*)calloc(1, sizeof(ntfs_inode));
53 * ntfs_inode_allocate - desc
55 ntfs_inode *ntfs_inode_allocate(ntfs_volume *vol)
57 return __ntfs_inode_allocate(vol);
63 * __ntfs_inode_release - desc
65 static __inline__ int __ntfs_inode_release(ntfs_inode *ni)
68 Dputs("Eeek. Discarding dirty inode!");
69 if (NInoAttrList(ni) && ni->attr_list)
71 if (NInoAttrListNonResident(ni) && ni->attr_list_rl)
72 free(ni->attr_list_rl);
80 * ntfs_inode_open - open an inode ready for access
81 * @vol: volume to get the inode from
82 * @mref: inode number / mft record number to open
84 * Allocate an ntfs_inode structure and initialize it for the given inode
85 * specified by @mref. @mref specifies the inode number / mft record to read,
86 * including the sequence number, which can be 0 if no sequence number checking
89 * Then, allocate a buffer for the mft record, read the mft record from the
90 * volume @vol, and attach it to the ntfs_inode structure (->mrec). The
91 * mft record is mst deprotected and sanity checked for validity and we abort
92 * if deprotection or checks fail.
94 * Finally, search for an attribute list attribute in the mft record and if one
95 * is found, load the attribute list attribute value and attach it to the
96 * ntfs_inode structure (->attr_list). Also set the NI_AttrList bit to indicate
97 * this as well as the NI_AttrListNonResident bit if the the attribute list is
98 * non-resident. In that case, also attach the decompressed runlist to the
99 * ntfs_inode structure (->attr_list_rl).
101 * Return a pointer to the ntfs_inode structure on success or NULL on error,
102 * with errno set to the error code.
104 ntfs_inode *ntfs_inode_open(ntfs_volume *vol, const MFT_REF mref)
108 ntfs_attr_search_ctx *ctx;
111 Dprintf("%s(): Entering for inode 0x%Lx.\n", __FUNCTION__, MREF(mref));
116 ni = __ntfs_inode_allocate(vol);
119 if (ntfs_file_record_read(vol, mref, &ni->mrec, NULL))
121 if (!(ni->mrec->flags & MFT_RECORD_IN_USE))
123 ni->mft_no = MREF(mref);
124 ctx = ntfs_attr_get_search_ctx(ni, NULL);
127 if (ntfs_attr_lookup(AT_ATTRIBUTE_LIST, AT_UNNAMED, 0, 0, 0, NULL, 0,
131 /* Attribute list attribute not present so we are done. */
132 ntfs_attr_put_search_ctx(ctx);
136 l = ntfs_get_attribute_value_length(ctx->attr);
143 ni->attr_list_size = l;
144 ni->attr_list = malloc(ni->attr_list_size);
147 l = ntfs_get_attribute_value(vol, ni->mrec, ctx->attr, ni->attr_list);
150 if (l != ni->attr_list_size) {
154 if (!ctx->attr->non_resident) {
155 /* Attribute list attribute is resident so we are done. */
156 ntfs_attr_put_search_ctx(ctx);
159 NInoSetAttrListNonResident(ni);
160 // FIXME: We are duplicating work here! (AIA)
161 ni->attr_list_rl = ntfs_mapping_pairs_decompress(vol, ctx->attr, NULL);
162 if (ni->attr_list_rl) {
163 /* We got the runlist, so we are done. */
164 ntfs_attr_put_search_ctx(ctx);
171 ntfs_attr_put_search_ctx(ctx);
175 __ntfs_inode_release(ni);
181 * ntfs_inode_close - close an ntfs inode and free all associated memory
182 * @ni: ntfs inode to close
184 * Make sure the ntfs inode @ni is clean.
186 * If the ntfs inode @ni is a base inode, close all associated extent inodes,
187 * then deallocate all memory attached to it, and finally free the ntfs inode
190 * If it is an extent inode, we disconnect it from its base inode before we
193 * Return 0 on success or -1 on error with errno set to the error code. On
194 * error, @ni has not been freed. The user should attempt to handle the error
195 * and call ntfs_inode_close() again. The following error codes are defined:
197 * EBUSY @ni and/or its attribute list runlist is/are dirty and the
198 * attempt to write it/them to disk failed.
199 * EINVAL @ni is invalid (probably it is an extent inode).
200 * EIO I/O error while trying to write inode to disk.
202 int ntfs_inode_close(ntfs_inode *ni)
204 /* If we have dirty metadata, write it out. */
205 if (NInoDirty(ni) || NInoAttrListDirty(ni)) {
206 if (ntfs_inode_sync(ni)) {
212 /* Is this a base inode with mapped extent inodes? */
213 if (ni->nr_extents > 0) {
216 // FIXME: Handle dirty case for each extent inode! (AIA)
217 for (i = 0; i < ni->nr_extents; i++)
218 __ntfs_inode_release(ni->extent_nis[i]);
219 free(ni->extent_nis);
220 } else if (ni->nr_extents == -1) {
221 ntfs_inode **tmp_nis;
226 * If the inode is an extent inode, disconnect it from the
227 * base inode before destroying it.
229 base_ni = ni->base_ni;
230 for (i = 0; i < base_ni->nr_extents; ++i) {
231 tmp_nis = base_ni->extent_nis;
232 if (tmp_nis[i] != ni)
234 /* Found it. Disconnect. */
235 memmove(tmp_nis + i, tmp_nis + i + 1,
236 (base_ni->nr_extents - i - 1) *
237 sizeof(ntfs_inode *));
238 base_ni->nr_extents--;
239 /* Resize the memory buffer. */
240 tmp_nis = realloc(tmp_nis, base_ni->nr_extents *
241 sizeof(ntfs_inode *));
242 /* Ignore errors, they don't really matter. */
244 base_ni->extent_nis = tmp_nis;
245 /* Allow for error checking. */
249 Dputs("Extent inode was not attached to base inode! "
250 "Weird! Continuing regardless.");
252 return __ntfs_inode_release(ni);
256 * ntfs_extent_inode_open - load an extent inode and attach it to its base
257 * @base_ni: base ntfs inode
258 * @mref: mft reference of the extent inode to load (in little endian)
260 * First check if the extent inode @mref is already attached to the base ntfs
261 * inode @base_ni, and if so, return a pointer to the attached extent inode.
263 * If the extent inode is not already attached to the base inode, allocate an
264 * ntfs_inode structure and initialize it for the given inode @mref. @mref
265 * specifies the inode number / mft record to read, including the sequence
266 * number, which can be 0 if no sequence number checking is to be performed.
268 * Then, allocate a buffer for the mft record, read the mft record from the
269 * volume @base_ni->vol, and attach it to the ntfs_inode structure (->mrec).
270 * The mft record is mst deprotected and sanity checked for validity and we
271 * abort if deprotection or checks fail.
273 * Finally attach the ntfs inode to its base inode @base_ni and return a
274 * pointer to the ntfs_inode structure on success or NULL on error, with errno
275 * set to the error code.
277 * Note, extent inodes are never closed directly. They are automatically
278 * disposed off by the closing of the base inode.
280 ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni, const MFT_REF mref)
282 u64 mft_no = MREF_LE(mref);
284 ntfs_inode **extent_nis;
291 Dprintf("Opening extent inode %Lu (base mft record 0x%Lu).\n",
292 (unsigned long long)mft_no,
293 (unsigned long long)base_ni->mft_no);
294 /* Is the extent inode already open and attached to the base inode? */
295 if (base_ni->nr_extents > 0) {
296 extent_nis = base_ni->extent_nis;
297 for (i = 0; i < base_ni->nr_extents; i++) {
301 if (mft_no != ni->mft_no)
303 /* Verify the sequence number if given. */
304 seq_no = MSEQNO_LE(mref);
305 if (seq_no && seq_no != le16_to_cpu(
306 ni->mrec->sequence_number)) {
307 Dputs("Found stale extent mft reference! "
308 "Corrupt file system. Run "
313 /* We are done, return the extent inode. */
317 /* Wasn't there, we need to load the extent inode. */
318 ni = __ntfs_inode_allocate(base_ni->vol);
321 if (ntfs_file_record_read(base_ni->vol, le64_to_cpu(mref), &ni->mrec,
326 ni->base_ni = base_ni;
327 /* Attach extent inode to base inode, reallocating memory if needed. */
328 if (!(base_ni->nr_extents & 3)) {
329 i = (base_ni->nr_extents + 4) * sizeof(ntfs_inode *);
331 extent_nis = (ntfs_inode**)malloc(i);
334 if (base_ni->extent_nis) {
335 memcpy(extent_nis, base_ni->extent_nis,
336 i - 4 * sizeof(ntfs_inode *));
337 free(base_ni->extent_nis);
339 base_ni->extent_nis = extent_nis;
341 base_ni->extent_nis[base_ni->nr_extents++] = ni;
345 __ntfs_inode_release(ni);
347 Dperror("Failed to open extent inode");
352 * ntfs_inode_sync - write the inode (and its dirty extents) to disk
353 * @ni: ntfs inode to write
355 * Write the inode @ni to disk as well as its dirty extent inodes if such
356 * exist and @ni is a base inode. If @ni is an extent inode, only @ni is
357 * written completely disregarding its base inode and any other extent inodes.
359 * For a base inode with dirty extent inodes if any writes fail for whatever
360 * reason, the failing inode is skipped and the sync process is continued. At
361 * the end the error condition that brought about the failure is returned. Thus
362 * the smallest amount of data loss possible occurs.
364 * Return 0 on success or -1 on error with errno set to the error code.
365 * The following error codes are defined:
366 * EINVAL - Invalid arguments were passed to the function.
367 * ENOTSUP - Syncing requires code that has not been imlemented yet.
368 * EBUSY - Inode and/or one of its extents is busy, try again later.
369 * EIO - I/O error while writing the inode (or one of its extents).
371 int ntfs_inode_sync(ntfs_inode *ni)
380 // TODO: Implement writing out of attribute list attribute. (AIA)
381 if (NInoAttrListDirty(ni)) {
386 /* Write this inode out to the $MFT (and $MFTMirr if applicable). */
387 if (NInoTestAndClearDirty(ni)) {
388 if (ntfs_mft_record_write(ni->vol, ni->mft_no, ni->mrec)) {
389 if (!err || errno == EIO) {
397 /* If this is a base inode with extents write all dirty extents, too. */
398 if (ni->nr_extents > 0) {
401 for (i = 0; i < ni->nr_extents; ++i) {
404 eni = ni->extent_nis[i];
405 if (NInoTestAndClearDirty(eni)) {
406 if (ntfs_mft_record_write(eni->vol, eni->mft_no,
408 if (!err || errno == EIO) {