"Fossies" - the Fresh Open Source Software Archive

Member "ntfs-3g_ntfsprogs-2017.3.23/libntfs-3g/attrib.c" (23 Mar 2017, 206658 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 "attrib.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  * attrib.c - Attribute handling code. Originated from the Linux-NTFS project.
    3  *
    4  * Copyright (c) 2000-2010 Anton Altaparmakov
    5  * Copyright (c) 2002-2005 Richard Russon
    6  * Copyright (c) 2002-2008 Szabolcs Szakacsits
    7  * Copyright (c) 2004-2007 Yura Pakhuchiy
    8  * Copyright (c) 2007-2015 Jean-Pierre Andre
    9  * Copyright (c) 2010      Erik Larsson
   10  *
   11  * This program/include file is free software; you can redistribute it and/or
   12  * modify it under the terms of the GNU General Public License as published
   13  * by the Free Software Foundation; either version 2 of the License, or
   14  * (at your option) any later version.
   15  *
   16  * This program/include file is distributed in the hope that it will be
   17  * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
   18  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   19  * GNU General Public License for more details.
   20  *
   21  * You should have received a copy of the GNU General Public License
   22  * along with this program (in the main directory of the NTFS-3G
   23  * distribution in the file COPYING); if not, write to the Free Software
   24  * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   25  */
   26 
   27 #ifdef HAVE_CONFIG_H
   28 #include "config.h"
   29 #endif
   30 
   31 #ifdef HAVE_STDIO_H
   32 #include <stdio.h>
   33 #endif
   34 #ifdef HAVE_STRING_H
   35 #include <string.h>
   36 #endif
   37 #ifdef HAVE_STDLIB_H
   38 #include <stdlib.h>
   39 #endif
   40 #ifdef HAVE_ERRNO_H
   41 #include <errno.h>
   42 #endif
   43 #ifdef HAVE_LIMITS_H
   44 #include <limits.h>
   45 #endif
   46 
   47 #include "param.h"
   48 #include "compat.h"
   49 #include "attrib.h"
   50 #include "attrlist.h"
   51 #include "device.h"
   52 #include "mft.h"
   53 #include "debug.h"
   54 #include "mst.h"
   55 #include "volume.h"
   56 #include "types.h"
   57 #include "layout.h"
   58 #include "inode.h"
   59 #include "runlist.h"
   60 #include "lcnalloc.h"
   61 #include "dir.h"
   62 #include "compress.h"
   63 #include "bitmap.h"
   64 #include "logging.h"
   65 #include "misc.h"
   66 #include "efs.h"
   67 
   68 ntfschar AT_UNNAMED[] = { const_cpu_to_le16('\0') };
   69 ntfschar STREAM_SDS[] = { const_cpu_to_le16('$'),
   70             const_cpu_to_le16('S'),
   71             const_cpu_to_le16('D'),
   72             const_cpu_to_le16('S'),
   73             const_cpu_to_le16('\0') };
   74 
   75 ntfschar TXF_DATA[] = { const_cpu_to_le16('$'),
   76             const_cpu_to_le16('T'),
   77             const_cpu_to_le16('X'),
   78             const_cpu_to_le16('F'),
   79             const_cpu_to_le16('_'),
   80             const_cpu_to_le16('D'),
   81             const_cpu_to_le16('A'),
   82             const_cpu_to_le16('T'),
   83             const_cpu_to_le16('A'),
   84             const_cpu_to_le16('\0') };
   85 
   86 static int NAttrFlag(ntfs_attr *na, FILE_ATTR_FLAGS flag)
   87 {
   88     if (na->type == AT_DATA && na->name == AT_UNNAMED)
   89         return (na->ni->flags & flag);
   90     return 0;
   91 }
   92 
   93 static void NAttrSetFlag(ntfs_attr *na, FILE_ATTR_FLAGS flag)
   94 {
   95     if (na->type == AT_DATA && na->name == AT_UNNAMED)
   96         na->ni->flags |= flag;
   97     else
   98         ntfs_log_trace("Denied setting flag %d for not unnamed data "
   99                    "attribute\n", le32_to_cpu(flag));
  100 }
  101 
  102 static void NAttrClearFlag(ntfs_attr *na, FILE_ATTR_FLAGS flag)
  103 {
  104     if (na->type == AT_DATA && na->name == AT_UNNAMED)
  105         na->ni->flags &= ~flag;
  106 }
  107 
  108 #define GenNAttrIno(func_name, flag)                    \
  109 int NAttr##func_name(ntfs_attr *na) { return NAttrFlag   (na, flag); }  \
  110 void NAttrSet##func_name(ntfs_attr *na)  { NAttrSetFlag  (na, flag); }  \
  111 void NAttrClear##func_name(ntfs_attr *na){ NAttrClearFlag(na, flag); }
  112 
  113 GenNAttrIno(Compressed, FILE_ATTR_COMPRESSED)
  114 GenNAttrIno(Encrypted,  FILE_ATTR_ENCRYPTED)
  115 GenNAttrIno(Sparse,     FILE_ATTR_SPARSE_FILE)
  116 
  117 /**
  118  * ntfs_get_attribute_value_length - Find the length of an attribute
  119  * @a:
  120  *
  121  * Description...
  122  *
  123  * Returns:
  124  */
  125 s64 ntfs_get_attribute_value_length(const ATTR_RECORD *a)
  126 {
  127     if (!a) {
  128         errno = EINVAL;
  129         return 0;
  130     }
  131     errno = 0;
  132     if (a->non_resident)
  133         return sle64_to_cpu(a->data_size);
  134     
  135     return (s64)le32_to_cpu(a->value_length);
  136 }
  137 
  138 /**
  139  * ntfs_get_attribute_value - Get a copy of an attribute
  140  * @vol:    
  141  * @a:  
  142  * @b:  
  143  *
  144  * Description...
  145  *
  146  * Returns:
  147  */
  148 s64 ntfs_get_attribute_value(const ntfs_volume *vol,
  149         const ATTR_RECORD *a, u8 *b)
  150 {
  151     runlist *rl;
  152     s64 total, r;
  153     int i;
  154 
  155     /* Sanity checks. */
  156     if (!vol || !a || !b) {
  157         errno = EINVAL;
  158         return 0;
  159     }
  160     /* Complex attribute? */
  161     /*
  162      * Ignore the flags in case they are not zero for an attribute list
  163      * attribute.  Windows does not complain about invalid flags and chkdsk
  164      * does not detect or fix them so we need to cope with it, too.
  165      */
  166     if (a->type != AT_ATTRIBUTE_LIST && a->flags) {
  167         ntfs_log_error("Non-zero (%04x) attribute flags. Cannot handle "
  168                    "this yet.\n", le16_to_cpu(a->flags));
  169         errno = EOPNOTSUPP;
  170         return 0;
  171     }
  172     if (!a->non_resident) {
  173         /* Attribute is resident. */
  174 
  175         /* Sanity check. */
  176         if (le32_to_cpu(a->value_length) + le16_to_cpu(a->value_offset)
  177                 > le32_to_cpu(a->length)) {
  178             return 0;
  179         }
  180 
  181         memcpy(b, (const char*)a + le16_to_cpu(a->value_offset),
  182                 le32_to_cpu(a->value_length));
  183         errno = 0;
  184         return (s64)le32_to_cpu(a->value_length);
  185     }
  186 
  187     /* Attribute is not resident. */
  188 
  189     /* If no data, return 0. */
  190     if (!(a->data_size)) {
  191         errno = 0;
  192         return 0;
  193     }
  194     /*
  195      * FIXME: What about attribute lists?!? (AIA)
  196      */
  197     /* Decompress the mapping pairs array into a runlist. */
  198     rl = ntfs_mapping_pairs_decompress(vol, a, NULL);
  199     if (!rl) {
  200         errno = EINVAL;
  201         return 0;
  202     }
  203     /*
  204      * FIXED: We were overflowing here in a nasty fashion when we
  205      * reach the last cluster in the runlist as the buffer will
  206      * only be big enough to hold data_size bytes while we are
  207      * reading in allocated_size bytes which is usually larger
  208      * than data_size, since the actual data is unlikely to have a
  209      * size equal to a multiple of the cluster size!
  210      * FIXED2:  We were also overflowing here in the same fashion
  211      * when the data_size was more than one run smaller than the
  212      * allocated size which happens with Windows XP sometimes.
  213      */
  214     /* Now load all clusters in the runlist into b. */
  215     for (i = 0, total = 0; rl[i].length; i++) {
  216         if (total + (rl[i].length << vol->cluster_size_bits) >=
  217                 sle64_to_cpu(a->data_size)) {
  218             unsigned char *intbuf = NULL;
  219             /*
  220              * We have reached the last run so we were going to
  221              * overflow when executing the ntfs_pread() which is
  222              * BAAAAAAAD!
  223              * Temporary fix:
  224              *  Allocate a new buffer with size:
  225              *  rl[i].length << vol->cluster_size_bits, do the
  226              *  read into our buffer, then memcpy the correct
  227              *  amount of data into the caller supplied buffer,
  228              *  free our buffer, and continue.
  229              * We have reached the end of data size so we were
  230              * going to overflow in the same fashion.
  231              * Temporary fix:  same as above.
  232              */
  233             intbuf = ntfs_malloc(rl[i].length << vol->cluster_size_bits);
  234             if (!intbuf) {
  235                 free(rl);
  236                 return 0;
  237             }
  238             /*
  239              * FIXME: If compressed file: Only read if lcn != -1.
  240              * Otherwise, we are dealing with a sparse run and we
  241              * just memset the user buffer to 0 for the length of
  242              * the run, which should be 16 (= compression unit
  243              * size).
  244              * FIXME: Really only when file is compressed, or can
  245              * we have sparse runs in uncompressed files as well?
  246              * - Yes we can, in sparse files! But not necessarily
  247              * size of 16, just run length.
  248              */
  249             r = ntfs_pread(vol->dev, rl[i].lcn <<
  250                     vol->cluster_size_bits, rl[i].length <<
  251                     vol->cluster_size_bits, intbuf);
  252             if (r != rl[i].length << vol->cluster_size_bits) {
  253 #define ESTR "Error reading attribute value"
  254                 if (r == -1)
  255                     ntfs_log_perror(ESTR);
  256                 else if (r < rl[i].length <<
  257                         vol->cluster_size_bits) {
  258                     ntfs_log_debug(ESTR ": Ran out of input data.\n");
  259                     errno = EIO;
  260                 } else {
  261                     ntfs_log_debug(ESTR ": unknown error\n");
  262                     errno = EIO;
  263                 }
  264 #undef ESTR
  265                 free(rl);
  266                 free(intbuf);
  267                 return 0;
  268             }
  269             memcpy(b + total, intbuf, sle64_to_cpu(a->data_size) -
  270                     total);
  271             free(intbuf);
  272             total = sle64_to_cpu(a->data_size);
  273             break;
  274         }
  275         /*
  276          * FIXME: If compressed file: Only read if lcn != -1.
  277          * Otherwise, we are dealing with a sparse run and we just
  278          * memset the user buffer to 0 for the length of the run, which
  279          * should be 16 (= compression unit size).
  280          * FIXME: Really only when file is compressed, or can
  281          * we have sparse runs in uncompressed files as well?
  282          * - Yes we can, in sparse files! But not necessarily size of
  283          * 16, just run length.
  284          */
  285         r = ntfs_pread(vol->dev, rl[i].lcn << vol->cluster_size_bits,
  286                 rl[i].length << vol->cluster_size_bits,
  287                 b + total);
  288         if (r != rl[i].length << vol->cluster_size_bits) {
  289 #define ESTR "Error reading attribute value"
  290             if (r == -1)
  291                 ntfs_log_perror(ESTR);
  292             else if (r < rl[i].length << vol->cluster_size_bits) {
  293                 ntfs_log_debug(ESTR ": Ran out of input data.\n");
  294                 errno = EIO;
  295             } else {
  296                 ntfs_log_debug(ESTR ": unknown error\n");
  297                 errno = EIO;
  298             }
  299 #undef ESTR
  300             free(rl);
  301             return 0;
  302         }
  303         total += r;
  304     }
  305     free(rl);
  306     return total;
  307 }
  308 
  309 /* Already cleaned up code below, but still look for FIXME:... */
  310 
  311 /**
  312  * __ntfs_attr_init - primary initialization of an ntfs attribute structure
  313  * @na:     ntfs attribute to initialize
  314  * @ni:     ntfs inode with which to initialize the ntfs attribute
  315  * @type:   attribute type
  316  * @name:   attribute name in little endian Unicode or NULL
  317  * @name_len:   length of attribute @name in Unicode characters (if @name given)
  318  *
  319  * Initialize the ntfs attribute @na with @ni, @type, @name, and @name_len.
  320  */
  321 static void __ntfs_attr_init(ntfs_attr *na, ntfs_inode *ni,
  322         const ATTR_TYPES type, ntfschar *name, const u32 name_len)
  323 {
  324     na->rl = NULL;
  325     na->ni = ni;
  326     na->type = type;
  327     na->name = name;
  328     if (name)
  329         na->name_len = name_len;
  330     else
  331         na->name_len = 0;
  332 }
  333 
  334 /**
  335  * ntfs_attr_init - initialize an ntfs_attr with data sizes and status
  336  * @na:
  337  * @non_resident:
  338  * @compressed:
  339  * @encrypted:
  340  * @sparse:
  341  * @allocated_size:
  342  * @data_size:
  343  * @initialized_size:
  344  * @compressed_size:
  345  * @compression_unit:
  346  *
  347  * Final initialization for an ntfs attribute.
  348  */
  349 void ntfs_attr_init(ntfs_attr *na, const BOOL non_resident,
  350         const ATTR_FLAGS data_flags,
  351         const BOOL encrypted, const BOOL sparse,
  352         const s64 allocated_size, const s64 data_size,
  353         const s64 initialized_size, const s64 compressed_size,
  354         const u8 compression_unit)
  355 {
  356     if (!NAttrInitialized(na)) {
  357         na->data_flags = data_flags;
  358         if (non_resident)
  359             NAttrSetNonResident(na);
  360         if (data_flags & ATTR_COMPRESSION_MASK)
  361             NAttrSetCompressed(na);
  362         if (encrypted)
  363             NAttrSetEncrypted(na);
  364         if (sparse)
  365             NAttrSetSparse(na);
  366         na->allocated_size = allocated_size;
  367         na->data_size = data_size;
  368         na->initialized_size = initialized_size;
  369         if ((data_flags & ATTR_COMPRESSION_MASK) || sparse) {
  370             ntfs_volume *vol = na->ni->vol;
  371 
  372             na->compressed_size = compressed_size;
  373             na->compression_block_clusters = 1 << compression_unit;
  374             na->compression_block_size = 1 << (compression_unit +
  375                     vol->cluster_size_bits);
  376             na->compression_block_size_bits = ffs(
  377                     na->compression_block_size) - 1;
  378         }
  379         NAttrSetInitialized(na);
  380     }
  381 }
  382 
  383 /**
  384  * ntfs_attr_open - open an ntfs attribute for access
  385  * @ni:     open ntfs inode in which the ntfs attribute resides
  386  * @type:   attribute type
  387  * @name:   attribute name in little endian Unicode or AT_UNNAMED or NULL
  388  * @name_len:   length of attribute @name in Unicode characters (if @name given)
  389  *
  390  * Allocate a new ntfs attribute structure, initialize it with @ni, @type,
  391  * @name, and @name_len, then return it. Return NULL on error with
  392  * errno set to the error code.
  393  *
  394  * If @name is AT_UNNAMED look specifically for an unnamed attribute.  If you
  395  * do not care whether the attribute is named or not set @name to NULL.  In
  396  * both those cases @name_len is not used at all.
  397  */
  398 ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type,
  399         ntfschar *name, u32 name_len)
  400 {
  401     ntfs_attr_search_ctx *ctx;
  402     ntfs_attr *na = NULL;
  403     ntfschar *newname = NULL;
  404     ATTR_RECORD *a;
  405     le16 cs;
  406 
  407     ntfs_log_enter("Entering for inode %lld, attr 0x%x.\n",
  408                (unsigned long long)ni->mft_no, le32_to_cpu(type));
  409     
  410     if (!ni || !ni->vol || !ni->mrec) {
  411         errno = EINVAL;
  412         goto out;
  413     }
  414     na = ntfs_calloc(sizeof(ntfs_attr));
  415     if (!na)
  416         goto out;
  417     if (name && name != AT_UNNAMED && name != NTFS_INDEX_I30) {
  418         name = ntfs_ucsndup(name, name_len);
  419         if (!name)
  420             goto err_out;
  421         newname = name;
  422     }
  423 
  424     ctx = ntfs_attr_get_search_ctx(ni, NULL);
  425     if (!ctx)
  426         goto err_out;
  427 
  428     if (ntfs_attr_lookup(type, name, name_len, 0, 0, NULL, 0, ctx))
  429         goto put_err_out;
  430 
  431     a = ctx->attr;
  432     
  433     if (!name) {
  434         if (a->name_length) {
  435             name = ntfs_ucsndup((ntfschar*)((u8*)a + le16_to_cpu(
  436                     a->name_offset)), a->name_length);
  437             if (!name)
  438                 goto put_err_out;
  439             newname = name;
  440             name_len = a->name_length;
  441         } else {
  442             name = AT_UNNAMED;
  443             name_len = 0;
  444         }
  445     }
  446     
  447     __ntfs_attr_init(na, ni, type, name, name_len);
  448     
  449     /*
  450      * Wipe the flags in case they are not zero for an attribute list
  451      * attribute.  Windows does not complain about invalid flags and chkdsk
  452      * does not detect or fix them so we need to cope with it, too.
  453      */
  454     if (type == AT_ATTRIBUTE_LIST)
  455         a->flags = const_cpu_to_le16(0);
  456 
  457     if ((type == AT_DATA)
  458        && (a->non_resident ? !a->initialized_size : !a->value_length)) {
  459         /*
  460          * Define/redefine the compression state if stream is
  461          * empty, based on the compression mark on parent
  462          * directory (for unnamed data streams) or on current
  463          * inode (for named data streams). The compression mark
  464          * may change any time, the compression state can only
  465          * change when stream is wiped out.
  466          * 
  467          * Also prevent compression on NTFS version < 3.0
  468          * or cluster size > 4K or compression is disabled
  469          */
  470         a->flags &= ~ATTR_COMPRESSION_MASK;
  471         if ((ni->flags & FILE_ATTR_COMPRESSED)
  472             && (ni->vol->major_ver >= 3)
  473             && NVolCompression(ni->vol)
  474             && (ni->vol->cluster_size <= MAX_COMPRESSION_CLUSTER_SIZE))
  475             a->flags |= ATTR_IS_COMPRESSED;
  476     }
  477     
  478     cs = a->flags & (ATTR_IS_COMPRESSED | ATTR_IS_SPARSE);
  479 
  480     /* a file may be sparse though its unnamed data is not (cf $UsnJrnl) */
  481     if (na->type == AT_DATA && na->name == AT_UNNAMED &&
  482         (((a->flags & ATTR_IS_SPARSE)     && !NAttrSparse(na)) ||
  483          (!(a->flags & ATTR_IS_ENCRYPTED)  != !NAttrEncrypted(na)))) {
  484         errno = EIO;
  485         ntfs_log_perror("Inode %lld has corrupt attribute flags "
  486                 "(0x%x <> 0x%x)",(unsigned long long)ni->mft_no,
  487                 le16_to_cpu(a->flags), le32_to_cpu(na->ni->flags));
  488         goto put_err_out;
  489     }
  490 
  491     if (a->non_resident) {
  492         if ((a->flags & ATTR_COMPRESSION_MASK)
  493                  && !a->compression_unit) {
  494             errno = EIO;
  495             ntfs_log_perror("Compressed inode %lld attr 0x%x has "
  496                     "no compression unit",
  497                     (unsigned long long)ni->mft_no, le32_to_cpu(type));
  498             goto put_err_out;
  499         }
  500         ntfs_attr_init(na, TRUE, a->flags,
  501                 a->flags & ATTR_IS_ENCRYPTED,
  502                 a->flags & ATTR_IS_SPARSE,
  503                 sle64_to_cpu(a->allocated_size),
  504                 sle64_to_cpu(a->data_size),
  505                 sle64_to_cpu(a->initialized_size),
  506                 cs ? sle64_to_cpu(a->compressed_size) : 0,
  507                 cs ? a->compression_unit : 0);
  508     } else {
  509         s64 l = le32_to_cpu(a->value_length);
  510         ntfs_attr_init(na, FALSE, a->flags,
  511                 a->flags & ATTR_IS_ENCRYPTED,
  512                 a->flags & ATTR_IS_SPARSE, (l + 7) & ~7, l, l,
  513                 cs ? (l + 7) & ~7 : 0, 0);
  514     }
  515     ntfs_attr_put_search_ctx(ctx);
  516 out:
  517     ntfs_log_leave("\n");   
  518     return na;
  519 
  520 put_err_out:
  521     ntfs_attr_put_search_ctx(ctx);
  522 err_out:
  523     free(newname);
  524     free(na);
  525     na = NULL;
  526     goto out;
  527 }
  528 
  529 /**
  530  * ntfs_attr_close - free an ntfs attribute structure
  531  * @na:     ntfs attribute structure to free
  532  *
  533  * Release all memory associated with the ntfs attribute @na and then release
  534  * @na itself.
  535  */
  536 void ntfs_attr_close(ntfs_attr *na)
  537 {
  538     if (!na)
  539         return;
  540     if (NAttrNonResident(na) && na->rl)
  541         free(na->rl);
  542     /* Don't release if using an internal constant. */
  543     if (na->name != AT_UNNAMED && na->name != NTFS_INDEX_I30
  544                 && na->name != STREAM_SDS)
  545         free(na->name);
  546     free(na);
  547 }
  548 
  549 /**
  550  * ntfs_attr_map_runlist - map (a part of) a runlist of an ntfs attribute
  551  * @na:     ntfs attribute for which to map (part of) a runlist
  552  * @vcn:    map runlist part containing this vcn
  553  *
  554  * Map the part of a runlist containing the @vcn of the ntfs attribute @na.
  555  *
  556  * Return 0 on success and -1 on error with errno set to the error code.
  557  */
  558 int ntfs_attr_map_runlist(ntfs_attr *na, VCN vcn)
  559 {
  560     LCN lcn;
  561     ntfs_attr_search_ctx *ctx;
  562 
  563     ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x, vcn 0x%llx.\n",
  564         (unsigned long long)na->ni->mft_no, le32_to_cpu(na->type), (long long)vcn);
  565 
  566     lcn = ntfs_rl_vcn_to_lcn(na->rl, vcn);
  567     if (lcn >= 0 || lcn == LCN_HOLE || lcn == LCN_ENOENT)
  568         return 0;
  569 
  570     ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
  571     if (!ctx)
  572         return -1;
  573 
  574     /* Find the attribute in the mft record. */
  575     if (!ntfs_attr_lookup(na->type, na->name, na->name_len, CASE_SENSITIVE,
  576             vcn, NULL, 0, ctx)) {
  577         runlist_element *rl;
  578 
  579         /* Decode the runlist. */
  580         rl = ntfs_mapping_pairs_decompress(na->ni->vol, ctx->attr,
  581                 na->rl);
  582         if (rl) {
  583             na->rl = rl;
  584             ntfs_attr_put_search_ctx(ctx);
  585             return 0;
  586         }
  587     }
  588     
  589     ntfs_attr_put_search_ctx(ctx);
  590     return -1;
  591 }
  592 
  593 #if PARTIAL_RUNLIST_UPDATING
  594 
  595 /*
  596  *      Map the runlist of an attribute from some point to the end
  597  *
  598  *  Returns 0 if success,
  599  *      -1 if it failed (errno telling why)
  600  */
  601 
  602 static int ntfs_attr_map_partial_runlist(ntfs_attr *na, VCN vcn)
  603 {
  604     VCN last_vcn;
  605     VCN highest_vcn;
  606     VCN needed;
  607     runlist_element *rl;
  608     ATTR_RECORD *a;
  609     BOOL startseen;
  610     ntfs_attr_search_ctx *ctx;
  611     BOOL done;
  612     BOOL newrunlist;
  613 
  614     if (NAttrFullyMapped(na))
  615         return 0;
  616 
  617     ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
  618     if (!ctx)
  619         return -1;
  620 
  621     /* Get the last vcn in the attribute. */
  622     last_vcn = na->allocated_size >> na->ni->vol->cluster_size_bits;
  623 
  624     needed = vcn;
  625     highest_vcn = 0;
  626     startseen = FALSE;
  627     done = FALSE;
  628     rl = (runlist_element*)NULL;
  629     do {
  630         newrunlist = FALSE;
  631         /* Find the attribute in the mft record. */
  632         if (!ntfs_attr_lookup(na->type, na->name, na->name_len, CASE_SENSITIVE,
  633                 needed, NULL, 0, ctx)) {
  634 
  635             a = ctx->attr;
  636                 /* Decode and merge the runlist. */
  637             if (ntfs_rl_vcn_to_lcn(na->rl, needed)
  638                         == LCN_RL_NOT_MAPPED) {
  639                 rl = ntfs_mapping_pairs_decompress(na->ni->vol,
  640                     a, na->rl);
  641                 newrunlist = TRUE;
  642             } else
  643                 rl = na->rl;
  644             if (rl) {
  645                 na->rl = rl;
  646                 highest_vcn = sle64_to_cpu(a->highest_vcn);
  647                 if (highest_vcn < needed) {
  648                 /* corruption detection on unchanged runlists */
  649                     if (newrunlist
  650                         && ((highest_vcn + 1) < last_vcn)) {
  651                         ntfs_log_error("Corrupt attribute list\n");
  652                         rl = (runlist_element*)NULL;
  653                         errno = EIO;
  654                     }
  655                     done = TRUE;
  656                 }
  657                 needed = highest_vcn + 1;
  658                 if (!a->lowest_vcn)
  659                     startseen = TRUE;
  660             }
  661         } else {
  662             done = TRUE;
  663         }
  664     } while (rl && !done && (needed < last_vcn));
  665     ntfs_attr_put_search_ctx(ctx);
  666         /*
  667          * Make sure we reached the end, unless the last
  668          * runlist was modified earlier (using HOLES_DELAY
  669          * leads to have a visibility over attributes which
  670          * have not yet been fully updated)
  671          */
  672     if (done && newrunlist && (needed < last_vcn)) {
  673         ntfs_log_error("End of runlist not reached\n");
  674         rl = (runlist_element*)NULL;
  675         errno = EIO;
  676     }
  677         /* mark fully mapped if we did so */
  678     if (rl && startseen)
  679         NAttrSetFullyMapped(na);
  680     return (rl ? 0 : -1);
  681 }
  682 
  683 #endif
  684 
  685 /**
  686  * ntfs_attr_map_whole_runlist - map the whole runlist of an ntfs attribute
  687  * @na:     ntfs attribute for which to map the runlist
  688  *
  689  * Map the whole runlist of the ntfs attribute @na.  For an attribute made up
  690  * of only one attribute extent this is the same as calling
  691  * ntfs_attr_map_runlist(na, 0) but for an attribute with multiple extents this
  692  * will map the runlist fragments from each of the extents thus giving access
  693  * to the entirety of the disk allocation of an attribute.
  694  *
  695  * Return 0 on success and -1 on error with errno set to the error code.
  696  */
  697 int ntfs_attr_map_whole_runlist(ntfs_attr *na)
  698 {
  699     VCN next_vcn, last_vcn, highest_vcn;
  700     ntfs_attr_search_ctx *ctx;
  701     ntfs_volume *vol = na->ni->vol;
  702     ATTR_RECORD *a;
  703     int ret = -1;
  704     int not_mapped;
  705 
  706     ntfs_log_enter("Entering for inode %llu, attr 0x%x.\n",
  707                (unsigned long long)na->ni->mft_no, le32_to_cpu(na->type));
  708 
  709         /* avoid multiple full runlist mappings */
  710     if (NAttrFullyMapped(na)) {
  711         ret = 0;
  712         goto out;
  713     }
  714     ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
  715     if (!ctx)
  716         goto out;
  717 
  718     /* Map all attribute extents one by one. */
  719     next_vcn = last_vcn = highest_vcn = 0;
  720     a = NULL;
  721     while (1) {
  722         runlist_element *rl;
  723 
  724         not_mapped = 0;
  725         if (ntfs_rl_vcn_to_lcn(na->rl, next_vcn) == LCN_RL_NOT_MAPPED)
  726             not_mapped = 1;
  727 
  728         if (ntfs_attr_lookup(na->type, na->name, na->name_len,
  729                 CASE_SENSITIVE, next_vcn, NULL, 0, ctx))
  730             break;
  731 
  732         a = ctx->attr;
  733 
  734         if (not_mapped) {
  735             /* Decode the runlist. */
  736             rl = ntfs_mapping_pairs_decompress(na->ni->vol,
  737                                 a, na->rl);
  738             if (!rl)
  739                 goto err_out;
  740             na->rl = rl;
  741         }
  742 
  743         /* Are we in the first extent? */
  744         if (!next_vcn) {
  745              if (a->lowest_vcn) {
  746                  errno = EIO;
  747                  ntfs_log_perror("First extent of inode %llu "
  748                     "attribute has non-zero lowest_vcn",
  749                     (unsigned long long)na->ni->mft_no);
  750                  goto err_out;
  751             }
  752             /* Get the last vcn in the attribute. */
  753             last_vcn = sle64_to_cpu(a->allocated_size) >>
  754                     vol->cluster_size_bits;
  755         }
  756 
  757         /* Get the lowest vcn for the next extent. */
  758         highest_vcn = sle64_to_cpu(a->highest_vcn);
  759         next_vcn = highest_vcn + 1;
  760 
  761         /* Only one extent or error, which we catch below. */
  762         if (next_vcn <= 0) {
  763             errno = ENOENT;
  764             break;
  765         }
  766 
  767         /* Avoid endless loops due to corruption. */
  768         if (next_vcn < sle64_to_cpu(a->lowest_vcn)) {
  769             errno = EIO;
  770             ntfs_log_perror("Inode %llu has corrupt attribute list",
  771                     (unsigned long long)na->ni->mft_no);
  772             goto err_out;
  773         }
  774     }
  775     if (!a) {
  776         ntfs_log_perror("Couldn't find attribute for runlist mapping");
  777         goto err_out;
  778     }
  779         /*
  780          * Cannot check highest_vcn when the last runlist has
  781          * been modified earlier, as runlists and sizes may be
  782          * updated without highest_vcn being in sync, when
  783          * HOLES_DELAY is used
  784          */
  785     if (not_mapped && highest_vcn && highest_vcn != last_vcn - 1) {
  786         errno = EIO;
  787         ntfs_log_perror("Failed to load full runlist: inode: %llu "
  788                 "highest_vcn: 0x%llx last_vcn: 0x%llx",
  789                 (unsigned long long)na->ni->mft_no, 
  790                 (long long)highest_vcn, (long long)last_vcn);
  791         goto err_out;
  792     }
  793     if (errno == ENOENT) {
  794         NAttrSetFullyMapped(na);
  795         ret = 0;
  796     }
  797 err_out:    
  798     ntfs_attr_put_search_ctx(ctx);
  799 out:
  800     ntfs_log_leave("\n");
  801     return ret;
  802 }
  803 
  804 /**
  805  * ntfs_attr_vcn_to_lcn - convert a vcn into a lcn given an ntfs attribute
  806  * @na:     ntfs attribute whose runlist to use for conversion
  807  * @vcn:    vcn to convert
  808  *
  809  * Convert the virtual cluster number @vcn of an attribute into a logical
  810  * cluster number (lcn) of a device using the runlist @na->rl to map vcns to
  811  * their corresponding lcns.
  812  *
  813  * If the @vcn is not mapped yet, attempt to map the attribute extent
  814  * containing the @vcn and retry the vcn to lcn conversion.
  815  *
  816  * Since lcns must be >= 0, we use negative return values with special meaning:
  817  *
  818  * Return value     Meaning / Description
  819  * ==========================================
  820  *  -1 = LCN_HOLE   Hole / not allocated on disk.
  821  *  -3 = LCN_ENOENT There is no such vcn in the attribute.
  822  *  -4 = LCN_EINVAL Input parameter error.
  823  *  -5 = LCN_EIO    Corrupt fs, disk i/o error, or not enough memory.
  824  */
  825 LCN ntfs_attr_vcn_to_lcn(ntfs_attr *na, const VCN vcn)
  826 {
  827     LCN lcn;
  828     BOOL is_retry = FALSE;
  829 
  830     if (!na || !NAttrNonResident(na) || vcn < 0)
  831         return (LCN)LCN_EINVAL;
  832 
  833     ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x.\n", (unsigned long
  834             long)na->ni->mft_no, le32_to_cpu(na->type));
  835 retry:
  836     /* Convert vcn to lcn. If that fails map the runlist and retry once. */
  837     lcn = ntfs_rl_vcn_to_lcn(na->rl, vcn);
  838     if (lcn >= 0)
  839         return lcn;
  840     if (!is_retry && !ntfs_attr_map_runlist(na, vcn)) {
  841         is_retry = TRUE;
  842         goto retry;
  843     }
  844     /*
  845      * If the attempt to map the runlist failed, or we are getting
  846      * LCN_RL_NOT_MAPPED despite having mapped the attribute extent
  847      * successfully, something is really badly wrong...
  848      */
  849     if (!is_retry || lcn == (LCN)LCN_RL_NOT_MAPPED)
  850         return (LCN)LCN_EIO;
  851     /* lcn contains the appropriate error code. */
  852     return lcn;
  853 }
  854 
  855 /**
  856  * ntfs_attr_find_vcn - find a vcn in the runlist of an ntfs attribute
  857  * @na:     ntfs attribute whose runlist to search
  858  * @vcn:    vcn to find
  859  *
  860  * Find the virtual cluster number @vcn in the runlist of the ntfs attribute
  861  * @na and return the the address of the runlist element containing the @vcn.
  862  *
  863  * Note you need to distinguish between the lcn of the returned runlist
  864  * element being >= 0 and LCN_HOLE. In the later case you have to return zeroes
  865  * on read and allocate clusters on write. You need to update the runlist, the
  866  * attribute itself as well as write the modified mft record to disk.
  867  *
  868  * If there is an error return NULL with errno set to the error code. The
  869  * following error codes are defined:
  870  *  EINVAL      Input parameter error.
  871  *  ENOENT      There is no such vcn in the runlist.
  872  *  ENOMEM      Not enough memory.
  873  *  EIO     I/O error or corrupt metadata.
  874  */
  875 runlist_element *ntfs_attr_find_vcn(ntfs_attr *na, const VCN vcn)
  876 {
  877     runlist_element *rl;
  878     BOOL is_retry = FALSE;
  879 
  880     if (!na || !NAttrNonResident(na) || vcn < 0) {
  881         errno = EINVAL;
  882         return NULL;
  883     }
  884 
  885     ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x, vcn %llx\n",
  886                (unsigned long long)na->ni->mft_no, le32_to_cpu(na->type),
  887                (long long)vcn);
  888 retry:
  889     rl = na->rl;
  890     if (!rl)
  891         goto map_rl;
  892     if (vcn < rl[0].vcn)
  893         goto map_rl;
  894     while (rl->length) {
  895         if (vcn < rl[1].vcn) {
  896             if (rl->lcn >= (LCN)LCN_HOLE)
  897                 return rl;
  898             break;
  899         }
  900         rl++;
  901     }
  902     switch (rl->lcn) {
  903     case (LCN)LCN_RL_NOT_MAPPED:
  904         goto map_rl;
  905     case (LCN)LCN_ENOENT:
  906         errno = ENOENT;
  907         break;
  908     case (LCN)LCN_EINVAL:
  909         errno = EINVAL;
  910         break;
  911     default:
  912         errno = EIO;
  913         break;
  914     }
  915     return NULL;
  916 map_rl:
  917     /* The @vcn is in an unmapped region, map the runlist and retry. */
  918     if (!is_retry && !ntfs_attr_map_runlist(na, vcn)) {
  919         is_retry = TRUE;
  920         goto retry;
  921     }
  922     /*
  923      * If we already retried or the mapping attempt failed something has
  924      * gone badly wrong. EINVAL and ENOENT coming from a failed mapping
  925      * attempt are equivalent to errors for us as they should not happen
  926      * in our code paths.
  927      */
  928     if (is_retry || errno == EINVAL || errno == ENOENT)
  929         errno = EIO;
  930     return NULL;
  931 }
  932 
  933 /**
  934  * ntfs_attr_pread_i - see description at ntfs_attr_pread()
  935  */ 
  936 static s64 ntfs_attr_pread_i(ntfs_attr *na, const s64 pos, s64 count, void *b)
  937 {
  938     s64 br, to_read, ofs, total, total2, max_read, max_init;
  939     ntfs_volume *vol;
  940     runlist_element *rl;
  941     u16 efs_padding_length;
  942 
  943     /* Sanity checking arguments is done in ntfs_attr_pread(). */
  944     
  945     if ((na->data_flags & ATTR_COMPRESSION_MASK) && NAttrNonResident(na)) {
  946         if ((na->data_flags & ATTR_COMPRESSION_MASK)
  947             == ATTR_IS_COMPRESSED)
  948             return ntfs_compressed_attr_pread(na, pos, count, b);
  949         else {
  950                 /* compression mode not supported */
  951             errno = EOPNOTSUPP;
  952             return -1;
  953         }
  954     }
  955     /*
  956      * Encrypted non-resident attributes are not supported.  We return
  957      * access denied, which is what Windows NT4 does, too.
  958      * However, allow if mounted with efs_raw option
  959      */
  960     vol = na->ni->vol;
  961     if (!vol->efs_raw && NAttrEncrypted(na) && NAttrNonResident(na)) {
  962         errno = EACCES;
  963         return -1;
  964     }
  965     
  966     if (!count)
  967         return 0;
  968         /*
  969          * Truncate reads beyond end of attribute,
  970          * but round to next 512 byte boundary for encrypted
  971          * attributes with efs_raw mount option
  972          */
  973     max_read = na->data_size;
  974     max_init = na->initialized_size;
  975     if (na->ni->vol->efs_raw
  976         && (na->data_flags & ATTR_IS_ENCRYPTED)
  977         && NAttrNonResident(na)) {
  978         if (na->data_size != na->initialized_size) {
  979             ntfs_log_error("uninitialized encrypted file not supported\n");
  980             errno = EINVAL;
  981             return -1;
  982         }   
  983         max_init = max_read = ((na->data_size + 511) & ~511) + 2;
  984     }
  985     if (pos + count > max_read) {
  986         if (pos >= max_read)
  987             return 0;
  988         count = max_read - pos;
  989     }
  990     /* If it is a resident attribute, get the value from the mft record. */
  991     if (!NAttrNonResident(na)) {
  992         ntfs_attr_search_ctx *ctx;
  993         char *val;
  994 
  995         ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
  996         if (!ctx)
  997             return -1;
  998         if (ntfs_attr_lookup(na->type, na->name, na->name_len, 0,
  999                 0, NULL, 0, ctx)) {
 1000 res_err_out:
 1001             ntfs_attr_put_search_ctx(ctx);
 1002             return -1;
 1003         }
 1004         val = (char*)ctx->attr + le16_to_cpu(ctx->attr->value_offset);
 1005         if (val < (char*)ctx->attr || val +
 1006                 le32_to_cpu(ctx->attr->value_length) >
 1007                 (char*)ctx->mrec + vol->mft_record_size) {
 1008             errno = EIO;
 1009             ntfs_log_perror("%s: Sanity check failed", __FUNCTION__);
 1010             goto res_err_out;
 1011         }
 1012         memcpy(b, val + pos, count);
 1013         ntfs_attr_put_search_ctx(ctx);
 1014         return count;
 1015     }
 1016     total = total2 = 0;
 1017     /* Zero out reads beyond initialized size. */
 1018     if (pos + count > max_init) {
 1019         if (pos >= max_init) {
 1020             memset(b, 0, count);
 1021             return count;
 1022         }
 1023         total2 = pos + count - max_init;
 1024         count -= total2;
 1025         memset((u8*)b + count, 0, total2);
 1026     }
 1027         /*
 1028          * for encrypted non-resident attributes with efs_raw set 
 1029          * the last two bytes aren't read from disk but contain
 1030          * the number of padding bytes so original size can be 
 1031          * restored
 1032          */
 1033     if (na->ni->vol->efs_raw && 
 1034             (na->data_flags & ATTR_IS_ENCRYPTED) && 
 1035             ((pos + count) > max_init-2)) {
 1036         efs_padding_length = 511 - ((na->data_size - 1) & 511);
 1037         if (pos+count == max_init) {
 1038             if (count == 1) {
 1039                 *((u8*)b+count-1) = (u8)(efs_padding_length >> 8);
 1040                 count--;
 1041                 total2++;
 1042             } else {
 1043                 *(le16*)((u8*)b+count-2) = cpu_to_le16(efs_padding_length);
 1044                 count -= 2;
 1045                 total2 +=2;
 1046             }
 1047         } else {
 1048             *((u8*)b+count-1) = (u8)(efs_padding_length & 0xff);
 1049             count--;
 1050             total2++;
 1051         }
 1052     }
 1053     
 1054     /* Find the runlist element containing the vcn. */
 1055     rl = ntfs_attr_find_vcn(na, pos >> vol->cluster_size_bits);
 1056     if (!rl) {
 1057         /*
 1058          * If the vcn is not present it is an out of bounds read.
 1059          * However, we already truncated the read to the data_size,
 1060          * so getting this here is an error.
 1061          */
 1062         if (errno == ENOENT) {
 1063             errno = EIO;
 1064             ntfs_log_perror("%s: Failed to find VCN #1", __FUNCTION__);
 1065         }
 1066         return -1;
 1067     }
 1068     /*
 1069      * Gather the requested data into the linear destination buffer. Note,
 1070      * a partial final vcn is taken care of by the @count capping of read
 1071      * length.
 1072      */
 1073     ofs = pos - (rl->vcn << vol->cluster_size_bits);
 1074     for (; count; rl++, ofs = 0) {
 1075         if (rl->lcn == LCN_RL_NOT_MAPPED) {
 1076             rl = ntfs_attr_find_vcn(na, rl->vcn);
 1077             if (!rl) {
 1078                 if (errno == ENOENT) {
 1079                     errno = EIO;
 1080                     ntfs_log_perror("%s: Failed to find VCN #2",
 1081                             __FUNCTION__);
 1082                 }
 1083                 goto rl_err_out;
 1084             }
 1085             /* Needed for case when runs merged. */
 1086             ofs = pos + total - (rl->vcn << vol->cluster_size_bits);
 1087         }
 1088         if (!rl->length) {
 1089             errno = EIO;
 1090             ntfs_log_perror("%s: Zero run length", __FUNCTION__);
 1091             goto rl_err_out;
 1092         }
 1093         if (rl->lcn < (LCN)0) {
 1094             if (rl->lcn != (LCN)LCN_HOLE) {
 1095                 ntfs_log_perror("%s: Bad run (%lld)", 
 1096                         __FUNCTION__,
 1097                         (long long)rl->lcn);
 1098                 goto rl_err_out;
 1099             }
 1100             /* It is a hole, just zero the matching @b range. */
 1101             to_read = min(count, (rl->length <<
 1102                     vol->cluster_size_bits) - ofs);
 1103             memset(b, 0, to_read);
 1104             /* Update progress counters. */
 1105             total += to_read;
 1106             count -= to_read;
 1107             b = (u8*)b + to_read;
 1108             continue;
 1109         }
 1110         /* It is a real lcn, read it into @dst. */
 1111         to_read = min(count, (rl->length << vol->cluster_size_bits) -
 1112                 ofs);
 1113 retry:
 1114         ntfs_log_trace("Reading %lld bytes from vcn %lld, lcn %lld, ofs"
 1115                 " %lld.\n", (long long)to_read, (long long)rl->vcn,
 1116                    (long long )rl->lcn, (long long)ofs);
 1117         br = ntfs_pread(vol->dev, (rl->lcn << vol->cluster_size_bits) +
 1118                 ofs, to_read, b);
 1119         /* If everything ok, update progress counters and continue. */
 1120         if (br > 0) {
 1121             total += br;
 1122             count -= br;
 1123             b = (u8*)b + br;
 1124         }
 1125         if (br == to_read)
 1126             continue;
 1127         /* If the syscall was interrupted, try again. */
 1128         if (br == (s64)-1 && errno == EINTR)
 1129             goto retry;
 1130         if (total)
 1131             return total;
 1132         if (!br)
 1133             errno = EIO;
 1134         ntfs_log_perror("%s: ntfs_pread failed", __FUNCTION__);
 1135         return -1;
 1136     }
 1137     /* Finally, return the number of bytes read. */
 1138     return total + total2;
 1139 rl_err_out:
 1140     if (total)
 1141         return total;
 1142     errno = EIO;
 1143     return -1;
 1144 }
 1145 
 1146 /**
 1147  * ntfs_attr_pread - read from an attribute specified by an ntfs_attr structure
 1148  * @na:     ntfs attribute to read from
 1149  * @pos:    byte position in the attribute to begin reading from
 1150  * @count:  number of bytes to read
 1151  * @b:      output data buffer
 1152  *
 1153  * This function will read @count bytes starting at offset @pos from the ntfs
 1154  * attribute @na into the data buffer @b.
 1155  *
 1156  * On success, return the number of successfully read bytes. If this number is
 1157  * lower than @count this means that the read reached end of file or that an
 1158  * error was encountered during the read so that the read is partial. 0 means
 1159  * end of file or nothing was read (also return 0 when @count is 0).
 1160  *
 1161  * On error and nothing has been read, return -1 with errno set appropriately
 1162  * to the return code of ntfs_pread(), or to EINVAL in case of invalid
 1163  * arguments.
 1164  */
 1165 s64 ntfs_attr_pread(ntfs_attr *na, const s64 pos, s64 count, void *b)
 1166 {
 1167     s64 ret;
 1168     
 1169     if (!na || !na->ni || !na->ni->vol || !b || pos < 0 || count < 0) {
 1170         errno = EINVAL;
 1171         ntfs_log_perror("%s: na=%p  b=%p  pos=%lld  count=%lld",
 1172                 __FUNCTION__, na, b, (long long)pos,
 1173                 (long long)count);
 1174         return -1;
 1175     }
 1176     
 1177     ntfs_log_enter("Entering for inode %lld attr 0x%x pos %lld count "
 1178                "%lld\n", (unsigned long long)na->ni->mft_no,
 1179                le32_to_cpu(na->type), (long long)pos, (long long)count);
 1180 
 1181     ret = ntfs_attr_pread_i(na, pos, count, b);
 1182     
 1183     ntfs_log_leave("\n");
 1184     return ret;
 1185 }
 1186 
 1187 static int ntfs_attr_fill_zero(ntfs_attr *na, s64 pos, s64 count)
 1188 {
 1189     char *buf;
 1190     s64 written, size, end = pos + count;
 1191     s64 ofsi;
 1192     const runlist_element *rli;
 1193     ntfs_volume *vol;
 1194     int ret = -1;
 1195 
 1196     ntfs_log_trace("pos %lld, count %lld\n", (long long)pos, 
 1197                (long long)count);
 1198     
 1199     if (!na || pos < 0 || count < 0) {
 1200         errno = EINVAL;
 1201         goto err_out;
 1202     }
 1203     
 1204     buf = ntfs_calloc(NTFS_BUF_SIZE);
 1205     if (!buf)
 1206         goto err_out;
 1207     
 1208     rli = na->rl;
 1209     ofsi = 0;
 1210     vol = na->ni->vol;
 1211     while (pos < end) {
 1212         while (rli->length && (ofsi + (rli->length <<
 1213                             vol->cluster_size_bits) <= pos)) {
 1214                     ofsi += (rli->length << vol->cluster_size_bits);
 1215             rli++;
 1216         }
 1217         size = min(end - pos, NTFS_BUF_SIZE);
 1218             /*
 1219              * If the zeroed block is fully within a hole,
 1220              * we need not write anything, so advance as far
 1221              * as possible within the hole.
 1222              */
 1223         if ((rli->lcn == (LCN)LCN_HOLE)
 1224             && (ofsi <= pos)
 1225             && (ofsi + (rli->length << vol->cluster_size_bits)
 1226                 >= (pos + size))) {
 1227             size = min(end - pos, ofsi - pos
 1228                 + (rli->length << vol->cluster_size_bits));
 1229             pos += size;
 1230         } else {
 1231             written = ntfs_rl_pwrite(vol, rli, ofsi, pos,
 1232                             size, buf);
 1233             if (written <= 0) {
 1234                 ntfs_log_perror("Failed to zero space");
 1235                 goto err_free;
 1236             }
 1237             pos += written;
 1238         }
 1239     }
 1240     
 1241     ret = 0;
 1242 err_free:   
 1243     free(buf);
 1244 err_out:
 1245     return ret; 
 1246 }
 1247 
 1248 static int ntfs_attr_fill_hole(ntfs_attr *na, s64 count, s64 *ofs, 
 1249                    runlist_element **rl, VCN *update_from)
 1250 {
 1251     s64 to_write;
 1252     s64 need;
 1253     ntfs_volume *vol = na->ni->vol;
 1254     int eo, ret = -1;
 1255     runlist *rlc;
 1256     LCN lcn_seek_from = -1;
 1257     VCN cur_vcn, from_vcn;
 1258 
 1259     to_write = min(count, ((*rl)->length << vol->cluster_size_bits) - *ofs);
 1260     
 1261     cur_vcn = (*rl)->vcn;
 1262     from_vcn = (*rl)->vcn + (*ofs >> vol->cluster_size_bits);
 1263     
 1264     ntfs_log_trace("count: %lld, cur_vcn: %lld, from: %lld, to: %lld, ofs: "
 1265                "%lld\n", (long long)count, (long long)cur_vcn, 
 1266                (long long)from_vcn, (long long)to_write, (long long)*ofs);
 1267      
 1268     /* Map the runlist to be able to update mapping pairs later. */
 1269 #if PARTIAL_RUNLIST_UPDATING
 1270     if (!na->rl) {
 1271         if (ntfs_attr_map_whole_runlist(na))
 1272             goto err_out;
 1273     } else {
 1274         /* make sure the run ahead of hole is mapped */
 1275         if ((*rl)->lcn == LCN_HOLE) {
 1276             if (ntfs_attr_map_partial_runlist(na,
 1277                 (cur_vcn ? cur_vcn - 1 : cur_vcn)))
 1278                     goto err_out;
 1279         }
 1280     }
 1281 #else
 1282     if (ntfs_attr_map_whole_runlist(na))
 1283         goto err_out;
 1284 #endif
 1285      
 1286     /* Restore @*rl, it probably get lost during runlist mapping. */
 1287     *rl = ntfs_attr_find_vcn(na, cur_vcn);
 1288     if (!*rl) {
 1289         ntfs_log_error("Failed to find run after mapping runlist. "
 1290                    "Please report to %s.\n", NTFS_DEV_LIST);
 1291         errno = EIO;
 1292         goto err_out;
 1293     }
 1294     
 1295     /* Search backwards to find the best lcn to start seek from. */
 1296     rlc = *rl;
 1297     while (rlc->vcn) {
 1298         rlc--;
 1299         if (rlc->lcn >= 0) {
 1300                 /*
 1301                  * avoid fragmenting a compressed file
 1302                  * Windows does not do that, and that may
 1303                  * not be desirable for files which can
 1304                  * be updated
 1305                  */
 1306             if (na->data_flags & ATTR_COMPRESSION_MASK)
 1307                 lcn_seek_from = rlc->lcn + rlc->length;
 1308             else
 1309                 lcn_seek_from = rlc->lcn + (from_vcn - rlc->vcn);
 1310             break;
 1311         }
 1312     }
 1313     if (lcn_seek_from == -1) {
 1314         /* Backwards search failed, search forwards. */
 1315         rlc = *rl;
 1316         while (rlc->length) {
 1317             rlc++;
 1318             if (rlc->lcn >= 0) {
 1319                 lcn_seek_from = rlc->lcn - (rlc->vcn - from_vcn);
 1320                 if (lcn_seek_from < -1)
 1321                     lcn_seek_from = -1;
 1322                 break;
 1323             }
 1324         }
 1325     }
 1326     
 1327     need = ((*ofs + to_write - 1) >> vol->cluster_size_bits)
 1328              + 1 + (*rl)->vcn - from_vcn;
 1329     if ((na->data_flags & ATTR_COMPRESSION_MASK)
 1330         && (need < na->compression_block_clusters)) {
 1331         /*
 1332          * for a compressed file, be sure to allocate the full
 1333          * compression block, as we may need space to decompress
 1334          * existing compressed data.
 1335          * So allocate the space common to compression block
 1336          * and existing hole.
 1337          */
 1338         VCN alloc_vcn;
 1339 
 1340         if ((from_vcn & -na->compression_block_clusters) <= (*rl)->vcn)
 1341             alloc_vcn = (*rl)->vcn;
 1342         else
 1343             alloc_vcn = from_vcn & -na->compression_block_clusters;
 1344         need = (alloc_vcn | (na->compression_block_clusters - 1))
 1345             + 1 - alloc_vcn;
 1346         if (need > (*rl)->length) {
 1347             ntfs_log_error("Cannot allocate %lld clusters"
 1348                     " within a hole of %lld\n",
 1349                     (long long)need,
 1350                     (long long)(*rl)->length);
 1351             errno = EIO;
 1352             goto err_out;
 1353         }
 1354         rlc = ntfs_cluster_alloc(vol, alloc_vcn, need,
 1355                  lcn_seek_from, DATA_ZONE);
 1356     } else
 1357         rlc = ntfs_cluster_alloc(vol, from_vcn, need,
 1358                  lcn_seek_from, DATA_ZONE);
 1359     if (!rlc)
 1360         goto err_out;
 1361     if (na->data_flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE))
 1362         na->compressed_size += need << vol->cluster_size_bits;
 1363     
 1364     *rl = ntfs_runlists_merge(na->rl, rlc);
 1365     NAttrSetRunlistDirty(na);
 1366         /*
 1367          * For a compressed attribute, we must be sure there are two
 1368          * available entries, so reserve them before it gets too late.
 1369          */
 1370     if (*rl && (na->data_flags & ATTR_COMPRESSION_MASK)) {
 1371         runlist_element *oldrl = na->rl;
 1372         na->rl = *rl;
 1373         *rl = ntfs_rl_extend(na,*rl,2);
 1374         if (!*rl) na->rl = oldrl; /* restore to original if failed */
 1375     }
 1376     if (!*rl) {
 1377         eo = errno;
 1378         ntfs_log_perror("Failed to merge runlists");
 1379         if (ntfs_cluster_free_from_rl(vol, rlc)) {
 1380             ntfs_log_perror("Failed to free hot clusters. "
 1381                     "Please run chkdsk /f");
 1382         }
 1383         errno = eo;
 1384         goto err_out;
 1385     }
 1386     na->unused_runs = 2;
 1387     na->rl = *rl;
 1388     if ((*update_from == -1) || (from_vcn < *update_from))
 1389         *update_from = from_vcn;
 1390     *rl = ntfs_attr_find_vcn(na, cur_vcn);
 1391     if (!*rl) {
 1392         /*
 1393          * It's definitely a BUG, if we failed to find @cur_vcn, because
 1394          * we missed it during instantiating of the hole.
 1395          */
 1396         ntfs_log_error("Failed to find run after hole instantiation. "
 1397                    "Please report to %s.\n", NTFS_DEV_LIST);
 1398         errno = EIO;
 1399         goto err_out;
 1400     }
 1401     /* If leaved part of the hole go to the next run. */
 1402     if ((*rl)->lcn < 0)
 1403         (*rl)++;
 1404     /* Now LCN shoudn't be less than 0. */
 1405     if ((*rl)->lcn < 0) {
 1406         ntfs_log_error("BUG! LCN is lesser than 0. "
 1407                    "Please report to the %s.\n", NTFS_DEV_LIST);
 1408         errno = EIO;
 1409         goto err_out;
 1410     }
 1411     if (*ofs) {
 1412         /* Clear non-sparse region from @cur_vcn to @*ofs. */
 1413         if (ntfs_attr_fill_zero(na, cur_vcn << vol->cluster_size_bits,
 1414                     *ofs))
 1415             goto err_out;
 1416     }
 1417     if ((*rl)->vcn < cur_vcn) {
 1418         /*
 1419          * Clusters that replaced hole are merged with
 1420          * previous run, so we need to update offset.
 1421          */
 1422         *ofs += (cur_vcn - (*rl)->vcn) << vol->cluster_size_bits;
 1423     }
 1424     if ((*rl)->vcn > cur_vcn) {
 1425         /*
 1426          * We left part of the hole, so we need to update offset
 1427          */
 1428         *ofs -= ((*rl)->vcn - cur_vcn) << vol->cluster_size_bits;
 1429     }
 1430     
 1431     ret = 0;
 1432 err_out:
 1433     return ret;
 1434 }
 1435 
 1436 static int stuff_hole(ntfs_attr *na, const s64 pos);
 1437 
 1438 /*
 1439  *      Split an existing hole for overwriting with data
 1440  *  The hole may have to be split into two or three parts, so
 1441  *  that the overwritten part fits within a single compression block
 1442  *
 1443  *  No cluster allocation is needed, this will be done later in
 1444  *  standard hole filling, hence no need to reserve runs for
 1445  *  future needs.
 1446  *
 1447  *  Returns the number of clusters with existing compressed data
 1448  *      in the compression block to be written to
 1449  *      (or the full block, if it was a full hole)
 1450  *      -1 if there were an error
 1451  */
 1452 
 1453 static int split_compressed_hole(ntfs_attr *na, runlist_element **prl,
 1454             s64 pos, s64 count, VCN *update_from)
 1455 {
 1456     int compressed_part;
 1457     int cluster_size_bits = na->ni->vol->cluster_size_bits;
 1458     runlist_element *rl = *prl;
 1459 
 1460     compressed_part
 1461         = na->compression_block_clusters;
 1462         /* reserve entries in runlist if we have to split */
 1463     if (rl->length > na->compression_block_clusters) {
 1464         *prl = ntfs_rl_extend(na,*prl,2);
 1465         if (!*prl) {
 1466             compressed_part = -1;
 1467         } else {
 1468             rl = *prl;
 1469             na->unused_runs = 2;
 1470         }
 1471     }
 1472     if (*prl && (rl->length > na->compression_block_clusters)) {
 1473         /*
 1474          * Locate the update part relative to beginning of
 1475          * current run
 1476          */
 1477         int beginwrite = (pos >> cluster_size_bits) - rl->vcn;
 1478         s32 endblock = (((pos + count - 1) >> cluster_size_bits)
 1479             | (na->compression_block_clusters - 1)) + 1 - rl->vcn;
 1480 
 1481         compressed_part = na->compression_block_clusters
 1482             - (rl->length & (na->compression_block_clusters - 1));
 1483         if ((beginwrite + compressed_part) >= na->compression_block_clusters)
 1484             compressed_part = na->compression_block_clusters;
 1485             /*
 1486              * if the run ends beyond end of needed block
 1487              * we have to split the run
 1488              */
 1489         if (endblock < rl[0].length) {
 1490             runlist_element *xrl;
 1491             int n;
 1492 
 1493             /*
 1494              * we have to split into three parts if the run
 1495              * does not end within the first compression block.
 1496              * This means the hole begins before the
 1497              * compression block.
 1498              */
 1499             if (endblock > na->compression_block_clusters) {
 1500                 if (na->unused_runs < 2) {
 1501 ntfs_log_error("No free run, case 1\n");
 1502                 }
 1503                 na->unused_runs -= 2;
 1504                 xrl = rl;
 1505                 n = 0;
 1506                 while (xrl->length) {
 1507                     xrl++;
 1508                     n++;
 1509                 }
 1510                 do {
 1511                     xrl[2] = *xrl;
 1512                     xrl--;
 1513                 } while (xrl != rl);
 1514                 rl[1].length = na->compression_block_clusters;
 1515                 rl[2].length = rl[0].length - endblock;
 1516                 rl[0].length = endblock
 1517                     - na->compression_block_clusters;
 1518                 rl[1].lcn = LCN_HOLE;
 1519                 rl[2].lcn = LCN_HOLE;
 1520                 rl[1].vcn = rl[0].vcn + rl[0].length;
 1521                 rl[2].vcn = rl[1].vcn
 1522                     + na->compression_block_clusters;
 1523                 rl = ++(*prl);
 1524             } else {
 1525                 /*
 1526                  * split into two parts and use the
 1527                  * first one
 1528                  */
 1529                 if (!na->unused_runs) {
 1530 ntfs_log_error("No free run, case 2\n");
 1531                 }
 1532                 na->unused_runs--;
 1533                 xrl = rl;
 1534                 n = 0;
 1535                 while (xrl->length) {
 1536                     xrl++;
 1537                     n++;
 1538                 }
 1539                 do {
 1540                     xrl[1] = *xrl;
 1541                     xrl--;
 1542                 } while (xrl != rl);
 1543                 if (beginwrite < endblock) {
 1544                     /* we will write into the first part of hole */
 1545                     rl[1].length = rl[0].length - endblock;
 1546                     rl[0].length = endblock;
 1547                     rl[1].vcn = rl[0].vcn + rl[0].length;
 1548                     rl[1].lcn = LCN_HOLE;
 1549                 } else {
 1550                     /* we will write into the second part of hole */
 1551 // impossible ?
 1552                     rl[1].length = rl[0].length - endblock;
 1553                     rl[0].length = endblock;
 1554                     rl[1].vcn = rl[0].vcn + rl[0].length;
 1555                     rl[1].lcn = LCN_HOLE;
 1556                     rl = ++(*prl);
 1557                 }
 1558             }
 1559         } else {
 1560             if (rl[1].length) {
 1561                 runlist_element *xrl;
 1562                 int n;
 1563 
 1564                 /*
 1565                  * split into two parts and use the
 1566                  * last one
 1567                  */
 1568                 if (!na->unused_runs) {
 1569 ntfs_log_error("No free run, case 4\n");
 1570                 }
 1571                 na->unused_runs--;
 1572                 xrl = rl;
 1573                 n = 0;
 1574                 while (xrl->length) {
 1575                     xrl++;
 1576                     n++;
 1577                 }
 1578                 do {
 1579                     xrl[1] = *xrl;
 1580                     xrl--;
 1581                 } while (xrl != rl);
 1582             } else {
 1583                 rl[2].lcn = rl[1].lcn;
 1584                 rl[2].vcn = rl[1].vcn;
 1585                 rl[2].length = rl[1].length;
 1586             }
 1587             rl[1].vcn -= na->compression_block_clusters;
 1588             rl[1].lcn = LCN_HOLE;
 1589             rl[1].length = na->compression_block_clusters;
 1590             rl[0].length -= na->compression_block_clusters;
 1591             if (pos >= (rl[1].vcn << cluster_size_bits)) {
 1592                 rl = ++(*prl);
 1593             }
 1594         }
 1595     NAttrSetRunlistDirty(na);
 1596     if ((*update_from == -1) || ((*prl)->vcn < *update_from))
 1597         *update_from = (*prl)->vcn;
 1598     }
 1599     return (compressed_part);
 1600 }
 1601 
 1602 /*
 1603  *      Borrow space from adjacent hole for appending data
 1604  *  The hole may have to be split so that the end of hole is not
 1605  *  affected by cluster allocation and overwriting
 1606  *  Cluster allocation is needed for the overwritten compression block
 1607  *
 1608  *  Must always leave two unused entries in the runlist
 1609  *
 1610  *  Returns the number of clusters with existing compressed data
 1611  *      in the compression block to be written to
 1612  *      -1 if there were an error
 1613  */
 1614 
 1615 static int borrow_from_hole(ntfs_attr *na, runlist_element **prl,
 1616             s64 pos, s64 count, VCN *update_from, BOOL wasnonresident)
 1617 {
 1618     int compressed_part = 0;
 1619     int cluster_size_bits = na->ni->vol->cluster_size_bits;
 1620     runlist_element *rl = *prl;
 1621     s32 endblock;
 1622     long long allocated;
 1623     runlist_element *zrl;
 1624     int irl;
 1625     BOOL undecided;
 1626     BOOL nothole;
 1627 
 1628         /* check whether the compression block is fully allocated */
 1629     endblock = (((pos + count - 1) >> cluster_size_bits) | (na->compression_block_clusters - 1)) + 1 - rl->vcn;
 1630     allocated = 0;
 1631     zrl = rl;
 1632     irl = 0;
 1633     while (zrl->length && (zrl->lcn >= 0) && (allocated < endblock)) {
 1634         allocated += zrl->length;
 1635         zrl++;
 1636         irl++;
 1637     }
 1638 
 1639     undecided = (allocated < endblock) && (zrl->lcn == LCN_RL_NOT_MAPPED);
 1640     nothole = (allocated >= endblock) || (zrl->lcn != LCN_HOLE);
 1641 
 1642     if (undecided || nothole) {
 1643         runlist_element *orl = na->rl;
 1644         s64 olcn = (*prl)->lcn;
 1645 #if PARTIAL_RUNLIST_UPDATING
 1646         VCN prevblock;
 1647 #endif
 1648             /*
 1649              * Map the runlist, unless it has not been created.
 1650              * If appending data, a partial mapping from the
 1651              * end of previous block will do.
 1652              */
 1653         irl = *prl - na->rl;
 1654 #if PARTIAL_RUNLIST_UPDATING
 1655         prevblock = pos >> cluster_size_bits;
 1656         if (prevblock)
 1657             prevblock--;
 1658         if (!NAttrBeingNonResident(na)
 1659             && (NAttrDataAppending(na)
 1660             ? ntfs_attr_map_partial_runlist(na,prevblock)
 1661             : ntfs_attr_map_whole_runlist(na))) {
 1662 #else
 1663         if (!NAttrBeingNonResident(na)
 1664             && ntfs_attr_map_whole_runlist(na)) {
 1665 #endif
 1666             rl = (runlist_element*)NULL;
 1667         } else {
 1668             /*
 1669              * Mapping the runlist may cause its relocation,
 1670              * and relocation may be at the same place with
 1671              * relocated contents.
 1672              * Have to find the current run again when this
 1673              * happens.
 1674              */
 1675             if ((na->rl != orl) || ((*prl)->lcn != olcn)) {
 1676                 zrl = &na->rl[irl];
 1677                 while (zrl->length && (zrl->lcn != olcn))
 1678                     zrl++;
 1679                 *prl = zrl;
 1680             }
 1681             if (!(*prl)->length) {
 1682                  ntfs_log_error("Mapped run not found,"
 1683                     " inode %lld lcn 0x%llx\n",
 1684                     (long long)na->ni->mft_no,
 1685                     (long long)olcn);
 1686                 rl = (runlist_element*)NULL;
 1687             } else {
 1688                 rl = ntfs_rl_extend(na,*prl,2);
 1689                 na->unused_runs = 2;
 1690             }
 1691         }
 1692         *prl = rl;
 1693         if (rl && undecided) {
 1694             allocated = 0;
 1695             zrl = rl;
 1696             irl = 0;
 1697             while (zrl->length && (zrl->lcn >= 0)
 1698                 && (allocated < endblock)) {
 1699                 allocated += zrl->length;
 1700                 zrl++;
 1701                 irl++;
 1702             }
 1703         }
 1704     }
 1705         /*
 1706          * compression block not fully allocated and followed
 1707          * by a hole : we must allocate in the hole.
 1708          */
 1709     if (rl && (allocated < endblock) && (zrl->lcn == LCN_HOLE)) {
 1710         s64 xofs;
 1711 
 1712             /*
 1713              * split the hole if not fully needed
 1714              */
 1715         if ((allocated + zrl->length) > endblock) {
 1716             runlist_element *xrl;
 1717 
 1718             *prl = ntfs_rl_extend(na,*prl,1);
 1719             if (*prl) {
 1720                     /* beware : rl was reallocated */
 1721                 rl = *prl;
 1722                 zrl = &rl[irl];
 1723                 na->unused_runs = 0;
 1724                 xrl = zrl;
 1725                 while (xrl->length) xrl++;
 1726                 do {
 1727                     xrl[1] = *xrl;
 1728                 } while (xrl-- != zrl);
 1729                 zrl->length = endblock - allocated;
 1730                 zrl[1].length -= zrl->length;
 1731                 zrl[1].vcn = zrl->vcn + zrl->length;
 1732                 NAttrSetRunlistDirty(na);
 1733             }
 1734         }
 1735         if (*prl) {
 1736             if (wasnonresident)
 1737                 compressed_part = na->compression_block_clusters
 1738                    - zrl->length;
 1739             xofs = 0;
 1740             if (ntfs_attr_fill_hole(na,
 1741                     zrl->length << cluster_size_bits,
 1742                     &xofs, &zrl, update_from))
 1743                     compressed_part = -1;
 1744             else {
 1745             /* go back to initial cluster, now reallocated */
 1746                 while (zrl->vcn > (pos >> cluster_size_bits))
 1747                     zrl--;
 1748                 *prl = zrl;
 1749             }
 1750         }
 1751     }
 1752     if (!*prl) {
 1753         ntfs_log_error("No elements to borrow from a hole\n");
 1754         compressed_part = -1;
 1755     } else
 1756         if ((*update_from == -1) || ((*prl)->vcn < *update_from))
 1757             *update_from = (*prl)->vcn;
 1758     return (compressed_part);
 1759 }
 1760 
 1761 static int ntfs_attr_truncate_i(ntfs_attr *na, const s64 newsize,
 1762                 hole_type holes);
 1763 
 1764 /**
 1765  * ntfs_attr_pwrite - positioned write to an ntfs attribute
 1766  * @na:     ntfs attribute to write to
 1767  * @pos:    position in the attribute to write to
 1768  * @count:  number of bytes to write
 1769  * @b:      data buffer to write to disk
 1770  *
 1771  * This function will write @count bytes from data buffer @b to ntfs attribute
 1772  * @na at position @pos.
 1773  *
 1774  * On success, return the number of successfully written bytes. If this number
 1775  * is lower than @count this means that an error was encountered during the
 1776  * write so that the write is partial. 0 means nothing was written (also return
 1777  * 0 when @count is 0).
 1778  *
 1779  * On error and nothing has been written, return -1 with errno set
 1780  * appropriately to the return code of ntfs_pwrite(), or to EINVAL in case of
 1781  * invalid arguments.
 1782  */
 1783 static s64 ntfs_attr_pwrite_i(ntfs_attr *na, const s64 pos, s64 count,
 1784                                 const void *b)
 1785 {
 1786     s64 written, to_write, ofs, old_initialized_size, old_data_size;
 1787     s64 total = 0;
 1788     VCN update_from = -1;
 1789     ntfs_volume *vol;
 1790     s64 fullcount;
 1791     ntfs_attr_search_ctx *ctx = NULL;
 1792     runlist_element *rl;
 1793     s64 hole_end;
 1794     int eo;
 1795     int compressed_part;
 1796     struct {
 1797         unsigned int undo_initialized_size  : 1;
 1798         unsigned int undo_data_size     : 1;
 1799     } need_to = { 0, 0 };
 1800     BOOL wasnonresident = FALSE;
 1801     BOOL compressed;
 1802 
 1803     vol = na->ni->vol;
 1804     compressed = (na->data_flags & ATTR_COMPRESSION_MASK)
 1805              != const_cpu_to_le16(0);
 1806     na->unused_runs = 0; /* prepare overflow checks */
 1807     /*
 1808      * Encrypted attributes are only supported in raw mode.  We return
 1809      * access denied, which is what Windows NT4 does, too.
 1810      * Moreover a file cannot be both encrypted and compressed.
 1811      */
 1812     if ((na->data_flags & ATTR_IS_ENCRYPTED)
 1813        && (compressed || !vol->efs_raw)) {
 1814         errno = EACCES;
 1815         goto errno_set;
 1816     }
 1817         /*
 1818          * Fill the gap, when writing beyond the end of a compressed
 1819          * file. This will make recursive calls
 1820          */
 1821     if (compressed
 1822         && (na->type == AT_DATA)
 1823         && (pos > na->initialized_size)
 1824         && stuff_hole(na,pos))
 1825         goto errno_set;
 1826     /* If this is a compressed attribute it needs special treatment. */
 1827     wasnonresident = NAttrNonResident(na) != 0;
 1828         /*
 1829          * Compression is restricted to data streams and
 1830          * only ATTR_IS_COMPRESSED compression mode is supported.
 1831                  */
 1832     if (compressed
 1833         && ((na->type != AT_DATA)
 1834         || ((na->data_flags & ATTR_COMPRESSION_MASK)
 1835              != ATTR_IS_COMPRESSED))) {
 1836         errno = EOPNOTSUPP;
 1837         goto errno_set;
 1838     }
 1839     
 1840     if (!count)
 1841         goto out;
 1842     /* for a compressed file, get prepared to reserve a full block */
 1843     fullcount = count;
 1844     /* If the write reaches beyond the end, extend the attribute. */
 1845     old_data_size = na->data_size;
 1846     /* identify whether this is appending to a non resident data attribute */
 1847     if ((na->type == AT_DATA) && (pos >= old_data_size)
 1848         && NAttrNonResident(na))
 1849         NAttrSetDataAppending(na);
 1850     if (pos + count > na->data_size) {
 1851 #if PARTIAL_RUNLIST_UPDATING
 1852         /*
 1853          * When appending data, the attribute is first extended
 1854          * before being filled with data. This may cause the
 1855          * attribute to be made temporarily sparse, which
 1856          * implies reformating the inode and reorganizing the
 1857          * full runlist. To avoid unnecessary reorganization,
 1858          * we avoid sparse testing until the data is filled in.
 1859          */
 1860         if (ntfs_attr_truncate_i(na, pos + count,
 1861                     (NAttrDataAppending(na) ?
 1862                         HOLES_DELAY : HOLES_OK))) {
 1863             ntfs_log_perror("Failed to enlarge attribute");
 1864             goto errno_set;
 1865         }
 1866         /*
 1867          * If we avoided updating the runlist, we must be sure
 1868          * to cancel the enlargement and put back the runlist to
 1869          * a clean state if we get into some error.
 1870          */
 1871         if (NAttrDataAppending(na))
 1872             need_to.undo_data_size = 1;
 1873 #else
 1874         if (ntfs_attr_truncate_i(na, pos + count, HOLES_OK)) {
 1875             ntfs_log_perror("Failed to enlarge attribute");
 1876             goto errno_set;
 1877         }
 1878 #endif
 1879             /* resizing may change the compression mode */
 1880         compressed = (na->data_flags & ATTR_COMPRESSION_MASK)
 1881                 != const_cpu_to_le16(0);
 1882         need_to.undo_data_size = 1;
 1883     }
 1884         /*
 1885          * For compressed data, a single full block was allocated
 1886          * to deal with compression, possibly in a previous call.
 1887          * We are not able to process several blocks because
 1888          * some clusters are freed after compression and
 1889          * new allocations have to be done before proceeding,
 1890          * so truncate the requested count if needed (big buffers).
 1891          */
 1892     if (compressed) {
 1893         fullcount = (pos | (na->compression_block_size - 1)) + 1 - pos;
 1894         if (count > fullcount)
 1895             count = fullcount;
 1896     }
 1897     old_initialized_size = na->initialized_size;
 1898     /* If it is a resident attribute, write the data to the mft record. */
 1899     if (!NAttrNonResident(na)) {
 1900         char *val;
 1901 
 1902         ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
 1903         if (!ctx)
 1904             goto err_out;
 1905         if (ntfs_attr_lookup(na->type, na->name, na->name_len, 0,
 1906                 0, NULL, 0, ctx)) {
 1907             ntfs_log_perror("%s: lookup failed", __FUNCTION__);
 1908             goto err_out;
 1909         }
 1910         val = (char*)ctx->attr + le16_to_cpu(ctx->attr->value_offset);
 1911         if (val < (char*)ctx->attr || val +
 1912                 le32_to_cpu(ctx->attr->value_length) >
 1913                 (char*)ctx->mrec + vol->mft_record_size) {
 1914             errno = EIO;
 1915             ntfs_log_perror("%s: Sanity check failed", __FUNCTION__);
 1916             goto err_out;
 1917         }
 1918         memcpy(val + pos, b, count);
 1919         if (ntfs_mft_record_write(vol, ctx->ntfs_ino->mft_no,
 1920                 ctx->mrec)) {
 1921             /*
 1922              * NOTE: We are in a bad state at this moment. We have
 1923              * dirtied the mft record but we failed to commit it to
 1924              * disk. Since we have read the mft record ok before,
 1925              * it is unlikely to fail writing it, so is ok to just
 1926              * return error here... (AIA)
 1927              */
 1928             ntfs_log_perror("%s: failed to write mft record", __FUNCTION__);
 1929             goto err_out;
 1930         }
 1931         ntfs_attr_put_search_ctx(ctx);
 1932         total = count;
 1933         goto out;
 1934     }
 1935     
 1936     /* Handle writes beyond initialized_size. */
 1937 
 1938     if (pos + count > na->initialized_size) {
 1939 #if PARTIAL_RUNLIST_UPDATING
 1940         /*
 1941          * When appending, we only need to map the end of the runlist,
 1942          * starting at the last previously allocated run, so that
 1943          * we are able a new one to it.
 1944          * However, for compressed file, we need the full compression
 1945          * block, which may be split in several extents.
 1946          */
 1947         if (compressed && !NAttrDataAppending(na)) {
 1948             if (ntfs_attr_map_whole_runlist(na))
 1949                 goto err_out;
 1950         } else {
 1951             VCN block_begin;
 1952 
 1953             if (NAttrDataAppending(na)
 1954                 || (pos < na->initialized_size))
 1955                 block_begin = pos >> vol->cluster_size_bits;
 1956             else
 1957                 block_begin = na->initialized_size >> vol->cluster_size_bits;
 1958 
 1959             if (compressed)
 1960                 block_begin &= -na->compression_block_clusters;
 1961             if (block_begin)
 1962                 block_begin--;
 1963             if (ntfs_attr_map_partial_runlist(na, block_begin))
 1964                 goto err_out;
 1965             if ((update_from == -1) || (block_begin < update_from))
 1966                 update_from = block_begin;
 1967         }
 1968 #else
 1969             if (ntfs_attr_map_whole_runlist(na))
 1970                 goto err_out;
 1971 #endif
 1972         /*
 1973          * For a compressed attribute, we must be sure there is an
 1974          * available entry, and, when reopening a compressed file,
 1975          * we may need to split a hole. So reserve the entries
 1976          * before it gets too late.
 1977          */
 1978         if (compressed) {
 1979             na->rl = ntfs_rl_extend(na,na->rl,2);
 1980             if (!na->rl)
 1981                 goto err_out;
 1982             na->unused_runs = 2;
 1983         }
 1984         /* Set initialized_size to @pos + @count. */
 1985         ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
 1986         if (!ctx)
 1987             goto err_out;
 1988         if (ntfs_attr_lookup(na->type, na->name, na->name_len, 0,
 1989                 0, NULL, 0, ctx))
 1990             goto err_out;
 1991         
 1992         /* If write starts beyond initialized_size, zero the gap. */
 1993         if (pos > na->initialized_size)
 1994             if (ntfs_attr_fill_zero(na, na->initialized_size, 
 1995                         pos - na->initialized_size))
 1996                 goto err_out;
 1997             
 1998         ctx->attr->initialized_size = cpu_to_sle64(pos + count);
 1999         /* fix data_size for compressed files */
 2000         if (compressed) {
 2001             na->data_size = pos + count;
 2002             ctx->attr->data_size = ctx->attr->initialized_size;
 2003         }
 2004         if (ntfs_mft_record_write(vol, ctx->ntfs_ino->mft_no,
 2005                 ctx->mrec)) {
 2006             /*
 2007              * Undo the change in the in-memory copy and send it
 2008              * back for writing.
 2009              */
 2010             ctx->attr->initialized_size =
 2011                     cpu_to_sle64(old_initialized_size);
 2012             ntfs_mft_record_write(vol, ctx->ntfs_ino->mft_no,
 2013                     ctx->mrec);
 2014             goto err_out;
 2015         }
 2016         na->initialized_size = pos + count;
 2017 #if CACHE_NIDATA_SIZE
 2018         if (na->ni->mrec->flags & MFT_RECORD_IS_DIRECTORY
 2019             ? na->type == AT_INDEX_ROOT && na->name == NTFS_INDEX_I30
 2020             : na->type == AT_DATA && na->name == AT_UNNAMED) {
 2021             na->ni->data_size = na->data_size;
 2022             if ((compressed || NAttrSparse(na))
 2023                     && NAttrNonResident(na))
 2024                 na->ni->allocated_size = na->compressed_size;
 2025             else
 2026                 na->ni->allocated_size = na->allocated_size;
 2027             set_nino_flag(na->ni,KnownSize);
 2028         }
 2029 #endif
 2030         ntfs_attr_put_search_ctx(ctx);
 2031         ctx = NULL;
 2032         /*
 2033          * NOTE: At this point the initialized_size in the mft record
 2034          * has been updated BUT there is random data on disk thus if
 2035          * we decide to abort, we MUST change the initialized_size
 2036          * again.
 2037          */
 2038         need_to.undo_initialized_size = 1;
 2039     }
 2040     /* Find the runlist element containing the vcn. */
 2041     rl = ntfs_attr_find_vcn(na, pos >> vol->cluster_size_bits);
 2042     if (!rl) {
 2043         /*
 2044          * If the vcn is not present it is an out of bounds write.
 2045          * However, we already extended the size of the attribute,
 2046          * so getting this here must be an error of some kind.
 2047          */
 2048         if (errno == ENOENT) {
 2049             errno = EIO;
 2050             ntfs_log_perror("%s: Failed to find VCN #3", __FUNCTION__);
 2051         }
 2052         goto err_out;
 2053     }
 2054         /*
 2055          * Determine if there is compressed data in the current
 2056          * compression block (when appending to an existing file).
 2057          * If so, decompression will be needed, and the full block
 2058          * must be allocated to be identified as uncompressed.
 2059          * This comes in two variants, depending on whether
 2060          * compression has saved at least one cluster.
 2061          * The compressed size can never be over full size by
 2062          * more than 485 (maximum for 15 compression blocks
 2063          * compressed to 4098 and the last 3640 bytes compressed
 2064          * to 3640 + 3640/8 = 4095, with 15*2 + 4095 - 3640 = 485)
 2065          * This is less than the smallest cluster, so the hole is
 2066          * is never beyond the cluster next to the position of
 2067          * the first uncompressed byte to write.
 2068          */
 2069     compressed_part = 0;
 2070     if (compressed) {
 2071         if ((rl->lcn == (LCN)LCN_HOLE)
 2072             && wasnonresident) {
 2073             if (rl->length < na->compression_block_clusters)
 2074                 /*
 2075                  * the needed block is in a hole smaller
 2076                  * than the compression block : we can use
 2077                  * it fully
 2078                  */
 2079                 compressed_part
 2080                     = na->compression_block_clusters
 2081                        - rl->length;
 2082             else {
 2083                 /*
 2084                  * the needed block is in a hole bigger
 2085                  * than the compression block : we must
 2086                  * split the hole and use it partially
 2087                  */
 2088                 compressed_part = split_compressed_hole(na,
 2089                     &rl, pos, count, &update_from);
 2090             }
 2091         } else {
 2092             if (rl->lcn >= 0) {
 2093                 /*
 2094                  * the needed block contains data, make
 2095                  * sure the full compression block is
 2096                  * allocated. Borrow from hole if needed
 2097                  */
 2098                 compressed_part = borrow_from_hole(na,
 2099                     &rl, pos, count, &update_from,
 2100                     wasnonresident);
 2101             }
 2102         }
 2103 
 2104         if (compressed_part < 0)
 2105             goto err_out;
 2106 
 2107             /* just making non-resident, so not yet compressed */
 2108         if (NAttrBeingNonResident(na)
 2109             && (compressed_part < na->compression_block_clusters))
 2110             compressed_part = 0;
 2111     }
 2112     ofs = pos - (rl->vcn << vol->cluster_size_bits);
 2113     /*
 2114      * Scatter the data from the linear data buffer to the volume. Note, a
 2115      * partial final vcn is taken care of by the @count capping of write
 2116      * length.
 2117      */
 2118     for (hole_end = 0; count; rl++, ofs = 0) {
 2119         if (rl->lcn == LCN_RL_NOT_MAPPED) {
 2120             rl = ntfs_attr_find_vcn(na, rl->vcn);
 2121             if (!rl) {
 2122                 if (errno == ENOENT) {
 2123                     errno = EIO;
 2124                     ntfs_log_perror("%s: Failed to find VCN"
 2125                             " #4", __FUNCTION__);
 2126                 }
 2127                 goto rl_err_out;
 2128             }
 2129             /* Needed for case when runs merged. */
 2130             ofs = pos + total - (rl->vcn << vol->cluster_size_bits);
 2131         }
 2132         if (!rl->length) {
 2133             errno = EIO;
 2134             ntfs_log_perror("%s: Zero run length", __FUNCTION__);
 2135             goto rl_err_out;
 2136         }
 2137         if (rl->lcn < (LCN)0) {
 2138             hole_end = rl->vcn + rl->length;
 2139 
 2140             if (rl->lcn != (LCN)LCN_HOLE) {
 2141                 errno = EIO;
 2142                 ntfs_log_perror("%s: Unexpected LCN (%lld)", 
 2143                         __FUNCTION__,
 2144                         (long long)rl->lcn);
 2145                 goto rl_err_out;
 2146             }
 2147             if (ntfs_attr_fill_hole(na, fullcount, &ofs, &rl,
 2148                      &update_from))
 2149                 goto err_out;
 2150         }
 2151         if (compressed) {
 2152             while (rl->length
 2153                 && (ofs >= (rl->length << vol->cluster_size_bits))) {
 2154                 ofs -= rl->length << vol->cluster_size_bits;
 2155                 rl++;
 2156             }
 2157         }
 2158 
 2159         /* It is a real lcn, write it to the volume. */
 2160         to_write = min(count, (rl->length << vol->cluster_size_bits) - ofs);
 2161 retry:
 2162         ntfs_log_trace("Writing %lld bytes to vcn %lld, lcn %lld, ofs "
 2163                    "%lld.\n", (long long)to_write, (long long)rl->vcn,
 2164                    (long long)rl->lcn, (long long)ofs);
 2165         if (!NVolReadOnly(vol)) {
 2166             
 2167             s64 wpos = (rl->lcn << vol->cluster_size_bits) + ofs;
 2168             s64 wend = (rl->vcn << vol->cluster_size_bits) + ofs + to_write;
 2169             u32 bsize = vol->cluster_size;
 2170             /* Byte size needed to zero fill a cluster */
 2171             s64 rounding = ((wend + bsize - 1) & ~(s64)(bsize - 1)) - wend;
 2172             /**
 2173              * Zero fill to cluster boundary if we're writing at the
 2174              * end of the attribute or into an ex-sparse cluster.
 2175              * This will cause the kernel not to seek and read disk 
 2176              * blocks during write(2) to fill the end of the buffer 
 2177              * which increases write speed by 2-10 fold typically.
 2178              *
 2179              * This is done even for compressed files, because
 2180              * data is generally first written uncompressed.
 2181              */
 2182             if (rounding && ((wend == na->initialized_size) ||
 2183                 (wend < (hole_end << vol->cluster_size_bits)))){
 2184                 
 2185                 char *cb;
 2186                 
 2187                 rounding += to_write;
 2188                 
 2189                 cb = ntfs_malloc(rounding);
 2190                 if (!cb)
 2191                     goto err_out;
 2192                 
 2193                 memcpy(cb, b, to_write);
 2194                 memset(cb + to_write, 0, rounding - to_write);
 2195                 
 2196                 if (compressed) {
 2197                     written = ntfs_compressed_pwrite(na,
 2198                         rl, wpos, ofs, to_write,
 2199                         rounding, cb, compressed_part,
 2200                         &update_from);
 2201                 } else {
 2202                     written = ntfs_pwrite(vol->dev, wpos,
 2203                         rounding, cb); 
 2204                     if (written == rounding)
 2205                         written = to_write;
 2206                 }
 2207                 
 2208                 free(cb);
 2209             } else {
 2210                 if (compressed) {
 2211                     written = ntfs_compressed_pwrite(na,
 2212                         rl, wpos, ofs, to_write, 
 2213                         to_write, b, compressed_part,
 2214                         &update_from);
 2215                 } else
 2216                     written = ntfs_pwrite(vol->dev, wpos,
 2217                         to_write, b);
 2218             }
 2219         } else
 2220             written = to_write;
 2221         /* If everything ok, update progress counters and continue. */
 2222         if (written > 0) {
 2223             total += written;
 2224             count -= written;
 2225             fullcount -= written;
 2226             b = (const u8*)b + written;
 2227         }
 2228         if (written != to_write) {
 2229             /* Partial write cannot be dealt with, stop there */
 2230             /* If the syscall was interrupted, try again. */
 2231             if (written == (s64)-1 && errno == EINTR)
 2232                 goto retry;
 2233             if (!written)
 2234                 errno = EIO;
 2235             goto rl_err_out;
 2236         }
 2237         compressed_part = 0;
 2238     }
 2239 done:
 2240     if (ctx)
 2241         ntfs_attr_put_search_ctx(ctx);
 2242         /*
 2243          *   Update mapping pairs if needed.
 2244          * For a compressed file, we try to make a partial update
 2245          * of the mapping list. This makes a difference only if
 2246          * inode extents were needed.
 2247          */
 2248     if (NAttrRunlistDirty(na)) {
 2249         if (ntfs_attr_update_mapping_pairs(na,
 2250                 (update_from < 0 ? 0 : update_from))) {
 2251             /*
 2252              * FIXME: trying to recover by goto rl_err_out; 
 2253              * could cause driver hang by infinite looping.
 2254              */
 2255             total = -1;
 2256             goto out;
 2257         }
 2258         if (!wasnonresident)
 2259             NAttrClearBeingNonResident(na);
 2260         NAttrClearDataAppending(na);
 2261     }
 2262 out:    
 2263     return total;
 2264 rl_err_out:
 2265     eo = errno;
 2266     if (total) {
 2267         if (need_to.undo_initialized_size) {
 2268             if (pos + total > na->initialized_size)
 2269                 goto done;
 2270             /*
 2271              * TODO: Need to try to change initialized_size. If it
 2272              * succeeds goto done, otherwise goto err_out. (AIA)
 2273              */
 2274             goto err_out;
 2275         }
 2276         goto done;
 2277     }
 2278     errno = eo;
 2279 err_out:
 2280     eo = errno;
 2281     if (need_to.undo_initialized_size) {
 2282         int err;
 2283 
 2284         err = 0;
 2285         if (!ctx) {
 2286             ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
 2287             if (!ctx)
 2288                 err = 1;
 2289         } else
 2290             ntfs_attr_reinit_search_ctx(ctx);
 2291         if (!err) {
 2292             err = ntfs_attr_lookup(na->type, na->name,
 2293                     na->name_len, 0, 0, NULL, 0, ctx);
 2294             if (!err) {
 2295                 na->initialized_size = old_initialized_size;
 2296                 ctx->attr->initialized_size = cpu_to_sle64(
 2297                         old_initialized_size);
 2298                 err = ntfs_mft_record_write(vol,
 2299                         ctx->ntfs_ino->mft_no,
 2300                         ctx->mrec);
 2301             }
 2302         }
 2303         if (err) {
 2304             /*
 2305              * FIXME: At this stage could try to recover by filling
 2306              * old_initialized_size -> new_initialized_size with
 2307              * data or at least zeroes. (AIA)
 2308              */
 2309             ntfs_log_error("Eeek! Failed to recover from error. "
 2310                     "Leaving metadata in inconsistent "
 2311                     "state! Run chkdsk!\n");
 2312         }
 2313     }
 2314     if (ctx)
 2315         ntfs_attr_put_search_ctx(ctx);
 2316     /* Update mapping pairs if needed. */
 2317     if (NAttrRunlistDirty(na))
 2318         ntfs_attr_update_mapping_pairs(na, 0);
 2319     /* Restore original data_size if needed. */
 2320     if (need_to.undo_data_size
 2321             && ntfs_attr_truncate_i(na, old_data_size, HOLES_OK))
 2322         ntfs_log_perror("Failed to restore data_size");
 2323     errno = eo;
 2324 errno_set:
 2325     total = -1;
 2326     goto out;
 2327 }
 2328 
 2329 s64 ntfs_attr_pwrite(ntfs_attr *na, const s64 pos, s64 count, const void *b)
 2330 {
 2331     s64 total;
 2332     s64 written;
 2333 
 2334     ntfs_log_enter("Entering for inode %lld, attr 0x%x, pos 0x%llx, count "
 2335                "0x%llx.\n", (long long)na->ni->mft_no, le32_to_cpu(na->type),
 2336                (long long)pos, (long long)count);
 2337     
 2338     total = 0;
 2339     if (!na || !na->ni || !na->ni->vol || !b || pos < 0 || count < 0) {
 2340         errno = EINVAL;
 2341         written = -1;
 2342         ntfs_log_perror("%s", __FUNCTION__);
 2343         goto out;
 2344     }
 2345 
 2346         /*
 2347          * Compressed attributes may be written partially, so
 2348          * we may have to iterate.
 2349          */
 2350     do {
 2351         written = ntfs_attr_pwrite_i(na, pos + total,
 2352                 count - total, (const u8*)b + total);
 2353         if (written > 0)
 2354             total += written;
 2355     } while ((written > 0) && (total < count));
 2356 out :
 2357     ntfs_log_leave("\n");
 2358     return (total > 0 ? total : written);
 2359 }
 2360 
 2361 
 2362 int ntfs_attr_pclose(ntfs_attr *na)
 2363 {
 2364     s64 ofs;
 2365     int failed;
 2366     BOOL ok = TRUE;
 2367     VCN update_from = -1;
 2368     ntfs_volume *vol;
 2369     ntfs_attr_search_ctx *ctx = NULL;
 2370     runlist_element *rl;
 2371     int eo;
 2372     int compressed_part;
 2373     BOOL compressed;
 2374 
 2375     ntfs_log_enter("Entering for inode 0x%llx, attr 0x%x.\n",
 2376             (unsigned long long)na->ni->mft_no,
 2377             le32_to_cpu(na->type));
 2378     
 2379     if (!na || !na->ni || !na->ni->vol) {
 2380         errno = EINVAL;
 2381         ntfs_log_perror("%s", __FUNCTION__);
 2382         goto errno_set;
 2383     }
 2384     vol = na->ni->vol;
 2385     na->unused_runs = 0;
 2386     compressed = (na->data_flags & ATTR_COMPRESSION_MASK)
 2387              != const_cpu_to_le16(0);
 2388     /*
 2389      * Encrypted non-resident attributes are not supported.  We return
 2390      * access denied, which is what Windows NT4 does, too.
 2391      */
 2392     if (NAttrEncrypted(na) && NAttrNonResident(na)) {
 2393         errno = EACCES;
 2394         goto errno_set;
 2395     }
 2396     /* If this is not a compressed attribute get out */
 2397     /* same if it is resident */
 2398     if (!compressed || !NAttrNonResident(na))
 2399         goto out;
 2400 
 2401         /* safety check : no recursion on close */
 2402     if (NAttrComprClosing(na)) {
 2403         errno = EIO;
 2404         ntfs_log_error("Bad ntfs_attr_pclose"
 2405                 " recursion on inode %lld\n",
 2406                 (long long)na->ni->mft_no);
 2407         goto out;
 2408     }
 2409     NAttrSetComprClosing(na);
 2410         /*
 2411          * For a compressed attribute, we must be sure there are two
 2412          * available entries, so reserve them before it gets too late.
 2413          */
 2414     if (ntfs_attr_map_whole_runlist(na))
 2415         goto err_out;
 2416     na->rl = ntfs_rl_extend(na,na->rl,2);
 2417     if (!na->rl)
 2418         goto err_out;
 2419     na->unused_runs = 2;
 2420     /* Find the runlist element containing the terminal vcn. */
 2421     rl = ntfs_attr_find_vcn(na, (na->initialized_size - 1) >> vol->cluster_size_bits);
 2422     if (!rl) {
 2423         /*
 2424          * If the vcn is not present it is an out of bounds write.
 2425          * However, we have already written the last byte uncompressed,
 2426          * so getting this here must be an error of some kind.
 2427          */
 2428         if (errno == ENOENT) {
 2429             errno = EIO;
 2430             ntfs_log_perror("%s: Failed to find VCN #5", __FUNCTION__);
 2431         }
 2432         goto err_out;
 2433     }
 2434     /*
 2435      * Scatter the data from the linear data buffer to the volume. Note, a
 2436      * partial final vcn is taken care of by the @count capping of write
 2437      * length.
 2438      */
 2439     compressed_part = 0;
 2440     if (rl->lcn >= 0) {
 2441         runlist_element *xrl;
 2442 
 2443         xrl = rl;
 2444         do {
 2445             xrl++;
 2446         } while (xrl->lcn >= 0);
 2447         compressed_part = (-xrl->length)
 2448                     & (na->compression_block_clusters - 1);
 2449     } else
 2450         if (rl->lcn == (LCN)LCN_HOLE) {
 2451             if (rl->length < na->compression_block_clusters)
 2452                 compressed_part
 2453                                     = na->compression_block_clusters
 2454                                                - rl->length;
 2455             else
 2456                 compressed_part
 2457                     = na->compression_block_clusters;
 2458         }
 2459         /* done, if the last block set was compressed */
 2460     if (compressed_part)
 2461         goto out;
 2462 
 2463     ofs = na->initialized_size - (rl->vcn << vol->cluster_size_bits);
 2464 
 2465     if (rl->lcn == LCN_RL_NOT_MAPPED) {
 2466         rl = ntfs_attr_find_vcn(na, rl->vcn);
 2467         if (!rl) {
 2468             if (errno == ENOENT) {
 2469                 errno = EIO;
 2470                 ntfs_log_perror("%s: Failed to find VCN"
 2471                         " #6", __FUNCTION__);
 2472             }
 2473             goto rl_err_out;
 2474         }
 2475             /* Needed for case when runs merged. */
 2476         ofs = na->initialized_size - (rl->vcn << vol->cluster_size_bits);
 2477     }
 2478     if (!rl->length) {
 2479         errno = EIO;
 2480         ntfs_log_perror("%s: Zero run length", __FUNCTION__);
 2481         goto rl_err_out;
 2482     }
 2483     if (rl->lcn < (LCN)0) {
 2484         if (rl->lcn != (LCN)LCN_HOLE) {
 2485             errno = EIO;
 2486             ntfs_log_perror("%s: Unexpected LCN (%lld)", 
 2487                     __FUNCTION__,
 2488                     (long long)rl->lcn);
 2489             goto rl_err_out;
 2490         }
 2491             
 2492         if (ntfs_attr_fill_hole(na, (s64)0, &ofs, &rl, &update_from))
 2493             goto err_out;
 2494     }
 2495     while (rl->length
 2496         && (ofs >= (rl->length << vol->cluster_size_bits))) {
 2497         ofs -= rl->length << vol->cluster_size_bits;
 2498         rl++;
 2499     }
 2500 
 2501 retry:
 2502     failed = 0;
 2503     if (update_from < 0) update_from = 0;
 2504     if (!NVolReadOnly(vol)) {
 2505         failed = ntfs_compressed_close(na, rl, ofs, &update_from);
 2506 #if CACHE_NIDATA_SIZE
 2507         if (na->ni->mrec->flags & MFT_RECORD_IS_DIRECTORY
 2508             ? na->type == AT_INDEX_ROOT && na->name == NTFS_INDEX_I30
 2509             : na->type == AT_DATA && na->name == AT_UNNAMED) {
 2510             na->ni->data_size = na->data_size;
 2511             na->ni->allocated_size = na->compressed_size;
 2512             set_nino_flag(na->ni,KnownSize);
 2513         }
 2514 #endif
 2515     }
 2516     if (failed) {
 2517         /* If the syscall was interrupted, try again. */
 2518         if (errno == EINTR)
 2519             goto retry;
 2520         else
 2521             goto rl_err_out;
 2522     }
 2523     if (ctx)
 2524         ntfs_attr_put_search_ctx(ctx);
 2525     /* Update mapping pairs if needed. */
 2526     if (NAttrFullyMapped(na))
 2527         if (ntfs_attr_update_mapping_pairs(na, update_from)) {
 2528             /*
 2529              * FIXME: trying to recover by goto rl_err_out; 
 2530              * could cause driver hang by infinite looping.
 2531              */
 2532             ok = FALSE;
 2533             goto out;
 2534     }
 2535 out:    
 2536     NAttrClearComprClosing(na);
 2537     ntfs_log_leave("\n");
 2538     return (!ok);
 2539 rl_err_out:
 2540         /*
 2541          * need not restore old sizes, only compressed_size
 2542          * can have changed. It has been set according to
 2543          * the current runlist while updating the mapping pairs,
 2544          * and must be kept consistent with the runlists.
 2545          */
 2546 err_out:
 2547     eo = errno;
 2548     if (ctx)
 2549         ntfs_attr_put_search_ctx(ctx);
 2550     /* Update mapping pairs if needed. */
 2551     if (NAttrFullyMapped(na))
 2552         ntfs_attr_update_mapping_pairs(na, 0);
 2553     errno = eo;
 2554 errno_set:
 2555     ok = FALSE;
 2556     goto out;
 2557 }
 2558 
 2559 /**
 2560  * ntfs_attr_mst_pread - multi sector transfer protected ntfs attribute read
 2561  * @na:     multi sector transfer protected ntfs attribute to read from
 2562  * @pos:    byte position in the attribute to begin reading from
 2563  * @bk_cnt: number of mst protected blocks to read
 2564  * @bk_size:    size of each mst protected block in bytes
 2565  * @dst:    output data buffer
 2566  *
 2567  * This function will read @bk_cnt blocks of size @bk_size bytes each starting
 2568  * at offset @pos from the ntfs attribute @na into the data buffer @b.
 2569  *
 2570  * On success, the multi sector transfer fixups are applied and the number of
 2571  * read blocks is returned. If this number is lower than @bk_cnt this means
 2572  * that the read has either reached end of attribute or that an error was
 2573  * encountered during the read so that the read is partial. 0 means end of
 2574  * attribute or nothing to read (also return 0 when @bk_cnt or @bk_size are 0).
 2575  *
 2576  * On error and nothing has been read, return -1 with errno set appropriately
 2577  * to the return code of ntfs_attr_pread() or to EINVAL in case of invalid
 2578  * arguments.
 2579  *
 2580  * NOTE: If an incomplete multi sector transfer is detected the magic is
 2581  * changed to BAAD but no error is returned, i.e. it is possible that any of
 2582  * the returned blocks have multi sector transfer errors. This should be
 2583  * detected by the caller by checking each block with is_baad_recordp(&block).
 2584  * The reasoning is that we want to fixup as many blocks as possible and we
 2585  * want to return even bad ones to the caller so, e.g. in case of ntfsck, the
 2586  * errors can be repaired.
 2587  */
 2588 s64 ntfs_attr_mst_pread(ntfs_attr *na, const s64 pos, const s64 bk_cnt,
 2589         const u32 bk_size, void *dst)
 2590 {
 2591     s64 br;
 2592     u8 *end;
 2593     BOOL warn;
 2594 
 2595     ntfs_log_trace("Entering for inode 0x%llx, attr type 0x%x, pos 0x%llx.\n",
 2596             (unsigned long long)na->ni->mft_no, le32_to_cpu(na->type),
 2597             (long long)pos);
 2598     if (bk_cnt < 0 || bk_size % NTFS_BLOCK_SIZE) {
 2599         errno = EINVAL;
 2600         ntfs_log_perror("%s", __FUNCTION__);
 2601         return -1;
 2602     }
 2603     br = ntfs_attr_pread(na, pos, bk_cnt * bk_size, dst);
 2604     if (br <= 0)
 2605         return br;
 2606     br /= bk_size;
 2607         /* log errors unless silenced */
 2608     warn = !na->ni || !na->ni->vol || !NVolNoFixupWarn(na->ni->vol);
 2609     for (end = (u8*)dst + br * bk_size; (u8*)dst < end; dst = (u8*)dst +
 2610             bk_size)
 2611         ntfs_mst_post_read_fixup_warn((NTFS_RECORD*)dst, bk_size, warn);
 2612     /* Finally, return the number of blocks read. */
 2613     return br;
 2614 }
 2615 
 2616 /**
 2617  * ntfs_attr_mst_pwrite - multi sector transfer protected ntfs attribute write
 2618  * @na:     multi sector transfer protected ntfs attribute to write to
 2619  * @pos:    position in the attribute to write to
 2620  * @bk_cnt: number of mst protected blocks to write
 2621  * @bk_size:    size of each mst protected block in bytes
 2622  * @src:    data buffer to write to disk
 2623  *
 2624  * This function will write @bk_cnt blocks of size @bk_size bytes each from
 2625  * data buffer @b to multi sector transfer (mst) protected ntfs attribute @na
 2626  * at position @pos.
 2627  *
 2628  * On success, return the number of successfully written blocks. If this number
 2629  * is lower than @bk_cnt this means that an error was encountered during the
 2630  * write so that the write is partial. 0 means nothing was written (also
 2631  * return 0 when @bk_cnt or @bk_size are 0).
 2632  *
 2633  * On error and nothing has been written, return -1 with errno set
 2634  * appropriately to the return code of ntfs_attr_pwrite(), or to EINVAL in case
 2635  * of invalid arguments.
 2636  *
 2637  * NOTE: We mst protect the data, write it, then mst deprotect it using a quick
 2638  * deprotect algorithm (no checking). This saves us from making a copy before
 2639  * the write and at the same time causes the usn to be incremented in the
 2640  * buffer. This conceptually fits in better with the idea that cached data is
 2641  * always deprotected and protection is performed when the data is actually
 2642  * going to hit the disk and the cache is immediately deprotected again
 2643  * simulating an mst read on the written data. This way cache coherency is
 2644  * achieved.
 2645  */
 2646 s64 ntfs_attr_mst_pwrite(ntfs_attr *na, const s64 pos, s64 bk_cnt,
 2647         const u32 bk_size, void *src)
 2648 {
 2649     s64 written, i;
 2650 
 2651     ntfs_log_trace("Entering for inode 0x%llx, attr type 0x%x, pos 0x%llx.\n",
 2652             (unsigned long long)na->ni->mft_no, le32_to_cpu(na->type),
 2653             (long long)pos);
 2654     if (bk_cnt < 0 || bk_size % NTFS_BLOCK_SIZE) {
 2655         errno = EINVAL;
 2656         return -1;
 2657     }
 2658     if (!bk_cnt)
 2659         return 0;
 2660     /* Prepare data for writing. */
 2661     for (i = 0; i < bk_cnt; ++i) {
 2662         int err;
 2663 
 2664         err = ntfs_mst_pre_write_fixup((NTFS_RECORD*)
 2665                 ((u8*)src + i * bk_size), bk_size);
 2666         if (err < 0) {
 2667             /* Abort write at this position. */
 2668             ntfs_log_perror("%s #1", __FUNCTION__);
 2669             if (!i)
 2670                 return err;
 2671             bk_cnt = i;
 2672             break;
 2673         }
 2674     }
 2675     /* Write the prepared data. */
 2676     written = ntfs_attr_pwrite(na, pos, bk_cnt * bk_size, src);
 2677     if (written <= 0) {
 2678         ntfs_log_perror("%s: written=%lld", __FUNCTION__,
 2679                 (long long)written);
 2680     }
 2681     /* Quickly deprotect the data again. */
 2682     for (i = 0; i < bk_cnt; ++i)
 2683         ntfs_mst_post_write_fixup((NTFS_RECORD*)((u8*)src + i *
 2684                 bk_size));
 2685     if (written <= 0)
 2686         return written;
 2687     /* Finally, return the number of complete blocks written. */
 2688     return written / bk_size;
 2689 }
 2690 
 2691 /**
 2692  * ntfs_attr_find - find (next) attribute in mft record
 2693  * @type:   attribute type to find
 2694  * @name:   attribute name to find (optional, i.e. NULL means don't care)
 2695  * @name_len:   attribute name length (only needed if @name present)
 2696  * @ic:     IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
 2697  * @val:    attribute value to find (optional, resident attributes only)
 2698  * @val_len:    attribute value length
 2699  * @ctx:    search context with mft record and attribute to search from
 2700  *
 2701  * You shouldn't need to call this function directly. Use lookup_attr() instead.
 2702  *
 2703  * ntfs_attr_find() takes a search context @ctx as parameter and searches the
 2704  * mft record specified by @ctx->mrec, beginning at @ctx->attr, for an
 2705  * attribute of @type, optionally @name and @val. If found, ntfs_attr_find()
 2706  * returns 0 and @ctx->attr will point to the found attribute.
 2707  *
 2708  * If not found, ntfs_attr_find() returns -1, with errno set to ENOENT and
 2709  * @ctx->attr will point to the attribute before which the attribute being
 2710  * searched for would need to be inserted if such an action were to be desired.
 2711  *
 2712  * On actual error, ntfs_attr_find() returns -1 with errno set to the error
 2713  * code but not to ENOENT.  In this case @ctx->attr is undefined and in
 2714  * particular do not rely on it not changing.
 2715  *
 2716  * If @ctx->is_first is TRUE, the search begins with @ctx->attr itself. If it
 2717  * is FALSE, the search begins after @ctx->attr.
 2718  *
 2719  * If @type is AT_UNUSED, return the first found attribute, i.e. one can
 2720  * enumerate all attributes by setting @type to AT_UNUSED and then calling
 2721  * ntfs_attr_find() repeatedly until it returns -1 with errno set to ENOENT to
 2722  * indicate that there are no more entries. During the enumeration, each
 2723  * successful call of ntfs_attr_find() will return the next attribute in the
 2724  * mft record @ctx->mrec.
 2725  *
 2726  * If @type is AT_END, seek to the end and return -1 with errno set to ENOENT.
 2727  * AT_END is not a valid attribute, its length is zero for example, thus it is
 2728  * safer to return error instead of success in this case. This also allows us
 2729  * to interoperate cleanly with ntfs_external_attr_find().
 2730  *
 2731  * If @name is AT_UNNAMED search for an unnamed attribute. If @name is present
 2732  * but not AT_UNNAMED search for a named attribute matching @name. Otherwise,
 2733  * match both named and unnamed attributes.
 2734  *
 2735  * If @ic is IGNORE_CASE, the @name comparison is not case sensitive and
 2736  * @ctx->ntfs_ino must be set to the ntfs inode to which the mft record
 2737  * @ctx->mrec belongs. This is so we can get at the ntfs volume and hence at
 2738  * the upcase table. If @ic is CASE_SENSITIVE, the comparison is case
 2739  * sensitive. When @name is present, @name_len is the @name length in Unicode
 2740  * characters.
 2741  *
 2742  * If @name is not present (NULL), we assume that the unnamed attribute is
 2743  * being searched for.
 2744  *
 2745  * Finally, the resident attribute value @val is looked for, if present.
 2746  * If @val is not present (NULL), @val_len is ignored.
 2747  *
 2748  * ntfs_attr_find() only searches the specified mft record and it ignores the
 2749  * presence of an attribute list attribute (unless it is the one being searched
 2750  * for, obviously). If you need to take attribute lists into consideration, use
 2751  * ntfs_attr_lookup() instead (see below). This also means that you cannot use
 2752  * ntfs_attr_find() to search for extent records of non-resident attributes, as
 2753  * extents with lowest_vcn != 0 are usually described by the attribute list
 2754  * attribute only. - Note that it is possible that the first extent is only in
 2755  * the attribute list while the last extent is in the base mft record, so don't
 2756  * rely on being able to find the first extent in the base mft record.
 2757  *
 2758  * Warning: Never use @val when looking for attribute types which can be
 2759  *      non-resident as this most likely will result in a crash!
 2760  */
 2761 static int ntfs_attr_find(const ATTR_TYPES type, const ntfschar *name,
 2762         const u32 name_len, const IGNORE_CASE_BOOL ic,
 2763         const u8 *val, const u32 val_len, ntfs_attr_search_ctx *ctx)
 2764 {
 2765     ATTR_RECORD *a;
 2766     ntfs_volume *vol;
 2767     ntfschar *upcase;
 2768     u32 upcase_len;
 2769 
 2770     ntfs_log_trace("attribute type 0x%x.\n", le32_to_cpu(type));
 2771 
 2772     if (ctx->ntfs_ino) {
 2773         vol = ctx->ntfs_ino->vol;
 2774         upcase = vol->upcase;
 2775         upcase_len = vol->upcase_len;
 2776     } else {
 2777         if (name && name != AT_UNNAMED) {
 2778             errno = EINVAL;
 2779             ntfs_log_perror("%s", __FUNCTION__);
 2780             return -1;
 2781         }
 2782         vol = NULL;
 2783         upcase = NULL;
 2784         upcase_len = 0;
 2785     }
 2786     /*
 2787      * Iterate over attributes in mft record starting at @ctx->attr, or the
 2788      * attribute following that, if @ctx->is_first is TRUE.
 2789      */
 2790     if (ctx->is_first) {
 2791         a = ctx->attr;
 2792         ctx->is_first = FALSE;
 2793     } else
 2794         a = (ATTR_RECORD*)((char*)ctx->attr +
 2795                 le32_to_cpu(ctx->attr->length));
 2796     for (;; a = (ATTR_RECORD*)((char*)a + le32_to_cpu(a->length))) {
 2797         if (p2n(a) < p2n(ctx->mrec) || (char*)a > (char*)ctx->mrec +
 2798                 le32_to_cpu(ctx->mrec->bytes_allocated))
 2799             break;
 2800         ctx->attr = a;
 2801         if (((type != AT_UNUSED) && (le32_to_cpu(a->type) >
 2802                 le32_to_cpu(type))) ||
 2803                 (a->type == AT_END)) {
 2804             errno = ENOENT;
 2805             return -1;
 2806         }
 2807         if (!a->length)
 2808             break;
 2809         /* If this is an enumeration return this attribute. */
 2810         if (type == AT_UNUSED)
 2811             return 0;
 2812         if (a->type != type)
 2813             continue;
 2814         /*
 2815          * If @name is AT_UNNAMED we want an unnamed attribute.
 2816          * If @name is present, compare the two names.
 2817          * Otherwise, match any attribute.
 2818          */
 2819         if (name == AT_UNNAMED) {
 2820             /* The search failed if the found attribute is named. */
 2821             if (a->name_length) {
 2822                 errno = ENOENT;
 2823                 return -1;
 2824             }
 2825         } else {
 2826             register int rc;
 2827             if (name && ((rc = ntfs_names_full_collate(name,
 2828                     name_len, (ntfschar*)((char*)a +
 2829                         le16_to_cpu(a->name_offset)),
 2830                     a->name_length, ic,
 2831                     upcase, upcase_len)))) {
 2832                 /*
 2833                  * If @name collates before a->name,
 2834                  * there is no matching attribute.
 2835                  */
 2836                 if (rc < 0) {
 2837                     errno = ENOENT;
 2838                     return -1;
 2839                 }
 2840             /* If the strings are not equal, continue search. */
 2841             continue;
 2842             }
 2843         }
 2844         /*
 2845          * The names match or @name not present and attribute is
 2846          * unnamed. If no @val specified, we have found the attribute
 2847          * and are done.
 2848          */
 2849         if (!val)
 2850             return 0;
 2851         /* @val is present; compare values. */
 2852         else {
 2853             register int rc;
 2854 
 2855             rc = memcmp(val, (char*)a +le16_to_cpu(a->value_offset),
 2856                     min(val_len,
 2857                     le32_to_cpu(a->value_length)));
 2858             /*
 2859              * If @val collates before the current attribute's
 2860              * value, there is no matching attribute.
 2861              */
 2862             if (!rc) {
 2863                 register u32 avl;
 2864                 avl = le32_to_cpu(a->value_length);
 2865                 if (val_len == avl)
 2866                     return 0;
 2867                 if (val_len < avl) {
 2868                     errno = ENOENT;
 2869                     return -1;
 2870                 }
 2871             } else if (rc < 0) {
 2872                 errno = ENOENT;
 2873                 return -1;
 2874             }
 2875         }
 2876     }
 2877     errno = EIO;
 2878     ntfs_log_perror("%s: Corrupt inode (%lld)", __FUNCTION__, 
 2879             ctx->ntfs_ino ? (long long)ctx->ntfs_ino->mft_no : -1);
 2880     return -1;
 2881 }
 2882 
 2883 void ntfs_attr_name_free(char **name)
 2884 {
 2885     if (*name) {
 2886         free(*name);
 2887         *name = NULL;
 2888     }
 2889 }
 2890 
 2891 char *ntfs_attr_name_get(const ntfschar *uname, const int uname_len)
 2892 {
 2893     char *name = NULL;
 2894     int name_len;
 2895 
 2896     name_len = ntfs_ucstombs(uname, uname_len, &name, 0);
 2897     if (name_len < 0) {
 2898         ntfs_log_perror("ntfs_ucstombs");
 2899         return NULL;
 2900 
 2901     } else if (name_len > 0)
 2902         return name;
 2903 
 2904     ntfs_attr_name_free(&name);
 2905     return NULL;
 2906 }
 2907 
 2908 /**
 2909  * ntfs_external_attr_find - find an attribute in the attribute list of an inode
 2910  * @type:   attribute type to find
 2911  * @name:   attribute name to find (optional, i.e. NULL means don't care)
 2912  * @name_len:   attribute name length (only needed if @name present)
 2913  * @ic:     IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
 2914  * @lowest_vcn: lowest vcn to find (optional, non-resident attributes only)
 2915  * @val:    attribute value to find (optional, resident attributes only)
 2916  * @val_len:    attribute value length
 2917  * @ctx:    search context with mft record and attribute to search from
 2918  *
 2919  * You shouldn't need to call this function directly. Use ntfs_attr_lookup()
 2920  * instead.
 2921  *
 2922  * Find an attribute by searching the attribute list for the corresponding
 2923  * attribute list entry. Having found the entry, map the mft record for read
 2924  * if the attribute is in a different mft record/inode, find the attribute in
 2925  * there and return it.
 2926  *
 2927  * If @type is AT_UNUSED, return the first found attribute, i.e. one can
 2928  * enumerate all attributes by setting @type to AT_UNUSED and then calling
 2929  * ntfs_external_attr_find() repeatedly until it returns -1 with errno set to
 2930  * ENOENT to indicate that there are no more entries. During the enumeration,
 2931  * each successful call of ntfs_external_attr_find() will return the next
 2932  * attribute described by the attribute list of the base mft record described
 2933  * by the search context @ctx.
 2934  *
 2935  * If @type is AT_END, seek to the end of the base mft record ignoring the
 2936  * attribute list completely and return -1 with errno set to ENOENT.  AT_END is
 2937  * not a valid attribute, its length is zero for example, thus it is safer to
 2938  * return error instead of success in this case.
 2939  *
 2940  * If @name is AT_UNNAMED search for an unnamed attribute. If @name is present
 2941  * but not AT_UNNAMED search for a named attribute matching @name. Otherwise,
 2942  * match both named and unnamed attributes.
 2943  *
 2944  * On first search @ctx->ntfs_ino must be the inode of the base mft record and
 2945  * @ctx must have been obtained from a call to ntfs_attr_get_search_ctx().
 2946  * On subsequent calls, @ctx->ntfs_ino can be any extent inode, too
 2947  * (@ctx->base_ntfs_ino is then the base inode).
 2948  *
 2949  * After finishing with the attribute/mft record you need to call
 2950  * ntfs_attr_put_search_ctx() to cleanup the search context (unmapping any
 2951  * mapped extent inodes, etc).
 2952  *
 2953  * Return 0 if the search was successful and -1 if not, with errno set to the
 2954  * error code.
 2955  *
 2956  * On success, @ctx->attr is the found attribute, it is in mft record
 2957  * @ctx->mrec, and @ctx->al_entry is the attribute list entry for this
 2958  * attribute with @ctx->base_* being the base mft record to which @ctx->attr
 2959  * belongs.
 2960  *
 2961  * On error ENOENT, i.e. attribute not found, @ctx->attr is set to the
 2962  * attribute which collates just after the attribute being searched for in the
 2963  * base ntfs inode, i.e. if one wants to add the attribute to the mft record
 2964  * this is the correct place to insert it into, and if there is not enough
 2965  * space, the attribute should be placed in an extent mft record.
 2966  * @ctx->al_entry points to the position within @ctx->base_ntfs_ino->attr_list
 2967  * at which the new attribute's attribute list entry should be inserted.  The
 2968  * other @ctx fields, base_ntfs_ino, base_mrec, and base_attr are set to NULL.
 2969  * The only exception to this is when @type is AT_END, in which case
 2970  * @ctx->al_entry is set to NULL also (see above).
 2971  *
 2972  * The following error codes are defined:
 2973  *  ENOENT  Attribute not found, not an error as such.
 2974  *  EINVAL  Invalid arguments.
 2975  *  EIO I/O error or corrupt data structures found.
 2976  *  ENOMEM  Not enough memory to allocate necessary buffers.
 2977  */
 2978 static int ntfs_external_attr_find(ATTR_TYPES type, const ntfschar *name,
 2979         const u32 name_len, const IGNORE_CASE_BOOL ic,
 2980         const VCN lowest_vcn, const u8 *val, const u32 val_len,
 2981         ntfs_attr_search_ctx *ctx)
 2982 {
 2983     ntfs_inode *base_ni, *ni;
 2984     ntfs_volume *vol;
 2985     ATTR_LIST_ENTRY *al_entry, *next_al_entry;
 2986     u8 *al_start, *al_end;
 2987     ATTR_RECORD *a;
 2988     ntfschar *al_name;
 2989     u32 al_name_len;
 2990     BOOL is_first_search = FALSE;
 2991 
 2992     ni = ctx->ntfs_ino;
 2993     base_ni = ctx->base_ntfs_ino;
 2994     ntfs_log_trace("Entering for inode %lld, attribute type 0x%x.\n",
 2995             (unsigned long long)ni->mft_no, le32_to_cpu(type));
 2996     if (!base_ni) {
 2997         /* First call happens with the base mft record. */
 2998         base_ni = ctx->base_ntfs_ino = ctx->ntfs_ino;
 2999         ctx->base_mrec = ctx->mrec;
 3000     }
 3001     if (ni == base_ni)
 3002         ctx->base_attr = ctx->attr;
 3003     if (type == AT_END)
 3004         goto not_found;
 3005     vol = base_ni->vol;
 3006     al_start = base_ni->attr_list;
 3007     al_end = al_start + base_ni->attr_list_size;
 3008     if (!ctx->al_entry) {
 3009         ctx->al_entry = (ATTR_LIST_ENTRY*)al_start;
 3010         is_first_search = TRUE;
 3011     }
 3012     /*
 3013      * Iterate over entries in attribute list starting at @ctx->al_entry,
 3014      * or the entry following that, if @ctx->is_first is TRUE.
 3015      */
 3016     if (ctx->is_first) {
 3017         al_entry = ctx->al_entry;
 3018         ctx->is_first = FALSE;
 3019         /*
 3020          * If an enumeration and the first attribute is higher than
 3021          * the attribute list itself, need to return the attribute list
 3022          * attribute.
 3023          */
 3024         if ((type == AT_UNUSED) && is_first_search &&
 3025                 le32_to_cpu(al_entry->type) >
 3026                 le32_to_cpu(AT_ATTRIBUTE_LIST))
 3027             goto find_attr_list_attr;
 3028     } else {
 3029         al_entry = (ATTR_LIST_ENTRY*)((char*)ctx->al_entry +
 3030                 le16_to_cpu(ctx->al_entry->length));
 3031         /*
 3032          * If this is an enumeration and the attribute list attribute
 3033          * is the next one in the enumeration sequence, just return the
 3034          * attribute list attribute from the base mft record as it is
 3035          * not listed in the attribute list itself.
 3036          */
 3037         if ((type == AT_UNUSED) && le32_to_cpu(ctx->al_entry->type) <
 3038                 le32_to_cpu(AT_ATTRIBUTE_LIST) &&
 3039                 le32_to_cpu(al_entry->type) >
 3040                 le32_to_cpu(AT_ATTRIBUTE_LIST)) {
 3041             int rc;
 3042 find_attr_list_attr:
 3043 
 3044             /* Check for bogus calls. */
 3045             if (name || name_len || val || val_len || lowest_vcn) {
 3046                 errno = EINVAL;
 3047                 ntfs_log_perror("%s", __FUNCTION__);
 3048                 return -1;
 3049             }
 3050 
 3051             /* We want the base record. */
 3052             ctx->ntfs_ino = base_ni;
 3053             ctx->mrec = ctx->base_mrec;
 3054             ctx->is_first = TRUE;
 3055             /* Sanity checks are performed elsewhere. */
 3056             ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
 3057                     le16_to_cpu(ctx->mrec->attrs_offset));
 3058 
 3059             /* Find the attribute list attribute. */
 3060             rc = ntfs_attr_find(AT_ATTRIBUTE_LIST, NULL, 0,
 3061                     IGNORE_CASE, NULL, 0, ctx);
 3062 
 3063             /*
 3064              * Setup the search context so the correct
 3065              * attribute is returned next time round.
 3066              */
 3067             ctx->al_entry = al_entry;
 3068             ctx->is_first = TRUE;
 3069 
 3070             /* Got it. Done. */
 3071             if (!rc)
 3072                 return 0;
 3073 
 3074             /* Error! If other than not found return it. */
 3075             if (errno != ENOENT)
 3076                 return rc;
 3077 
 3078             /* Not found?!? Absurd! */
 3079             errno = EIO;
 3080             ntfs_log_error("Attribute list wasn't found");
 3081             return -1;
 3082         }
 3083     }
 3084     for (;; al_entry = next_al_entry) {
 3085         /* Out of bounds check. */
 3086         if ((u8*)al_entry < base_ni->attr_list ||
 3087                 (u8*)al_entry > al_end)
 3088             break;  /* Inode is corrupt. */
 3089         ctx->al_entry = al_entry;
 3090         /* Catch the end of the attribute list. */
 3091         if ((u8*)al_entry == al_end)
 3092             goto not_found;
 3093         if (!al_entry->length)
 3094             break;
 3095         if ((u8*)al_entry + 6 > al_end || (u8*)al_entry +
 3096                 le16_to_cpu(al_entry->length) > al_end)
 3097             break;
 3098         next_al_entry = (ATTR_LIST_ENTRY*)((u8*)al_entry +
 3099                 le16_to_cpu(al_entry->length));
 3100         if (type != AT_UNUSED) {
 3101             if (le32_to_cpu(al_entry->type) > le32_to_cpu(type))
 3102                 goto not_found;
 3103             if (type != al_entry->type)
 3104                 continue;
 3105         }
 3106         al_name_len = al_entry->name_length;
 3107         al_name = (ntfschar*)((u8*)al_entry + al_entry->name_offset);
 3108         /*
 3109          * If !@type we want the attribute represented by this
 3110          * attribute list entry.
 3111          */
 3112         if (type == AT_UNUSED)
 3113             goto is_enumeration;
 3114         /*
 3115          * If @name is AT_UNNAMED we want an unnamed attribute.
 3116          * If @name is present, compare the two names.
 3117          * Otherwise, match any attribute.
 3118          */
 3119         if (name == AT_UNNAMED) {
 3120             if (al_name_len)
 3121                 goto not_found;
 3122         } else {
 3123             int rc;
 3124 
 3125             if (name && ((rc = ntfs_names_full_collate(name,
 3126                     name_len, al_name, al_name_len, ic,
 3127                     vol->upcase, vol->upcase_len)))) {
 3128 
 3129                 /*
 3130                  * If @name collates before al_name,
 3131                  * there is no matching attribute.
 3132                  */
 3133                 if (rc < 0)
 3134                     goto not_found;
 3135                 /* If the strings are not equal, continue search. */
 3136                 continue;
 3137             }
 3138         }
 3139         /*
 3140          * The names match or @name not present and attribute is
 3141          * unnamed. Now check @lowest_vcn. Continue search if the
 3142          * next attribute list entry still fits @lowest_vcn. Otherwise
 3143          * we have reached the right one or the search has failed.
 3144          */
 3145         if (lowest_vcn && (u8*)next_al_entry >= al_start        &&
 3146                 (u8*)next_al_entry + 6 < al_end     &&
 3147                 (u8*)next_al_entry + le16_to_cpu(
 3148                     next_al_entry->length) <= al_end    &&
 3149                 sle64_to_cpu(next_al_entry->lowest_vcn) <=
 3150                     lowest_vcn              &&
 3151                 next_al_entry->type == al_entry->type       &&
 3152                 next_al_entry->name_length == al_name_len   &&
 3153                 ntfs_names_are_equal((ntfschar*)((char*)
 3154                     next_al_entry +
 3155                     next_al_entry->name_offset),
 3156                     next_al_entry->name_length,
 3157                     al_name, al_name_len, CASE_SENSITIVE,
 3158                     vol->upcase, vol->upcase_len))
 3159             continue;
 3160 is_enumeration:
 3161         if (MREF_LE(al_entry->mft_reference) == ni->mft_no) {
 3162             if (MSEQNO_LE(al_entry->mft_reference) !=
 3163                     le16_to_cpu(
 3164                     ni->mrec->sequence_number)) {
 3165                 ntfs_log_error("Found stale mft reference in "
 3166                         "attribute list!\n");
 3167                 break;
 3168             }
 3169         } else { /* Mft references do not match. */
 3170             /* Do we want the base record back? */
 3171             if (MREF_LE(al_entry->mft_reference) ==
 3172                     base_ni->mft_no) {
 3173                 ni = ctx->ntfs_ino = base_ni;
 3174                 ctx->mrec = ctx->base_mrec;
 3175             } else {
 3176                 /* We want an extent record. */
 3177                 ni = ntfs_extent_inode_open(base_ni,
 3178                         al_entry->mft_reference);
 3179                 if (!ni)
 3180                     break;
 3181                 ctx->ntfs_ino = ni;
 3182                 ctx->mrec = ni->mrec;
 3183             }
 3184         }
 3185         a = ctx->attr = (ATTR_RECORD*)((char*)ctx->mrec +
 3186                 le16_to_cpu(ctx->mrec->attrs_offset));
 3187         /*
 3188          * ctx->ntfs_ino, ctx->mrec, and ctx->attr now point to the
 3189          * mft record containing the attribute represented by the
 3190          * current al_entry.
 3191          *
 3192          * We could call into ntfs_attr_find() to find the right
 3193          * attribute in this mft record but this would be less
 3194          * efficient and not quite accurate as ntfs_attr_find() ignores
 3195          * the attribute instance numbers for example which become
 3196          * important when one plays with attribute lists. Also, because
 3197          * a proper match has been found in the attribute list entry
 3198          * above, the comparison can now be optimized. So it is worth
 3199          * re-implementing a simplified ntfs_attr_find() here.
 3200          *
 3201          * Use a manual loop so we can still use break and continue
 3202          * with the same meanings as above.
 3203          */
 3204 do_next_attr_loop:
 3205         if ((char*)a < (char*)ctx->mrec || (char*)a > (char*)ctx->mrec +
 3206                 le32_to_cpu(ctx->mrec->bytes_allocated))
 3207             break;
 3208         if (a->type == AT_END)
 3209             continue;
 3210         if (!a->length)
 3211             break;
 3212         if (al_entry->instance != a->instance)
 3213             goto do_next_attr;
 3214         /*
 3215          * If the type and/or the name are/is mismatched between the
 3216          * attribute list entry and the attribute record, there is
 3217          * corruption so we break and return error EIO.
 3218          */
 3219         if (al_entry->type != a->type)
 3220             break;
 3221         if (!ntfs_names_are_equal((ntfschar*)((char*)a +
 3222                 le16_to_cpu(a->name_offset)),
 3223                 a->name_length, al_name,
 3224                 al_name_len, CASE_SENSITIVE,
 3225                 vol->upcase, vol->upcase_len))
 3226             break;
 3227         ctx->attr = a;
 3228         /*
 3229          * If no @val specified or @val specified and it matches, we
 3230          * have found it! Also, if !@type, it is an enumeration, so we
 3231          * want the current attribute.
 3232          */
 3233         if ((type == AT_UNUSED) || !val || (!a->non_resident &&
 3234                 le32_to_cpu(a->value_length) == val_len &&
 3235                 !memcmp((char*)a + le16_to_cpu(a->value_offset),
 3236                 val, val_len))) {
 3237             return 0;
 3238         }
 3239 do_next_attr:
 3240         /* Proceed to the next attribute in the current mft record. */
 3241         a = (ATTR_RECORD*)((char*)a + le32_to_cpu(a->length));
 3242         goto do_next_attr_loop;
 3243     }
 3244     if (ni != base_ni) {
 3245         ctx->ntfs_ino = base_ni;
 3246         ctx->mrec = ctx->base_mrec;
 3247         ctx->attr = ctx->base_attr;
 3248     }
 3249     errno = EIO;
 3250     ntfs_log_perror("Inode is corrupt (%lld)", (long long)base_ni->mft_no);
 3251     return -1;
 3252 not_found:
 3253     /*
 3254      * If we were looking for AT_END or we were enumerating and reached the
 3255      * end, we reset the search context @ctx and use ntfs_attr_find() to
 3256      * seek to the end of the base mft record.
 3257      */
 3258     if (type == AT_UNUSED || type == AT_END) {
 3259         ntfs_attr_reinit_search_ctx(ctx);
 3260         return ntfs_attr_find(AT_END, name, name_len, ic, val, val_len,
 3261                 ctx);
 3262     }
 3263     /*
 3264      * The attribute wasn't found.  Before we return, we want to ensure
 3265      * @ctx->mrec and @ctx->attr indicate the position at which the
 3266      * attribute should be inserted in the base mft record.  Since we also
 3267      * want to preserve @ctx->al_entry we cannot reinitialize the search
 3268      * context using ntfs_attr_reinit_search_ctx() as this would set
 3269      * @ctx->al_entry to NULL.  Thus we do the necessary bits manually (see
 3270      * ntfs_attr_init_search_ctx() below).  Note, we _only_ preserve
 3271      * @ctx->al_entry as the remaining fields (base_*) are identical to
 3272      * their non base_ counterparts and we cannot set @ctx->base_attr
 3273      * correctly yet as we do not know what @ctx->attr will be set to by
 3274      * the call to ntfs_attr_find() below.
 3275      */
 3276     ctx->mrec = ctx->base_mrec;
 3277     ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
 3278             le16_to_cpu(ctx->mrec->attrs_offset));
 3279     ctx->is_first = TRUE;
 3280     ctx->ntfs_ino = ctx->base_ntfs_ino;
 3281     ctx->base_ntfs_ino = NULL;
 3282     ctx->base_mrec = NULL;
 3283     ctx->base_attr = NULL;
 3284     /*
 3285      * In case there are multiple matches in the base mft record, need to
 3286      * keep enumerating until we get an attribute not found response (or
 3287      * another error), otherwise we would keep returning the same attribute
 3288      * over and over again and all programs using us for enumeration would
 3289      * lock up in a tight loop.
 3290      */
 3291     {
 3292         int ret;
 3293 
 3294         do {
 3295             ret = ntfs_attr_find(type, name, name_len, ic, val,
 3296                     val_len, ctx);
 3297         } while (!ret);
 3298         return ret;
 3299     }
 3300 }
 3301 
 3302 /**
 3303  * ntfs_attr_lookup - find an attribute in an ntfs inode
 3304  * @type:   attribute type to find
 3305  * @name:   attribute name to find (optional, i.e. NULL means don't care)
 3306  * @name_len:   attribute name length (only needed if @name present)
 3307  * @ic:     IGNORE_CASE or CASE_SENSITIVE (ignored if @name not present)
 3308  * @lowest_vcn: lowest vcn to find (optional, non-resident attributes only)
 3309  * @val:    attribute value to find (optional, resident attributes only)
 3310  * @val_len:    attribute value length
 3311  * @ctx:    search context with mft record and attribute to search from
 3312  *
 3313  * Find an attribute in an ntfs inode. On first search @ctx->ntfs_ino must
 3314  * be the base mft record and @ctx must have been obtained from a call to
 3315  * ntfs_attr_get_search_ctx().
 3316  *
 3317  * This function transparently handles attribute lists and @ctx is used to
 3318  * continue searches where they were left off at.
 3319  *
 3320  * If @type is AT_UNUSED, return the first found attribute, i.e. one can
 3321  * enumerate all attributes by setting @type to AT_UNUSED and then calling
 3322  * ntfs_attr_lookup() repeatedly until it returns -1 with errno set to ENOENT
 3323  * to indicate that there are no more entries. During the enumeration, each
 3324  * successful call of ntfs_attr_lookup() will return the next attribute, with
 3325  * the current attribute being described by the search context @ctx.
 3326  *
 3327  * If @type is AT_END, seek to the end of the base mft record ignoring the
 3328  * attribute list completely and return -1 with errno set to ENOENT.  AT_END is
 3329  * not a valid attribute, its length is zero for example, thus it is safer to
 3330  * return error instead of success in this case.  It should never be needed to
 3331  * do this, but we implement the functionality because it allows for simpler
 3332  * code inside ntfs_external_attr_find().
 3333  *
 3334  * If @name is AT_UNNAMED search for an unnamed attribute. If @name is present
 3335  * but not AT_UNNAMED search for a named attribute matching @name. Otherwise,
 3336  * match both named and unnamed attributes.
 3337  *
 3338  * After finishing with the attribute/mft record you need to call
 3339  * ntfs_attr_put_search_ctx() to cleanup the search context (unmapping any
 3340  * mapped extent inodes, etc).
 3341  *
 3342  * Return 0 if the search was successful and -1 if not, with errno set to the
 3343  * error code.
 3344  *
 3345  * On success, @ctx->attr is the found attribute, it is in mft record
 3346  * @ctx->mrec, and @ctx->al_entry is the attribute list entry for this
 3347  * attribute with @ctx->base_* being the base mft record to which @ctx->attr
 3348  * belongs.  If no attribute list attribute is present @ctx->al_entry and
 3349  * @ctx->base_* are NULL.
 3350  *
 3351  * On error ENOENT, i.e. attribute not found, @ctx->attr is set to the
 3352  * attribute which collates just after the attribute being searched for in the
 3353  * base ntfs inode, i.e. if one wants to add the attribute to the mft record
 3354  * this is the correct place to insert it into, and if there is not enough
 3355  * space, the attribute should be placed in an extent mft record.
 3356  * @ctx->al_entry points to the position within @ctx->base_ntfs_ino->attr_list
 3357  * at which the new attribute's attribute list entry should be inserted.  The
 3358  * other @ctx fields, base_ntfs_ino, base_mrec, and base_attr are set to NULL.
 3359  * The only exception to this is when @type is AT_END, in which case
 3360  * @ctx->al_entry is set to NULL also (see above).
 3361  *
 3362  *
 3363  * The following error codes are defined:
 3364  *  ENOENT  Attribute not found, not an error as such.
 3365  *  EINVAL  Invalid arguments.
 3366  *  EIO I/O error or corrupt data structures found.
 3367  *  ENOMEM  Not enough memory to allocate necessary buffers.
 3368  */
 3369 int ntfs_attr_lookup(const ATTR_TYPES type, const ntfschar *name,
 3370         const u32 name_len, const IGNORE_CASE_BOOL ic,
 3371         const VCN lowest_vcn, const u8 *val, const u32 val_len,
 3372         ntfs_attr_search_ctx *ctx)
 3373 {
 3374     ntfs_volume *vol;
 3375     ntfs_inode *base_ni;
 3376     int ret = -1;
 3377 
 3378     ntfs_log_enter("Entering for attribute type 0x%x\n", le32_to_cpu(type));
 3379     
 3380     if (!ctx || !ctx->mrec || !ctx->attr || (name && name != AT_UNNAMED &&
 3381             (!ctx->ntfs_ino || !(vol = ctx->ntfs_ino->vol) ||
 3382             !vol->upcase || !vol->upcase_len))) {
 3383         errno = EINVAL;
 3384         ntfs_log_perror("%s", __FUNCTION__);
 3385         goto out;
 3386     }
 3387     
 3388     if (ctx->base_ntfs_ino)
 3389         base_ni = ctx->base_ntfs_ino;
 3390     else
 3391         base_ni = ctx->ntfs_ino;
 3392     if (!base_ni || !NInoAttrList(base_ni) || type == AT_ATTRIBUTE_LIST)
 3393         ret = ntfs_attr_find(type, name, name_len, ic, val, val_len, ctx);
 3394     else
 3395         ret = ntfs_external_attr_find(type, name, name_len, ic, 
 3396                           lowest_vcn, val, val_len, ctx);
 3397 out:
 3398     ntfs_log_leave("\n");
 3399     return ret;
 3400 }
 3401 
 3402 /**
 3403  * ntfs_attr_position - find given or next attribute type in an ntfs inode
 3404  * @type:   attribute type to start lookup
 3405  * @ctx:    search context with mft record and attribute to search from
 3406  *
 3407  * Find an attribute type in an ntfs inode or the next attribute which is not
 3408  * the AT_END attribute. Please see more details at ntfs_attr_lookup.
 3409  *
 3410  * Return 0 if the search was successful and -1 if not, with errno set to the
 3411  * error code.
 3412  *
 3413  * The following error codes are defined:
 3414  *  EINVAL  Invalid arguments.
 3415  *  EIO I/O error or corrupt data structures found.
 3416  *  ENOMEM  Not enough memory to allocate necessary buffers.
 3417  *  ENOSPC  No attribute was found after 'type', only AT_END.
 3418  */
 3419 int ntfs_attr_position(const ATTR_TYPES type, ntfs_attr_search_ctx *ctx)
 3420 {
 3421     if (ntfs_attr_lookup(type, NULL, 0, CASE_SENSITIVE, 0, NULL, 0, ctx)) {
 3422         if (errno != ENOENT)
 3423             return -1;
 3424         if (ctx->attr->type == AT_END) {
 3425             errno = ENOSPC;
 3426             return -1;
 3427         }
 3428     }
 3429     return 0;
 3430 }
 3431 
 3432 /**
 3433  * ntfs_attr_init_search_ctx - initialize an attribute search context
 3434  * @ctx:    attribute search context to initialize
 3435  * @ni:     ntfs inode with which to initialize the search context
 3436  * @mrec:   mft record with which to initialize the search context
 3437  *
 3438  * Initialize the attribute search context @ctx with @ni and @mrec.
 3439  */
 3440 static void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx,
 3441         ntfs_inode *ni, MFT_RECORD *mrec)
 3442 {
 3443     if (!mrec)
 3444         mrec = ni->mrec;
 3445     ctx->mrec = mrec;
 3446     /* Sanity checks are performed elsewhere. */
 3447     ctx->attr = (ATTR_RECORD*)((u8*)mrec + le16_to_cpu(mrec->attrs_offset));
 3448     ctx->is_first = TRUE;
 3449     ctx->ntfs_ino = ni;
 3450     ctx->al_entry = NULL;
 3451     ctx->base_ntfs_ino = NULL;
 3452     ctx->base_mrec = NULL;
 3453     ctx->base_attr = NULL;
 3454 }
 3455 
 3456 /**
 3457  * ntfs_attr_reinit_search_ctx - reinitialize an attribute search context
 3458  * @ctx:    attribute search context to reinitialize
 3459  *
 3460  * Reinitialize the attribute search context @ctx.
 3461  *
 3462  * This is used when a search for a new attribute is being started to reset
 3463  * the search context to the beginning.
 3464  */
 3465 void ntfs_attr_reinit_search_ctx(ntfs_attr_search_ctx *ctx)
 3466 {
 3467     if (!ctx->base_ntfs_ino) {
 3468         /* No attribute list. */
 3469         ctx->is_first = TRUE;
 3470         /* Sanity checks are performed elsewhere. */
 3471         ctx->attr = (ATTR_RECORD*)((u8*)ctx->mrec +
 3472                 le16_to_cpu(ctx->mrec->attrs_offset));
 3473         /*
 3474          * This needs resetting due to ntfs_external_attr_find() which
 3475          * can leave it set despite having zeroed ctx->base_ntfs_ino.
 3476          */
 3477         ctx->al_entry = NULL;
 3478         return;
 3479     } /* Attribute list. */
 3480     ntfs_attr_init_search_ctx(ctx, ctx->base_ntfs_ino, ctx->base_mrec);
 3481     return;
 3482 }
 3483 
 3484 /**
 3485  * ntfs_attr_get_search_ctx - allocate/initialize a new attribute search context
 3486  * @ni:     ntfs inode with which to initialize the search context
 3487  * @mrec:   mft record with which to initialize the search context
 3488  *
 3489  * Allocate a new attribute search context, initialize it with @ni and @mrec,
 3490  * and return it. Return NULL on error with errno set.
 3491  *
 3492  * @mrec can be NULL, in which case the mft record is taken from @ni.
 3493  *
 3494  * Note: For low level utilities which know what they are doing we allow @ni to
 3495  * be NULL and @mrec to be set.  Do NOT do this unless you understand the
 3496  * implications!!!  For example it is no longer safe to call ntfs_attr_lookup().
 3497  */
 3498 ntfs_attr_search_ctx *ntfs_attr_get_search_ctx(ntfs_inode *ni, MFT_RECORD *mrec)
 3499 {
 3500     ntfs_attr_search_ctx *ctx;
 3501 
 3502     if (!ni && !mrec) {
 3503         errno = EINVAL;
 3504         ntfs_log_perror("NULL arguments");
 3505         return NULL;
 3506     }
 3507     ctx = ntfs_malloc(sizeof(ntfs_attr_search_ctx));
 3508     if (ctx)
 3509         ntfs_attr_init_search_ctx(ctx, ni, mrec);
 3510     return ctx;
 3511 }
 3512 
 3513 /**
 3514  * ntfs_attr_put_search_ctx - release an attribute search context
 3515  * @ctx:    attribute search context to free
 3516  *
 3517  * Release the attribute search context @ctx.
 3518  */
 3519 void ntfs_attr_put_search_ctx(ntfs_attr_search_ctx *ctx)
 3520 {
 3521     // NOTE: save errno if it could change and function stays void!
 3522     free(ctx);
 3523 }
 3524 
 3525 /**
 3526  * ntfs_attr_find_in_attrdef - find an attribute in the $AttrDef system file
 3527  * @vol:    ntfs volume to which the attribute belongs
 3528  * @type:   attribute type which to find
 3529  *
 3530  * Search for the attribute definition record corresponding to the attribute
 3531  * @type in the $AttrDef system file.
 3532  *
 3533  * Return the attribute type definition record if found and NULL if not found
 3534  * or an error occurred. On error the error code is stored in errno. The
 3535  * following error codes are defined:
 3536  *  ENOENT  - The attribute @type is not specified in $AttrDef.
 3537  *  EINVAL  - Invalid parameters (e.g. @vol is not valid).
 3538  */
 3539 ATTR_DEF *ntfs_attr_find_in_attrdef(const ntfs_volume *vol,
 3540         const ATTR_TYPES type)
 3541 {
 3542     ATTR_DEF *ad;
 3543 
 3544     if (!vol || !vol->attrdef || !type) {
 3545         errno = EINVAL;
 3546         ntfs_log_perror("%s: type=%d", __FUNCTION__, le32_to_cpu(type));
 3547         return NULL;
 3548     }
 3549     for (ad = vol->attrdef; (u8*)ad - (u8*)vol->attrdef <
 3550             vol->attrdef_len && ad->type; ++ad) {
 3551         /* We haven't found it yet, carry on searching. */
 3552         if (le32_to_cpu(ad->type) < le32_to_cpu(type))
 3553             continue;
 3554         /* We found the attribute; return it. */
 3555         if (ad->type == type)
 3556             return ad;
 3557         /* We have gone too far already. No point in continuing. */
 3558         break;
 3559     }
 3560     errno = ENOENT;
 3561     ntfs_log_perror("%s: type=%d", __FUNCTION__, le32_to_cpu(type));
 3562     return NULL;
 3563 }
 3564 
 3565 /**
 3566  * ntfs_attr_size_bounds_check - check a size of an attribute type for validity
 3567  * @vol:    ntfs volume to which the attribute belongs
 3568  * @type:   attribute type which to check
 3569  * @size:   size which to check
 3570  *
 3571  * Check whether the @size in bytes is valid for an attribute of @type on the
 3572  * ntfs volume @vol. This information is obtained from $AttrDef system file.
 3573  *
 3574  * Return 0 if valid and -1 if not valid or an error occurred. On error the
 3575  * error code is stored in errno. The following error codes are defined:
 3576  *  ERANGE  - @size is not valid for the attribute @type.
 3577  *  ENOENT  - The attribute @type is not specified in $AttrDef.
 3578  *  EINVAL  - Invalid parameters (e.g. @size is < 0 or @vol is not valid).
 3579  */
 3580 int ntfs_attr_size_bounds_check(const ntfs_volume *vol, const ATTR_TYPES type,
 3581         const s64 size)
 3582 {
 3583     ATTR_DEF *ad;
 3584     s64 min_size, max_size;
 3585 
 3586     if (size < 0) {
 3587         errno = EINVAL;
 3588         ntfs_log_perror("%s: size=%lld", __FUNCTION__,
 3589                 (long long)size);
 3590         return -1;
 3591     }
 3592 
 3593     /*
 3594      * $ATTRIBUTE_LIST shouldn't be greater than 0x40000, otherwise 
 3595      * Windows would crash. This is not listed in the AttrDef.
 3596      */
 3597     if (type == AT_ATTRIBUTE_LIST && size > 0x40000) {
 3598         errno = ERANGE;
 3599         ntfs_log_perror("Too large attrlist (%lld)", (long long)size);
 3600         return -1;
 3601     }
 3602 
 3603     ad = ntfs_attr_find_in_attrdef(vol, type);
 3604     if (!ad)
 3605         return -1;
 3606     
 3607     min_size = sle64_to_cpu(ad->min_size);
 3608     max_size = sle64_to_cpu(ad->max_size);
 3609 
 3610     /* The $AttrDef generated by Windows specifies 2 as min_size for the
 3611      * volume name attribute, but in reality Windows sets it to 0 when
 3612      * clearing the volume name. If we want to be able to clear the volume
 3613      * name we must also accept 0 as min_size, despite the $AttrDef
 3614      * definition. */
 3615     if(type == AT_VOLUME_NAME)
 3616         min_size = 0;
 3617     
 3618     if ((min_size && (size < min_size)) || 
 3619         ((max_size > 0) && (size > max_size))) {
 3620         errno = ERANGE;
 3621         ntfs_log_perror("Attr type %d size check failed (min,size,max="
 3622             "%lld,%lld,%lld)", le32_to_cpu(type), (long long)min_size,
 3623             (long long)size, (long long)max_size);
 3624         return -1;
 3625     }
 3626     return 0;
 3627 }
 3628 
 3629 /**
 3630  * ntfs_attr_can_be_non_resident - check if an attribute can be non-resident
 3631  * @vol:    ntfs volume to which the attribute belongs
 3632  * @type:   attribute type to check
 3633  * @name:   attribute name to check
 3634  * @name_len:   attribute name length
 3635  *
 3636  * Check whether the attribute of @type and @name with name length @name_len on
 3637  * the ntfs volume @vol is allowed to be non-resident.  This information is
 3638  * obtained from $AttrDef system file and is augmented by rules imposed by
 3639  * Microsoft (e.g. see http://support.microsoft.com/kb/974729/).
 3640  *
 3641  * Return 0 if the attribute is allowed to be non-resident and -1 if not or an
 3642  * error occurred. On error the error code is stored in errno. The following
 3643  * error codes are defined:
 3644  *  EPERM   - The attribute is not allowed to be non-resident.
 3645  *  ENOENT  - The attribute @type is not specified in $AttrDef.
 3646  *  EINVAL  - Invalid parameters (e.g. @vol is not valid).
 3647  */
 3648 static int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPES type,
 3649                     const ntfschar *name, int name_len)
 3650 {
 3651     ATTR_DEF *ad;
 3652     BOOL allowed;
 3653 
 3654     /*
 3655      * Microsoft has decreed that $LOGGED_UTILITY_STREAM attributes with a
 3656      * name of $TXF_DATA must be resident despite the entry for
 3657      * $LOGGED_UTILITY_STREAM in $AttrDef allowing them to be non-resident.
 3658      * Failure to obey this on the root directory mft record of a volume
 3659      * causes Windows Vista and later to see the volume as a RAW volume and
 3660      * thus cannot mount it at all.
 3661      */
 3662     if ((type == AT_LOGGED_UTILITY_STREAM)
 3663         && name
 3664         && ntfs_names_are_equal(TXF_DATA, 9, name, name_len,
 3665             CASE_SENSITIVE, vol->upcase, vol->upcase_len))
 3666         allowed = FALSE;
 3667     else {
 3668         /* Find the attribute definition record in $AttrDef. */
 3669         ad = ntfs_attr_find_in_attrdef(vol, type);
 3670         if (!ad)
 3671             return -1;
 3672         /* Check the flags and return the result. */
 3673         allowed = !(ad->flags & ATTR_DEF_RESIDENT);
 3674     }
 3675     if (!allowed) {
 3676         errno = EPERM;
 3677         ntfs_log_trace("Attribute can't be non-resident\n");
 3678         return -1;
 3679     }
 3680     return 0;
 3681 }
 3682 
 3683 /**
 3684  * ntfs_attr_can_be_resident - check if an attribute can be resident
 3685  * @vol:    ntfs volume to which the attribute belongs
 3686  * @type:   attribute type which to check
 3687  *
 3688  * Check whether the attribute of @type on the ntfs volume @vol is allowed to
 3689  * be resident. This information is derived from our ntfs knowledge and may
 3690  * not be completely accurate, especially when user defined attributes are
 3691  * present. Basically we allow everything to be resident except for index
 3692  * allocation and extended attribute attributes.
 3693  *
 3694  * Return 0 if the attribute is allowed to be resident and -1 if not or an
 3695  * error occurred. On error the error code is stored in errno. The following
 3696  * error codes are defined:
 3697  *  EPERM   - The attribute is not allowed to be resident.
 3698  *  EINVAL  - Invalid parameters (e.g. @vol is not valid).
 3699  *
 3700  * Warning: In the system file $MFT the attribute $Bitmap must be non-resident
 3701  *      otherwise windows will not boot (blue screen of death)!  We cannot
 3702  *      check for this here as we don't know which inode's $Bitmap is being
 3703  *      asked about so the caller needs to special case this.
 3704  */
 3705 int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPES type)
 3706 {
 3707     if (!vol || !vol->attrdef || !type) {
 3708         errno = EINVAL;
 3709         return -1;
 3710     }
 3711     if (type != AT_INDEX_ALLOCATION)
 3712         return 0;
 3713     
 3714     ntfs_log_trace("Attribute can't be resident\n");
 3715     errno = EPERM;
 3716     return -1;
 3717 }
 3718 
 3719 /**
 3720  * ntfs_make_room_for_attr - make room for an attribute inside an mft record
 3721  * @m:      mft record
 3722  * @pos:    position at which to make space
 3723  * @size:   byte size to make available at this position
 3724  *
 3725  * @pos points to the attribute in front of which we want to make space.
 3726  *
 3727  * Return 0 on success or -1 on error. On error the error code is stored in
 3728  * errno. Possible error codes are:
 3729  *  ENOSPC  - There is not enough space available to complete operation. The
 3730  *        caller has to make space before calling this.
 3731  *  EINVAL  - Input parameters were faulty.
 3732  */
 3733 int ntfs_make_room_for_attr(MFT_RECORD *m, u8 *pos, u32 size)
 3734 {
 3735     u32 biu;
 3736 
 3737     ntfs_log_trace("Entering for pos 0x%d, size %u.\n",
 3738         (int)(pos - (u8*)m), (unsigned) size);
 3739 
 3740     /* Make size 8-byte alignment. */
 3741     size = (size + 7) & ~7;
 3742 
 3743     /* Rigorous consistency checks. */
 3744     if (!m || !pos || pos < (u8*)m) {
 3745         errno = EINVAL;
 3746         ntfs_log_perror("%s: pos=%p  m=%p", __FUNCTION__, pos, m);
 3747         return -1;
 3748     }
 3749     /* The -8 is for the attribute terminator. */
 3750     if (pos - (u8*)m > (int)le32_to_cpu(m->bytes_in_use) - 8) {
 3751         errno = EINVAL;
 3752         return -1;
 3753     }
 3754     /* Nothing to do. */
 3755     if (!size)
 3756         return 0;
 3757 
 3758     biu = le32_to_cpu(m->bytes_in_use);
 3759     /* Do we have enough space? */
 3760     if (biu + size > le32_to_cpu(m->bytes_allocated) ||
 3761         pos + size > (u8*)m + le32_to_cpu(m->bytes_allocated)) {
 3762         errno = ENOSPC;
 3763         ntfs_log_trace("No enough space in the MFT record\n");
 3764         return -1;
 3765     }
 3766     /* Move everything after pos to pos + size. */
 3767     memmove(pos + size, pos, biu - (pos - (u8*)m));
 3768     /* Update mft record. */
 3769     m->bytes_in_use = cpu_to_le32(biu + size);
 3770     return 0;
 3771 }
 3772 
 3773 /**
 3774  * ntfs_resident_attr_record_add - add resident attribute to inode
 3775  * @ni:     opened ntfs inode to which MFT record add attribute
 3776  * @type:   type of the new attribute
 3777  * @name:   name of the new attribute
 3778  * @name_len:   name length of the new attribute
 3779  * @val:    value of the new attribute
 3780  * @size:   size of new attribute (length of @val, if @val != NULL)
 3781  * @flags:  flags of the new attribute
 3782  *
 3783  * Return offset to attribute from the beginning of the mft record on success
 3784  * and -1 on error. On error the error code is stored in errno.
 3785  * Possible error codes are:
 3786  *  EINVAL  - Invalid arguments passed to function.
 3787  *  EEXIST  - Attribute of such type and with same name already exists.
 3788  *  EIO - I/O error occurred or damaged filesystem.
 3789  */
 3790 int ntfs_resident_attr_record_add(ntfs_inode *ni, ATTR_TYPES type,
 3791             const ntfschar *name, u8 name_len, const u8 *val,
 3792             u32 size, ATTR_FLAGS data_flags)
 3793 {
 3794     ntfs_attr_search_ctx *ctx;
 3795     u32 length;
 3796     ATTR_RECORD *a;
 3797     MFT_RECORD *m;
 3798     int err, offset;
 3799     ntfs_inode *base_ni;
 3800 
 3801     ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x, flags 0x%x.\n",
 3802         (long long) ni->mft_no, (unsigned) le32_to_cpu(type), (unsigned) le16_to_cpu(data_flags));
 3803 
 3804     if (!ni || (!name && name_len)) {
 3805         errno = EINVAL;
 3806         return -1;
 3807     }
 3808 
 3809     if (ntfs_attr_can_be_resident(ni->vol, type)) {
 3810         if (errno == EPERM)
 3811             ntfs_log_trace("Attribute can't be resident.\n");
 3812         else
 3813             ntfs_log_trace("ntfs_attr_can_be_resident failed.\n");
 3814         return -1;
 3815     }
 3816 
 3817     /* Locate place where record should be. */
 3818     ctx = ntfs_attr_get_search_ctx(ni, NULL);
 3819     if (!ctx)
 3820         return -1;
 3821     /*
 3822      * Use ntfs_attr_find instead of ntfs_attr_lookup to find place for
 3823      * attribute in @ni->mrec, not any extent inode in case if @ni is base
 3824      * file record.
 3825      */
 3826     if (!ntfs_attr_find(type, name, name_len, CASE_SENSITIVE, val, size,
 3827             ctx)) {
 3828         err = EEXIST;
 3829         ntfs_log_trace("Attribute already present.\n");
 3830         goto put_err_out;
 3831     }
 3832     if (errno != ENOENT) {
 3833         err = EIO;
 3834         goto put_err_out;
 3835     }
 3836     a = ctx->attr;
 3837     m = ctx->mrec;
 3838 
 3839     /* Make room for attribute. */
 3840     length = offsetof(ATTR_RECORD, resident_end) +
 3841                 ((name_len * sizeof(ntfschar) + 7) & ~7) +
 3842                 ((size + 7) & ~7);
 3843     if (ntfs_make_room_for_attr(ctx->mrec, (u8*) ctx->attr, length)) {
 3844         err = errno;
 3845         ntfs_log_trace("Failed to make room for attribute.\n");
 3846         goto put_err_out;
 3847     }
 3848 
 3849     /* Setup record fields. */
 3850     offset = ((u8*)a - (u8*)m);
 3851     a->type = type;
 3852     a->length = cpu_to_le32(length);
 3853     a->non_resident = 0;
 3854     a->name_length = name_len;
 3855     a->name_offset = (name_len
 3856         ? const_cpu_to_le16(offsetof(ATTR_RECORD, resident_end))
 3857         : const_cpu_to_le16(0));
 3858     a->flags = data_flags;
 3859     a->instance = m->next_attr_instance;
 3860     a->value_length = cpu_to_le32(size);
 3861     a->value_offset = cpu_to_le16(length - ((size + 7) & ~7));
 3862     if (val)
 3863         memcpy((u8*)a + le16_to_cpu(a->value_offset), val, size);
 3864     else
 3865         memset((u8*)a + le16_to_cpu(a->value_offset), 0, size);
 3866     if (type == AT_FILE_NAME)
 3867         a->resident_flags = RESIDENT_ATTR_IS_INDEXED;
 3868     else
 3869         a->resident_flags = 0;
 3870     if (name_len)
 3871         memcpy((u8*)a + le16_to_cpu(a->name_offset),
 3872             name, sizeof(ntfschar) * name_len);
 3873     m->next_attr_instance =
 3874         cpu_to_le16((le16_to_cpu(m->next_attr_instance) + 1) & 0xffff);
 3875     if (ni->nr_extents == -1)
 3876         base_ni = ni->base_ni;
 3877     else
 3878         base_ni = ni;
 3879     if (type != AT_ATTRIBUTE_LIST && NInoAttrList(base_ni)) {
 3880         if (ntfs_attrlist_entry_add(ni, a)) {
 3881             err = errno;
 3882             ntfs_attr_record_resize(m, a, 0);
 3883             ntfs_log_trace("Failed add attribute entry to "
 3884                     "ATTRIBUTE_LIST.\n");
 3885             goto put_err_out;
 3886         }
 3887     }
 3888     if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY
 3889         ? type == AT_INDEX_ROOT && name == NTFS_INDEX_I30
 3890         : type == AT_DATA && name == AT_UNNAMED) {
 3891         ni->data_size = size;
 3892         ni->allocated_size = (size + 7) & ~7;
 3893         set_nino_flag(ni,KnownSize);
 3894     }
 3895     ntfs_inode_mark_dirty(ni);
 3896     ntfs_attr_put_search_ctx(ctx);
 3897     return offset;
 3898 put_err_out:
 3899     ntfs_attr_put_search_ctx(ctx);
 3900     errno = err;
 3901     return -1;
 3902 }
 3903 
 3904 /**
 3905  * ntfs_non_resident_attr_record_add - add extent of non-resident attribute
 3906  * @ni:         opened ntfs inode to which MFT record add attribute
 3907  * @type:       type of the new attribute extent
 3908  * @name:       name of the new attribute extent
 3909  * @name_len:       name length of the new attribute extent
 3910  * @lowest_vcn:     lowest vcn of the new attribute extent
 3911  * @dataruns_size:  dataruns size of the new attribute extent
 3912  * @flags:      flags of the new attribute extent
 3913  *
 3914  * Return offset to attribute from the beginning of the mft record on success
 3915  * and -1 on error. On error the error code is stored in errno.
 3916  * Possible error codes are:
 3917  *  EINVAL  - Invalid arguments passed to function.
 3918  *  EEXIST  - Attribute of such type, with same lowest vcn and with same
 3919  *        name already exists.
 3920  *  EIO - I/O error occurred or damaged filesystem.
 3921  */
 3922 int ntfs_non_resident_attr_record_add(ntfs_inode *ni, ATTR_TYPES type,
 3923         const ntfschar *name, u8 name_len, VCN lowest_vcn, int dataruns_size,
 3924         ATTR_FLAGS flags)
 3925 {
 3926     ntfs_attr_search_ctx *ctx;
 3927     u32 length;
 3928     ATTR_RECORD *a;
 3929     MFT_RECORD *m;
 3930     ntfs_inode *base_ni;
 3931     int err, offset;
 3932 
 3933     ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x, lowest_vcn %lld, "
 3934             "dataruns_size %d, flags 0x%x.\n",
 3935             (long long) ni->mft_no, (unsigned) le32_to_cpu(type),
 3936             (long long) lowest_vcn, dataruns_size, (unsigned) le16_to_cpu(flags));
 3937 
 3938     if (!ni || dataruns_size <= 0 || (!name && name_len)) {
 3939         errno = EINVAL;
 3940         return -1;
 3941     }
 3942 
 3943     if (ntfs_attr_can_be_non_resident(ni->vol, type, name, name_len)) {
 3944         if (errno == EPERM)
 3945             ntfs_log_perror("Attribute can't be non resident");
 3946         else
 3947             ntfs_log_perror("ntfs_attr_can_be_non_resident failed");
 3948         return -1;
 3949     }
 3950 
 3951     /* Locate place where record should be. */
 3952     ctx = ntfs_attr_get_search_ctx(ni, NULL);
 3953     if (!ctx)
 3954         return -1;
 3955     /*
 3956      * Use ntfs_attr_find instead of ntfs_attr_lookup to find place for
 3957      * attribute in @ni->mrec, not any extent inode in case if @ni is base
 3958      * file record.
 3959      */
 3960     if (!ntfs_attr_find(type, name, name_len, CASE_SENSITIVE, NULL, 0,
 3961             ctx)) {
 3962         err = EEXIST;
 3963         ntfs_log_perror("Attribute 0x%x already present", le32_to_cpu(type));
 3964         goto put_err_out;
 3965     }
 3966     if (errno != ENOENT) {
 3967         ntfs_log_perror("ntfs_attr_find failed");
 3968         err = EIO;
 3969         goto put_err_out;
 3970     }
 3971     a = ctx->attr;
 3972     m = ctx->mrec;
 3973 
 3974     /* Make room for attribute. */
 3975     dataruns_size = (dataruns_size + 7) & ~7;
 3976     length = offsetof(ATTR_RECORD, compressed_size) + ((sizeof(ntfschar) *
 3977             name_len + 7) & ~7) + dataruns_size +
 3978             ((flags & (ATTR_IS_COMPRESSED | ATTR_IS_SPARSE)) ?
 3979             sizeof(a->compressed_size) : 0);
 3980     if (ntfs_make_room_for_attr(ctx->mrec, (u8*) ctx->attr, length)) {
 3981         err = errno;
 3982         ntfs_log_perror("Failed to make room for attribute");
 3983         goto put_err_out;
 3984     }
 3985 
 3986     /* Setup record fields. */
 3987     a->type = type;
 3988     a->length = cpu_to_le32(length);
 3989     a->non_resident = 1;
 3990     a->name_length = name_len;
 3991     a->name_offset = cpu_to_le16(offsetof(ATTR_RECORD, compressed_size) +
 3992             ((flags & (ATTR_IS_COMPRESSED | ATTR_IS_SPARSE)) ?
 3993             sizeof(a->compressed_size) : 0));
 3994     a->flags = flags;
 3995     a->instance = m->next_attr_instance;
 3996     a->lowest_vcn = cpu_to_sle64(lowest_vcn);
 3997     a->mapping_pairs_offset = cpu_to_le16(length - dataruns_size);
 3998     a->compression_unit = (flags & ATTR_IS_COMPRESSED)
 3999             ? STANDARD_COMPRESSION_UNIT : 0;
 4000     /* If @lowest_vcn == 0, than setup empty attribute. */
 4001     if (!lowest_vcn) {
 4002         a->highest_vcn = const_cpu_to_sle64(-1);
 4003         a->allocated_size = const_cpu_to_sle64(0);
 4004         a->data_size = const_cpu_to_sle64(0);
 4005         a->initialized_size = const_cpu_to_sle64(0);
 4006         /* Set empty mapping pairs. */
 4007         *((u8*)a + le16_to_cpu(a->mapping_pairs_offset)) = 0;
 4008     }
 4009     if (name_len)
 4010         memcpy((u8*)a + le16_to_cpu(a->name_offset),
 4011             name, sizeof(ntfschar) * name_len);
 4012     m->next_attr_instance =
 4013         cpu_to_le16((le16_to_cpu(m->next_attr_instance) + 1) & 0xffff);
 4014     if (ni->nr_extents == -1)
 4015         base_ni = ni->base_ni;
 4016     else
 4017         base_ni = ni;
 4018     if (type != AT_ATTRIBUTE_LIST && NInoAttrList(base_ni)) {
 4019         if (ntfs_attrlist_entry_add(ni, a)) {
 4020             err = errno;
 4021             ntfs_log_perror("Failed add attr entry to attrlist");
 4022             ntfs_attr_record_resize(m, a, 0);
 4023             goto put_err_out;
 4024         }
 4025     }
 4026     ntfs_inode_mark_dirty(ni);
 4027     /*
 4028      * Locate offset from start of the MFT record where new attribute is
 4029      * placed. We need relookup it, because record maybe moved during
 4030      * update of attribute list.
 4031      */
 4032     ntfs_attr_reinit_search_ctx(ctx);
 4033     if (ntfs_attr_lookup(type, name, name_len, CASE_SENSITIVE,
 4034                     lowest_vcn, NULL, 0, ctx)) {
 4035         ntfs_log_perror("%s: attribute lookup failed", __FUNCTION__);
 4036         ntfs_attr_put_search_ctx(ctx);
 4037         return -1;
 4038 
 4039     }
 4040     offset = (u8*)ctx->attr - (u8*)ctx->mrec;
 4041     ntfs_attr_put_search_ctx(ctx);
 4042     return offset;
 4043 put_err_out:
 4044     ntfs_attr_put_search_ctx(ctx);
 4045     errno = err;
 4046     return -1;
 4047 }
 4048 
 4049 /**
 4050  * ntfs_attr_record_rm - remove attribute extent
 4051  * @ctx:    search context describing the attribute which should be removed
 4052  *
 4053  * If this function succeed, user should reinit search context if he/she wants
 4054  * use it anymore.
 4055  *
 4056  * Return 0 on success and -1 on error. On error the error code is stored in
 4057  * errno. Possible error codes are:
 4058  *  EINVAL  - Invalid arguments passed to function.
 4059  *  EIO - I/O error occurred or damaged filesystem.
 4060  */
 4061 int ntfs_attr_record_rm(ntfs_attr_search_ctx *ctx)
 4062 {
 4063     ntfs_inode *base_ni, *ni;
 4064     ATTR_TYPES type;
 4065 
 4066     if (!ctx || !ctx->ntfs_ino || !ctx->mrec || !ctx->attr) {
 4067         errno = EINVAL;
 4068         return -1;
 4069     }
 4070 
 4071     ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x.\n",
 4072             (long long) ctx->ntfs_ino->mft_no,
 4073             (unsigned) le32_to_cpu(ctx->attr->type));
 4074     type = ctx->attr->type;
 4075     ni = ctx->ntfs_ino;
 4076     if (ctx->base_ntfs_ino)
 4077         base_ni = ctx->base_ntfs_ino;
 4078     else
 4079         base_ni = ctx->ntfs_ino;
 4080 
 4081     /* Remove attribute itself. */
 4082     if (ntfs_attr_record_resize(ctx->mrec, ctx->attr, 0)) {
 4083         ntfs_log_trace("Couldn't remove attribute record. Bug or damaged MFT "
 4084                 "record.\n");
 4085         if (NInoAttrList(base_ni) && type != AT_ATTRIBUTE_LIST)
 4086             if (ntfs_attrlist_entry_add(ni, ctx->attr))
 4087                 ntfs_log_trace("Rollback failed. Leaving inconstant "
 4088                         "metadata.\n");
 4089         errno = EIO;
 4090         return -1;
 4091     }
 4092     ntfs_inode_mark_dirty(ni);
 4093 
 4094     /*
 4095      * Remove record from $ATTRIBUTE_LIST if present and we don't want
 4096      * delete $ATTRIBUTE_LIST itself.
 4097      */
 4098     if (NInoAttrList(base_ni) && type != AT_ATTRIBUTE_LIST) {
 4099         if (ntfs_attrlist_entry_rm(ctx)) {
 4100             ntfs_log_trace("Couldn't delete record from "
 4101                     "$ATTRIBUTE_LIST.\n");
 4102             return -1;
 4103         }
 4104     }
 4105 
 4106     /* Post $ATTRIBUTE_LIST delete setup. */
 4107     if (type == AT_ATTRIBUTE_LIST) {
 4108         if (NInoAttrList(base_ni) && base_ni->attr_list)
 4109             free(base_ni->attr_list);
 4110         base_ni->attr_list = NULL;
 4111         NInoClearAttrList(base_ni);
 4112         NInoAttrListClearDirty(base_ni);
 4113     }
 4114 
 4115     /* Free MFT record, if it doesn't contain attributes. */
 4116     if (le32_to_cpu(ctx->mrec->bytes_in_use) -
 4117             le16_to_cpu(ctx->mrec->attrs_offset) == 8) {
 4118         if (ntfs_mft_record_free(ni->vol, ni)) {
 4119             // FIXME: We need rollback here.
 4120             ntfs_log_trace("Couldn't free MFT record.\n");
 4121             errno = EIO;
 4122             return -1;
 4123         }
 4124         /* Remove done if we freed base inode. */
 4125         if (ni == base_ni)
 4126             return 0;
 4127     }
 4128 
 4129     if (type == AT_ATTRIBUTE_LIST || !NInoAttrList(base_ni))
 4130         return 0;
 4131 
 4132     /* Remove attribute list if we don't need it any more. */
 4133     if (!ntfs_attrlist_need(base_ni)) {
 4134         ntfs_attr_reinit_search_ctx(ctx);
 4135         if (ntfs_attr_lookup(AT_ATTRIBUTE_LIST, NULL, 0, CASE_SENSITIVE,
 4136                 0, NULL, 0, ctx)) {
 4137             /*
 4138              * FIXME: Should we succeed here? Definitely something
 4139              * goes wrong because NInoAttrList(base_ni) returned
 4140              * that we have got attribute list.
 4141              */
 4142             ntfs_log_trace("Couldn't find attribute list. Succeed "
 4143                     "anyway.\n");
 4144             return 0;
 4145         }
 4146         /* Deallocate clusters. */
 4147         if (ctx->attr->non_resident) {
 4148             runlist *al_rl;
 4149 
 4150             al_rl = ntfs_mapping_pairs_decompress(base_ni->vol,
 4151                     ctx->attr, NULL);
 4152             if (!al_rl) {
 4153                 ntfs_log_trace("Couldn't decompress attribute list "
 4154                         "runlist. Succeed anyway.\n");
 4155                 return 0;
 4156             }
 4157             if (ntfs_cluster_free_from_rl(base_ni->vol, al_rl)) {
 4158                 ntfs_log_trace("Leaking clusters! Run chkdsk. "
 4159                         "Couldn't free clusters from "
 4160                         "attribute list runlist.\n");
 4161             }
 4162             free(al_rl);
 4163         }
 4164         /* Remove attribute record itself. */
 4165         if (ntfs_attr_record_rm(ctx)) {
 4166             /*
 4167              * FIXME: Should we succeed here? BTW, chkdsk doesn't
 4168              * complain if it find MFT record with attribute list,
 4169              * but without extents.
 4170              */
 4171             ntfs_log_trace("Couldn't remove attribute list. Succeed "
 4172                     "anyway.\n");
 4173             return 0;
 4174         }
 4175     }
 4176     return 0;
 4177 }
 4178 
 4179 /**
 4180  * ntfs_attr_add - add attribute to inode
 4181  * @ni:     opened ntfs inode to which add attribute
 4182  * @type:   type of the new attribute
 4183  * @name:   name in unicode of the new attribute
 4184  * @name_len:   name length in unicode characters of the new attribute
 4185  * @val:    value of new attribute
 4186  * @size:   size of the new attribute / length of @val (if specified)
 4187  *
 4188  * @val should always be specified for always resident attributes (eg. FILE_NAME
 4189  * attribute), for attributes that can become non-resident @val can be NULL
 4190  * (eg. DATA attribute). @size can be specified even if @val is NULL, in this
 4191  * case data size will be equal to @size and initialized size will be equal
 4192  * to 0.
 4193  *
 4194  * If inode haven't got enough space to add attribute, add attribute to one of
 4195  * it extents, if no extents present or no one of them have enough space, than
 4196  * allocate new extent and add attribute to it.
 4197  *
 4198  * If on one of this steps attribute list is needed but not present, than it is
 4199  * added transparently to caller. So, this function should not be called with
 4200  * @type == AT_ATTRIBUTE_LIST, if you really need to add attribute list call
 4201  * ntfs_inode_add_attrlist instead.
 4202  *
 4203  * On success return 0. On error return -1 with errno set to the error code.
 4204  */
 4205 int ntfs_attr_add(ntfs_inode *ni, ATTR_TYPES type,
 4206         ntfschar *name, u8 name_len, const u8 *val, s64 size)
 4207 {
 4208     u32 attr_rec_size;
 4209     int err, i, offset;
 4210     BOOL is_resident;
 4211     BOOL can_be_non_resident = FALSE;
 4212     ntfs_inode *attr_ni;
 4213     ntfs_attr *na;
 4214     ATTR_FLAGS data_flags;
 4215 
 4216     if (!ni || size < 0 || type == AT_ATTRIBUTE_LIST) {
 4217         errno = EINVAL;
 4218         ntfs_log_perror("%s: ni=%p  size=%lld", __FUNCTION__, ni,
 4219                 (long long)size);
 4220         return -1;
 4221     }
 4222 
 4223     ntfs_log_trace("Entering for inode %lld, attr %x, size %lld.\n",
 4224             (long long)ni->mft_no, le32_to_cpu(type), (long long)size);
 4225 
 4226     if (ni->nr_extents == -1)
 4227         ni = ni->base_ni;
 4228 
 4229     /* Check the attribute type and the size. */
 4230     if (ntfs_attr_size_bounds_check(ni->vol, type, size)) {
 4231         if (errno == ENOENT)
 4232             errno = EIO;
 4233         return -1;
 4234     }
 4235 
 4236     /* Sanity checks for always resident attributes. */
 4237     if (ntfs_attr_can_be_non_resident(ni->vol, type, name, name_len)) {
 4238         if (errno != EPERM) {
 4239             err = errno;
 4240             ntfs_log_perror("ntfs_attr_can_be_non_resident failed");
 4241             goto err_out;
 4242         }
 4243         /* @val is mandatory. */
 4244         if (!val) {
 4245             errno = EINVAL;
 4246             ntfs_log_perror("val is mandatory for always resident "
 4247                     "attributes");
 4248             return -1;
 4249         }
 4250         if (size > ni->vol->mft_record_size) {
 4251             errno = ERANGE;
 4252             ntfs_log_perror("Attribute is too big");
 4253             return -1;
 4254         }
 4255     } else
 4256         can_be_non_resident = TRUE;
 4257 
 4258     /*
 4259      * Determine resident or not will be new attribute. We add 8 to size in
 4260      * non resident case for mapping pairs.
 4261      */
 4262     if (!ntfs_attr_can_be_resident(ni->vol, type)) {
 4263         is_resident = TRUE;
 4264     } else {
 4265         if (errno != EPERM) {
 4266             err = errno;
 4267             ntfs_log_perror("ntfs_attr_can_be_resident failed");
 4268             goto err_out;
 4269         }
 4270         is_resident = FALSE;
 4271     }
 4272     /* Calculate attribute record size. */
 4273     if (is_resident)
 4274         attr_rec_size = offsetof(ATTR_RECORD, resident_end) +
 4275                 ((name_len * sizeof(ntfschar) + 7) & ~7) +
 4276                 ((size + 7) & ~7);
 4277     else
 4278         attr_rec_size = offsetof(ATTR_RECORD, non_resident_end) +
 4279                 ((name_len * sizeof(ntfschar) + 7) & ~7) + 8;
 4280 
 4281     /*
 4282      * If we have enough free space for the new attribute in the base MFT
 4283      * record, then add attribute to it.
 4284      */
 4285     if (le32_to_cpu(ni->mrec->bytes_allocated) -
 4286             le32_to_cpu(ni->mrec->bytes_in_use) >= attr_rec_size) {
 4287         attr_ni = ni;
 4288         goto add_attr_record;
 4289     }
 4290 
 4291     /* Try to add to extent inodes. */
 4292     if (ntfs_inode_attach_all_extents(ni)) {
 4293         err = errno;
 4294         ntfs_log_perror("Failed to attach all extents to inode");
 4295         goto err_out;
 4296     }
 4297     for (i = 0; i < ni->nr_extents; i++) {
 4298         attr_ni = ni->extent_nis[i];
 4299         if (le32_to_cpu(attr_ni->mrec->bytes_allocated) -
 4300                 le32_to_cpu(attr_ni->mrec->bytes_in_use) >=
 4301                 attr_rec_size)
 4302             goto add_attr_record;
 4303     }
 4304 
 4305     /* There is no extent that contain enough space for new attribute. */
 4306     if (!NInoAttrList(ni)) {
 4307         /* Add attribute list not present, add it and retry. */
 4308         if (ntfs_inode_add_attrlist(ni)) {
 4309             err = errno;
 4310             ntfs_log_perror("Failed to add attribute list");
 4311             goto err_out;
 4312         }
 4313         return ntfs_attr_add(ni, type, name, name_len, val, size);
 4314     }
 4315     /* Allocate new extent. */
 4316     attr_ni = ntfs_mft_record_alloc(ni->vol, ni);
 4317     if (!attr_ni) {
 4318         err = errno;
 4319         ntfs_log_perror("Failed to allocate extent record");
 4320         goto err_out;
 4321     }
 4322 
 4323 add_attr_record:
 4324     if ((ni->flags & FILE_ATTR_COMPRESSED)
 4325         && (ni->vol->major_ver >= 3)
 4326         && NVolCompression(ni->vol)
 4327         && (ni->vol->cluster_size <= MAX_COMPRESSION_CLUSTER_SIZE)
 4328         && ((type == AT_DATA)
 4329            || ((type == AT_INDEX_ROOT) && (name == NTFS_INDEX_I30))))
 4330         data_flags = ATTR_IS_COMPRESSED;
 4331     else
 4332         data_flags = const_cpu_to_le16(0);
 4333     if (is_resident) {
 4334         /* Add resident attribute. */
 4335         offset = ntfs_resident_attr_record_add(attr_ni, type, name,
 4336                 name_len, val, size, data_flags);
 4337         if (offset < 0) {
 4338             if (errno == ENOSPC && can_be_non_resident)
 4339                 goto add_non_resident;
 4340             err = errno;
 4341             ntfs_log_perror("Failed to add resident attribute");
 4342             goto free_err_out;
 4343         }
 4344         return 0;
 4345     }
 4346 
 4347 add_non_resident:
 4348     /* Add non resident attribute. */
 4349     offset = ntfs_non_resident_attr_record_add(attr_ni, type, name,
 4350                 name_len, 0, 8, data_flags);
 4351     if (offset < 0) {
 4352         err = errno;
 4353         ntfs_log_perror("Failed to add non resident attribute");
 4354         goto free_err_out;
 4355     }
 4356 
 4357     /* If @size == 0, we are done. */
 4358     if (!size)
 4359         return 0;
 4360 
 4361     /* Open new attribute and resize it. */
 4362     na = ntfs_attr_open(ni, type, name, name_len);
 4363     if (!na) {
 4364         err = errno;
 4365         ntfs_log_perror("Failed to open just added attribute");
 4366         goto rm_attr_err_out;
 4367     }
 4368     /* Resize and set attribute value. */
 4369     if (ntfs_attr_truncate_i(na, size, HOLES_OK) ||
 4370             (val && (ntfs_attr_pwrite(na, 0, size, val) != size))) {
 4371         err = errno;
 4372         ntfs_log_perror("Failed to initialize just added attribute");
 4373         if (ntfs_attr_rm(na))
 4374             ntfs_log_perror("Failed to remove just added attribute");
 4375         ntfs_attr_close(na);
 4376         goto err_out;
 4377     }
 4378     ntfs_attr_close(na);
 4379     return 0;
 4380 
 4381 rm_attr_err_out:
 4382     /* Remove just added attribute. */
 4383     if (ntfs_attr_record_resize(attr_ni->mrec,
 4384             (ATTR_RECORD*)((u8*)attr_ni->mrec + offset), 0))
 4385         ntfs_log_perror("Failed to remove just added attribute #2");
 4386 free_err_out:
 4387     /* Free MFT record, if it doesn't contain attributes. */
 4388     if (le32_to_cpu(attr_ni->mrec->bytes_in_use) -
 4389             le16_to_cpu(attr_ni->mrec->attrs_offset) == 8)
 4390         if (ntfs_mft_record_free(attr_ni->vol, attr_ni))
 4391             ntfs_log_perror("Failed to free MFT record");
 4392 err_out:
 4393     errno = err;
 4394     return -1;
 4395 }
 4396 
 4397 /*
 4398  *      Change an attribute flag
 4399  */
 4400 
 4401 int ntfs_attr_set_flags(ntfs_inode *ni, ATTR_TYPES type, const ntfschar *name,
 4402         u8 name_len, ATTR_FLAGS flags, ATTR_FLAGS mask)
 4403 {
 4404     ntfs_attr_search_ctx *ctx;
 4405     int res;
 4406 
 4407     res = -1;
 4408     /* Search for designated attribute */
 4409     ctx = ntfs_attr_get_search_ctx(ni, NULL);
 4410     if (ctx) {
 4411         if (!ntfs_attr_lookup(type, name, name_len,
 4412                     CASE_SENSITIVE, 0, NULL, 0, ctx)) {
 4413             /* do the requested change (all small endian le16) */
 4414             ctx->attr->flags = (ctx->attr->flags & ~mask)
 4415                         | (flags & mask);
 4416             NInoSetDirty(ni);
 4417             res = 0;
 4418         }
 4419         ntfs_attr_put_search_ctx(ctx);
 4420     }
 4421     return (res);
 4422 }
 4423 
 4424 
 4425 /**
 4426  * ntfs_attr_rm - remove attribute from ntfs inode
 4427  * @na:     opened ntfs attribute to delete
 4428  *
 4429  * Remove attribute and all it's extents from ntfs inode. If attribute was non
 4430  * resident also free all clusters allocated by attribute.
 4431  *
 4432  * Return 0 on success or -1 on error with errno set to the error code.
 4433  */
 4434 int ntfs_attr_rm(ntfs_attr *na)
 4435 {
 4436     ntfs_attr_search_ctx *ctx;
 4437     int ret = 0;
 4438 
 4439     if (!na) {
 4440         ntfs_log_trace("Invalid arguments passed.\n");
 4441         errno = EINVAL;
 4442         return -1;
 4443     }
 4444 
 4445     ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x.\n",
 4446         (long long) na->ni->mft_no, le32_to_cpu(na->type));
 4447 
 4448     /* Free cluster allocation. */
 4449     if (NAttrNonResident(na)) {
 4450         if (ntfs_attr_map_whole_runlist(na))
 4451             return -1;
 4452         if (ntfs_cluster_free(na->ni->vol, na, 0, -1) < 0) {
 4453             ntfs_log_trace("Failed to free cluster allocation. Leaving "
 4454                     "inconstant metadata.\n");
 4455             ret = -1;
 4456         }
 4457     }
 4458 
 4459     /* Search for attribute extents and remove them all. */
 4460     ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
 4461     if (!ctx)
 4462         return -1;
 4463     while (!ntfs_attr_lookup(na->type, na->name, na->name_len,
 4464                 CASE_SENSITIVE, 0, NULL, 0, ctx)) {
 4465         if (ntfs_attr_record_rm(ctx)) {
 4466             ntfs_log_trace("Failed to remove attribute extent. Leaving "
 4467                     "inconstant metadata.\n");
 4468             ret = -1;
 4469         }
 4470         ntfs_attr_reinit_search_ctx(ctx);
 4471     }
 4472     ntfs_attr_put_search_ctx(ctx);
 4473     if (errno != ENOENT) {
 4474         ntfs_log_trace("Attribute lookup failed. Probably leaving inconstant "
 4475                 "metadata.\n");
 4476         ret = -1;
 4477     }
 4478 
 4479     return ret;
 4480 }
 4481 
 4482 /**
 4483  * ntfs_attr_record_resize - resize an attribute record
 4484  * @m:      mft record containing attribute record
 4485  * @a:      attribute record to resize
 4486  * @new_size:   new size in bytes to which to resize the attribute record @a
 4487  *
 4488  * Resize the attribute record @a, i.e. the resident part of the attribute, in
 4489  * the mft record @m to @new_size bytes.
 4490  *
 4491  * Return 0 on success and -1 on error with errno set to the error code.
 4492  * The following error codes are defined:
 4493  *  ENOSPC  - Not enough space in the mft record @m to perform the resize.
 4494  * Note that on error no modifications have been performed whatsoever.
 4495  *
 4496  * Warning: If you make a record smaller without having copied all the data you
 4497  *      are interested in the data may be overwritten!
 4498  */
 4499 int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size)
 4500 {
 4501     u32 old_size, alloc_size, attr_size;
 4502     
 4503     old_size   = le32_to_cpu(m->bytes_in_use);
 4504     alloc_size = le32_to_cpu(m->bytes_allocated);
 4505     attr_size  = le32_to_cpu(a->length);
 4506     
 4507     ntfs_log_trace("Sizes: old=%u alloc=%u attr=%u new=%u\n", 
 4508                (unsigned)old_size, (unsigned)alloc_size, 
 4509                (unsigned)attr_size, (unsigned)new_size);
 4510 
 4511     /* Align to 8 bytes, just in case the caller hasn't. */
 4512     new_size = (new_size + 7) & ~7;
 4513     
 4514     /* If the actual attribute length has changed, move things around. */
 4515     if (new_size != attr_size) {
 4516         
 4517         u32 new_muse = old_size - attr_size + new_size;
 4518         
 4519         /* Not enough space in this mft record. */
 4520         if (new_muse > alloc_size) {
 4521             errno = ENOSPC;
 4522             ntfs_log_trace("Not enough space in the MFT record "
 4523                        "(%u > %u)\n", new_muse, alloc_size);
 4524             return -1;
 4525         }
 4526 
 4527         if (a->type == AT_INDEX_ROOT && new_size > attr_size &&
 4528             new_muse + 120 > alloc_size && old_size + 120 <= alloc_size) {
 4529             errno = ENOSPC;
 4530             ntfs_log_trace("Too big INDEX_ROOT (%u > %u)\n",
 4531                     new_muse, alloc_size);
 4532             return STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT;
 4533         }
 4534         
 4535         /* Move attributes following @a to their new location. */
 4536         memmove((u8 *)a + new_size, (u8 *)a + attr_size,
 4537             old_size - ((u8 *)a - (u8 *)m) - attr_size);
 4538         
 4539         /* Adjust @m to reflect the change in used space. */
 4540         m->bytes_in_use = cpu_to_le32(new_muse);
 4541         
 4542         /* Adjust @a to reflect the new size. */
 4543         if (new_size >= offsetof(ATTR_REC, length) + sizeof(a->length))
 4544             a->length = cpu_to_le32(new_size);
 4545     }
 4546     return 0;
 4547 }
 4548 
 4549 /**
 4550  * ntfs_resident_attr_value_resize - resize the value of a resident attribute
 4551  * @m:      mft record containing attribute record
 4552  * @a:      attribute record whose value to resize
 4553  * @new_size:   new size in bytes to which to resize the attribute value of @a
 4554  *
 4555  * Resize the value of the attribute @a in the mft record @m to @new_size bytes.
 4556  * If the value is made bigger, the newly "allocated" space is cleared.
 4557  *
 4558  * Return 0 on success and -1 on error with errno set to the error code.
 4559  * The following error codes are defined:
 4560  *  ENOSPC  - Not enough space in the mft record @m to perform the resize.
 4561  * Note that on error no modifications have been performed whatsoever.
 4562  */
 4563 int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
 4564         const u32 new_size)
 4565 {
 4566     int ret;
 4567     
 4568     ntfs_log_trace("Entering for new size %u.\n", (unsigned)new_size);
 4569 
 4570     /* Resize the resident part of the attribute record. */
 4571     if ((ret = ntfs_attr_record_resize(m, a, (le16_to_cpu(a->value_offset) +
 4572             new_size + 7) & ~7)) < 0)
 4573         return ret;
 4574     /*
 4575      * If we made the attribute value bigger, clear the area between the
 4576      * old size and @new_size.
 4577      */
 4578     if (new_size > le32_to_cpu(a->value_length))
 4579         memset((u8*)a + le16_to_cpu(a->value_offset) +
 4580                 le32_to_cpu(a->value_length), 0, new_size -
 4581                 le32_to_cpu(a->value_length));
 4582     /* Finally update the length of the attribute value. */
 4583     a->value_length = cpu_to_le32(new_size);
 4584     return 0;
 4585 }
 4586 
 4587 /**
 4588  * ntfs_attr_record_move_to - move attribute record to target inode
 4589  * @ctx:    attribute search context describing the attribute record
 4590  * @ni:     opened ntfs inode to which move attribute record
 4591  *
 4592  * If this function succeed, user should reinit search context if he/she wants
 4593  * use it anymore.
 4594  *
 4595  * Return 0 on success and -1 on error with errno set to the error code.
 4596  */
 4597 int ntfs_attr_record_move_to(ntfs_attr_search_ctx *ctx, ntfs_inode *ni)
 4598 {
 4599     ntfs_attr_search_ctx *nctx;
 4600     ATTR_RECORD *a;
 4601     int err;
 4602 
 4603     if (!ctx || !ctx->attr || !ctx->ntfs_ino || !ni) {
 4604         ntfs_log_trace("Invalid arguments passed.\n");
 4605         errno = EINVAL;
 4606         return -1;
 4607     }
 4608 
 4609     ntfs_log_trace("Entering for ctx->attr->type 0x%x, ctx->ntfs_ino->mft_no "
 4610             "0x%llx, ni->mft_no 0x%llx.\n",
 4611             (unsigned) le32_to_cpu(ctx->attr->type),
 4612             (long long) ctx->ntfs_ino->mft_no,
 4613             (long long) ni->mft_no);
 4614 
 4615     if (ctx->ntfs_ino == ni)
 4616         return 0;
 4617 
 4618     if (!ctx->al_entry) {
 4619         ntfs_log_trace("Inode should contain attribute list to use this "
 4620                 "function.\n");
 4621         errno = EINVAL;
 4622         return -1;
 4623     }
 4624 
 4625     /* Find place in MFT record where attribute will be moved. */
 4626     a = ctx->attr;
 4627     nctx = ntfs_attr_get_search_ctx(ni, NULL);
 4628     if (!nctx)
 4629         return -1;
 4630 
 4631     /*
 4632      * Use ntfs_attr_find instead of ntfs_attr_lookup to find place for
 4633      * attribute in @ni->mrec, not any extent inode in case if @ni is base
 4634      * file record.
 4635      */
 4636     if (!ntfs_attr_find(a->type, (ntfschar*)((u8*)a + le16_to_cpu(
 4637             a->name_offset)), a->name_length, CASE_SENSITIVE, NULL,
 4638             0, nctx)) {
 4639         ntfs_log_trace("Attribute of such type, with same name already "
 4640                 "present in this MFT record.\n");
 4641         err = EEXIST;
 4642         goto put_err_out;
 4643     }
 4644     if (errno != ENOENT) {
 4645         err = errno;
 4646         ntfs_log_debug("Attribute lookup failed.\n");
 4647         goto put_err_out;
 4648     }
 4649 
 4650     /* Make space and move attribute. */
 4651     if (ntfs_make_room_for_attr(ni->mrec, (u8*) nctx->attr,
 4652                     le32_to_cpu(a->length))) {
 4653         err = errno;
 4654         ntfs_log_trace("Couldn't make space for attribute.\n");
 4655         goto put_err_out;
 4656     }
 4657     memcpy(nctx->attr, a, le32_to_cpu(a->length));
 4658     nctx->attr->instance = nctx->mrec->next_attr_instance;
 4659     nctx->mrec->next_attr_instance = cpu_to_le16(
 4660         (le16_to_cpu(nctx->mrec->next_attr_instance) + 1) & 0xffff);
 4661     ntfs_attr_record_resize(ctx->mrec, a, 0);
 4662     ntfs_inode_mark_dirty(ctx->ntfs_ino);
 4663     ntfs_inode_mark_dirty(ni);
 4664 
 4665     /* Update attribute list. */
 4666     ctx->al_entry->mft_reference =
 4667         MK_LE_MREF(ni->mft_no, le16_to_cpu(ni->mrec->sequence_number));
 4668     ctx->al_entry->instance = nctx->attr->instance;
 4669     ntfs_attrlist_mark_dirty(ni);
 4670 
 4671     ntfs_attr_put_search_ctx(nctx);
 4672     return 0;
 4673 put_err_out:
 4674     ntfs_attr_put_search_ctx(nctx);
 4675     errno = err;
 4676     return -1;
 4677 }
 4678 
 4679 /**
 4680  * ntfs_attr_record_move_away - move away attribute record from it's mft record
 4681  * @ctx:    attribute search context describing the attribute record
 4682  * @extra:  minimum amount of free space in the new holder of record
 4683  *
 4684  * New attribute record holder must have free @extra bytes after moving
 4685  * attribute record to it.
 4686  *
 4687  * If this function succeed, user should reinit search context if he/she wants
 4688  * use it anymore.
 4689  *
 4690  * Return 0 on success and -1 on error with errno set to the error code.
 4691  */
 4692 int ntfs_attr_record_move_away(ntfs_attr_search_ctx *ctx, int extra)
 4693 {
 4694     ntfs_inode *base_ni, *ni;
 4695     MFT_RECORD *m;
 4696     int i;
 4697 
 4698     if (!ctx || !ctx->attr || !ctx->ntfs_ino || extra < 0) {
 4699         errno = EINVAL;
 4700         ntfs_log_perror("%s: ctx=%p ctx->attr=%p extra=%d", __FUNCTION__,
 4701                 ctx, ctx ? ctx->attr : NULL, extra);
 4702         return -1;
 4703     }
 4704 
 4705     ntfs_log_trace("Entering for attr 0x%x, inode %llu\n",
 4706             (unsigned) le32_to_cpu(ctx->attr->type),
 4707             (unsigned long long)ctx->ntfs_ino->mft_no);
 4708 
 4709     if (ctx->ntfs_ino->nr_extents == -1)
 4710         base_ni = ctx->base_ntfs_ino;
 4711     else
 4712         base_ni = ctx->ntfs_ino;
 4713 
 4714     if (!NInoAttrList(base_ni)) {
 4715         errno = EINVAL;
 4716         ntfs_log_perror("Inode %llu has no attrlist", 
 4717                 (unsigned long long)base_ni->mft_no);
 4718         return -1;
 4719     }
 4720 
 4721     if (ntfs_inode_attach_all_extents(ctx->ntfs_ino)) {
 4722         ntfs_log_perror("Couldn't attach extents, inode=%llu", 
 4723                 (unsigned long long)base_ni->mft_no);
 4724         return -1;
 4725     }
 4726 
 4727     /* Walk through all extents and try to move attribute to them. */
 4728     for (i = 0; i < base_ni->nr_extents; i++) {
 4729         ni = base_ni->extent_nis[i];
 4730         m = ni->mrec;
 4731 
 4732         if (ctx->ntfs_ino->mft_no == ni->mft_no)
 4733             continue;
 4734 
 4735         if (le32_to_cpu(m->bytes_allocated) -
 4736                 le32_to_cpu(m->bytes_in_use) <
 4737                 le32_to_cpu(ctx->attr->length) + extra)
 4738             continue;
 4739 
 4740         /*
 4741          * ntfs_attr_record_move_to can fail if extent with other lowest
 4742          * VCN already present in inode we trying move record to. So,
 4743          * do not return error.
 4744          */
 4745         if (!ntfs_attr_record_move_to(ctx, ni))
 4746             return 0;
 4747     }
 4748 
 4749     /*
 4750      * Failed to move attribute to one of the current extents, so allocate
 4751      * new extent and move attribute to it.
 4752      */
 4753     ni = ntfs_mft_record_alloc(base_ni->vol, base_ni);
 4754     if (!ni) {
 4755         ntfs_log_perror("Couldn't allocate MFT record");
 4756         return -1;
 4757     }
 4758     if (ntfs_attr_record_move_to(ctx, ni)) {
 4759         ntfs_log_perror("Couldn't move attribute to MFT record");
 4760         return -1;
 4761     }
 4762     return 0;
 4763 }
 4764 
 4765 /**
 4766  * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute
 4767  * @na:     open ntfs attribute to make non-resident
 4768  * @ctx:    ntfs search context describing the attribute
 4769  *
 4770  * Convert a resident ntfs attribute to a non-resident one.
 4771  *
 4772  * Return 0 on success and -1 on error with errno set to the error code. The
 4773  * following error codes are defined:
 4774  *  EPERM   - The attribute is not allowed to be non-resident.
 4775  *  TODO: others...
 4776  *
 4777  * NOTE to self: No changes in the attribute list are required to move from
 4778  *       a resident to a non-resident attribute.
 4779  *
 4780  * Warning: We do not set the inode dirty and we do not write out anything!
 4781  *      We expect the caller to do this as this is a fairly low level
 4782  *      function and it is likely there will be further changes made.
 4783  */
 4784 int ntfs_attr_make_non_resident(ntfs_attr *na,
 4785         ntfs_attr_search_ctx *ctx)
 4786 {
 4787     s64 new_allocated_size, bw;
 4788     ntfs_volume *vol = na->ni->vol;
 4789     ATTR_REC *a = ctx->attr;
 4790     runlist *rl;
 4791     int mp_size, mp_ofs, name_ofs, arec_size, err;
 4792 
 4793     ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x.\n", (unsigned long
 4794             long)na->ni->mft_no, le32_to_cpu(na->type));
 4795 
 4796     /* Some preliminary sanity checking. */
 4797     if (NAttrNonResident(na)) {
 4798         ntfs_log_trace("Eeek!  Trying to make non-resident attribute "
 4799                 "non-resident.  Aborting...\n");
 4800         errno = EINVAL;
 4801         return -1;
 4802     }
 4803 
 4804     /* Check that the attribute is allowed to be non-resident. */
 4805     if (ntfs_attr_can_be_non_resident(vol, na->type, na->name, na->name_len))
 4806         return -1;
 4807 
 4808     new_allocated_size = (le32_to_cpu(a->value_length) + vol->cluster_size
 4809             - 1) & ~(vol->cluster_size - 1);
 4810 
 4811     if (new_allocated_size > 0) {
 4812             if ((a->flags & ATTR_COMPRESSION_MASK)
 4813                     == ATTR_IS_COMPRESSED) {
 4814                 /* must allocate full compression blocks */
 4815                 new_allocated_size = ((new_allocated_size - 1)
 4816                     | ((1L << (STANDARD_COMPRESSION_UNIT
 4817                        + vol->cluster_size_bits)) - 1)) + 1;
 4818             }
 4819         /* Start by allocating clusters to hold the attribute value. */
 4820         rl = ntfs_cluster_alloc(vol, 0, new_allocated_size >>
 4821                 vol->cluster_size_bits, -1, DATA_ZONE);
 4822         if (!rl)
 4823             return -1;
 4824     } else
 4825         rl = NULL;
 4826     /*
 4827      * Setup the in-memory attribute structure to be non-resident so that
 4828      * we can use ntfs_attr_pwrite().
 4829      */
 4830     NAttrSetNonResident(na);
 4831     NAttrSetBeingNonResident(na);
 4832     na->rl = rl;
 4833     na->allocated_size = new_allocated_size;
 4834     na->data_size = na->initialized_size = le32_to_cpu(a->value_length);
 4835     /*
 4836      * FIXME: For now just clear all of these as we don't support them when
 4837      * writing.
 4838      */
 4839     NAttrClearSparse(na);
 4840     NAttrClearEncrypted(na);
 4841     if ((a->flags & ATTR_COMPRESSION_MASK) == ATTR_IS_COMPRESSED) {
 4842             /* set compression writing parameters */
 4843         na->compression_block_size
 4844             = 1 << (STANDARD_COMPRESSION_UNIT + vol->cluster_size_bits);
 4845         na->compression_block_clusters = 1 << STANDARD_COMPRESSION_UNIT;
 4846     }
 4847 
 4848     if (rl) {
 4849         /* Now copy the attribute value to the allocated cluster(s). */
 4850         bw = ntfs_attr_pwrite(na, 0, le32_to_cpu(a->value_length),
 4851                 (u8*)a + le16_to_cpu(a->value_offset));
 4852         if (bw != le32_to_cpu(a->value_length)) {
 4853             err = errno;
 4854             ntfs_log_debug("Eeek!  Failed to write out attribute value "
 4855                     "(bw = %lli, errno = %i).  "
 4856                     "Aborting...\n", (long long)bw, err);
 4857             if (bw >= 0)
 4858                 err = EIO;
 4859             goto cluster_free_err_out;
 4860         }
 4861     }
 4862     /* Determine the size of the mapping pairs array. */
 4863     mp_size = ntfs_get_size_for_mapping_pairs(vol, rl, 0, INT_MAX);
 4864     if (mp_size < 0) {
 4865         err = errno;
 4866         ntfs_log_debug("Eeek!  Failed to get size for mapping pairs array.  "
 4867                 "Aborting...\n");
 4868         goto cluster_free_err_out;
 4869     }
 4870     /* Calculate new offsets for the name and the mapping pairs array. */
 4871     if (na->ni->flags & FILE_ATTR_COMPRESSED)
 4872         name_ofs = (sizeof(ATTR_REC) + 7) & ~7;
 4873     else
 4874         name_ofs = (sizeof(ATTR_REC) - sizeof(a->compressed_size) + 7) & ~7;
 4875     mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
 4876     /*
 4877      * Determine the size of the resident part of the non-resident
 4878      * attribute record. (Not compressed thus no compressed_size element
 4879      * present.)
 4880      */
 4881     arec_size = (mp_ofs + mp_size + 7) & ~7;
 4882 
 4883     /* Resize the resident part of the attribute record. */
 4884     if (ntfs_attr_record_resize(ctx->mrec, a, arec_size) < 0) {
 4885         err = errno;
 4886         goto cluster_free_err_out;
 4887     }
 4888 
 4889     /*
 4890      * Convert the resident part of the attribute record to describe a
 4891      * non-resident attribute.
 4892      */
 4893     a->non_resident = 1;
 4894 
 4895     /* Move the attribute name if it exists and update the offset. */
 4896     if (a->name_length)
 4897         memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
 4898                 a->name_length * sizeof(ntfschar));
 4899     a->name_offset = cpu_to_le16(name_ofs);
 4900 
 4901     /* Setup the fields specific to non-resident attributes. */
 4902     a->lowest_vcn = const_cpu_to_sle64(0);
 4903     a->highest_vcn = cpu_to_sle64((new_allocated_size - 1) >>
 4904                         vol->cluster_size_bits);
 4905 
 4906     a->mapping_pairs_offset = cpu_to_le16(mp_ofs);
 4907 
 4908     /*
 4909      * Update the flags to match the in-memory ones.
 4910      * However cannot change the compression state if we had
 4911      * a fuse_file_info open with a mark for release.
 4912      * The decisions about compression can only be made when
 4913      * creating/recreating the stream, not when making non resident.
 4914      */
 4915     a->flags &= ~(ATTR_IS_SPARSE | ATTR_IS_ENCRYPTED);
 4916     if ((a->flags & ATTR_COMPRESSION_MASK) == ATTR_IS_COMPRESSED) {
 4917             /* support only ATTR_IS_COMPRESSED compression mode */
 4918         a->compression_unit = STANDARD_COMPRESSION_UNIT;
 4919         a->compressed_size = const_cpu_to_sle64(0);
 4920     } else {
 4921         a->compression_unit = 0;
 4922         a->flags &= ~ATTR_COMPRESSION_MASK;
 4923         na->data_flags = a->flags;
 4924     }
 4925 
 4926     memset(&a->reserved1, 0, sizeof(a->reserved1));
 4927 
 4928     a->allocated_size = cpu_to_sle64(new_allocated_size);
 4929     a->data_size = a->initialized_size = cpu_to_sle64(na->data_size);
 4930 
 4931     /* Generate the mapping pairs array in the attribute record. */
 4932     if (ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs, arec_size - mp_ofs,
 4933             rl, 0, NULL) < 0) {
 4934         // FIXME: Eeek! We need rollback! (AIA)
 4935         ntfs_log_trace("Eeek!  Failed to build mapping pairs.  Leaving "
 4936                 "corrupt attribute record on disk.  In memory "
 4937                 "runlist is still intact!  Error code is %i.  "
 4938                 "FIXME:  Need to rollback instead!\n", errno);
 4939         return -1;
 4940     }
 4941 
 4942     /* Done! */
 4943     return 0;
 4944 
 4945 cluster_free_err_out:
 4946     if (rl && ntfs_cluster_free(vol, na, 0, -1) < 0)
 4947         ntfs_log_trace("Eeek!  Failed to release allocated clusters in error "
 4948                 "code path.  Leaving inconsistent metadata...\n");
 4949     NAttrClearNonResident(na);
 4950     NAttrClearFullyMapped(na);
 4951     na->allocated_size = na->data_size;
 4952     na->rl = NULL;
 4953     free(rl);
 4954     errno = err;
 4955     return -1;
 4956 }
 4957 
 4958 
 4959 static int ntfs_resident_attr_resize(ntfs_attr *na, const s64 newsize);
 4960 
 4961 /**
 4962  * ntfs_resident_attr_resize - resize a resident, open ntfs attribute
 4963  * @na:     resident ntfs attribute to resize
 4964  * @newsize:    new size (in bytes) to which to resize the attribute
 4965  *
 4966  * Change the size of a resident, open ntfs attribute @na to @newsize bytes.
 4967  * Can also be used to force an attribute non-resident. In this case, the
 4968  * size cannot be changed.
 4969  *
 4970  * On success return 0 
 4971  * On error return values are:
 4972  *  STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT
 4973  *  STATUS_ERROR - otherwise
 4974  * The following error codes are defined:
 4975  *  ENOMEM - Not enough memory to complete operation.
 4976  *  ERANGE - @newsize is not valid for the attribute type of @na.
 4977  *  ENOSPC - There is no enough space in base mft to resize $ATTRIBUTE_LIST.
 4978  */
 4979 static int ntfs_resident_attr_resize_i(ntfs_attr *na, const s64 newsize,
 4980             hole_type holes)
 4981 {
 4982     ntfs_attr_search_ctx *ctx;
 4983     ntfs_volume *vol;
 4984     ntfs_inode *ni;
 4985     int err, ret = STATUS_ERROR;
 4986 
 4987     ntfs_log_trace("Inode 0x%llx attr 0x%x new size %lld\n", 
 4988                (unsigned long long)na->ni->mft_no, le32_to_cpu(na->type),
 4989                (long long)newsize);
 4990 
 4991     /* Get the attribute record that needs modification. */
 4992     ctx = ntfs_attr_get_search_ctx(na->ni, NULL);
 4993     if (!ctx)
 4994         return -1;
 4995     if (ntfs_attr_lookup(na->type, na->name, na->name_len, 0, 0, NULL, 0,
 4996             ctx)) {
 4997         err = errno;
 4998         ntfs_log_perror("ntfs_attr_lookup failed");
 4999         goto put_err_out;
 5000     }
 5001     vol = na->ni->vol;
 5002     /*
 5003      * Check the attribute type and the corresponding minimum and maximum
 5004      * sizes against @newsize and fail if @newsize is out of bounds.
 5005      */
 5006     if (ntfs_attr_size_bounds_check(vol, na->type, newsize) < 0) {
 5007         err = errno;
 5008         if (err == ENOENT)
 5009             err = EIO;
 5010         ntfs_log_perror("%s: bounds check failed", __FUNCTION__);
 5011         goto put_err_out;
 5012     }
 5013     /*
 5014      * If @newsize is bigger than the mft record we need to make the
 5015      * attribute non-resident if the attribute type supports it. If it is
 5016      * smaller we can go ahead and attempt the resize.
 5017      */
 5018     if ((newsize < vol->mft_record_size) && (holes != HOLES_NONRES)) {
 5019         /* Perform the resize of the attribute record. */
 5020         if (!(ret = ntfs_resident_attr_value_resize(ctx->mrec, ctx->attr,
 5021                 newsize))) {
 5022             /* Update attribute size everywhere. */
 5023             na->data_size = na->initialized_size = newsize;
 5024             na->allocated_size = (newsize + 7) & ~7;
 5025             if ((na->data_flags & ATTR_COMPRESSION_MASK)
 5026                 || NAttrSparse(na))
 5027                 na->compressed_size = na->allocated_size;
 5028             if (na->ni->mrec->flags & MFT_RECORD_IS_DIRECTORY
 5029                 ? na->type == AT_INDEX_ROOT && na->name == NTFS_INDEX_I30
 5030                 : na->type == AT_DATA && na->name == AT_UNNAMED) {
 5031                 na->ni->data_size = na->data_size;
 5032                 if (((na->data_flags & ATTR_COMPRESSION_MASK)
 5033                     || NAttrSparse(na))
 5034                         && NAttrNonResident(na))
 5035                     na->ni->allocated_size
 5036                         = na->compressed_size;
 5037                 else
 5038                     na->ni->allocated_size
 5039                         = na->allocated_size;
 5040                 set_nino_flag(na->ni,KnownSize);
 5041                 if (na->type == AT_DATA)
 5042                     NInoFileNameSetDirty(na->ni);
 5043             }
 5044             goto resize_done;
 5045         }
 5046         /* Prefer AT_INDEX_ALLOCATION instead of AT_ATTRIBUTE_LIST */
 5047         if (ret == STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT) {
 5048             err = errno;
 5049             goto put_err_out;
 5050         }
 5051     }
 5052     /* There is not enough space in the mft record to perform the resize. */
 5053 
 5054     /* Make the attribute non-resident if possible. */
 5055     if (!ntfs_attr_make_non_resident(na, ctx)) {
 5056         ntfs_inode_mark_dirty(ctx->ntfs_ino);
 5057         ntfs_attr_put_search_ctx(ctx);
 5058         /*
 5059          * do not truncate when forcing non-resident, this
 5060          * could cause the attribute to be made resident again,
 5061          * so size changes are not allowed.
 5062          */
 5063         if (holes == HOLES_NONRES) {
 5064             ret = 0;
 5065             if (newsize != na->data_size) {
 5066                 ntfs_log_error("Cannot change size when"
 5067                     " forcing non-resident\n");
 5068                 errno = EIO;
 5069                 ret = STATUS_ERROR;
 5070             }
 5071             return (ret);
 5072         }
 5073         /* Resize non-resident attribute */
 5074         return ntfs_attr_truncate_i(na, newsize, holes);
 5075     } else if (errno != ENOSPC && errno != EPERM) {
 5076         err = errno;
 5077         ntfs_log_perror("Failed to make attribute non-resident");
 5078         goto put_err_out;
 5079     }
 5080 
 5081     /* Try to make other attributes non-resident and retry each time. */
 5082     ntfs_attr_init_search_ctx(ctx, NULL, na->ni->mrec);
 5083     while (!ntfs_attr_lookup(AT_UNUSED, NULL, 0, 0, 0, NULL, 0, ctx)) {
 5084         ntfs_attr *tna;
 5085         ATTR_RECORD *a;
 5086 
 5087         a = ctx->attr;
 5088         if (a->non_resident)
 5089             continue;
 5090 
 5091         /*
 5092          * Check out whether convert is reasonable. Assume that mapping
 5093          * pairs will take 8 bytes.
 5094          */
 5095         if (le32_to_cpu(a->length) <= offsetof(ATTR_RECORD,
 5096                 compressed_size) + ((a->name_length *
 5097                 sizeof(ntfschar) + 7) & ~7) + 8)
 5098             continue;
 5099 
 5100         tna = ntfs_attr_open(na->ni, a->type, (ntfschar*)((u8*)a +
 5101                 le16_to_cpu(a->name_offset)), a->name_length);
 5102         if (!tna) {
 5103             err = errno;
 5104             ntfs_log_perror("Couldn't open attribute");
 5105             goto put_err_out;
 5106         }
 5107         if (ntfs_attr_make_non_resident(tna, ctx)) {
 5108             ntfs_attr_close(tna);
 5109             continue;
 5110         }
 5111         if ((tna->type == AT_DATA) && !tna->name_len) {
 5112             /*
 5113              * If we had to make the unnamed data attribute
 5114              * non-resident, propagate its new allocated size
 5115              * to all name attributes and directory indexes
 5116              */
 5117             tna->ni->allocated_size = tna->allocated_size;
 5118             NInoFileNameSetDirty(tna->ni);
 5119         }
 5120         if (((tna->data_flags & ATTR_COMPRESSION_MASK)
 5121                         == ATTR_IS_COMPRESSED)
 5122            && ntfs_attr_pclose(tna)) {
 5123             err = errno;
 5124             ntfs_attr_close(tna);
 5125             goto put_err_out;
 5126         }
 5127         ntfs_inode_mark_dirty(tna->ni);
 5128         ntfs_attr_close(tna);
 5129         ntfs_attr_put_search_ctx(ctx);
 5130         return ntfs_resident_attr_resize_i(na, newsize, holes);
 5131     }
 5132     /* Check whether error occurred. */
 5133     if (errno != ENOENT) {
 5134         err = errno;
 5135         ntfs_log_perror("%s: Attribute lookup failed 1", __FUNCTION__);
 5136         goto put_err_out;
 5137     }
 5138     
 5139     /* 
 5140      * The standard information and attribute list attributes can't be
 5141      * moved out from the base MFT record, so try to move out others. 
 5142      */
 5143     if (na->type==AT_STANDARD_INFORMATION || na->type==AT_ATTRIBUTE_LIST) {
 5144         ntfs_attr_put_search_ctx(ctx);
 5145         if (!NInoAttrList(na->ni) && ntfs_inode_add_attrlist(na->ni)) {
 5146             ntfs_log_perror("Could not add attribute list");
 5147             return -1;
 5148         }
 5149         if (ntfs_inode_free_space(na->ni, offsetof(ATTR_RECORD,
 5150                 non_resident_end) + 8)) {
 5151             ntfs_log_perror("Could not free space in MFT record");
 5152             return -1;
 5153         }
 5154         return ntfs_resident_attr_resize_i(na, newsize, holes);
 5155     }
 5156 
 5157     /*
 5158      * Move the attribute to a new mft record, creating an attribute list
 5159      * attribute or modifying it if it is already present.
 5160      */
 5161 
 5162     /* Point search context back to attribute which we need resize. */
 5163     ntfs_attr_init_search_ctx(ctx, na->ni, NULL);
 5164     if (ntfs_attr_lookup(na->type, na->name, na->name_len, CASE_SENSITIVE,
 5165             0, NULL, 0, ctx)) {
 5166         ntfs_log_perror("%s: Attribute lookup failed 2", __FUNCTION__);
 5167         err = errno;
 5168         goto put_err_out;
 5169     }
 5170 
 5171     /*
 5172      * Check whether attribute is already single in this MFT record.
 5173      * 8 added for the attribute terminator.
 5174      */
 5175     if (le32_to_cpu(ctx->mrec->bytes_in_use) ==
 5176             le16_to_cpu(ctx->mrec->attrs_offset) +
 5177             le32_to_cpu(ctx->attr->length) + 8) {
 5178         err = ENOSPC;
 5179         ntfs_log_trace("MFT record is filled with one attribute\n");
 5180         ret = STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT;
 5181         goto put_err_out;
 5182     }
 5183 
 5184     /* Add attribute list if not present. */
 5185     if (na->ni->nr_extents == -1)
 5186         ni = na->ni->base_ni;
 5187     else
 5188         ni = na->ni;
 5189     if (!NInoAttrList(ni)) {
 5190         ntfs_attr_put_search_ctx(ctx);
 5191         if (ntfs_inode_add_attrlist(ni))
 5192             return -1;
 5193         return ntfs_resident_attr_resize_i(na, newsize, holes);
 5194     }
 5195     /* Allocate new mft record. */
 5196     ni = ntfs_mft_record_alloc(vol, ni);
 5197     if (!ni) {
 5198         err = errno;
 5199         ntfs_log_perror("Couldn't allocate new MFT record");
 5200         goto put_err_out;
 5201     }
 5202     /* Move attribute to it. */
 5203     if (ntfs_attr_record_move_to(ctx, ni)) {
 5204         err = errno;
 5205         ntfs_log_perror("Couldn't move attribute to new MFT record");
 5206         goto put_err_out;
 5207     }
 5208     /* Update ntfs attribute. */
 5209     if (na->ni->nr_extents == -1)
 5210         na->ni = ni;
 5211 
 5212     ntfs_attr_put_search_ctx(ctx);
 5213     /* Try to perform resize once again. */
 5214     return ntfs_resident_attr_resize_i(na, newsize, holes);
 5215 
 5216 resize_done:
 5217     /*
 5218      * Set the inode (and its base inode if it exists) dirty so it is
 5219      * written out later.
 5220      */
 5221     ntfs_inode_mark_dirty(ctx->ntfs_ino);
 5222     ntfs_attr_put_search_ctx(ctx);
 5223     return 0;
 5224 put_err_out:
 5225     ntfs_attr_put_search_ctx(ctx);
 5226     errno = err;
 5227     return ret;
 5228 }
 5229 
 5230 static int ntfs_resident_attr_resize(ntfs_attr *na, const s64 newsize)
 5231 {
 5232     int ret; 
 5233     
 5234     ntfs_log_enter("Entering\n");
 5235     ret = ntfs_resident_attr_resize_i(na, newsize, HOLES_OK);
 5236     ntfs_log_leave("\n");
 5237     return ret;
 5238 }
 5239 
 5240 /*
 5241  *      Force an attribute to be made non-resident without
 5242  *  changing its size.
 5243  *
 5244  *  This is particularly needed when the attribute has no data,
 5245  *  as the non-resident variant requires more space in the MFT
 5246  *  record, and may imply expelling some other attribute.
 5247  *
 5248  *  As a consequence the existing ntfs_attr_search_ctx's have to
 5249  *  be closed or reinitialized.
 5250  *
 5251  *  returns 0 if successful,
 5252  *      < 0 if failed, with errno telling why
 5253  */
 5254 
 5255 int ntfs_attr_force_non_resident(ntfs_attr *na)
 5256 {
 5257     int res;
 5258 
 5259     res = ntfs_resident_attr_resize_i(na, na->data_size, HOLES_NONRES);
 5260     if (!res && !NAttrNonResident(na)) {
 5261         res = -1;
 5262         errno = EIO;
 5263         ntfs_log_error("Failed to force non-resident\n");
 5264     }
 5265     return (res);
 5266 }
 5267 
 5268 /**
 5269  * ntfs_attr_make_resident - convert a non-resident to a resident attribute
 5270  * @na:     open ntfs attribute to make resident
 5271  * @ctx:    ntfs search context describing the attribute
 5272  *
 5273  * Convert a non-resident ntfs attribute to a resident one.
 5274  *
 5275  * Return 0 on success and -1 on error with errno set to the error code. The
 5276  * following error codes are defined:
 5277  *  EINVAL     - Invalid arguments passed.
 5278  *  EPERM      - The attribute is not allowed to be resident.
 5279  *  EIO    - I/O error, damaged inode or bug.
 5280  *  ENOSPC     - There is no enough space to perform conversion.
 5281  *  EOPNOTSUPP - Requested conversion is not supported yet.
 5282  *
 5283  * Warning: We do not set the inode dirty and we do not write out anything!
 5284  *      We expect the caller to do this as this is a fairly low level
 5285  *      function and it is likely there will be further changes made.
 5286  */
 5287 static int ntfs_attr_make_resident(ntfs_attr *na, ntfs_attr_search_ctx *ctx)
 5288 {
 5289     ntfs_volume *vol = na->ni->vol;
 5290     ATTR_REC *a = ctx->attr;
 5291     int name_ofs, val_ofs, err = EIO;
 5292     s64 arec_size, bytes_read;
 5293 
 5294     ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x.\n", (unsigned long
 5295             long)na->ni->mft_no, le32_to_cpu(na->type));
 5296 
 5297     /* Should be called for the first extent of the attribute. */
 5298     if (sle64_to_cpu(a->lowest_vcn)) {
 5299         ntfs_log_trace("Eeek!  Should be called for the first extent of the "
 5300                 "attribute.  Aborting...\n");
 5301         errno = EINVAL;
 5302         return -1;
 5303     }
 5304 
 5305     /* Some preliminary sanity checking. */
 5306     if (!NAttrNonResident(na)) {
 5307         ntfs_log_trace("Eeek!  Trying to make resident attribute resident.  "
 5308                 "Aborting...\n");
 5309         errno = EINVAL;
 5310         return -1;
 5311     }
 5312 
 5313     /* Make sure this is not $MFT/$BITMAP or Windows will not boot! */
 5314     if (na->type == AT_BITMAP && na->ni->mft_no == FILE_MFT) {
 5315         errno = EPERM;
 5316         return -1;
 5317     }
 5318 
 5319     /* Check that the attribute is allowed to be resident. */
 5320     if (ntfs_attr_can_be_resident(vol, na->type))
 5321         return -1;
 5322 
 5323     if (na->data_flags & ATTR_IS_ENCRYPTED) {
 5324         ntfs_log_trace("Making encrypted streams resident is not "
 5325                 "implemented yet.\n");
 5326         errno = EOPNOTSUPP;
 5327         return -1;
 5328     }
 5329 
 5330     /* Work out offsets into and size of the resident attribute. */
 5331     name_ofs = 24; /* = sizeof(resident_ATTR_REC); */
 5332     val_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7;
 5333     arec_size = (val_ofs + na->data_size + 7) & ~7;
 5334 
 5335     /* Sanity check the size before we start modifying the attribute. */
 5336     if (le32_to_cpu(ctx->mrec->bytes_in_use) - le32_to_cpu(a->length) +
 5337             arec_size > le32_to_cpu(ctx->mrec->bytes_allocated)) {
 5338         errno = ENOSPC;
 5339         ntfs_log_trace("Not enough space to make attribute resident\n");
 5340         return -1;
 5341     }
 5342 
 5343     /* Read and cache the whole runlist if not already done. */
 5344     if (ntfs_attr_map_whole_runlist(na))
 5345         return -1;
 5346 
 5347     /* Move the attribute name if it exists and update the offset. */
 5348     if (a->name_length) {
 5349         memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset),
 5350                 a->name_length * sizeof(ntfschar));
 5351     }
 5352     a->name_offset = cpu_to_le16(name_ofs);
 5353 
 5354     /* Resize the resident part of the attribute record. */
 5355     if (ntfs_attr_record_resize(ctx->mrec, a, arec_size) < 0) {
 5356         /*
 5357          * Bug, because ntfs_attr_record_resize should not fail (we
 5358          * already checked that attribute fits MFT record).
 5359          */
 5360         ntfs_log_error("BUG! Failed to resize attribute record. "
 5361                 "Please report to the %s.  Aborting...\n",
 5362                 NTFS_DEV_LIST);
 5363         errno = EIO;
 5364         return -1;
 5365     }
 5366 
 5367     /* Convert the attribute record to describe a resident attribute. */
 5368     a->non_resident = 0;
 5369     a->flags = const_cpu_to_le16(0);
 5370     a->value_length = cpu_to_le32(na->data_size);
 5371     a->value_offset = cpu_to_le16(val_ofs);
 5372     /*
 5373      *  If a data stream was wiped out, adjust the compression mode
 5374      *  to current state of compression flag
 5375      */
 5376     if (!na->data_size
 5377         && (na->type == AT_DATA)
 5378         && (na->ni->vol->major_ver >= 3)
 5379         && NVolCompression(na->ni->vol)
 5380         && (na->ni->vol->cluster_size <= MAX_COMPRESSION_CLUSTER_SIZE)
 5381         && (na->ni->flags & FILE_ATTR_COMPRESSED)) {
 5382         a->flags |= ATTR_IS_COMPRESSED;
 5383         na->data_flags = a->flags;
 5384     }
 5385     /*
 5386      * File names cannot be non-resident so we would never see this here
 5387      * but at least it serves as a reminder that there may be attributes
 5388      * for which we do need to set this flag. (AIA)
 5389      */
 5390     if (a->type == AT_FILE_NAME)
 5391         a->resident_flags = RESIDENT_ATTR_IS_INDEXED;
 5392     else
 5393         a->resident_flags = 0;
 5394     a->reservedR = 0;
 5395 
 5396     /* Sanity fixup...  Shouldn't really happen. (AIA) */
 5397     if (na->initialized_size > na->data_size)
 5398         na->initialized_size = na->data_size;
 5399 
 5400     /* Copy data from run list to resident attribute value. */
 5401     bytes_read = ntfs_rl_pread(vol, na->rl, 0, na->initialized_size,
 5402             (u8*)a + val_ofs);
 5403     if (bytes_read != na->initialized_size) {
 5404         if (bytes_read < 0)
 5405             err = errno;
 5406         ntfs_log_trace("Eeek! Failed to read attribute data. Leaving "
 5407                 "inconstant metadata. Run chkdsk.  "
 5408                 "Aborting...\n");
 5409         errno = err;
 5410         return -1;
 5411     }
 5412 
 5413     /* Clear memory in gap between initialized_size and data_size. */
 5414     if (na->initialized_size < na->data_size)
 5415         memset((u8*)a + val_ofs + na->initialized_size, 0,
 5416                 na->data_size - na->initialized_size);
 5417 
 5418     /*
 5419      * Deallocate clusters from the runlist.
 5420      *
 5421      * NOTE: We can use ntfs_cluster_free() because we have already mapped
 5422      * the whole run list and thus it doesn't matter that the attribute
 5423      * record is in a transiently corrupted state at this moment in time.
 5424      */
 5425     if (ntfs_cluster_free(vol, na, 0, -1) < 0) {
 5426         ntfs_log_perror("Eeek! Failed to release allocated clusters");
 5427         ntfs_log_trace("Ignoring error and leaving behind wasted "
 5428                 "clusters.\n");
 5429     }
 5430 
 5431     /* Throw away the now unused runlist. */
 5432     free(na->rl);
 5433     na->rl = NULL;
 5434 
 5435     /* Update in-memory struct ntfs_attr. */
 5436     NAttrClearNonResident(na);
 5437     NAttrClearFullyMapped(na);
 5438     NAttrClearSparse(na);
 5439     NAttrClearEncrypted(na);
 5440     na->initialized_size = na->data_size;
 5441     na->allocated_size = na->compressed_size = (na->data_size + 7) & ~7;
 5442     na->compression_block_size = 0;
 5443     na->compression_block_size_bits = na->compression_block_clusters = 0;
 5444     return 0;
 5445 }
 5446 
 5447 /*
 5448  * If we are in the first extent, then set/clean sparse bit,
 5449  * update allocated and compressed size.
 5450  */
 5451 static int ntfs_attr_update_meta(ATTR_RECORD *a, ntfs_attr *na, MFT_RECORD *m,
 5452                 hole_type holes, ntfs_attr_search_ctx *ctx)
 5453 {
 5454     int sparse, ret = 0;
 5455     
 5456     ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x\n", 
 5457                (unsigned long long)na->ni->mft_no, le32_to_cpu(na->type));
 5458     
 5459     if (a->lowest_vcn)
 5460         goto out;
 5461 
 5462     a->allocated_size = cpu_to_sle64(na->allocated_size);
 5463 
 5464     /* Update sparse bit, unless this is an intermediate state */
 5465     if (holes == HOLES_DELAY)
 5466         sparse = (a->flags & ATTR_IS_SPARSE) != const_cpu_to_le16(0);
 5467     else {
 5468         sparse = ntfs_rl_sparse(na->rl);
 5469         if (sparse == -1) {
 5470             errno = EIO;
 5471             goto error;
 5472         }
 5473     }
 5474 
 5475     /* Check whether attribute becomes sparse, unless check is delayed. */
 5476     if ((holes != HOLES_DELAY)
 5477         && sparse
 5478         && !(a->flags & (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED))) {
 5479         /*
 5480          * Move attribute to another mft record, if attribute is too 
 5481          * small to add compressed_size field to it and we have no 
 5482          * free space in the current mft record.
 5483          */
 5484         if ((le32_to_cpu(a->length) - 
 5485                 le16_to_cpu(a->mapping_pairs_offset) == 8)
 5486             && !(le32_to_cpu(m->bytes_allocated) - 
 5487                 le32_to_cpu(m->bytes_in_use))) {
 5488 
 5489             if (!NInoAttrList(na->ni)) {
 5490                 ntfs_attr_put_search_ctx(ctx);