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