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