"Fossies" - the Fresh Open Source Software Archive

Member "ntfs-3g_ntfsprogs-2017.3.23/libntfs-3g/inode.c" (23 Mar 2017, 43988 Bytes) of package /linux/misc/ntfs-3g_ntfsprogs-2017.3.23.tgz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "inode.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3g_ntfsprogs-2016.2.22_vs_3g_ntfsprogs-2017.3.23.

    1 /**
    2  * inode.c - Inode handling code. Originated from the Linux-NTFS project.
    3  *
    4  * Copyright (c) 2002-2005 Anton Altaparmakov
    5  * Copyright (c) 2002-2008 Szabolcs Szakacsits
    6  * Copyright (c) 2004-2007 Yura Pakhuchiy
    7  * Copyright (c) 2004-2005 Richard Russon
    8  * Copyright (c) 2009-2010 Jean-Pierre Andre
    9  *
   10  * This program/include file is free software; you can redistribute it and/or
   11  * modify it under the terms of the GNU General Public License as published
   12  * by the Free Software Foundation; either version 2 of the License, or
   13  * (at your option) any later version.
   14  *
   15  * This program/include file is distributed in the hope that it will be
   16  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
   17  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   18  * GNU General Public License for more details.
   19  *
   20  * You should have received a copy of the GNU General Public License
   21  * along with this program (in the main directory of the NTFS-3G
   22  * distribution in the file COPYING); if not, write to the Free Software
   23  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   24  */
   25 
   26 #ifdef HAVE_CONFIG_H
   27 #include "config.h"
   28 #endif
   29 
   30 #ifdef HAVE_STDLIB_H
   31 #include <stdlib.h>
   32 #endif
   33 #ifdef HAVE_STRING_H
   34 #include <string.h>
   35 #endif
   36 #ifdef HAVE_ERRNO_H
   37 #include <errno.h>
   38 #endif
   39 
   40 #include "param.h"
   41 #include "compat.h"
   42 #include "types.h"
   43 #include "volume.h"
   44 #include "cache.h"
   45 #include "inode.h"
   46 #include "attrib.h"
   47 #include "debug.h"
   48 #include "mft.h"
   49 #include "attrlist.h"
   50 #include "runlist.h"
   51 #include "lcnalloc.h"
   52 #include "index.h"
   53 #include "dir.h"
   54 #include "ntfstime.h"
   55 #include "logging.h"
   56 #include "misc.h"
   57 #include "xattrs.h"
   58 
   59 ntfs_inode *ntfs_inode_base(ntfs_inode *ni)
   60 {
   61     if (ni->nr_extents == -1)
   62         return ni->base_ni;
   63     return ni;
   64 }
   65 
   66 /**
   67  * ntfs_inode_mark_dirty - set the inode (and its base inode if it exists) dirty
   68  * @ni:     ntfs inode to set dirty
   69  *
   70  * Set the inode @ni dirty so it is written out later (at the latest at
   71  * ntfs_inode_close() time). If @ni is an extent inode, set the base inode
   72  * dirty, too.
   73  *
   74  * This function cannot fail.
   75  */
   76 void ntfs_inode_mark_dirty(ntfs_inode *ni)
   77 {
   78     NInoSetDirty(ni);
   79     if (ni->nr_extents == -1)
   80         NInoSetDirty(ni->base_ni);
   81 }
   82 
   83 /**
   84  * __ntfs_inode_allocate - Create and initialise an NTFS inode object
   85  * @vol:
   86  *
   87  * Description...
   88  *
   89  * Returns:
   90  */
   91 static ntfs_inode *__ntfs_inode_allocate(ntfs_volume *vol)
   92 {
   93     ntfs_inode *ni;
   94 
   95     ni = (ntfs_inode*)ntfs_calloc(sizeof(ntfs_inode));
   96     if (ni)
   97         ni->vol = vol;
   98     return ni;
   99 }
  100 
  101 /**
  102  * ntfs_inode_allocate - Create an NTFS inode object
  103  * @vol:
  104  *
  105  * Description...
  106  *
  107  * Returns:
  108  */
  109 ntfs_inode *ntfs_inode_allocate(ntfs_volume *vol)
  110 {
  111     return __ntfs_inode_allocate(vol);
  112 }
  113 
  114 /**
  115  * __ntfs_inode_release - Destroy an NTFS inode object
  116  * @ni:
  117  *
  118  * Description...
  119  *
  120  * Returns:
  121  */
  122 static void __ntfs_inode_release(ntfs_inode *ni)
  123 {
  124     if (NInoDirty(ni))
  125         ntfs_log_error("Releasing dirty inode %lld!\n", 
  126                    (long long)ni->mft_no);
  127     if (NInoAttrList(ni) && ni->attr_list)
  128         free(ni->attr_list);
  129     free(ni->mrec);
  130     free(ni);
  131     return;
  132 }
  133 
  134 /**
  135  * ntfs_inode_open - open an inode ready for access
  136  * @vol:    volume to get the inode from
  137  * @mref:   inode number / mft record number to open
  138  *
  139  * Allocate an ntfs_inode structure and initialize it for the given inode
  140  * specified by @mref. @mref specifies the inode number / mft record to read,
  141  * including the sequence number, which can be 0 if no sequence number checking
  142  * is to be performed.
  143  *
  144  * Then, allocate a buffer for the mft record, read the mft record from the
  145  * volume @vol, and attach it to the ntfs_inode structure (->mrec). The
  146  * mft record is mst deprotected and sanity checked for validity and we abort
  147  * if deprotection or checks fail.
  148  *
  149  * Finally, search for an attribute list attribute in the mft record and if one
  150  * is found, load the attribute list attribute value and attach it to the
  151  * ntfs_inode structure (->attr_list). Also set the NI_AttrList bit to indicate
  152  * this.
  153  *
  154  * Return a pointer to the ntfs_inode structure on success or NULL on error,
  155  * with errno set to the error code.
  156  */
  157 static ntfs_inode *ntfs_inode_real_open(ntfs_volume *vol, const MFT_REF mref)
  158 {
  159     s64 l;
  160     ntfs_inode *ni = NULL;
  161     ntfs_attr_search_ctx *ctx;
  162     STANDARD_INFORMATION *std_info;
  163     le32 lthle;
  164     int olderrno;
  165 
  166     ntfs_log_enter("Entering for inode %lld\n", (long long)MREF(mref));
  167     if (!vol) {
  168         errno = EINVAL;
  169         goto out;
  170     }
  171     ni = __ntfs_inode_allocate(vol);
  172     if (!ni)
  173         goto out;
  174     if (ntfs_file_record_read(vol, mref, &ni->mrec, NULL))
  175         goto err_out;
  176     if (!(ni->mrec->flags & MFT_RECORD_IN_USE)) {
  177         errno = ENOENT;
  178         goto err_out;
  179     }
  180     ni->mft_no = MREF(mref);
  181     ctx = ntfs_attr_get_search_ctx(ni, NULL);
  182     if (!ctx)
  183         goto err_out;
  184     /* Receive some basic information about inode. */
  185     if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED,
  186                 0, CASE_SENSITIVE, 0, NULL, 0, ctx)) {
  187         if (!ni->mrec->base_mft_record)
  188             ntfs_log_perror("No STANDARD_INFORMATION in base record"
  189                     " %lld", (long long)MREF(mref));
  190         goto put_err_out;
  191     }
  192     std_info = (STANDARD_INFORMATION *)((u8 *)ctx->attr +
  193             le16_to_cpu(ctx->attr->value_offset));
  194     ni->flags = std_info->file_attributes;
  195     ni->creation_time = std_info->creation_time;
  196     ni->last_data_change_time = std_info->last_data_change_time;
  197     ni->last_mft_change_time = std_info->last_mft_change_time;
  198     ni->last_access_time = std_info->last_access_time;
  199         /* JPA insert v3 extensions if present */
  200                 /* length may be seen as 72 (v1.x) or 96 (v3.x) */
  201     lthle = ctx->attr->length;
  202     if (le32_to_cpu(lthle) > sizeof(STANDARD_INFORMATION)) {
  203         set_nino_flag(ni, v3_Extensions);
  204         ni->owner_id = std_info->owner_id;
  205         ni->security_id = std_info->security_id;
  206         ni->quota_charged = std_info->quota_charged;
  207         ni->usn = std_info->usn;
  208     } else {
  209         clear_nino_flag(ni, v3_Extensions);
  210         ni->owner_id = const_cpu_to_le32(0);
  211         ni->security_id = const_cpu_to_le32(0);
  212     }
  213     /* Set attribute list information. */
  214     olderrno = errno;
  215     if (ntfs_attr_lookup(AT_ATTRIBUTE_LIST, AT_UNNAMED, 0,
  216             CASE_SENSITIVE, 0, NULL, 0, ctx)) {
  217         if (errno != ENOENT)
  218             goto put_err_out;
  219         /* Attribute list attribute does not present. */
  220         /* restore previous errno to avoid misinterpretation */
  221         errno = olderrno;
  222         goto get_size;
  223     }
  224     NInoSetAttrList(ni);
  225     l = ntfs_get_attribute_value_length(ctx->attr);
  226     if (!l)
  227         goto put_err_out;
  228     if (l > 0x40000) {
  229         errno = EIO;
  230         ntfs_log_perror("Too large attrlist attribute (%lld), inode "
  231                 "%lld", (long long)l, (long long)MREF(mref));
  232         goto put_err_out;
  233     }
  234     ni->attr_list_size = l;
  235     ni->attr_list = ntfs_malloc(ni->attr_list_size);
  236     if (!ni->attr_list)
  237         goto put_err_out;
  238     l = ntfs_get_attribute_value(vol, ctx->attr, ni->attr_list);
  239     if (!l)
  240         goto put_err_out;
  241     if (l != ni->attr_list_size) {
  242         errno = EIO;
  243         ntfs_log_perror("Unexpected attrlist size (%lld <> %u), inode "
  244                 "%lld", (long long)l, ni->attr_list_size, 
  245                 (long long)MREF(mref));
  246         goto put_err_out;
  247     }
  248 get_size:
  249     olderrno = errno;
  250     if (ntfs_attr_lookup(AT_DATA, AT_UNNAMED, 0, 0, 0, NULL, 0, ctx)) {
  251         if (errno != ENOENT)
  252             goto put_err_out;
  253         /* Directory or special file. */
  254         /* restore previous errno to avoid misinterpretation */
  255         errno = olderrno;
  256         ni->data_size = ni->allocated_size = 0;
  257     } else {
  258         if (ctx->attr->non_resident) {
  259             ni->data_size = sle64_to_cpu(ctx->attr->data_size);
  260             if (ctx->attr->flags &
  261                     (ATTR_IS_COMPRESSED | ATTR_IS_SPARSE))
  262                 ni->allocated_size = sle64_to_cpu(
  263                         ctx->attr->compressed_size);
  264             else
  265                 ni->allocated_size = sle64_to_cpu(
  266                         ctx->attr->allocated_size);
  267         } else {
  268             ni->data_size = le32_to_cpu(ctx->attr->value_length);
  269             ni->allocated_size = (ni->data_size + 7) & ~7;
  270         }
  271         set_nino_flag(ni,KnownSize);
  272     }
  273     ntfs_attr_put_search_ctx(ctx);
  274 out:    
  275     ntfs_log_leave("\n");
  276     return ni;
  277 
  278 put_err_out:
  279     ntfs_attr_put_search_ctx(ctx);
  280 err_out:
  281     __ntfs_inode_release(ni);
  282     ni = NULL;
  283     goto out;
  284 }
  285 
  286 /**
  287  * ntfs_inode_close - close an ntfs inode and free all associated memory
  288  * @ni:     ntfs inode to close
  289  *
  290  * Make sure the ntfs inode @ni is clean.
  291  *
  292  * If the ntfs inode @ni is a base inode, close all associated extent inodes,
  293  * then deallocate all memory attached to it, and finally free the ntfs inode
  294  * structure itself.
  295  *
  296  * If it is an extent inode, we disconnect it from its base inode before we
  297  * destroy it.
  298  *
  299  * It is OK to pass NULL to this function, it is just noop in this case.
  300  *
  301  * Return 0 on success or -1 on error with errno set to the error code. On
  302  * error, @ni has not been freed. The user should attempt to handle the error
  303  * and call ntfs_inode_close() again. The following error codes are defined:
  304  *
  305  *  EBUSY   @ni and/or its attribute list runlist is/are dirty and the
  306  *      attempt to write it/them to disk failed.
  307  *  EINVAL  @ni is invalid (probably it is an extent inode).
  308  *  EIO I/O error while trying to write inode to disk.
  309  */
  310 
  311 int ntfs_inode_real_close(ntfs_inode *ni)
  312 {
  313     int ret = -1;
  314     
  315     if (!ni)
  316         return 0;
  317 
  318     ntfs_log_enter("Entering for inode %lld\n", (long long)ni->mft_no);
  319 
  320     /* If we have dirty metadata, write it out. */
  321     if (NInoDirty(ni) || NInoAttrListDirty(ni)) {
  322         if (ntfs_inode_sync(ni)) {
  323             if (errno != EIO)
  324                 errno = EBUSY;
  325             goto err;
  326         }
  327     }
  328     /* Is this a base inode with mapped extent inodes? */
  329     if (ni->nr_extents > 0) {
  330         while (ni->nr_extents > 0) {
  331             if (ntfs_inode_real_close(ni->extent_nis[0])) {
  332                 if (errno != EIO)
  333                     errno = EBUSY;
  334                 goto err;
  335             }
  336         }
  337     } else if (ni->nr_extents == -1) {
  338         ntfs_inode **tmp_nis;
  339         ntfs_inode *base_ni;
  340         s32 i;
  341 
  342         /*
  343          * If the inode is an extent inode, disconnect it from the
  344          * base inode before destroying it.
  345          */
  346         base_ni = ni->base_ni;
  347         for (i = 0; i < base_ni->nr_extents; ++i) {
  348             tmp_nis = base_ni->extent_nis;
  349             if (tmp_nis[i] != ni)
  350                 continue;
  351             /* Found it. Disconnect. */
  352             memmove(tmp_nis + i, tmp_nis + i + 1,
  353                     (base_ni->nr_extents - i - 1) *
  354                     sizeof(ntfs_inode *));
  355             /* Buffer should be for multiple of four extents. */
  356             if ((--base_ni->nr_extents) & 3) {
  357                 i = -1;
  358                 break;
  359             }
  360             /*
  361              * ElectricFence is unhappy with realloc(x,0) as free(x)
  362              * thus we explicitly separate these two cases.
  363              */
  364             if (base_ni->nr_extents) {
  365                 /* Resize the memory buffer. */
  366                 tmp_nis = realloc(tmp_nis, base_ni->nr_extents *
  367                           sizeof(ntfs_inode *));
  368                 /* Ignore errors, they don't really matter. */
  369                 if (tmp_nis)
  370                     base_ni->extent_nis = tmp_nis;
  371             } else if (tmp_nis) {
  372                 free(tmp_nis);
  373                 base_ni->extent_nis = (ntfs_inode**)NULL;
  374             }
  375             /* Allow for error checking. */
  376             i = -1;
  377             break;
  378         }
  379         
  380         /* 
  381          *  We could successfully sync, so only log this error
  382          *  and try to sync other inode extents too.
  383          */
  384         if (i != -1)
  385             ntfs_log_error("Extent inode %lld was not found\n",
  386                        (long long)ni->mft_no);
  387     }
  388     
  389     __ntfs_inode_release(ni);
  390     ret = 0;
  391 err:
  392     ntfs_log_leave("\n");
  393     return ret;
  394 }
  395 
  396 #if CACHE_NIDATA_SIZE
  397 
  398 /*
  399  *      Free an inode structure when there is not more space
  400  *  in the cache
  401  */
  402 
  403 void ntfs_inode_nidata_free(const struct CACHED_GENERIC *cached)
  404 {
  405         ntfs_inode_real_close(((const struct CACHED_NIDATA*)cached)->ni);
  406 }
  407 
  408 /*
  409  *      Compute a hash value for an inode entry
  410  */
  411 
  412 int ntfs_inode_nidata_hash(const struct CACHED_GENERIC *item)
  413 {
  414     return (((const struct CACHED_NIDATA*)item)->inum
  415             % (2*CACHE_NIDATA_SIZE));
  416 }
  417 
  418 /*
  419  *      inum comparing for entering/fetching from cache
  420  */
  421 
  422 static int idata_cache_compare(const struct CACHED_GENERIC *cached,
  423             const struct CACHED_GENERIC *wanted)
  424 {
  425     return (((const struct CACHED_NIDATA*)cached)->inum
  426             != ((const struct CACHED_NIDATA*)wanted)->inum);
  427 }
  428 
  429 /*
  430  *      Invalidate an inode entry when not needed anymore.
  431  *  The entry should have been synced, it may be reused later,
  432  *  if it is requested before it is dropped from cache.
  433  */
  434 
  435 void ntfs_inode_invalidate(ntfs_volume *vol, const MFT_REF mref)
  436 {
  437     struct CACHED_NIDATA item;
  438 
  439     item.inum = MREF(mref);
  440     item.ni = (ntfs_inode*)NULL;
  441     item.pathname = (const char*)NULL;
  442     item.varsize = 0;
  443     ntfs_invalidate_cache(vol->nidata_cache,
  444                 GENERIC(&item),idata_cache_compare,CACHE_FREE);
  445 }
  446 
  447 #endif
  448 
  449 /*
  450  *      Open an inode
  451  *
  452  *  When possible, an entry recorded in the cache is reused
  453  *
  454  *  **NEVER REOPEN** an inode, this can lead to a duplicated
  455  *  cache entry (hard to detect), and to an obsolete one being
  456  *  reused. System files are however protected from being cached.
  457  */
  458 
  459 ntfs_inode *ntfs_inode_open(ntfs_volume *vol, const MFT_REF mref)
  460 {
  461     ntfs_inode *ni;
  462 #if CACHE_NIDATA_SIZE
  463     struct CACHED_NIDATA item;
  464     struct CACHED_NIDATA *cached;
  465 
  466         /* fetch idata from cache */
  467     item.inum = MREF(mref);
  468     debug_double_inode(item.inum,1);
  469     item.pathname = (const char*)NULL;
  470     item.varsize = 0;
  471     cached = (struct CACHED_NIDATA*)ntfs_fetch_cache(vol->nidata_cache,
  472                 GENERIC(&item),idata_cache_compare);
  473     if (cached) {
  474         ni = cached->ni;
  475         /* do not keep open entries in cache */
  476         ntfs_remove_cache(vol->nidata_cache,
  477                 (struct CACHED_GENERIC*)cached,0);
  478     } else {
  479         ni = ntfs_inode_real_open(vol, mref);
  480     }
  481     if (!ni) {
  482         debug_double_inode(item.inum, 0);
  483     }
  484 #else
  485     ni = ntfs_inode_real_open(vol, mref);
  486 #endif
  487     return (ni);
  488 }
  489 
  490 /*
  491  *      Close an inode entry
  492  *
  493  *  If cacheing is in use, the entry is synced and kept available
  494  *  in cache for further use.
  495  *
  496  *  System files (inode < 16 or having the IS_4 flag) are protected
  497  *  against being cached.
  498  */
  499 
  500 int ntfs_inode_close(ntfs_inode *ni)
  501 {
  502     int res;
  503 #if CACHE_NIDATA_SIZE
  504     BOOL dirty;
  505     struct CACHED_NIDATA item;
  506 
  507     if (ni) {
  508         debug_double_inode(ni->mft_no,0);
  509         /* do not cache system files : could lead to double entries */
  510         if (ni->vol && ni->vol->nidata_cache
  511             && ((ni->mft_no == FILE_root)
  512                 || ((ni->mft_no >= FILE_first_user)
  513                 && !(ni->mrec->flags & MFT_RECORD_IS_4)))) {
  514             /* If we have dirty metadata, write it out. */
  515             dirty = NInoDirty(ni) || NInoAttrListDirty(ni);
  516             if (dirty) {
  517                 res = ntfs_inode_sync(ni);
  518                     /* do a real close if sync failed */
  519                 if (res)
  520                     ntfs_inode_real_close(ni);
  521             } else
  522                 res = 0;
  523 
  524             if (!res) {
  525                     /* feed idata into cache */
  526                 item.inum = ni->mft_no;
  527                 item.ni = ni;
  528                 item.pathname = (const char*)NULL;
  529                 item.varsize = 0;
  530                 debug_cached_inode(ni);
  531                 ntfs_enter_cache(ni->vol->nidata_cache,
  532                     GENERIC(&item), idata_cache_compare);
  533             }
  534         } else {
  535             /* cache not ready or system file, really close */
  536             res = ntfs_inode_real_close(ni);
  537         }
  538     } else
  539         res = 0;
  540 #else
  541     res = ntfs_inode_real_close(ni);
  542 #endif
  543     return (res);
  544 }
  545 
  546 /**
  547  * ntfs_extent_inode_open - load an extent inode and attach it to its base
  548  * @base_ni:    base ntfs inode
  549  * @mref:   mft reference of the extent inode to load (in little endian)
  550  *
  551  * First check if the extent inode @mref is already attached to the base ntfs
  552  * inode @base_ni, and if so, return a pointer to the attached extent inode.
  553  *
  554  * If the extent inode is not already attached to the base inode, allocate an
  555  * ntfs_inode structure and initialize it for the given inode @mref. @mref
  556  * specifies the inode number / mft record to read, including the sequence
  557  * number, which can be 0 if no sequence number checking is to be performed.
  558  *
  559  * Then, allocate a buffer for the mft record, read the mft record from the
  560  * volume @base_ni->vol, and attach it to the ntfs_inode structure (->mrec).
  561  * The mft record is mst deprotected and sanity checked for validity and we
  562  * abort if deprotection or checks fail.
  563  *
  564  * Finally attach the ntfs inode to its base inode @base_ni and return a
  565  * pointer to the ntfs_inode structure on success or NULL on error, with errno
  566  * set to the error code.
  567  *
  568  * Note, extent inodes are never closed directly. They are automatically
  569  * disposed off by the closing of the base inode.
  570  */
  571 ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni, const leMFT_REF mref)
  572 {
  573     u64 mft_no = MREF_LE(mref);
  574     VCN extent_vcn;
  575     runlist_element *rl;
  576     ntfs_volume *vol;
  577     ntfs_inode *ni = NULL;
  578     ntfs_inode **extent_nis;
  579     int i;
  580 
  581     if (!base_ni) {
  582         errno = EINVAL;
  583         ntfs_log_perror("%s", __FUNCTION__);
  584         return NULL;
  585     }
  586     
  587     ntfs_log_enter("Opening extent inode %lld (base mft record %lld).\n",
  588             (unsigned long long)mft_no,
  589             (unsigned long long)base_ni->mft_no);
  590     
  591     if (!base_ni->mft_no) {
  592             /*
  593              * When getting extents of MFT, we must be sure
  594              * they are in the MFT part which has already
  595              * been mapped, otherwise we fall into an endless
  596              * recursion.
  597              * Situations have been met where extents locations
  598              * are described in themselves.
  599              * This is a severe error which chkdsk cannot fix.
  600              */
  601         vol = base_ni->vol;
  602         extent_vcn = mft_no << vol->mft_record_size_bits
  603                 >> vol->cluster_size_bits;
  604         rl = vol->mft_na->rl;
  605         if (rl) {
  606             while (rl->length
  607                 && ((rl->vcn + rl->length) <= extent_vcn))
  608                 rl++;
  609         }
  610         if (!rl || (rl->lcn < 0)) {
  611             ntfs_log_error("MFT is corrupt, cannot read"
  612                 " its unmapped extent record %lld\n",
  613                     (long long)mft_no);
  614             ntfs_log_error("Note : chkdsk cannot fix this,"
  615                 " try ntfsfix\n");
  616             errno = EIO;
  617             ni = (ntfs_inode*)NULL;
  618             goto out;
  619         }
  620     }
  621 
  622     /* Is the extent inode already open and attached to the base inode? */
  623     if (base_ni->nr_extents > 0) {
  624         extent_nis = base_ni->extent_nis;
  625         for (i = 0; i < base_ni->nr_extents; i++) {
  626             u16 seq_no;
  627 
  628             ni = extent_nis[i];
  629             if (mft_no != ni->mft_no)
  630                 continue;
  631             /* Verify the sequence number if given. */
  632             seq_no = MSEQNO_LE(mref);
  633             if (seq_no && seq_no != le16_to_cpu(
  634                     ni->mrec->sequence_number)) {
  635                 errno = EIO;
  636                 ntfs_log_perror("Found stale extent mft "
  637                     "reference mft=%lld",
  638                     (long long)ni->mft_no);
  639                 goto out;
  640             }
  641             goto out;
  642         }
  643     }
  644     /* Wasn't there, we need to load the extent inode. */
  645     ni = __ntfs_inode_allocate(base_ni->vol);
  646     if (!ni)
  647         goto out;
  648     if (ntfs_file_record_read(base_ni->vol, le64_to_cpu(mref), &ni->mrec, NULL))
  649         goto err_out;
  650     ni->mft_no = mft_no;
  651     ni->nr_extents = -1;
  652     ni->base_ni = base_ni;
  653     /* Attach extent inode to base inode, reallocating memory if needed. */
  654     if (!(base_ni->nr_extents & 3)) {
  655         i = (base_ni->nr_extents + 4) * sizeof(ntfs_inode *);
  656 
  657         extent_nis = ntfs_malloc(i);
  658         if (!extent_nis)
  659             goto err_out;
  660         if (base_ni->nr_extents) {
  661             memcpy(extent_nis, base_ni->extent_nis,
  662                     i - 4 * sizeof(ntfs_inode *));
  663             free(base_ni->extent_nis);
  664         }
  665         base_ni->extent_nis = extent_nis;
  666     }
  667     base_ni->extent_nis[base_ni->nr_extents++] = ni;
  668 out:
  669     ntfs_log_leave("\n");
  670     return ni;
  671 err_out:
  672     __ntfs_inode_release(ni);
  673     ni = NULL;
  674     goto out;
  675 }
  676 
  677 /**
  678  * ntfs_inode_attach_all_extents - attach all extents for target inode
  679  * @ni:     opened ntfs inode for which perform attach
  680  *
  681  * Return 0 on success and -1 on error with errno set to the error code.
  682  */
  683 int ntfs_inode_attach_all_extents(ntfs_inode *ni)
  684 {
  685     ATTR_LIST_ENTRY *ale;
  686     u64 prev_attached = 0;
  687 
  688     if (!ni) {
  689         ntfs_log_trace("Invalid arguments.\n");
  690         errno = EINVAL;
  691         return -1;
  692     }
  693 
  694     if (ni->nr_extents == -1)
  695         ni = ni->base_ni;
  696 
  697     ntfs_log_trace("Entering for inode 0x%llx.\n", (long long) ni->mft_no);
  698 
  699     /* Inode haven't got attribute list, thus nothing to attach. */
  700     if (!NInoAttrList(ni))
  701         return 0;
  702 
  703     if (!ni->attr_list) {
  704         ntfs_log_trace("Corrupt in-memory struct.\n");
  705         errno = EINVAL;
  706         return -1;
  707     }
  708 
  709     /* Walk through attribute list and attach all extents. */
  710     errno = 0;
  711     ale = (ATTR_LIST_ENTRY *)ni->attr_list;
  712     while ((u8*)ale < ni->attr_list + ni->attr_list_size) {
  713         if (ni->mft_no != MREF_LE(ale->mft_reference) &&
  714                 prev_attached != MREF_LE(ale->mft_reference)) {
  715             if (!ntfs_extent_inode_open(ni, ale->mft_reference)) {
  716                 ntfs_log_trace("Couldn't attach extent inode.\n");
  717                 return -1;
  718             }
  719             prev_attached = MREF_LE(ale->mft_reference);
  720         }
  721         ale = (ATTR_LIST_ENTRY *)((u8*)ale + le16_to_cpu(ale->length));
  722     }
  723     return 0;
  724 }
  725 
  726 /**
  727  * ntfs_inode_sync_standard_information - update standard information attribute
  728  * @ni:     ntfs inode to update standard information
  729  *
  730  * Return 0 on success or -1 on error with errno set to the error code.
  731  */
  732 static int ntfs_inode_sync_standard_information(ntfs_inode *ni)
  733 {
  734     ntfs_attr_search_ctx *ctx;
  735     STANDARD_INFORMATION *std_info;
  736     u32 lth;
  737     le32 lthle;
  738 
  739     ntfs_log_trace("Entering for inode %lld\n", (long long)ni->mft_no);
  740 
  741     ctx = ntfs_attr_get_search_ctx(ni, NULL);
  742     if (!ctx)
  743         return -1;
  744     if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED,
  745                  0, CASE_SENSITIVE, 0, NULL, 0, ctx)) {
  746         ntfs_log_perror("Failed to sync standard info (inode %lld)",
  747                 (long long)ni->mft_no);
  748         ntfs_attr_put_search_ctx(ctx);
  749         return -1;
  750     }
  751     std_info = (STANDARD_INFORMATION *)((u8 *)ctx->attr +
  752             le16_to_cpu(ctx->attr->value_offset));
  753     std_info->file_attributes = ni->flags;
  754     if (!test_nino_flag(ni, TimesSet)) {
  755         std_info->creation_time = ni->creation_time;
  756         std_info->last_data_change_time = ni->last_data_change_time;
  757         std_info->last_mft_change_time = ni->last_mft_change_time;
  758         std_info->last_access_time = ni->last_access_time;
  759     }
  760 
  761         /* JPA update v3.x extensions, ensuring consistency */
  762 
  763     lthle = ctx->attr->length;
  764     lth = le32_to_cpu(lthle);
  765     if (test_nino_flag(ni, v3_Extensions)
  766         && (lth <= sizeof(STANDARD_INFORMATION)))
  767         ntfs_log_error("bad sync of standard information\n");
  768 
  769     if (lth > sizeof(STANDARD_INFORMATION)) {
  770         std_info->owner_id = ni->owner_id;
  771         std_info->security_id = ni->security_id;
  772         std_info->quota_charged = ni->quota_charged;
  773         std_info->usn = ni->usn;
  774     }
  775     ntfs_inode_mark_dirty(ctx->ntfs_ino);
  776     ntfs_attr_put_search_ctx(ctx);
  777     return 0;
  778 }
  779 
  780 /**
  781  * ntfs_inode_sync_file_name - update FILE_NAME attributes
  782  * @ni:     ntfs inode to update FILE_NAME attributes
  783  *
  784  * Update all FILE_NAME attributes for inode @ni in the index.
  785  *
  786  * Return 0 on success or -1 on error with errno set to the error code.
  787  */
  788 static int ntfs_inode_sync_file_name(ntfs_inode *ni, ntfs_inode *dir_ni)
  789 {
  790     ntfs_attr_search_ctx *ctx = NULL;
  791     ntfs_index_context *ictx;
  792     ntfs_inode *index_ni;
  793     FILE_NAME_ATTR *fn;
  794     FILE_NAME_ATTR *fnx;
  795     REPARSE_POINT *rpp;
  796     le32 reparse_tag;
  797     int err = 0;
  798 
  799     ntfs_log_trace("Entering for inode %lld\n", (long long)ni->mft_no);
  800 
  801     ctx = ntfs_attr_get_search_ctx(ni, NULL);
  802     if (!ctx) {
  803         err = errno;
  804         goto err_out;
  805     }
  806     /* Collect the reparse tag, if any */
  807     reparse_tag = const_cpu_to_le32(0);
  808     if (ni->flags & FILE_ATTR_REPARSE_POINT) {
  809         if (!ntfs_attr_lookup(AT_REPARSE_POINT, NULL,
  810                 0, CASE_SENSITIVE, 0, NULL, 0, ctx)) {
  811             rpp = (REPARSE_POINT*)((u8 *)ctx->attr +
  812                     le16_to_cpu(ctx->attr->value_offset));
  813             reparse_tag = rpp->reparse_tag;
  814         }
  815         ntfs_attr_reinit_search_ctx(ctx);
  816     }
  817     /* Walk through all FILE_NAME attributes and update them. */
  818     while (!ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, 0, 0, NULL, 0, ctx)) {
  819         fn = (FILE_NAME_ATTR *)((u8 *)ctx->attr +
  820                 le16_to_cpu(ctx->attr->value_offset));
  821         if (MREF_LE(fn->parent_directory) == ni->mft_no) {
  822             /*
  823              * WARNING: We cheat here and obtain 2 attribute
  824              * search contexts for one inode (first we obtained
  825              * above, second will be obtained inside
  826              * ntfs_index_lookup), it's acceptable for library,
  827              * but will deadlock in the kernel.
  828              */
  829             index_ni = ni;
  830         } else
  831             if (dir_ni)
  832                 index_ni = dir_ni;
  833             else
  834                 index_ni = ntfs_inode_open(ni->vol, 
  835                     le64_to_cpu(fn->parent_directory));
  836         if (!index_ni) {
  837             if (!err)
  838                 err = errno;
  839             ntfs_log_perror("Failed to open inode %lld with index",
  840                 (long long)le64_to_cpu(fn->parent_directory));
  841             continue;
  842         }
  843         ictx = ntfs_index_ctx_get(index_ni, NTFS_INDEX_I30, 4);
  844         if (!ictx) {
  845             if (!err)
  846                 err = errno;
  847             ntfs_log_perror("Failed to get index ctx, inode %lld",
  848                     (long long)index_ni->mft_no);
  849             if ((ni != index_ni) && !dir_ni
  850                 && ntfs_inode_close(index_ni) && !err)
  851                 err = errno;
  852             continue;
  853         }
  854         if (ntfs_index_lookup(fn, sizeof(FILE_NAME_ATTR), ictx)) {
  855             if (!err) {
  856                 if (errno == ENOENT)
  857                     err = EIO;
  858                 else
  859                     err = errno;
  860             }
  861             ntfs_log_perror("Index lookup failed, inode %lld",
  862                     (long long)index_ni->mft_no);
  863             ntfs_index_ctx_put(ictx);
  864             if (ni != index_ni && ntfs_inode_close(index_ni) && !err)
  865                 err = errno;
  866             continue;
  867         }
  868         /* Update flags and file size. */
  869         fnx = (FILE_NAME_ATTR *)ictx->data;
  870         fnx->file_attributes =
  871                 (fnx->file_attributes & ~FILE_ATTR_VALID_FLAGS) |
  872                 (ni->flags & FILE_ATTR_VALID_FLAGS);
  873         if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)
  874             fnx->data_size = fnx->allocated_size
  875                 = const_cpu_to_sle64(0);
  876         else {
  877             fnx->allocated_size = cpu_to_sle64(ni->allocated_size);
  878             fnx->data_size = cpu_to_sle64(ni->data_size);
  879             /*
  880              * The file name record has also to be fixed if some
  881              * attribute update implied the unnamed data to be
  882              * made non-resident
  883              */
  884             fn->allocated_size = fnx->allocated_size;
  885         }
  886             /* update or clear the reparse tag in the index */
  887         fnx->reparse_point_tag = reparse_tag;
  888         if (!test_nino_flag(ni, TimesSet)) {
  889             fnx->creation_time = ni->creation_time;
  890             fnx->last_data_change_time = ni->last_data_change_time;
  891             fnx->last_mft_change_time = ni->last_mft_change_time;
  892             fnx->last_access_time = ni->last_access_time;
  893         } else {
  894             fnx->creation_time = fn->creation_time;
  895             fnx->last_data_change_time = fn->last_data_change_time;
  896             fnx->last_mft_change_time = fn->last_mft_change_time;
  897             fnx->last_access_time = fn->last_access_time;
  898         }
  899         ntfs_index_entry_mark_dirty(ictx);
  900         ntfs_index_ctx_put(ictx);
  901         if ((ni != index_ni) && !dir_ni
  902             && ntfs_inode_close(index_ni) && !err)
  903             err = errno;
  904     }
  905     /* Check for real error occurred. */
  906     if (errno != ENOENT) {
  907         err = errno;
  908         ntfs_log_perror("Attribute lookup failed, inode %lld",
  909                 (long long)ni->mft_no);
  910         goto err_out;
  911     }
  912     ntfs_attr_put_search_ctx(ctx);
  913     if (err) {
  914         errno = err;
  915         return -1;
  916     }
  917     return 0;
  918 err_out:
  919     if (ctx)
  920         ntfs_attr_put_search_ctx(ctx);
  921     errno = err;
  922     return -1;
  923 }
  924 
  925 /**
  926  * ntfs_inode_sync - write the inode (and its dirty extents) to disk
  927  * @ni:     ntfs inode to write
  928  *
  929  * Write the inode @ni to disk as well as its dirty extent inodes if such
  930  * exist and @ni is a base inode. If @ni is an extent inode, only @ni is
  931  * written completely disregarding its base inode and any other extent inodes.
  932  *
  933  * For a base inode with dirty extent inodes if any writes fail for whatever
  934  * reason, the failing inode is skipped and the sync process is continued. At
  935  * the end the error condition that brought about the failure is returned. Thus
  936  * the smallest amount of data loss possible occurs.
  937  *
  938  * Return 0 on success or -1 on error with errno set to the error code.
  939  * The following error codes are defined:
  940  *  EINVAL  - Invalid arguments were passed to the function.
  941  *  EBUSY   - Inode and/or one of its extents is busy, try again later.
  942  *  EIO - I/O error while writing the inode (or one of its extents).
  943  */
  944 static int ntfs_inode_sync_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
  945 {
  946     int ret = 0;
  947     int err = 0;
  948     if (!ni) {
  949         errno = EINVAL;
  950         ntfs_log_error("Failed to sync NULL inode\n");
  951         return -1;
  952     }
  953 
  954     ntfs_log_enter("Entering for inode %lld\n", (long long)ni->mft_no);
  955 
  956     /* Update STANDARD_INFORMATION. */
  957     if ((ni->mrec->flags & MFT_RECORD_IN_USE) && ni->nr_extents != -1 &&
  958             ntfs_inode_sync_standard_information(ni)) {
  959         if (!err || errno == EIO) {
  960             err = errno;
  961             if (err != EIO)
  962                 err = EBUSY;
  963         }
  964     }
  965 
  966     /* Update FILE_NAME's in the index. */
  967     if ((ni->mrec->flags & MFT_RECORD_IN_USE) && ni->nr_extents != -1 &&
  968             NInoFileNameTestAndClearDirty(ni) &&
  969             ntfs_inode_sync_file_name(ni, dir_ni)) {
  970         if (!err || errno == EIO) {
  971             err = errno;
  972             if (err != EIO)
  973                 err = EBUSY;
  974         }
  975         ntfs_log_perror("Failed to sync FILE_NAME (inode %lld)",
  976                 (long long)ni->mft_no);
  977         NInoFileNameSetDirty(ni);
  978     }
  979 
  980     /* Write out attribute list from cache to disk. */
  981     if ((ni->mrec->flags & MFT_RECORD_IN_USE) && ni->nr_extents != -1 &&
  982             NInoAttrList(ni) && NInoAttrListTestAndClearDirty(ni)) {
  983         ntfs_attr *na;
  984 
  985         na = ntfs_attr_open(ni, AT_ATTRIBUTE_LIST, AT_UNNAMED, 0);
  986         if (!na) {
  987             if (!err || errno == EIO) {
  988                 err = errno;
  989                 if (err != EIO)
  990                     err = EBUSY;
  991                 ntfs_log_perror("Attribute list sync failed "
  992                         "(open, inode %lld)",
  993                         (long long)ni->mft_no);
  994             }
  995             NInoAttrListSetDirty(ni);
  996             goto sync_inode;
  997         } 
  998         
  999         if (na->data_size == ni->attr_list_size) {
 1000             if (ntfs_attr_pwrite(na, 0, ni->attr_list_size,
 1001                         ni->attr_list) != ni->attr_list_size) {
 1002                 if (!err || errno == EIO) {
 1003                     err = errno;
 1004                     if (err != EIO)
 1005                         err = EBUSY;
 1006                     ntfs_log_perror("Attribute list sync "
 1007                         "failed (write, inode %lld)",
 1008                         (long long)ni->mft_no);
 1009                 }
 1010                 NInoAttrListSetDirty(ni);
 1011             }
 1012         } else {
 1013             err = EIO;
 1014             ntfs_log_error("Attribute list sync failed (bad size, "
 1015                        "inode %lld)\n", (long long)ni->mft_no);
 1016             NInoAttrListSetDirty(ni);
 1017         }
 1018         ntfs_attr_close(na);
 1019     }
 1020     
 1021 sync_inode:
 1022     /* Write this inode out to the $MFT (and $MFTMirr if applicable). */
 1023     if (NInoTestAndClearDirty(ni)) {
 1024         if (ntfs_mft_record_write(ni->vol, ni->mft_no, ni->mrec)) {
 1025             if (!err || errno == EIO) {
 1026                 err = errno;
 1027                 if (err != EIO)
 1028                     err = EBUSY;
 1029             }
 1030             NInoSetDirty(ni);
 1031             ntfs_log_perror("MFT record sync failed, inode %lld",
 1032                     (long long)ni->mft_no);
 1033         }
 1034     }
 1035 
 1036     /* If this is a base inode with extents write all dirty extents, too. */
 1037     if (ni->nr_extents > 0) {
 1038         s32 i;
 1039 
 1040         for (i = 0; i < ni->nr_extents; ++i) {
 1041             ntfs_inode *eni;
 1042 
 1043             eni = ni->extent_nis[i];
 1044             if (!NInoTestAndClearDirty(eni))
 1045                 continue;
 1046             
 1047             if (ntfs_mft_record_write(eni->vol, eni->mft_no, 
 1048                           eni->mrec)) {
 1049                 if (!err || errno == EIO) {
 1050                     err = errno;
 1051                     if (err != EIO)
 1052                         err = EBUSY;
 1053                 }
 1054                 NInoSetDirty(eni);
 1055                 ntfs_log_perror("Extent MFT record sync failed,"
 1056                         " inode %lld/%lld",
 1057                         (long long)ni->mft_no,
 1058                         (long long)eni->mft_no);
 1059             }
 1060         }
 1061     }
 1062 
 1063     if (err) {
 1064         errno = err;
 1065         ret = -1;
 1066     }
 1067     
 1068     ntfs_log_leave("\n");
 1069     return ret;
 1070 }
 1071 
 1072 int ntfs_inode_sync(ntfs_inode *ni)
 1073 {
 1074     return (ntfs_inode_sync_in_dir(ni, (ntfs_inode*)NULL));
 1075 }
 1076 
 1077 /*
 1078  *      Close an inode with an open parent inode
 1079  */
 1080 
 1081 int ntfs_inode_close_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
 1082 {
 1083     int res;
 1084 
 1085     res = ntfs_inode_sync_in_dir(ni, dir_ni);
 1086     if (res) {
 1087         if (errno != EIO)
 1088             errno = EBUSY;
 1089     } else
 1090         res = ntfs_inode_close(ni);
 1091     return (res);
 1092 }
 1093 
 1094 /**
 1095  * ntfs_inode_add_attrlist - add attribute list to inode and fill it
 1096  * @ni: opened ntfs inode to which add attribute list
 1097  *
 1098  * Return 0 on success or -1 on error with errno set to the error code.
 1099  * The following error codes are defined:
 1100  *  EINVAL  - Invalid arguments were passed to the function.
 1101  *  EEXIST  - Attribute list already exist.
 1102  *  EIO - Input/Ouput error occurred.
 1103  *  ENOMEM  - Not enough memory to perform add.
 1104  */
 1105 int ntfs_inode_add_attrlist(ntfs_inode *ni)
 1106 {
 1107     int err;
 1108     ntfs_attr_search_ctx *ctx;
 1109     u8 *al = NULL, *aln;
 1110     int al_len = 0;
 1111     ATTR_LIST_ENTRY *ale = NULL;
 1112     ntfs_attr *na;
 1113 
 1114     if (!ni) {
 1115         errno = EINVAL;
 1116         ntfs_log_perror("%s", __FUNCTION__);
 1117         return -1;
 1118     }
 1119 
 1120     ntfs_log_trace("inode %llu\n", (unsigned long long) ni->mft_no);
 1121 
 1122     if (NInoAttrList(ni) || ni->nr_extents) {
 1123         errno = EEXIST;
 1124         ntfs_log_perror("Inode already has attribute list");
 1125         return -1;
 1126     }
 1127 
 1128     /* Form attribute list. */
 1129     ctx = ntfs_attr_get_search_ctx(ni, NULL);
 1130     if (!ctx) {
 1131         err = errno;
 1132         goto err_out;
 1133     }
 1134     /* Walk through all attributes. */
 1135     while (!ntfs_attr_lookup(AT_UNUSED, NULL, 0, 0, 0, NULL, 0, ctx)) {
 1136         
 1137         int ale_size;
 1138         
 1139         if (ctx->attr->type == AT_ATTRIBUTE_LIST) {
 1140             err = EIO;
 1141             ntfs_log_perror("Attribute list already present");
 1142             goto put_err_out;
 1143         }
 1144         
 1145         ale_size = (sizeof(ATTR_LIST_ENTRY) + sizeof(ntfschar) *
 1146                     ctx->attr->name_length + 7) & ~7;
 1147         al_len += ale_size;
 1148         
 1149         aln = realloc(al, al_len);
 1150         if (!aln) {
 1151             err = errno;
 1152             ntfs_log_perror("Failed to realloc %d bytes", al_len);
 1153             goto put_err_out;
 1154         }
 1155         ale = (ATTR_LIST_ENTRY *)(aln + ((u8 *)ale - al));
 1156         al = aln;
 1157         
 1158         memset(ale, 0, ale_size);
 1159         
 1160         /* Add attribute to attribute list. */
 1161         ale->type = ctx->attr->type;
 1162         ale->length = cpu_to_le16((sizeof(ATTR_LIST_ENTRY) +
 1163             sizeof(ntfschar) * ctx->attr->name_length + 7) & ~7);
 1164         ale->name_length = ctx->attr->name_length;
 1165         ale->name_offset = (u8 *)ale->name - (u8 *)ale;
 1166         if (ctx->attr->non_resident)
 1167             ale->lowest_vcn = ctx->attr->lowest_vcn;
 1168         else
 1169             ale->lowest_vcn = const_cpu_to_sle64(0);
 1170         ale->mft_reference = MK_LE_MREF(ni->mft_no,
 1171             le16_to_cpu(ni->mrec->sequence_number));
 1172         ale->instance = ctx->attr->instance;
 1173         memcpy(ale->name, (u8 *)ctx->attr +
 1174                 le16_to_cpu(ctx->attr->name_offset),
 1175                 ctx->attr->name_length * sizeof(ntfschar));
 1176         ale = (ATTR_LIST_ENTRY *)(al + al_len);
 1177     }
 1178     /* Check for real error occurred. */
 1179     if (errno != ENOENT) {
 1180         err = errno;
 1181         ntfs_log_perror("%s: Attribute lookup failed, inode %lld",
 1182                 __FUNCTION__, (long long)ni->mft_no);
 1183         goto put_err_out;
 1184     }
 1185 
 1186     /* Set in-memory attribute list. */
 1187     ni->attr_list = al;
 1188     ni->attr_list_size = al_len;
 1189     NInoSetAttrList(ni);
 1190     NInoAttrListSetDirty(ni);
 1191 
 1192     /* Free space if there is not enough it for $ATTRIBUTE_LIST. */
 1193     if (le32_to_cpu(ni->mrec->bytes_allocated) -
 1194             le32_to_cpu(ni->mrec->bytes_in_use) <
 1195             offsetof(ATTR_RECORD, resident_end)) {
 1196         if (ntfs_inode_free_space(ni,
 1197                 offsetof(ATTR_RECORD, resident_end))) {
 1198             /* Failed to free space. */
 1199             err = errno;
 1200             ntfs_log_perror("Failed to free space for attrlist");
 1201             goto rollback;
 1202         }
 1203     }
 1204 
 1205     /* Add $ATTRIBUTE_LIST to mft record. */
 1206     if (ntfs_resident_attr_record_add(ni,
 1207                 AT_ATTRIBUTE_LIST, NULL, 0, NULL, 0, const_cpu_to_le16(0)) < 0) {
 1208         err = errno;
 1209         ntfs_log_perror("Couldn't add $ATTRIBUTE_LIST to MFT");
 1210         goto rollback;
 1211     }
 1212 
 1213     /* Resize it. */
 1214     na = ntfs_attr_open(ni, AT_ATTRIBUTE_LIST, AT_UNNAMED, 0);
 1215     if (!na) {
 1216         err = errno;
 1217         ntfs_log_perror("Failed to open just added $ATTRIBUTE_LIST");
 1218         goto remove_attrlist_record;
 1219     }
 1220     if (ntfs_attr_truncate(na, al_len)) {
 1221         err = errno;
 1222         ntfs_log_perror("Failed to resize just added $ATTRIBUTE_LIST");
 1223         ntfs_attr_close(na);
 1224         goto remove_attrlist_record;;
 1225     }
 1226     
 1227     ntfs_attr_put_search_ctx(ctx);
 1228     ntfs_attr_close(na);
 1229     return 0;
 1230 
 1231 remove_attrlist_record:
 1232     /* Prevent ntfs_attr_recorm_rm from freeing attribute list. */
 1233     ni->attr_list = NULL;
 1234     NInoClearAttrList(ni);
 1235     /* Remove $ATTRIBUTE_LIST record. */
 1236     ntfs_attr_reinit_search_ctx(ctx);
 1237     if (!ntfs_attr_lookup(AT_ATTRIBUTE_LIST, NULL, 0,
 1238                 CASE_SENSITIVE, 0, NULL, 0, ctx)) {
 1239         if (ntfs_attr_record_rm(ctx))
 1240             ntfs_log_perror("Rollback failed to remove attrlist");
 1241     } else
 1242         ntfs_log_perror("Rollback failed to find attrlist");
 1243     /* Setup back in-memory runlist. */
 1244     ni->attr_list = al;
 1245     ni->attr_list_size = al_len;
 1246     NInoSetAttrList(ni);
 1247 rollback:
 1248     /*
 1249      * Scan attribute list for attributes that placed not in the base MFT
 1250      * record and move them to it.
 1251      */
 1252     ntfs_attr_reinit_search_ctx(ctx);
 1253     ale = (ATTR_LIST_ENTRY*)al;
 1254     while ((u8*)ale < al + al_len) {
 1255         if (MREF_LE(ale->mft_reference) != ni->mft_no) {
 1256             if (!ntfs_attr_lookup(ale->type, ale->name,
 1257                         ale->name_length,
 1258                         CASE_SENSITIVE,
 1259                         sle64_to_cpu(ale->lowest_vcn),
 1260                         NULL, 0, ctx)) {
 1261                 if (ntfs_attr_record_move_to(ctx, ni))
 1262                     ntfs_log_perror("Rollback failed to "
 1263                             "move attribute");
 1264             } else
 1265                 ntfs_log_perror("Rollback failed to find attr");
 1266             ntfs_attr_reinit_search_ctx(ctx);
 1267         }
 1268         ale = (ATTR_LIST_ENTRY*)((u8*)ale + le16_to_cpu(ale->length));
 1269     }
 1270     /* Remove in-memory attribute list. */
 1271     ni->attr_list = NULL;
 1272     ni->attr_list_size = 0;
 1273     NInoClearAttrList(ni);
 1274     NInoAttrListClearDirty(ni);
 1275 put_err_out:
 1276     ntfs_attr_put_search_ctx(ctx);
 1277 err_out:
 1278     free(al);
 1279     errno = err;
 1280     return -1;
 1281 }
 1282 
 1283 /**
 1284  * ntfs_inode_free_space - free space in the MFT record of an inode
 1285  * @ni:     ntfs inode in which MFT record needs more free space
 1286  * @size:   amount of space needed to free
 1287  *
 1288  * Return 0 on success or -1 on error with errno set to the error code.
 1289  */
 1290 int ntfs_inode_free_space(ntfs_inode *ni, int size)
 1291 {
 1292     ntfs_attr_search_ctx *ctx;
 1293     int freed;
 1294 
 1295     if (!ni || size < 0) {
 1296         errno = EINVAL;
 1297         ntfs_log_perror("%s: ni=%p size=%d", __FUNCTION__, ni, size);
 1298         return -1;
 1299     }
 1300 
 1301     ntfs_log_trace("Entering for inode %lld, size %d\n",
 1302                (unsigned long long)ni->mft_no, size);
 1303 
 1304     freed = (le32_to_cpu(ni->mrec->bytes_allocated) -
 1305                 le32_to_cpu(ni->mrec->bytes_in_use));
 1306 
 1307     if (size <= freed)
 1308         return 0;
 1309 
 1310     ctx = ntfs_attr_get_search_ctx(ni, NULL);
 1311     if (!ctx)
 1312         return -1;
 1313     /*
 1314      * $STANDARD_INFORMATION and $ATTRIBUTE_LIST must stay in the base MFT
 1315      * record, so position search context on the first attribute after them.
 1316      */
 1317     if (ntfs_attr_position(AT_FILE_NAME, ctx))
 1318         goto put_err_out;
 1319 
 1320     while (1) {
 1321         int record_size;
 1322         /*
 1323          * Check whether attribute is from different MFT record. If so,
 1324          * find next, because we don't need such.
 1325          */
 1326         while (ctx->ntfs_ino->mft_no != ni->mft_no) {
 1327 retry:          
 1328             if (ntfs_attr_position(AT_UNUSED, ctx))
 1329                 goto put_err_out;
 1330         }
 1331 
 1332         if (ntfs_inode_base(ctx->ntfs_ino)->mft_no == FILE_MFT && 
 1333             ctx->attr->type == AT_DATA)
 1334             goto retry;
 1335 
 1336         if (ctx->attr->type == AT_INDEX_ROOT)
 1337             goto retry;
 1338 
 1339         record_size = le32_to_cpu(ctx->attr->length);
 1340 
 1341         if (ntfs_attr_record_move_away(ctx, 0)) {
 1342             ntfs_log_perror("Failed to move out attribute #2");
 1343             break;
 1344         }
 1345         freed += record_size;
 1346 
 1347         /* Check whether we are done. */
 1348         if (size <= freed) {
 1349             ntfs_attr_put_search_ctx(ctx);
 1350             return 0;
 1351         }
 1352         /*
 1353          * Reposition to first attribute after $STANDARD_INFORMATION 
 1354          * and $ATTRIBUTE_LIST instead of simply skipping this attribute 
 1355          * because in the case when we have got only in-memory attribute 
 1356          * list then ntfs_attr_lookup will fail when it tries to find 
 1357          * $ATTRIBUTE_LIST.
 1358          */
 1359         ntfs_attr_reinit_search_ctx(ctx);
 1360         if (ntfs_attr_position(AT_FILE_NAME, ctx))
 1361             break;
 1362     }
 1363 put_err_out:
 1364     ntfs_attr_put_search_ctx(ctx);
 1365     if (errno == ENOSPC)
 1366         ntfs_log_trace("No attributes left that could be moved out.\n");
 1367     return -1;
 1368 }
 1369 
 1370 /**
 1371  * ntfs_inode_update_times - update selected time fields for ntfs inode
 1372  * @ni:     ntfs inode for which update time fields
 1373  * @mask:   select which time fields should be updated
 1374  *
 1375  * This function updates time fields to current time. Fields to update are
 1376  * selected using @mask (see enum @ntfs_time_update_flags for posssible values).
 1377  */
 1378 void ntfs_inode_update_times(ntfs_inode *ni, ntfs_time_update_flags mask)
 1379 {
 1380     ntfs_time now;
 1381 
 1382     if (!ni) {
 1383         ntfs_log_error("%s(): Invalid arguments.\n", __FUNCTION__);
 1384         return;
 1385     }
 1386 
 1387     if ((ni->mft_no < FILE_first_user && ni->mft_no != FILE_root) ||
 1388             NVolReadOnly(ni->vol) || !mask)
 1389         return;
 1390 
 1391     now = ntfs_current_time();
 1392     if (mask & NTFS_UPDATE_ATIME)
 1393         ni->last_access_time = now;
 1394     if (mask & NTFS_UPDATE_MTIME)
 1395         ni->last_data_change_time = now;
 1396     if (mask & NTFS_UPDATE_CTIME)
 1397         ni->last_mft_change_time = now;
 1398     
 1399     NInoFileNameSetDirty(ni);
 1400     NInoSetDirty(ni);
 1401 }
 1402 
 1403 /**
 1404  * ntfs_inode_badclus_bad - check for $Badclus:$Bad data attribute
 1405  * @mft_no:     mft record number where @attr is present
 1406  * @attr:       attribute record used to check for the $Bad attribute
 1407  *
 1408  * Check if the mft record given by @mft_no and @attr contains the bad sector
 1409  * list. Please note that mft record numbers describing $Badclus extent inodes
 1410  * will not match the current $Badclus:$Bad check.
 1411  * 
 1412  * On success return 1 if the file is $Badclus:$Bad, otherwise return 0.
 1413  * On error return -1 with errno set to the error code.
 1414  */
 1415 int ntfs_inode_badclus_bad(u64 mft_no, ATTR_RECORD *attr)
 1416 {
 1417     int len, ret = 0;
 1418     ntfschar *ustr;
 1419 
 1420     if (!attr) {
 1421         ntfs_log_error("Invalid argument.\n");
 1422         errno = EINVAL;
 1423         return -1;
 1424     }
 1425     
 1426     if (mft_no != FILE_BadClus)
 1427             return 0;
 1428 
 1429     if (attr->type != AT_DATA)
 1430             return 0;
 1431 
 1432     if ((ustr = ntfs_str2ucs("$Bad", &len)) == NULL) {
 1433         ntfs_log_perror("Couldn't convert '$Bad' to Unicode");
 1434         return -1;
 1435     }
 1436 
 1437     if (ustr && ntfs_names_are_equal(ustr, len,
 1438             (ntfschar *)((u8 *)attr + le16_to_cpu(attr->name_offset)),
 1439             attr->name_length, 0, NULL, 0))
 1440         ret = 1;
 1441 
 1442     ntfs_ucsfree(ustr);
 1443 
 1444     return ret;
 1445 }
 1446 
 1447 /*
 1448  *      Get high precision NTFS times
 1449  *
 1450  *  They are returned in following order : create, update, access, change
 1451  *  provided they fit in requested size.
 1452  *
 1453  *  Returns the modified size if successfull (or 32 if buffer size is null)
 1454  *      -errno if failed
 1455  */
 1456 
 1457 int ntfs_inode_get_times(ntfs_inode *ni, char *value, size_t size)
 1458 {
 1459     ntfs_attr_search_ctx *ctx;
 1460     STANDARD_INFORMATION *std_info;
 1461     u64 *times;
 1462     int ret;
 1463 
 1464     ret = 0;
 1465     ctx = ntfs_attr_get_search_ctx(ni, NULL);
 1466     if (ctx) {
 1467         if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED,
 1468                      0, CASE_SENSITIVE, 0, NULL, 0, ctx)) {
 1469             ntfs_log_perror("Failed to get standard info (inode %lld)",
 1470                     (long long)ni->mft_no);
 1471         } else {
 1472             std_info = (STANDARD_INFORMATION *)((u8 *)ctx->attr +
 1473                     le16_to_cpu(ctx->attr->value_offset));
 1474             if (value && (size >= 8)) {
 1475                 times = (u64*)value;
 1476                 times[0] = sle64_to_cpu(std_info->creation_time);
 1477                 ret = 8;
 1478                 if (size >= 16) {
 1479                     times[1] = sle64_to_cpu(std_info->last_data_change_time);
 1480                     ret = 16;
 1481                 }
 1482                 if (size >= 24) {
 1483                     times[2] = sle64_to_cpu(std_info->last_access_time);
 1484                     ret = 24;
 1485                 }
 1486                 if (size >= 32) {
 1487                     times[3] = sle64_to_cpu(std_info->last_mft_change_time);
 1488                     ret = 32;
 1489                 }
 1490             } else
 1491                 if (!size)
 1492                     ret = 32;
 1493                 else
 1494                     ret = -ERANGE;
 1495             }
 1496         ntfs_attr_put_search_ctx(ctx);
 1497     }       
 1498     return (ret ? ret : -errno);
 1499 }
 1500 
 1501 /*
 1502  *      Set high precision NTFS times
 1503  *
 1504  *  They are expected in this order : create, update, access
 1505  *  provided they are present in input. The change time is set to
 1506  *  current time.
 1507  *
 1508  *  The times are inserted directly in the standard_information and
 1509  *  file names attributes to avoid manipulating low precision times
 1510  *
 1511  *  Returns 0 if success
 1512  *      -1 if there were an error (described by errno)
 1513  */
 1514 
 1515 int ntfs_inode_set_times(ntfs_inode *ni, const char *value, size_t size,
 1516             int flags)
 1517 {
 1518     ntfs_attr_search_ctx *ctx;
 1519     STANDARD_INFORMATION *std_info;
 1520     FILE_NAME_ATTR *fn;
 1521     const u64 *times;
 1522     ntfs_time now;
 1523     int cnt;
 1524     int ret;
 1525 
 1526     ret = -1;
 1527     if ((size >= 8) && !(flags & XATTR_CREATE)) {
 1528         times = (const u64*)value;
 1529         now = ntfs_current_time();
 1530             /* update the standard information attribute */
 1531         ctx = ntfs_attr_get_search_ctx(ni, NULL);
 1532         if (ctx) {
 1533             if (ntfs_attr_lookup(AT_STANDARD_INFORMATION,
 1534                     AT_UNNAMED, 0, CASE_SENSITIVE,
 1535                     0, NULL, 0, ctx)) {
 1536                 ntfs_log_perror("Failed to get standard info (inode %lld)",
 1537                         (long long)ni->mft_no);
 1538             } else {
 1539                 std_info = (STANDARD_INFORMATION *)((u8 *)ctx->attr +
 1540                     le16_to_cpu(ctx->attr->value_offset));
 1541                 /*
 1542                  * Mark times set to avoid overwriting
 1543                  * them when the inode is closed.
 1544                  * The inode structure must also be updated
 1545                  * (with loss of precision) because of cacheing.
 1546                  * TODO : use NTFS precision in inode, and
 1547                  * return sub-second times in getattr()
 1548                  */
 1549                 set_nino_flag(ni, TimesSet);
 1550                 std_info->creation_time = cpu_to_sle64(times[0]);
 1551                 ni->creation_time
 1552                     = std_info->creation_time;
 1553                 if (size >= 16) {
 1554                     std_info->last_data_change_time = cpu_to_sle64(times[1]);
 1555                     ni->last_data_change_time
 1556                         = std_info->last_data_change_time;
 1557                 }
 1558                 if (size >= 24) {
 1559                     std_info->last_access_time = cpu_to_sle64(times[2]);
 1560                     ni->last_access_time
 1561                         = std_info->last_access_time;
 1562                 }
 1563                 std_info->last_mft_change_time = now;
 1564                 ni->last_mft_change_time = now;
 1565                 ntfs_inode_mark_dirty(ctx->ntfs_ino);
 1566                 NInoFileNameSetDirty(ni);
 1567 
 1568                 /* update the file names attributes */
 1569                 ntfs_attr_reinit_search_ctx(ctx);
 1570                 cnt = 0;
 1571                 while (!ntfs_attr_lookup(AT_FILE_NAME,
 1572                         AT_UNNAMED, 0, CASE_SENSITIVE,
 1573                         0, NULL, 0, ctx)) {
 1574                     fn = (FILE_NAME_ATTR*)((u8 *)ctx->attr +
 1575                         le16_to_cpu(ctx->attr->value_offset));
 1576                     fn->creation_time
 1577                         = cpu_to_sle64(times[0]);
 1578                     if (size >= 16)
 1579                         fn->last_data_change_time
 1580                             = cpu_to_sle64(times[1]);
 1581                     if (size >= 24)
 1582                         fn->last_access_time
 1583                             = cpu_to_sle64(times[2]);
 1584                     fn->last_mft_change_time = now;
 1585                     cnt++;
 1586                 }
 1587                 if (cnt)
 1588                     ret = 0;
 1589                 else {
 1590                     ntfs_log_perror("Failed to get file names (inode %lld)",
 1591                         (long long)ni->mft_no);
 1592                 }
 1593             }
 1594             ntfs_attr_put_search_ctx(ctx);
 1595         }
 1596     } else
 1597         if (size < 8)
 1598             errno = ERANGE;
 1599         else
 1600             errno = EEXIST;
 1601     return (ret);
 1602 }