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