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