1 /** 2 * inode.c - Inode handling code. Originated from the Linux-NTFS project. 3 * 4 * Copyright (c) 2002-2005 Anton Altaparmakov 5 * Copyright (c) 2002-2008 Szabolcs Szakacsits 6 * Copyright (c) 2004-2007 Yura Pakhuchiy 7 * Copyright (c) 2004-2005 Richard Russon 8 * Copyright (c) 2009-2010 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_STDLIB_H 31 #include <stdlib.h> 32 #endif 33 #ifdef HAVE_STRING_H 34 #include <string.h> 35 #endif 36 #ifdef HAVE_ERRNO_H 37 #include <errno.h> 38 #endif 39 #ifdef HAVE_SETXATTR 40 #include <sys/xattr.h> 41 #endif 42 43 #include "param.h" 44 #include "compat.h" 45 #include "types.h" 46 #include "volume.h" 47 #include "cache.h" 48 #include "inode.h" 49 #include "attrib.h" 50 #include "debug.h" 51 #include "mft.h" 52 #include "attrlist.h" 53 #include "runlist.h" 54 #include "lcnalloc.h" 55 #include "index.h" 56 #include "dir.h" 57 #include "ntfstime.h" 58 #include "logging.h" 59 #include "misc.h" 60 61 ntfs_inode *ntfs_inode_base(ntfs_inode *ni) 62 { 63 if (ni->nr_extents == -1) 64 return ni->base_ni; 65 return ni; 66 } 67 68 /** 69 * ntfs_inode_mark_dirty - set the inode (and its base inode if it exists) dirty 70 * @ni: ntfs inode to set dirty 71 * 72 * Set the inode @ni dirty so it is written out later (at the latest at 73 * ntfs_inode_close() time). If @ni is an extent inode, set the base inode 74 * dirty, too. 75 * 76 * This function cannot fail. 77 */ 78 void ntfs_inode_mark_dirty(ntfs_inode *ni) 79 { 80 NInoSetDirty(ni); 81 if (ni->nr_extents == -1) 82 NInoSetDirty(ni->base_ni); 83 } 84 85 /** 86 * __ntfs_inode_allocate - Create and initialise an NTFS inode object 87 * @vol: 88 * 89 * Description... 90 * 91 * Returns: 92 */ 93 static ntfs_inode *__ntfs_inode_allocate(ntfs_volume *vol) 94 { 95 ntfs_inode *ni; 96 97 ni = (ntfs_inode*)ntfs_calloc(sizeof(ntfs_inode)); 98 if (ni) 99 ni->vol = vol; 100 return ni; 101 } 102 103 /** 104 * ntfs_inode_allocate - Create an NTFS inode object 105 * @vol: 106 * 107 * Description... 108 * 109 * Returns: 110 */ 111 ntfs_inode *ntfs_inode_allocate(ntfs_volume *vol) 112 { 113 return __ntfs_inode_allocate(vol); 114 } 115 116 /** 117 * __ntfs_inode_release - Destroy an NTFS inode object 118 * @ni: 119 * 120 * Description... 121 * 122 * Returns: 123 */ 124 static void __ntfs_inode_release(ntfs_inode *ni) 125 { 126 if (NInoDirty(ni)) 127 ntfs_log_error("Releasing dirty inode %lld!\n", 128 (long long)ni->mft_no); 129 if (NInoAttrList(ni) && ni->attr_list) 130 free(ni->attr_list); 131 free(ni->mrec); 132 free(ni); 133 return; 134 } 135 136 /** 137 * ntfs_inode_open - open an inode ready for access 138 * @vol: volume to get the inode from 139 * @mref: inode number / mft record number to open 140 * 141 * Allocate an ntfs_inode structure and initialize it for the given inode 142 * specified by @mref. @mref specifies the inode number / mft record to read, 143 * including the sequence number, which can be 0 if no sequence number checking 144 * is to be performed. 145 * 146 * Then, allocate a buffer for the mft record, read the mft record from the 147 * volume @vol, and attach it to the ntfs_inode structure (->mrec). The 148 * mft record is mst deprotected and sanity checked for validity and we abort 149 * if deprotection or checks fail. 150 * 151 * Finally, search for an attribute list attribute in the mft record and if one 152 * is found, load the attribute list attribute value and attach it to the 153 * ntfs_inode structure (->attr_list). Also set the NI_AttrList bit to indicate 154 * this. 155 * 156 * Return a pointer to the ntfs_inode structure on success or NULL on error, 157 * with errno set to the error code. 158 */ 159 static ntfs_inode *ntfs_inode_real_open(ntfs_volume *vol, const MFT_REF mref) 160 { 161 s64 l; 162 ntfs_inode *ni = NULL; 163 ntfs_attr_search_ctx *ctx; 164 STANDARD_INFORMATION *std_info; 165 le32 lthle; 166 int olderrno; 167 168 ntfs_log_enter("Entering for inode %lld\n", (long long)MREF(mref)); 169 if (!vol) { 170 errno = EINVAL; 171 goto out; 172 } 173 ni = __ntfs_inode_allocate(vol); 174 if (!ni) 175 goto out; 176 if (ntfs_file_record_read(vol, mref, &ni->mrec, NULL)) 177 goto err_out; 178 if (!(ni->mrec->flags & MFT_RECORD_IN_USE)) { 179 errno = ENOENT; 180 goto err_out; 181 } 182 ni->mft_no = MREF(mref); 183 ctx = ntfs_attr_get_search_ctx(ni, NULL); 184 if (!ctx) 185 goto err_out; 186 /* Receive some basic information about inode. */ 187 if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED, 188 0, CASE_SENSITIVE, 0, NULL, 0, ctx)) { 189 if (!ni->mrec->base_mft_record) 190 ntfs_log_perror("No STANDARD_INFORMATION in base record" 191 " %lld", (long long)MREF(mref)); 192 goto put_err_out; 193 } 194 std_info = (STANDARD_INFORMATION *)((u8 *)ctx->attr + 195 le16_to_cpu(ctx->attr->value_offset)); 196 ni->flags = std_info->file_attributes; 197 ni->creation_time = std_info->creation_time; 198 ni->last_data_change_time = std_info->last_data_change_time; 199 ni->last_mft_change_time = std_info->last_mft_change_time; 200 ni->last_access_time = std_info->last_access_time; 201 /* JPA insert v3 extensions if present */ 202 /* length may be seen as 72 (v1.x) or 96 (v3.x) */ 203 lthle = ctx->attr->length; 204 if (le32_to_cpu(lthle) > sizeof(STANDARD_INFORMATION)) { 205 set_nino_flag(ni, v3_Extensions); 206 ni->owner_id = std_info->owner_id; 207 ni->security_id = std_info->security_id; 208 ni->quota_charged = std_info->quota_charged; 209 ni->usn = std_info->usn; 210 } else { 211 clear_nino_flag(ni, v3_Extensions); 212 ni->owner_id = const_cpu_to_le32(0); 213 ni->security_id = const_cpu_to_le32(0); 214 } 215 /* Set attribute list information. */ 216 olderrno = errno; 217 if (ntfs_attr_lookup(AT_ATTRIBUTE_LIST, AT_UNNAMED, 0, 218 CASE_SENSITIVE, 0, NULL, 0, ctx)) { 219 if (errno != ENOENT) 220 goto put_err_out; 221 /* Attribute list attribute does not present. */ 222 /* restore previous errno to avoid misinterpretation */ 223 errno = olderrno; 224 goto get_size; 225 } 226 NInoSetAttrList(ni); 227 l = ntfs_get_attribute_value_length(ctx->attr); 228 if (!l) 229 goto put_err_out; 230 if (l > 0x40000) { 231 errno = EIO; 232 ntfs_log_perror("Too large attrlist attribute (%lld), inode " 233 "%lld", (long long)l, (long long)MREF(mref)); 234 goto put_err_out; 235 } 236 ni->attr_list_size = l; 237 ni->attr_list = ntfs_malloc(ni->attr_list_size); 238 if (!ni->attr_list) 239 goto put_err_out; 240 l = ntfs_get_attribute_value(vol, ctx->attr, ni->attr_list); 241 if (!l) 242 goto put_err_out; 243 if (l != ni->attr_list_size) { 244 errno = EIO; 245 ntfs_log_perror("Unexpected attrlist size (%lld <> %u), inode " 246 "%lld", (long long)l, ni->attr_list_size, 247 (long long)MREF(mref)); 248 goto put_err_out; 249 } 250 get_size: 251 olderrno = errno; 252 if (ntfs_attr_lookup(AT_DATA, AT_UNNAMED, 0, 0, 0, NULL, 0, ctx)) { 253 if (errno != ENOENT) 254 goto put_err_out; 255 /* Directory or special file. */ 256 /* restore previous errno to avoid misinterpretation */ 257 errno = olderrno; 258 ni->data_size = ni->allocated_size = 0; 259 } else { 260 if (ctx->attr->non_resident) { 261 ni->data_size = sle64_to_cpu(ctx->attr->data_size); 262 if (ctx->attr->flags & 263 (ATTR_IS_COMPRESSED | ATTR_IS_SPARSE)) 264 ni->allocated_size = sle64_to_cpu( 265 ctx->attr->compressed_size); 266 else 267 ni->allocated_size = sle64_to_cpu( 268 ctx->attr->allocated_size); 269 } else { 270 ni->data_size = le32_to_cpu(ctx->attr->value_length); 271 ni->allocated_size = (ni->data_size + 7) & ~7; 272 } 273 set_nino_flag(ni,KnownSize); 274 } 275 ntfs_attr_put_search_ctx(ctx); 276 out: 277 ntfs_log_leave("\n"); 278 return ni; 279 280 put_err_out: 281 ntfs_attr_put_search_ctx(ctx); 282 err_out: 283 __ntfs_inode_release(ni); 284 ni = NULL; 285 goto out; 286 } 287 288 /** 289 * ntfs_inode_close - close an ntfs inode and free all associated memory 290 * @ni: ntfs inode to close 291 * 292 * Make sure the ntfs inode @ni is clean. 293 * 294 * If the ntfs inode @ni is a base inode, close all associated extent inodes, 295 * then deallocate all memory attached to it, and finally free the ntfs inode 296 * structure itself. 297 * 298 * If it is an extent inode, we disconnect it from its base inode before we 299 * destroy it. 300 * 301 * It is OK to pass NULL to this function, it is just noop in this case. 302 * 303 * Return 0 on success or -1 on error with errno set to the error code. On 304 * error, @ni has not been freed. The user should attempt to handle the error 305 * and call ntfs_inode_close() again. The following error codes are defined: 306 * 307 * EBUSY @ni and/or its attribute list runlist is/are dirty and the 308 * attempt to write it/them to disk failed. 309 * EINVAL @ni is invalid (probably it is an extent inode). 310 * EIO I/O error while trying to write inode to disk. 311 */ 312 313 int ntfs_inode_real_close(ntfs_inode *ni) 314 { 315 int ret = -1; 316 317 if (!ni) 318 return 0; 319 320 ntfs_log_enter("Entering for inode %lld\n", (long long)ni->mft_no); 321 322 /* If we have dirty metadata, write it out. */ 323 if (NInoDirty(ni) || NInoAttrListDirty(ni)) { 324 if (ntfs_inode_sync(ni)) { 325 if (errno != EIO) 326 errno = EBUSY; 327 goto err; 328 } 329 } 330 /* Is this a base inode with mapped extent inodes? */ 331 if (ni->nr_extents > 0) { 332 while (ni->nr_extents > 0) { 333 if (ntfs_inode_real_close(ni->extent_nis[0])) { 334 if (errno != EIO) 335 errno = EBUSY; 336 goto err; 337 } 338 } 339 } else if (ni->nr_extents == -1) { 340 ntfs_inode **tmp_nis; 341 ntfs_inode *base_ni; 342 s32 i; 343 344 /* 345 * If the inode is an extent inode, disconnect it from the 346 * base inode before destroying it. 347 */ 348 base_ni = ni->base_ni; 349 for (i = 0; i < base_ni->nr_extents; ++i) { 350 tmp_nis = base_ni->extent_nis; 351 if (tmp_nis[i] != ni) 352 continue; 353 /* Found it. Disconnect. */ 354 memmove(tmp_nis + i, tmp_nis + i + 1, 355 (base_ni->nr_extents - i - 1) * 356 sizeof(ntfs_inode *)); 357 /* Buffer should be for multiple of four extents. */ 358 if ((--base_ni->nr_extents) & 3) { 359 i = -1; 360 break; 361 } 362 /* 363 * ElectricFence is unhappy with realloc(x,0) as free(x) 364 * thus we explicitly separate these two cases. 365 */ 366 if (base_ni->nr_extents) { 367 /* Resize the memory buffer. */ 368 tmp_nis = realloc(tmp_nis, base_ni->nr_extents * 369 sizeof(ntfs_inode *)); 370 /* Ignore errors, they don't really matter. */ 371 if (tmp_nis) 372 base_ni->extent_nis = tmp_nis; 373 } else if (tmp_nis) { 374 free(tmp_nis); 375 base_ni->extent_nis = (ntfs_inode**)NULL; 376 } 377 /* Allow for error checking. */ 378 i = -1; 379 break; 380 } 381 382 /* 383 * We could successfully sync, so only log this error 384 * and try to sync other inode extents too. 385 */ 386 if (i != -1) 387 ntfs_log_error("Extent inode %lld was not found\n", 388 (long long)ni->mft_no); 389 } 390 391 __ntfs_inode_release(ni); 392 ret = 0; 393 err: 394 ntfs_log_leave("\n"); 395 return ret; 396 } 397 398 #if CACHE_NIDATA_SIZE 399 400 /* 401 * Free an inode structure when there is not more space 402 * in the cache 403 */ 404 405 void ntfs_inode_nidata_free(const struct CACHED_GENERIC *cached) 406 { 407 ntfs_inode_real_close(((const struct CACHED_NIDATA*)cached)->ni); 408 } 409 410 /* 411 * Compute a hash value for an inode entry 412 */ 413 414 int ntfs_inode_nidata_hash(const struct CACHED_GENERIC *item) 415 { 416 return (((const struct CACHED_NIDATA*)item)->inum 417 % (2*CACHE_NIDATA_SIZE)); 418 } 419 420 /* 421 * inum comparing for entering/fetching from cache 422 */ 423 424 static int idata_cache_compare(const struct CACHED_GENERIC *cached, 425 const struct CACHED_GENERIC *wanted) 426 { 427 return (((const struct CACHED_NIDATA*)cached)->inum 428 != ((const struct CACHED_NIDATA*)wanted)->inum); 429 } 430 431 /* 432 * Invalidate an inode entry when not needed anymore. 433 * The entry should have been synced, it may be reused later, 434 * if it is requested before it is dropped from cache. 435 */ 436 437 void ntfs_inode_invalidate(ntfs_volume *vol, const MFT_REF mref) 438 { 439 struct CACHED_NIDATA item; 440 int count; 441 442 item.inum = MREF(mref); 443 item.ni = (ntfs_inode*)NULL; 444 item.pathname = (const char*)NULL; 445 item.varsize = 0; 446 count = ntfs_invalidate_cache(vol->nidata_cache, 447 GENERIC(&item),idata_cache_compare,CACHE_FREE); 448 } 449 450 #endif 451 452 /* 453 * Open an inode 454 * 455 * When possible, an entry recorded in the cache is reused 456 * 457 * **NEVER REOPEN** an inode, this can lead to a duplicated 458 * cache entry (hard to detect), and to an obsolete one being 459 * reused. System files are however protected from being cached. 460 */ 461 462 ntfs_inode *ntfs_inode_open(ntfs_volume *vol, const MFT_REF mref) 463 { 464 ntfs_inode *ni; 465 #if CACHE_NIDATA_SIZE 466 struct CACHED_NIDATA item; 467 struct CACHED_NIDATA *cached; 468 469 /* fetch idata from cache */ 470 item.inum = MREF(mref); 471 debug_double_inode(item.inum,1); 472 item.pathname = (const char*)NULL; 473 item.varsize = 0; 474 cached = (struct CACHED_NIDATA*)ntfs_fetch_cache(vol->nidata_cache, 475 GENERIC(&item),idata_cache_compare); 476 if (cached) { 477 ni = cached->ni; 478 /* do not keep open entries in cache */ 479 ntfs_remove_cache(vol->nidata_cache, 480 (struct CACHED_GENERIC*)cached,0); 481 } else { 482 ni = ntfs_inode_real_open(vol, mref); 483 } 484 #else 485 ni = ntfs_inode_real_open(vol, mref); 486 #endif 487 return (ni); 488 } 489 490 /* 491 * Close an inode entry 492 * 493 * If cacheing is in use, the entry is synced and kept available 494 * in cache for further use. 495 * 496 * System files (inode < 16 or having the IS_4 flag) are protected 497 * against being cached. 498 */ 499 500 int ntfs_inode_close(ntfs_inode *ni) 501 { 502 int res; 503 #if CACHE_NIDATA_SIZE 504 BOOL dirty; 505 struct CACHED_NIDATA item; 506 507 if (ni) { 508 debug_double_inode(ni->mft_no,0); 509 /* do not cache system files : could lead to double entries */ 510 if (ni->vol && ni->vol->nidata_cache 511 && ((ni->mft_no == FILE_root) 512 || ((ni->mft_no >= FILE_first_user) 513 && !(ni->mrec->flags & MFT_RECORD_IS_4)))) { 514 /* If we have dirty metadata, write it out. */ 515 dirty = NInoDirty(ni) || NInoAttrListDirty(ni); 516 if (dirty) { 517 res = ntfs_inode_sync(ni); 518 /* do a real close if sync failed */ 519 if (res) 520 ntfs_inode_real_close(ni); 521 } else 522 res = 0; 523 524 if (!res) { 525 /* feed idata into cache */ 526 item.inum = ni->mft_no; 527 item.ni = ni; 528 item.pathname = (const char*)NULL; 529 item.varsize = 0; 530 debug_cached_inode(ni); 531 ntfs_enter_cache(ni->vol->nidata_cache, 532 GENERIC(&item), idata_cache_compare); 533 } 534 } else { 535 /* cache not ready or system file, really close */ 536 res = ntfs_inode_real_close(ni); 537 } 538 } else 539 res = 0; 540 #else 541 res = ntfs_inode_real_close(ni); 542 #endif 543 return (res); 544 } 545 546 /** 547 * ntfs_extent_inode_open - load an extent inode and attach it to its base 548 * @base_ni: base ntfs inode 549 * @mref: mft reference of the extent inode to load (in little endian) 550 * 551 * First check if the extent inode @mref is already attached to the base ntfs 552 * inode @base_ni, and if so, return a pointer to the attached extent inode. 553 * 554 * If the extent inode is not already attached to the base inode, allocate an 555 * ntfs_inode structure and initialize it for the given inode @mref. @mref 556 * specifies the inode number / mft record to read, including the sequence 557 * number, which can be 0 if no sequence number checking is to be performed. 558 * 559 * Then, allocate a buffer for the mft record, read the mft record from the 560 * volume @base_ni->vol, and attach it to the ntfs_inode structure (->mrec). 561 * The mft record is mst deprotected and sanity checked for validity and we 562 * abort if deprotection or checks fail. 563 * 564 * Finally attach the ntfs inode to its base inode @base_ni and return a 565 * pointer to the ntfs_inode structure on success or NULL on error, with errno 566 * set to the error code. 567 * 568 * Note, extent inodes are never closed directly. They are automatically 569 * disposed off by the closing of the base inode. 570 */ 571 ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni, const MFT_REF mref) 572 { 573 u64 mft_no = MREF_LE(mref); 574 ntfs_inode *ni = NULL; 575 ntfs_inode **extent_nis; 576 int i; 577 578 if (!base_ni) { 579 errno = EINVAL; 580 ntfs_log_perror("%s", __FUNCTION__); 581 return NULL; 582 } 583 584 ntfs_log_enter("Opening extent inode %lld (base mft record %lld).\n", 585 (unsigned long long)mft_no, 586 (unsigned long long)base_ni->mft_no); 587 588 /* Is the extent inode already open and attached to the base inode? */ 589 if (base_ni->nr_extents > 0) { 590 extent_nis = base_ni->extent_nis; 591 for (i = 0; i < base_ni->nr_extents; i++) { 592 u16 seq_no; 593 594 ni = extent_nis[i]; 595 if (mft_no != ni->mft_no) 596 continue; 597 /* Verify the sequence number if given. */ 598 seq_no = MSEQNO_LE(mref); 599 if (seq_no && seq_no != le16_to_cpu( 600 ni->mrec->sequence_number)) { 601 errno = EIO; 602 ntfs_log_perror("Found stale extent mft " 603 "reference mft=%lld", 604 (long long)ni->mft_no); 605 goto out; 606 } 607 goto out; 608 } 609 } 610 /* Wasn't there, we need to load the extent inode. */ 611 ni = __ntfs_inode_allocate(base_ni->vol); 612 if (!ni) 613 goto out; 614 if (ntfs_file_record_read(base_ni->vol, le64_to_cpu(mref), &ni->mrec, NULL)) 615 goto err_out; 616 ni->mft_no = mft_no; 617 ni->nr_extents = -1; 618 ni->base_ni = base_ni; 619 /* Attach extent inode to base inode, reallocating memory if needed. */ 620 if (!(base_ni->nr_extents & 3)) { 621 i = (base_ni->nr_extents + 4) * sizeof(ntfs_inode *); 622 623 extent_nis = ntfs_malloc(i); 624 if (!extent_nis) 625 goto err_out; 626 if (base_ni->nr_extents) { 627 memcpy(extent_nis, base_ni->extent_nis, 628 i - 4 * sizeof(ntfs_inode *)); 629 free(base_ni->extent_nis); 630 } 631 base_ni->extent_nis = extent_nis; 632 } 633 base_ni->extent_nis[base_ni->nr_extents++] = ni; 634 out: 635 ntfs_log_leave("\n"); 636 return ni; 637 err_out: 638 __ntfs_inode_release(ni); 639 ni = NULL; 640 goto out; 641 } 642 643 /** 644 * ntfs_inode_attach_all_extents - attach all extents for target inode 645 * @ni: opened ntfs inode for which perform attach 646 * 647 * Return 0 on success and -1 on error with errno set to the error code. 648 */ 649 int ntfs_inode_attach_all_extents(ntfs_inode *ni) 650 { 651 ATTR_LIST_ENTRY *ale; 652 u64 prev_attached = 0; 653 654 if (!ni) { 655 ntfs_log_trace("Invalid arguments.\n"); 656 errno = EINVAL; 657 return -1; 658 } 659 660 if (ni->nr_extents == -1) 661 ni = ni->base_ni; 662 663 ntfs_log_trace("Entering for inode 0x%llx.\n", (long long) ni->mft_no); 664 665 /* Inode haven't got attribute list, thus nothing to attach. */ 666 if (!NInoAttrList(ni)) 667 return 0; 668 669 if (!ni->attr_list) { 670 ntfs_log_trace("Corrupt in-memory struct.\n"); 671 errno = EINVAL; 672 return -1; 673 } 674 675 /* Walk through attribute list and attach all extents. */ 676 errno = 0; 677 ale = (ATTR_LIST_ENTRY *)ni->attr_list; 678 while ((u8*)ale < ni->attr_list + ni->attr_list_size) { 679 if (ni->mft_no != MREF_LE(ale->mft_reference) && 680 prev_attached != MREF_LE(ale->mft_reference)) { 681 if (!ntfs_extent_inode_open(ni, ale->mft_reference)) { 682 ntfs_log_trace("Couldn't attach extent inode.\n"); 683 return -1; 684 } 685 prev_attached = MREF_LE(ale->mft_reference); 686 } 687 ale = (ATTR_LIST_ENTRY *)((u8*)ale + le16_to_cpu(ale->length)); 688 } 689 return 0; 690 } 691 692 /** 693 * ntfs_inode_sync_standard_information - update standard information attribute 694 * @ni: ntfs inode to update standard information 695 * 696 * Return 0 on success or -1 on error with errno set to the error code. 697 */ 698 static int ntfs_inode_sync_standard_information(ntfs_inode *ni) 699 { 700 ntfs_attr_search_ctx *ctx; 701 STANDARD_INFORMATION *std_info; 702 u32 lth; 703 le32 lthle; 704 705 ntfs_log_trace("Entering for inode %lld\n", (long long)ni->mft_no); 706 707 ctx = ntfs_attr_get_search_ctx(ni, NULL); 708 if (!ctx) 709 return -1; 710 if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED, 711 0, CASE_SENSITIVE, 0, NULL, 0, ctx)) { 712 ntfs_log_perror("Failed to sync standard info (inode %lld)", 713 (long long)ni->mft_no); 714 ntfs_attr_put_search_ctx(ctx); 715 return -1; 716 } 717 std_info = (STANDARD_INFORMATION *)((u8 *)ctx->attr + 718 le16_to_cpu(ctx->attr->value_offset)); 719 std_info->file_attributes = ni->flags; 720 if (!test_nino_flag(ni, TimesSet)) { 721 std_info->creation_time = ni->creation_time; 722 std_info->last_data_change_time = ni->last_data_change_time; 723 std_info->last_mft_change_time = ni->last_mft_change_time; 724 std_info->last_access_time = ni->last_access_time; 725 } 726 727 /* JPA update v3.x extensions, ensuring consistency */ 728 729 lthle = ctx->attr->length; 730 lth = le32_to_cpu(lthle); 731 if (test_nino_flag(ni, v3_Extensions) 732 && (lth <= sizeof(STANDARD_INFORMATION))) 733 ntfs_log_error("bad sync of standard information\n"); 734 735 if (lth > sizeof(STANDARD_INFORMATION)) { 736 std_info->owner_id = ni->owner_id; 737 std_info->security_id = ni->security_id; 738 std_info->quota_charged = ni->quota_charged; 739 std_info->usn = ni->usn; 740 } 741 ntfs_inode_mark_dirty(ctx->ntfs_ino); 742 ntfs_attr_put_search_ctx(ctx); 743 return 0; 744 } 745 746 /** 747 * ntfs_inode_sync_file_name - update FILE_NAME attributes 748 * @ni: ntfs inode to update FILE_NAME attributes 749 * 750 * Update all FILE_NAME attributes for inode @ni in the index. 751 * 752 * Return 0 on success or -1 on error with errno set to the error code. 753 */ 754 static int ntfs_inode_sync_file_name(ntfs_inode *ni, ntfs_inode *dir_ni) 755 { 756 ntfs_attr_search_ctx *ctx = NULL; 757 ntfs_index_context *ictx; 758 ntfs_inode *index_ni; 759 FILE_NAME_ATTR *fn; 760 FILE_NAME_ATTR *fnx; 761 REPARSE_POINT *rpp; 762 le32 reparse_tag; 763 int err = 0; 764 765 ntfs_log_trace("Entering for inode %lld\n", (long long)ni->mft_no); 766 767 ctx = ntfs_attr_get_search_ctx(ni, NULL); 768 if (!ctx) { 769 err = errno; 770 goto err_out; 771 } 772 /* Collect the reparse tag, if any */ 773 reparse_tag = cpu_to_le32(0); 774 if (ni->flags & FILE_ATTR_REPARSE_POINT) { 775 if (!ntfs_attr_lookup(AT_REPARSE_POINT, NULL, 776 0, CASE_SENSITIVE, 0, NULL, 0, ctx)) { 777 rpp = (REPARSE_POINT*)((u8 *)ctx->attr + 778 le16_to_cpu(ctx->attr->value_offset)); 779 reparse_tag = rpp->reparse_tag; 780 } 781 ntfs_attr_reinit_search_ctx(ctx); 782 } 783 /* Walk through all FILE_NAME attributes and update them. */ 784 while (!ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, 0, 0, NULL, 0, ctx)) { 785 fn = (FILE_NAME_ATTR *)((u8 *)ctx->attr + 786 le16_to_cpu(ctx->attr->value_offset)); 787 if (MREF_LE(fn->parent_directory) == ni->mft_no) { 788 /* 789 * WARNING: We cheat here and obtain 2 attribute 790 * search contexts for one inode (first we obtained 791 * above, second will be obtained inside 792 * ntfs_index_lookup), it's acceptable for library, 793 * but will deadlock in the kernel. 794 */ 795 index_ni = ni; 796 } else 797 if (dir_ni) 798 index_ni = dir_ni; 799 else 800 index_ni = ntfs_inode_open(ni->vol, 801 le64_to_cpu(fn->parent_directory)); 802 if (!index_ni) { 803 if (!err) 804 err = errno; 805 ntfs_log_perror("Failed to open inode %lld with index", 806 (long long)le64_to_cpu(fn->parent_directory)); 807 continue; 808 } 809 ictx = ntfs_index_ctx_get(index_ni, NTFS_INDEX_I30, 4); 810 if (!ictx) { 811 if (!err) 812 err = errno; 813 ntfs_log_perror("Failed to get index ctx, inode %lld", 814 (long long)index_ni->mft_no); 815 if ((ni != index_ni) && !dir_ni 816 && ntfs_inode_close(index_ni) && !err) 817 err = errno; 818 continue; 819 } 820 if (ntfs_index_lookup(fn, sizeof(FILE_NAME_ATTR), ictx)) { 821 if (!err) { 822 if (errno == ENOENT) 823 err = EIO; 824 else 825 err = errno; 826 } 827 ntfs_log_perror("Index lookup failed, inode %lld", 828 (long long)index_ni->mft_no); 829 ntfs_index_ctx_put(ictx); 830 if (ni != index_ni && ntfs_inode_close(index_ni) && !err) 831 err = errno; 832 continue; 833 } 834 /* Update flags and file size. */ 835 fnx = (FILE_NAME_ATTR *)ictx->data; 836 fnx->file_attributes = 837 (fnx->file_attributes & ~FILE_ATTR_VALID_FLAGS) | 838 (ni->flags & FILE_ATTR_VALID_FLAGS); 839 if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) 840 fnx->data_size = fnx->allocated_size 841 = const_cpu_to_le64(0); 842 else { 843 fnx->allocated_size = cpu_to_sle64(ni->allocated_size); 844 fnx->data_size = cpu_to_sle64(ni->data_size); 845 } 846 /* update or clear the reparse tag in the index */ 847 fnx->reparse_point_tag = reparse_tag; 848 if (!test_nino_flag(ni, TimesSet)) { 849 fnx->creation_time = ni->creation_time; 850 fnx->last_data_change_time = ni->last_data_change_time; 851 fnx->last_mft_change_time = ni->last_mft_change_time; 852 fnx->last_access_time = ni->last_access_time; 853 } else { 854 fnx->creation_time = fn->creation_time; 855 fnx->last_data_change_time = fn->last_data_change_time; 856 fnx->last_mft_change_time = fn->last_mft_change_time; 857 fnx->last_access_time = fn->last_access_time; 858 } 859 ntfs_index_entry_mark_dirty(ictx); 860 ntfs_index_ctx_put(ictx); 861 if ((ni != index_ni) && !dir_ni 862 && ntfs_inode_close(index_ni) && !err) 863 err = errno; 864 } 865 /* Check for real error occurred. */ 866 if (errno != ENOENT) { 867 err = errno; 868 ntfs_log_perror("Attribute lookup failed, inode %lld", 869 (long long)ni->mft_no); 870 goto err_out; 871 } 872 ntfs_attr_put_search_ctx(ctx); 873 if (err) { 874 errno = err; 875 return -1; 876 } 877 return 0; 878 err_out: 879 if (ctx) 880 ntfs_attr_put_search_ctx(ctx); 881 errno = err; 882 return -1; 883 } 884 885 /** 886 * ntfs_inode_sync - write the inode (and its dirty extents) to disk 887 * @ni: ntfs inode to write 888 * 889 * Write the inode @ni to disk as well as its dirty extent inodes if such 890 * exist and @ni is a base inode. If @ni is an extent inode, only @ni is 891 * written completely disregarding its base inode and any other extent inodes. 892 * 893 * For a base inode with dirty extent inodes if any writes fail for whatever 894 * reason, the failing inode is skipped and the sync process is continued. At 895 * the end the error condition that brought about the failure is returned. Thus 896 * the smallest amount of data loss possible occurs. 897 * 898 * Return 0 on success or -1 on error with errno set to the error code. 899 * The following error codes are defined: 900 * EINVAL - Invalid arguments were passed to the function. 901 * EBUSY - Inode and/or one of its extents is busy, try again later. 902 * EIO - I/O error while writing the inode (or one of its extents). 903 */ 904 static int ntfs_inode_sync_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni) 905 { 906 int ret = 0; 907 int err = 0; 908 if (!ni) { 909 errno = EINVAL; 910 ntfs_log_error("Failed to sync NULL inode\n"); 911 return -1; 912 } 913 914 ntfs_log_enter("Entering for inode %lld\n", (long long)ni->mft_no); 915 916 /* Update STANDARD_INFORMATION. */ 917 if ((ni->mrec->flags & MFT_RECORD_IN_USE) && ni->nr_extents != -1 && 918 ntfs_inode_sync_standard_information(ni)) { 919 if (!err || errno == EIO) { 920 err = errno; 921 if (err != EIO) 922 err = EBUSY; 923 } 924 } 925 926 /* Update FILE_NAME's in the index. */ 927 if ((ni->mrec->flags & MFT_RECORD_IN_USE) && ni->nr_extents != -1 && 928 NInoFileNameTestAndClearDirty(ni) && 929 ntfs_inode_sync_file_name(ni, dir_ni)) { 930 if (!err || errno == EIO) { 931 err = errno; 932 if (err != EIO) 933 err = EBUSY; 934 } 935 ntfs_log_perror("Failed to sync FILE_NAME (inode %lld)", 936 (long long)ni->mft_no); 937 NInoFileNameSetDirty(ni); 938 } 939 940 /* Write out attribute list from cache to disk. */ 941 if ((ni->mrec->flags & MFT_RECORD_IN_USE) && ni->nr_extents != -1 && 942 NInoAttrList(ni) && NInoAttrListTestAndClearDirty(ni)) { 943 ntfs_attr *na; 944 945 na = ntfs_attr_open(ni, AT_ATTRIBUTE_LIST, AT_UNNAMED, 0); 946 if (!na) { 947 if (!err || errno == EIO) { 948 err = errno; 949 if (err != EIO) 950 err = EBUSY; 951 ntfs_log_perror("Attribute list sync failed " 952 "(open, inode %lld)", 953 (long long)ni->mft_no); 954 } 955 NInoAttrListSetDirty(ni); 956 goto sync_inode; 957 } 958 959 if (na->data_size == ni->attr_list_size) { 960 if (ntfs_attr_pwrite(na, 0, ni->attr_list_size, 961 ni->attr_list) != ni->attr_list_size) { 962 if (!err || errno == EIO) { 963 err = errno; 964 if (err != EIO) 965 err = EBUSY; 966 ntfs_log_perror("Attribute list sync " 967 "failed (write, inode %lld)", 968 (long long)ni->mft_no); 969 } 970 NInoAttrListSetDirty(ni); 971 } 972 } else { 973 err = EIO; 974 ntfs_log_error("Attribute list sync failed (bad size, " 975 "inode %lld)\n", (long long)ni->mft_no); 976 NInoAttrListSetDirty(ni); 977 } 978 ntfs_attr_close(na); 979 } 980 981 sync_inode: 982 /* Write this inode out to the $MFT (and $MFTMirr if applicable). */ 983 if (NInoTestAndClearDirty(ni)) { 984 if (ntfs_mft_record_write(ni->vol, ni->mft_no, ni->mrec)) { 985 if (!err || errno == EIO) { 986 err = errno; 987 if (err != EIO) 988 err = EBUSY; 989 } 990 NInoSetDirty(ni); 991 ntfs_log_perror("MFT record sync failed, inode %lld", 992 (long long)ni->mft_no); 993 } 994 } 995 996 /* If this is a base inode with extents write all dirty extents, too. */ 997 if (ni->nr_extents > 0) { 998 s32 i; 999 1000 for (i = 0; i < ni->nr_extents; ++i) { 1001 ntfs_inode *eni; 1002 1003 eni = ni->extent_nis[i]; 1004 if (!NInoTestAndClearDirty(eni)) 1005 continue; 1006 1007 if (ntfs_mft_record_write(eni->vol, eni->mft_no, 1008 eni->mrec)) { 1009 if (!err || errno == EIO) { 1010 err = errno; 1011 if (err != EIO) 1012 err = EBUSY; 1013 } 1014 NInoSetDirty(eni); 1015 ntfs_log_perror("Extent MFT record sync failed," 1016 " inode %lld/%lld", 1017 (long long)ni->mft_no, 1018 (long long)eni->mft_no); 1019 } 1020 } 1021 } 1022 1023 if (err) { 1024 errno = err; 1025 ret = -1; 1026 } 1027 1028 ntfs_log_leave("\n"); 1029 return ret; 1030 } 1031 1032 int ntfs_inode_sync(ntfs_inode *ni) 1033 { 1034 return (ntfs_inode_sync_in_dir(ni, (ntfs_inode*)NULL)); 1035 } 1036 1037 /* 1038 * Close an inode with an open parent inode 1039 */ 1040 1041 int ntfs_inode_close_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni) 1042 { 1043 int res; 1044 1045 res = ntfs_inode_sync_in_dir(ni, dir_ni); 1046 if (res) { 1047 if (errno != EIO) 1048 errno = EBUSY; 1049 } else 1050 res = ntfs_inode_close(ni); 1051 return (res); 1052 } 1053 1054 /** 1055 * ntfs_inode_add_attrlist - add attribute list to inode and fill it 1056 * @ni: opened ntfs inode to which add attribute list 1057 * 1058 * Return 0 on success or -1 on error with errno set to the error code. 1059 * The following error codes are defined: 1060 * EINVAL - Invalid arguments were passed to the function. 1061 * EEXIST - Attribute list already exist. 1062 * EIO - Input/Ouput error occurred. 1063 * ENOMEM - Not enough memory to perform add. 1064 */ 1065 int ntfs_inode_add_attrlist(ntfs_inode *ni) 1066 { 1067 int err; 1068 ntfs_attr_search_ctx *ctx; 1069 u8 *al = NULL, *aln; 1070 int al_len = 0; 1071 ATTR_LIST_ENTRY *ale = NULL; 1072 ntfs_attr *na; 1073 1074 if (!ni) { 1075 errno = EINVAL; 1076 ntfs_log_perror("%s", __FUNCTION__); 1077 return -1; 1078 } 1079 1080 ntfs_log_trace("inode %llu\n", (unsigned long long) ni->mft_no); 1081 1082 if (NInoAttrList(ni) || ni->nr_extents) { 1083 errno = EEXIST; 1084 ntfs_log_perror("Inode already has attribute list"); 1085 return -1; 1086 } 1087 1088 /* Form attribute list. */ 1089 ctx = ntfs_attr_get_search_ctx(ni, NULL); 1090 if (!ctx) { 1091 err = errno; 1092 goto err_out; 1093 } 1094 /* Walk through all attributes. */ 1095 while (!ntfs_attr_lookup(AT_UNUSED, NULL, 0, 0, 0, NULL, 0, ctx)) { 1096 1097 int ale_size; 1098 1099 if (ctx->attr->type == AT_ATTRIBUTE_LIST) { 1100 err = EIO; 1101 ntfs_log_perror("Attribute list already present"); 1102 goto put_err_out; 1103 } 1104 1105 ale_size = (sizeof(ATTR_LIST_ENTRY) + sizeof(ntfschar) * 1106 ctx->attr->name_length + 7) & ~7; 1107 al_len += ale_size; 1108 1109 aln = realloc(al, al_len); 1110 if (!aln) { 1111 err = errno; 1112 ntfs_log_perror("Failed to realloc %d bytes", al_len); 1113 goto put_err_out; 1114 } 1115 ale = (ATTR_LIST_ENTRY *)(aln + ((u8 *)ale - al)); 1116 al = aln; 1117 1118 memset(ale, 0, ale_size); 1119 1120 /* Add attribute to attribute list. */ 1121 ale->type = ctx->attr->type; 1122 ale->length = cpu_to_le16((sizeof(ATTR_LIST_ENTRY) + 1123 sizeof(ntfschar) * ctx->attr->name_length + 7) & ~7); 1124 ale->name_length = ctx->attr->name_length; 1125 ale->name_offset = (u8 *)ale->name - (u8 *)ale; 1126 if (ctx->attr->non_resident) 1127 ale->lowest_vcn = ctx->attr->lowest_vcn; 1128 else 1129 ale->lowest_vcn = 0; 1130 ale->mft_reference = MK_LE_MREF(ni->mft_no, 1131 le16_to_cpu(ni->mrec->sequence_number)); 1132 ale->instance = ctx->attr->instance; 1133 memcpy(ale->name, (u8 *)ctx->attr + 1134 le16_to_cpu(ctx->attr->name_offset), 1135 ctx->attr->name_length * sizeof(ntfschar)); 1136 ale = (ATTR_LIST_ENTRY *)(al + al_len); 1137 } 1138 /* Check for real error occurred. */ 1139 if (errno != ENOENT) { 1140 err = errno; 1141 ntfs_log_perror("%s: Attribute lookup failed, inode %lld", 1142 __FUNCTION__, (long long)ni->mft_no); 1143 goto put_err_out; 1144 } 1145 1146 /* Set in-memory attribute list. */ 1147 ni->attr_list = al; 1148 ni->attr_list_size = al_len; 1149 NInoSetAttrList(ni); 1150 NInoAttrListSetDirty(ni); 1151 1152 /* Free space if there is not enough it for $ATTRIBUTE_LIST. */ 1153 if (le32_to_cpu(ni->mrec->bytes_allocated) - 1154 le32_to_cpu(ni->mrec->bytes_in_use) < 1155 offsetof(ATTR_RECORD, resident_end)) { 1156 if (ntfs_inode_free_space(ni, 1157 offsetof(ATTR_RECORD, resident_end))) { 1158 /* Failed to free space. */ 1159 err = errno; 1160 ntfs_log_perror("Failed to free space for attrlist"); 1161 goto rollback; 1162 } 1163 } 1164 1165 /* Add $ATTRIBUTE_LIST to mft record. */ 1166 if (ntfs_resident_attr_record_add(ni, 1167 AT_ATTRIBUTE_LIST, NULL, 0, NULL, 0, 0) < 0) { 1168 err = errno; 1169 ntfs_log_perror("Couldn't add $ATTRIBUTE_LIST to MFT"); 1170 goto rollback; 1171 } 1172 1173 /* Resize it. */ 1174 na = ntfs_attr_open(ni, AT_ATTRIBUTE_LIST, AT_UNNAMED, 0); 1175 if (!na) { 1176 err = errno; 1177 ntfs_log_perror("Failed to open just added $ATTRIBUTE_LIST"); 1178 goto remove_attrlist_record; 1179 } 1180 if (ntfs_attr_truncate(na, al_len)) { 1181 err = errno; 1182 ntfs_log_perror("Failed to resize just added $ATTRIBUTE_LIST"); 1183 ntfs_attr_close(na); 1184 goto remove_attrlist_record;; 1185 } 1186 1187 ntfs_attr_put_search_ctx(ctx); 1188 ntfs_attr_close(na); 1189 return 0; 1190 1191 remove_attrlist_record: 1192 /* Prevent ntfs_attr_recorm_rm from freeing attribute list. */ 1193 ni->attr_list = NULL; 1194 NInoClearAttrList(ni); 1195 /* Remove $ATTRIBUTE_LIST record. */ 1196 ntfs_attr_reinit_search_ctx(ctx); 1197 if (!ntfs_attr_lookup(AT_ATTRIBUTE_LIST, NULL, 0, 1198 CASE_SENSITIVE, 0, NULL, 0, ctx)) { 1199 if (ntfs_attr_record_rm(ctx)) 1200 ntfs_log_perror("Rollback failed to remove attrlist"); 1201 } else 1202 ntfs_log_perror("Rollback failed to find attrlist"); 1203 /* Setup back in-memory runlist. */ 1204 ni->attr_list = al; 1205 ni->attr_list_size = al_len; 1206 NInoSetAttrList(ni); 1207 rollback: 1208 /* 1209 * Scan attribute list for attributes that placed not in the base MFT 1210 * record and move them to it. 1211 */ 1212 ntfs_attr_reinit_search_ctx(ctx); 1213 ale = (ATTR_LIST_ENTRY*)al; 1214 while ((u8*)ale < al + al_len) { 1215 if (MREF_LE(ale->mft_reference) != ni->mft_no) { 1216 if (!ntfs_attr_lookup(ale->type, ale->name, 1217 ale->name_length, 1218 CASE_SENSITIVE, 1219 sle64_to_cpu(ale->lowest_vcn), 1220 NULL, 0, ctx)) { 1221 if (ntfs_attr_record_move_to(ctx, ni)) 1222 ntfs_log_perror("Rollback failed to " 1223 "move attribute"); 1224 } else 1225 ntfs_log_perror("Rollback failed to find attr"); 1226 ntfs_attr_reinit_search_ctx(ctx); 1227 } 1228 ale = (ATTR_LIST_ENTRY*)((u8*)ale + le16_to_cpu(ale->length)); 1229 } 1230 /* Remove in-memory attribute list. */ 1231 ni->attr_list = NULL; 1232 ni->attr_list_size = 0; 1233 NInoClearAttrList(ni); 1234 NInoAttrListClearDirty(ni); 1235 put_err_out: 1236 ntfs_attr_put_search_ctx(ctx); 1237 err_out: 1238 free(al); 1239 errno = err; 1240 return -1; 1241 } 1242 1243 /** 1244 * ntfs_inode_free_space - free space in the MFT record of an inode 1245 * @ni: ntfs inode in which MFT record needs more free space 1246 * @size: amount of space needed to free 1247 * 1248 * Return 0 on success or -1 on error with errno set to the error code. 1249 */ 1250 int ntfs_inode_free_space(ntfs_inode *ni, int size) 1251 { 1252 ntfs_attr_search_ctx *ctx; 1253 int freed; 1254 1255 if (!ni || size < 0) { 1256 errno = EINVAL; 1257 ntfs_log_perror("%s: ni=%p size=%d", __FUNCTION__, ni, size); 1258 return -1; 1259 } 1260 1261 ntfs_log_trace("Entering for inode %lld, size %d\n", 1262 (unsigned long long)ni->mft_no, size); 1263 1264 freed = (le32_to_cpu(ni->mrec->bytes_allocated) - 1265 le32_to_cpu(ni->mrec->bytes_in_use)); 1266 1267 if (size <= freed) 1268 return 0; 1269 1270 ctx = ntfs_attr_get_search_ctx(ni, NULL); 1271 if (!ctx) 1272 return -1; 1273 /* 1274 * $STANDARD_INFORMATION and $ATTRIBUTE_LIST must stay in the base MFT 1275 * record, so position search context on the first attribute after them. 1276 */ 1277 if (ntfs_attr_position(AT_FILE_NAME, ctx)) 1278 goto put_err_out; 1279 1280 while (1) { 1281 int record_size; 1282 /* 1283 * Check whether attribute is from different MFT record. If so, 1284 * find next, because we don't need such. 1285 */ 1286 while (ctx->ntfs_ino->mft_no != ni->mft_no) { 1287 retry: 1288 if (ntfs_attr_position(AT_UNUSED, ctx)) 1289 goto put_err_out; 1290 } 1291 1292 if (ntfs_inode_base(ctx->ntfs_ino)->mft_no == FILE_MFT && 1293 ctx->attr->type == AT_DATA) 1294 goto retry; 1295 1296 if (ctx->attr->type == AT_INDEX_ROOT) 1297 goto retry; 1298 1299 record_size = le32_to_cpu(ctx->attr->length); 1300 1301 if (ntfs_attr_record_move_away(ctx, 0)) { 1302 ntfs_log_perror("Failed to move out attribute #2"); 1303 break; 1304 } 1305 freed += record_size; 1306 1307 /* Check whether we are done. */ 1308 if (size <= freed) { 1309 ntfs_attr_put_search_ctx(ctx); 1310 return 0; 1311 } 1312 /* 1313 * Reposition to first attribute after $STANDARD_INFORMATION 1314 * and $ATTRIBUTE_LIST instead of simply skipping this attribute 1315 * because in the case when we have got only in-memory attribute 1316 * list then ntfs_attr_lookup will fail when it tries to find 1317 * $ATTRIBUTE_LIST. 1318 */ 1319 ntfs_attr_reinit_search_ctx(ctx); 1320 if (ntfs_attr_position(AT_FILE_NAME, ctx)) 1321 break; 1322 } 1323 put_err_out: 1324 ntfs_attr_put_search_ctx(ctx); 1325 if (errno == ENOSPC) 1326 ntfs_log_trace("No attributes left that could be moved out.\n"); 1327 return -1; 1328 } 1329 1330 /** 1331 * ntfs_inode_update_times - update selected time fields for ntfs inode 1332 * @ni: ntfs inode for which update time fields 1333 * @mask: select which time fields should be updated 1334 * 1335 * This function updates time fields to current time. Fields to update are 1336 * selected using @mask (see enum @ntfs_time_update_flags for posssible values). 1337 */ 1338 void ntfs_inode_update_times(ntfs_inode *ni, ntfs_time_update_flags mask) 1339 { 1340 ntfs_time now; 1341 1342 if (!ni) { 1343 ntfs_log_error("%s(): Invalid arguments.\n", __FUNCTION__); 1344 return; 1345 } 1346 1347 if ((ni->mft_no < FILE_first_user && ni->mft_no != FILE_root) || 1348 NVolReadOnly(ni->vol) || !mask) 1349 return; 1350 1351 now = ntfs_current_time(); 1352 if (mask & NTFS_UPDATE_ATIME) 1353 ni->last_access_time = now; 1354 if (mask & NTFS_UPDATE_MTIME) 1355 ni->last_data_change_time = now; 1356 if (mask & NTFS_UPDATE_CTIME) 1357 ni->last_mft_change_time = now; 1358 1359 NInoFileNameSetDirty(ni); 1360 NInoSetDirty(ni); 1361 } 1362 1363 /** 1364 * ntfs_inode_badclus_bad - check for $Badclus:$Bad data attribute 1365 * @mft_no: mft record number where @attr is present 1366 * @attr: attribute record used to check for the $Bad attribute 1367 * 1368 * Check if the mft record given by @mft_no and @attr contains the bad sector 1369 * list. Please note that mft record numbers describing $Badclus extent inodes 1370 * will not match the current $Badclus:$Bad check. 1371 * 1372 * On success return 1 if the file is $Badclus:$Bad, otherwise return 0. 1373 * On error return -1 with errno set to the error code. 1374 */ 1375 int ntfs_inode_badclus_bad(u64 mft_no, ATTR_RECORD *attr) 1376 { 1377 int len, ret = 0; 1378 ntfschar *ustr; 1379 1380 if (!attr) { 1381 ntfs_log_error("Invalid argument.\n"); 1382 errno = EINVAL; 1383 return -1; 1384 } 1385 1386 if (mft_no != FILE_BadClus) 1387 return 0; 1388 1389 if (attr->type != AT_DATA) 1390 return 0; 1391 1392 if ((ustr = ntfs_str2ucs("$Bad", &len)) == NULL) { 1393 ntfs_log_perror("Couldn't convert '$Bad' to Unicode"); 1394 return -1; 1395 } 1396 1397 if (ustr && ntfs_names_are_equal(ustr, len, 1398 (ntfschar *)((u8 *)attr + le16_to_cpu(attr->name_offset)), 1399 attr->name_length, 0, NULL, 0)) 1400 ret = 1; 1401 1402 ntfs_ucsfree(ustr); 1403 1404 return ret; 1405 } 1406 1407 #ifdef HAVE_SETXATTR /* extended attributes interface required */ 1408 1409 /* 1410 * Get high precision NTFS times 1411 * 1412 * They are returned in following order : create, update, access, change 1413 * provided they fit in requested size. 1414 * 1415 * Returns the modified size if successfull (or 32 if buffer size is null) 1416 * -errno if failed 1417 */ 1418 1419 int ntfs_inode_get_times(ntfs_inode *ni, char *value, size_t size) 1420 { 1421 ntfs_attr_search_ctx *ctx; 1422 STANDARD_INFORMATION *std_info; 1423 u64 *times; 1424 int ret; 1425 1426 ret = 0; 1427 ctx = ntfs_attr_get_search_ctx(ni, NULL); 1428 if (ctx) { 1429 if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, AT_UNNAMED, 1430 0, CASE_SENSITIVE, 0, NULL, 0, ctx)) { 1431 ntfs_log_perror("Failed to get standard info (inode %lld)", 1432 (long long)ni->mft_no); 1433 } else { 1434 std_info = (STANDARD_INFORMATION *)((u8 *)ctx->attr + 1435 le16_to_cpu(ctx->attr->value_offset)); 1436 if (value && (size >= 8)) { 1437 times = (u64*)value; 1438 times[0] = le64_to_cpu(std_info->creation_time); 1439 ret = 8; 1440 if (size >= 16) { 1441 times[1] = le64_to_cpu(std_info->last_data_change_time); 1442 ret = 16; 1443 } 1444 if (size >= 24) { 1445 times[2] = le64_to_cpu(std_info->last_access_time); 1446 ret = 24; 1447 } 1448 if (size >= 32) { 1449 times[3] = le64_to_cpu(std_info->last_mft_change_time); 1450 ret = 32; 1451 } 1452 } else 1453 if (!size) 1454 ret = 32; 1455 else 1456 ret = -ERANGE; 1457 } 1458 ntfs_attr_put_search_ctx(ctx); 1459 } 1460 return (ret ? ret : -errno); 1461 } 1462 1463 /* 1464 * Set high precision NTFS times 1465 * 1466 * They are expected in this order : create, update, access 1467 * provided they are present in input. The change time is set to 1468 * current time. 1469 * 1470 * The times are inserted directly in the standard_information and 1471 * file names attributes to avoid manipulating low precision times 1472 * 1473 * Returns 0 if success 1474 * -1 if there were an error (described by errno) 1475 */ 1476 1477 int ntfs_inode_set_times(ntfs_inode *ni, const char *value, size_t size, 1478 int flags) 1479 { 1480 ntfs_attr_search_ctx *ctx; 1481 STANDARD_INFORMATION *std_info; 1482 FILE_NAME_ATTR *fn; 1483 const u64 *times; 1484 ntfs_time now; 1485 int cnt; 1486 int ret; 1487 1488 ret = -1; 1489 if ((size >= 8) && !(flags & XATTR_CREATE)) { 1490 times = (const u64*)value; 1491 now = ntfs_current_time(); 1492 /* update the standard information attribute */ 1493 ctx = ntfs_attr_get_search_ctx(ni, NULL); 1494 if (ctx) { 1495 if (ntfs_attr_lookup(AT_STANDARD_INFORMATION, 1496 AT_UNNAMED, 0, CASE_SENSITIVE, 1497 0, NULL, 0, ctx)) { 1498 ntfs_log_perror("Failed to get standard info (inode %lld)", 1499 (long long)ni->mft_no); 1500 } else { 1501 std_info = (STANDARD_INFORMATION *)((u8 *)ctx->attr + 1502 le16_to_cpu(ctx->attr->value_offset)); 1503 /* 1504 * Mark times set to avoid overwriting 1505 * them when the inode is closed. 1506 * The inode structure must also be updated 1507 * (with loss of precision) because of cacheing. 1508 * TODO : use NTFS precision in inode, and 1509 * return sub-second times in getattr() 1510 */ 1511 set_nino_flag(ni, TimesSet); 1512 std_info->creation_time = cpu_to_le64(times[0]); 1513 ni->creation_time 1514 = std_info->creation_time; 1515 if (size >= 16) { 1516 std_info->last_data_change_time = cpu_to_le64(times[1]); 1517 ni->last_data_change_time 1518 = std_info->last_data_change_time; 1519 } 1520 if (size >= 24) { 1521 std_info->last_access_time = cpu_to_le64(times[2]); 1522 ni->last_access_time 1523 = std_info->last_access_time; 1524 } 1525 std_info->last_mft_change_time = now; 1526 ni->last_mft_change_time = now; 1527 ntfs_inode_mark_dirty(ctx->ntfs_ino); 1528 NInoFileNameSetDirty(ni); 1529 1530 /* update the file names attributes */ 1531 ntfs_attr_reinit_search_ctx(ctx); 1532 cnt = 0; 1533 while (!ntfs_attr_lookup(AT_FILE_NAME, 1534 AT_UNNAMED, 0, CASE_SENSITIVE, 1535 0, NULL, 0, ctx)) { 1536 fn = (FILE_NAME_ATTR*)((u8 *)ctx->attr + 1537 le16_to_cpu(ctx->attr->value_offset)); 1538 fn->creation_time 1539 = cpu_to_le64(times[0]); 1540 if (size >= 16) 1541 fn->last_data_change_time 1542 = cpu_to_le64(times[1]); 1543 if (size >= 24) 1544 fn->last_access_time 1545 = cpu_to_le64(times[2]); 1546 fn->last_mft_change_time = now; 1547 cnt++; 1548 } 1549 if (cnt) 1550 ret = 0; 1551 else { 1552 ntfs_log_perror("Failed to get file names (inode %lld)", 1553 (long long)ni->mft_no); 1554 } 1555 } 1556 ntfs_attr_put_search_ctx(ctx); 1557 } 1558 } else 1559 if (size < 8) 1560 errno = ERANGE; 1561 else 1562 errno = EEXIST; 1563 return (ret); 1564 } 1565 1566 #endif /* HAVE_SETXATTR */ 1567