Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge master.kernel.org:/pub/scm/linux/kernel/git/aia21/ntfs-2.6

+2533 -907
+27 -2
Documentation/filesystems/ntfs.txt
··· 21 21 ======== 22 22 23 23 Linux-NTFS comes with a number of user-space programs known as ntfsprogs. 24 - These include mkntfs, a full-featured ntfs file system format utility, 24 + These include mkntfs, a full-featured ntfs filesystem format utility, 25 25 ntfsundelete used for recovering files that were unintentionally deleted 26 26 from an NTFS volume and ntfsresize which is used to resize an NTFS partition. 27 27 See the web site for more information. ··· 149 149 name, if it exists. If case_sensitive, you will need 150 150 to provide the correct case of the short file name. 151 151 152 - errors=opt What to do when critical file system errors are found. 152 + disable_sparse=<BOOL> If disable_sparse is specified, creation of sparse 153 + regions, i.e. holes, inside files is disabled for the 154 + volume (for the duration of this mount only). By 155 + default, creation of sparse regions is enabled, which 156 + is consistent with the behaviour of traditional Unix 157 + filesystems. 158 + 159 + errors=opt What to do when critical filesystem errors are found. 153 160 Following values can be used for "opt": 154 161 continue: DEFAULT, try to clean-up as much as 155 162 possible, e.g. marking a corrupt inode as ··· 439 432 440 433 Note, a technical ChangeLog aimed at kernel hackers is in fs/ntfs/ChangeLog. 441 434 435 + 2.1.23: 436 + - Stamp the user space journal, aka transaction log, aka $UsnJrnl, if 437 + it is present and active thus telling Windows and applications using 438 + the transaction log that changes can have happened on the volume 439 + which are not recorded in $UsnJrnl. 440 + - Detect the case when Windows has been hibernated (suspended to disk) 441 + and if this is the case do not allow (re)mounting read-write to 442 + prevent data corruption when you boot back into the suspended 443 + Windows session. 444 + - Implement extension of resident files using the normal file write 445 + code paths, i.e. most very small files can be extended to be a little 446 + bit bigger but not by much. 447 + - Add new mount option "disable_sparse". (See list of mount options 448 + above for details.) 449 + - Improve handling of ntfs volumes with errors and strange boot sectors 450 + in particular. 451 + - Fix various bugs including a nasty deadlock that appeared in recent 452 + kernels (around 2.6.11-2.6.12 timeframe). 442 453 2.1.22: 443 454 - Improve handling of ntfs volumes with errors. 444 455 - Fix various bugs and race conditions.
+161 -18
fs/ntfs/ChangeLog
··· 1 1 ToDo/Notes: 2 2 - Find and fix bugs. 3 - - Checkpoint or disable the user space journal ($UsnJrnl). 4 3 - In between ntfs_prepare/commit_write, need exclusion between 5 - simultaneous file extensions. Need perhaps an NInoResizeUnderway() 6 - flag which we can set in ntfs_prepare_write() and clear again in 7 - ntfs_commit_write(). Just have to be careful in readpage/writepage, 8 - as well as in truncate, that we play nice... We might need to have 9 - a data_size field in the ntfs_inode to store the real attribute 10 - length. Also need to be careful with initialized_size extention in 4 + simultaneous file extensions. This is given to us by holding i_sem 5 + on the inode. The only places in the kernel when a file is resized 6 + are prepare/commit write and truncate for both of which i_sem is 7 + held. Just have to be careful in readpage/writepage and all other 8 + helpers not running under i_sem that we play nice... 9 + Also need to be careful with initialized_size extention in 11 10 ntfs_prepare_write. Basically, just be _very_ careful in this code... 12 - OTOH, perhaps i_sem, which is held accross generic_file_write is 13 - sufficient for synchronisation here. We then just need to make sure 14 - ntfs_readpage/writepage/truncate interoperate properly with us. 15 - UPDATE: The above is all ok as it is due to i_sem held. The only 16 - thing that needs to be checked is ntfs_writepage() which does not 17 - hold i_sem. It cannot change i_size but it needs to cope with a 18 - concurrent i_size change. 11 + UPDATE: The only things that need to be checked are read/writepage 12 + which do not hold i_sem. Note writepage cannot change i_size but it 13 + needs to cope with a concurrent i_size change, just like readpage. 14 + Also both need to cope with concurrent changes to the other sizes, 15 + i.e. initialized/allocated/compressed size, as well. 19 16 - Implement mft.c::sync_mft_mirror_umount(). We currently will just 20 17 leave the volume dirty on umount if the final iput(vol->mft_ino) 21 18 causes a write of any mirrored mft records due to the mft mirror ··· 22 25 - Enable the code for setting the NT4 compatibility flag when we start 23 26 making NTFS 1.2 specific modifications. 24 27 25 - 2.1.23-WIP 28 + 2.1.23 - Implement extension of resident files and make writing safe as well as 29 + many bug fixes, cleanups, and enhancements... 26 30 27 31 - Add printk rate limiting for ntfs_warning() and ntfs_error() when 28 32 compiled without debug. This avoids a possible denial of service 29 33 attack. Thanks to Carl-Daniel Hailfinger from SuSE for pointing this 30 34 out. 35 + - Fix compilation warnings on ia64. (Randy Dunlap) 36 + - Use i_size_{read,write}() instead of reading i_size by hand and cache 37 + the value where apropriate. 38 + - Add size_lock to the ntfs_inode structure. This is an rw spinlock 39 + and it locks against access to the inode sizes. Note, ->size_lock 40 + is also accessed from irq context so you must use the _irqsave and 41 + _irqrestore lock and unlock functions, respectively. Protect all 42 + accesses to allocated_size, initialized_size, and compressed_size. 43 + - Minor optimization to fs/ntfs/super.c::ntfs_statfs() and its helpers. 44 + - Implement extension of resident files in the regular file write code 45 + paths (fs/ntfs/aops.c::ntfs_{prepare,commit}_write()). At present 46 + this only works until the data attribute becomes too big for the mft 47 + record after which we abort the write returning -EOPNOTSUPP from 48 + ntfs_prepare_write(). 49 + - Add disable_sparse mount option together with a per volume sparse 50 + enable bit which is set appropriately and a per inode sparse disable 51 + bit which is preset on some system file inodes as appropriate. 52 + - Enforce that sparse support is disabled on NTFS volumes pre 3.0. 53 + - Fix a bug in fs/ntfs/runlist.c::ntfs_mapping_pairs_decompress() in 54 + the creation of the unmapped runlist element for the base attribute 55 + extent. 56 + - Split ntfs_map_runlist() into ntfs_map_runlist() and a non-locking 57 + helper ntfs_map_runlist_nolock() which is used by ntfs_map_runlist(). 58 + This allows us to map runlist fragments with the runlist lock already 59 + held without having to drop and reacquire it around the call. Adapt 60 + all callers. 61 + - Change ntfs_find_vcn() to ntfs_find_vcn_nolock() which takes a locked 62 + runlist. This allows us to find runlist elements with the runlist 63 + lock already held without having to drop and reacquire it around the 64 + call. Adapt all callers. 65 + - Change time to u64 in time.h::ntfs2utc() as it otherwise generates a 66 + warning in the do_div() call on sparc32. Thanks to Meelis Roos for 67 + the report and analysis of the warning. 68 + - Fix a nasty runlist merge bug when merging two holes. 69 + - Set the ntfs_inode->allocated_size to the real allocated size in the 70 + mft record for resident attributes (fs/ntfs/inode.c). 71 + - Small readability cleanup to use "a" instead of "ctx->attr" 72 + everywhere (fs/ntfs/inode.c). 73 + - Make fs/ntfs/namei.c::ntfs_get_{parent,dentry} static and move the 74 + definition of ntfs_export_ops from fs/ntfs/super.c to namei.c. Also, 75 + declare ntfs_export_ops in fs/ntfs/ntfs.h. 76 + - Correct sparse file handling. The compressed values need to be 77 + checked and set in the ntfs inode as done for compressed files and 78 + the compressed size needs to be used for vfs inode->i_blocks instead 79 + of the allocated size, again, as done for compressed files. 80 + - Add AT_EA in addition to AT_DATA to whitelist for being allowed to be 81 + non-resident in fs/ntfs/attrib.c::ntfs_attr_can_be_non_resident(). 82 + - Add fs/ntfs/attrib.c::ntfs_attr_vcn_to_lcn_nolock() used by the new 83 + write code. 84 + - Fix bug in fs/ntfs/attrib.c::ntfs_find_vcn_nolock() where after 85 + dropping the read lock and taking the write lock we were not checking 86 + whether someone else did not already do the work we wanted to do. 87 + - Rename fs/ntfs/attrib.c::ntfs_find_vcn_nolock() to 88 + ntfs_attr_find_vcn_nolock() and update all callers. 89 + - Add fs/ntfs/attrib.[hc]::ntfs_attr_make_non_resident(). 90 + - Fix sign of various error return values to be negative in 91 + fs/ntfs/lcnalloc.c. 92 + - Modify ->readpage and ->writepage (fs/ntfs/aops.c) so they detect and 93 + handle the case where an attribute is converted from resident to 94 + non-resident by a concurrent file write. 95 + - Remove checks for NULL before calling kfree() since kfree() does the 96 + checking itself. (Jesper Juhl) 97 + - Some utilities modify the boot sector but do not update the checksum. 98 + Thus, relax the checking in fs/ntfs/super.c::is_boot_sector_ntfs() to 99 + only emit a warning when the checksum is incorrect rather than 100 + refusing the mount. Thanks to Bernd Casimir for pointing this 101 + problem out. 102 + - Update attribute definition handling. 103 + - Add NTFS_MAX_CLUSTER_SIZE and NTFS_MAX_PAGES_PER_CLUSTER constants. 104 + - Use NTFS_MAX_CLUSTER_SIZE in super.c instead of hard coding 0x10000. 105 + - Use MAX_BUF_PER_PAGE instead of variable sized array allocation for 106 + better code generation and one less sparse warning in fs/ntfs/aops.c. 107 + - Remove spurious void pointer casts from fs/ntfs/. (Pekka Enberg) 108 + - Use C99 style structure initialization after memory allocation where 109 + possible (fs/ntfs/{attrib.c,index.c,super.c}). Thanks to Al Viro and 110 + Pekka Enberg. 111 + - Stamp the transaction log ($UsnJrnl), aka user space journal, if it 112 + is active on the volume and we are mounting read-write or remounting 113 + from read-only to read-write. 114 + - Fix a bug in address space operations error recovery code paths where 115 + if the runlist was not mapped at all and a mapping error occured we 116 + would leave the runlist locked on exit to the function so that the 117 + next access to the same file would try to take the lock and deadlock. 118 + - Detect the case when Windows has been suspended to disk on the volume 119 + to be mounted and if this is the case do not allow (re)mounting 120 + read-write. This is done by parsing hiberfil.sys if present. 121 + - Fix several occurences of a bug where we would perform 'var & ~const' 122 + with a 64-bit variable and a int, i.e. 32-bit, constant. This causes 123 + the higher order 32-bits of the 64-bit variable to be zeroed. To fix 124 + this cast the 'const' to the same 64-bit type as 'var'. 125 + - Change the runlist terminator of the newly allocated cluster(s) to 126 + LCN_ENOENT in ntfs_attr_make_non_resident(). Otherwise the runlist 127 + code gets confused. 128 + - Add an extra parameter @last_vcn to ntfs_get_size_for_mapping_pairs() 129 + and ntfs_mapping_pairs_build() to allow the runlist encoding to be 130 + partial which is desirable when filling holes in sparse attributes. 131 + Update all callers. 132 + - Change ntfs_map_runlist_nolock() to only decompress the mapping pairs 133 + if the requested vcn is inside it. Otherwise we get into problems 134 + when we try to map an out of bounds vcn because we then try to map 135 + the already mapped runlist fragment which causes 136 + ntfs_mapping_pairs_decompress() to fail and return error. Update 137 + ntfs_attr_find_vcn_nolock() accordingly. 138 + - Fix a nasty deadlock that appeared in recent kernels. 139 + The situation: VFS inode X on a mounted ntfs volume is dirty. For 140 + same inode X, the ntfs_inode is dirty and thus corresponding on-disk 141 + inode, i.e. mft record, which is in a dirty PAGE_CACHE_PAGE belonging 142 + to the table of inodes, i.e. $MFT, inode 0. 143 + What happens: 144 + Process 1: sys_sync()/umount()/whatever... calls 145 + __sync_single_inode() for $MFT -> do_writepages() -> write_page for 146 + the dirty page containing the on-disk inode X, the page is now locked 147 + -> ntfs_write_mst_block() which clears PageUptodate() on the page to 148 + prevent anyone else getting hold of it whilst it does the write out. 149 + This is necessary as the on-disk inode needs "fixups" applied before 150 + the write to disk which are removed again after the write and 151 + PageUptodate is then set again. It then analyses the page looking 152 + for dirty on-disk inodes and when it finds one it calls 153 + ntfs_may_write_mft_record() to see if it is safe to write this 154 + on-disk inode. This then calls ilookup5() to check if the 155 + corresponding VFS inode is in icache(). This in turn calls ifind() 156 + which waits on the inode lock via wait_on_inode whilst holding the 157 + global inode_lock. 158 + Process 2: pdflush results in a call to __sync_single_inode for the 159 + same VFS inode X on the ntfs volume. This locks the inode (I_LOCK) 160 + then calls write-inode -> ntfs_write_inode -> map_mft_record() -> 161 + read_cache_page() for the page (in page cache of table of inodes 162 + $MFT, inode 0) containing the on-disk inode. This page has 163 + PageUptodate() clear because of Process 1 (see above) so 164 + read_cache_page() blocks when it tries to take the page lock for the 165 + page so it can call ntfs_read_page(). 166 + Thus Process 1 is holding the page lock on the page containing the 167 + on-disk inode X and it is waiting on the inode X to be unlocked in 168 + ifind() so it can write the page out and then unlock the page. 169 + And Process 2 is holding the inode lock on inode X and is waiting for 170 + the page to be unlocked so it can call ntfs_readpage() or discover 171 + that Process 1 set PageUptodate() again and use the page. 172 + Thus we have a deadlock due to ifind() waiting on the inode lock. 173 + The solution: The fix is to use the newly introduced 174 + ilookup5_nowait() which does not wait on the inode's lock and hence 175 + avoids the deadlock. This is safe as we do not care about the VFS 176 + inode and only use the fact that it is in the VFS inode cache and the 177 + fact that the vfs and ntfs inodes are one struct in memory to find 178 + the ntfs inode in memory if present. Also, the ntfs inode has its 179 + own locking so it does not matter if the vfs inode is locked. 31 180 32 181 2.1.22 - Many bug and race fixes and error handling improvements. 33 182 ··· 1180 1037 - Further runlist merging work. (Richard Russon) 1181 1038 - Backwards compatibility for gcc-2.95. (Richard Russon) 1182 1039 - Update to kernel 2.5.5-pre1 and rediff the now tiny patch. 1183 - - Convert to new file system declaration using ->ntfs_get_sb() and 1040 + - Convert to new filesystem declaration using ->ntfs_get_sb() and 1184 1041 replacing ntfs_read_super() with ntfs_fill_super(). 1185 1042 - Set s_maxbytes to MAX_LFS_FILESIZE to avoid page cache page index 1186 1043 overflow on 32-bit architectures. ··· 1476 1333 The driver is now actually useful! Yey. (-: It undoubtedly has got bugs 1477 1334 though and it doesn't implement accesssing compressed files yet. Also, 1478 1335 accessing files with attribute list attributes is not implemented yet 1479 - either. But for small or simple file systems it should work and allow 1336 + either. But for small or simple filesystems it should work and allow 1480 1337 you to list directories, use stat on directory entries and the file 1481 1338 system, open, read, mmap and llseek around in files. A big mile stone 1482 1339 has been reached! ··· 1484 1341 tng-0.0.0 - Initial version tag. 1485 1342 1486 1343 Initial driver implementation. The driver can mount and umount simple 1487 - NTFS file systems (i.e. ones without attribute lists in the system 1344 + NTFS filesystems (i.e. ones without attribute lists in the system 1488 1345 files). If the mount fails there might be problems in the error handling 1489 1346 code paths, so be warned. Otherwise it seems to be loading the system 1490 1347 files nicely and the mft record read mapping/unmapping seems to be
+2 -2
fs/ntfs/Makefile
··· 6 6 index.o inode.o mft.o mst.o namei.o runlist.o super.o sysctl.o \ 7 7 unistr.o upcase.o 8 8 9 - EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.22\" 9 + EXTRA_CFLAGS = -DNTFS_VERSION=\"2.1.23\" 10 10 11 11 ifeq ($(CONFIG_NTFS_DEBUG),y) 12 12 EXTRA_CFLAGS += -DDEBUG ··· 15 15 ifeq ($(CONFIG_NTFS_RW),y) 16 16 EXTRA_CFLAGS += -DNTFS_RW 17 17 18 - ntfs-objs += bitmap.o lcnalloc.o logfile.o quota.o 18 + ntfs-objs += bitmap.o lcnalloc.o logfile.o quota.o usnjrnl.o 19 19 endif
+110 -56
fs/ntfs/aops.c
··· 2 2 * aops.c - NTFS kernel address space operations and page cache handling. 3 3 * Part of the Linux-NTFS project. 4 4 * 5 - * Copyright (c) 2001-2004 Anton Altaparmakov 5 + * Copyright (c) 2001-2005 Anton Altaparmakov 6 6 * Copyright (c) 2002 Richard Russon 7 7 * 8 8 * This program/include file is free software; you can redistribute it and/or ··· 66 66 ni = NTFS_I(page->mapping->host); 67 67 68 68 if (likely(uptodate)) { 69 - s64 file_ofs; 69 + s64 file_ofs, initialized_size; 70 70 71 71 set_buffer_uptodate(bh); 72 72 73 73 file_ofs = ((s64)page->index << PAGE_CACHE_SHIFT) + 74 74 bh_offset(bh); 75 + read_lock_irqsave(&ni->size_lock, flags); 76 + initialized_size = ni->initialized_size; 77 + read_unlock_irqrestore(&ni->size_lock, flags); 75 78 /* Check for the current buffer head overflowing. */ 76 - if (file_ofs + bh->b_size > ni->initialized_size) { 79 + if (file_ofs + bh->b_size > initialized_size) { 77 80 char *addr; 78 81 int ofs = 0; 79 82 80 - if (file_ofs < ni->initialized_size) 81 - ofs = ni->initialized_size - file_ofs; 83 + if (file_ofs < initialized_size) 84 + ofs = initialized_size - file_ofs; 82 85 addr = kmap_atomic(page, KM_BIO_SRC_IRQ); 83 86 memset(addr + bh_offset(bh) + ofs, 0, bh->b_size - ofs); 84 87 flush_dcache_page(page); ··· 135 132 i * rec_size), rec_size); 136 133 flush_dcache_page(page); 137 134 kunmap_atomic(addr, KM_BIO_SRC_IRQ); 138 - if (likely(!PageError(page) && page_uptodate)) 135 + if (likely(page_uptodate && !PageError(page))) 139 136 SetPageUptodate(page); 140 137 } 141 138 unlock_page(page); ··· 171 168 runlist_element *rl; 172 169 struct buffer_head *bh, *head, *arr[MAX_BUF_PER_PAGE]; 173 170 sector_t iblock, lblock, zblock; 171 + unsigned long flags; 174 172 unsigned int blocksize, vcn_ofs; 175 173 int i, nr; 176 174 unsigned char blocksize_bits; ··· 194 190 } 195 191 196 192 iblock = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits); 193 + read_lock_irqsave(&ni->size_lock, flags); 197 194 lblock = (ni->allocated_size + blocksize - 1) >> blocksize_bits; 198 195 zblock = (ni->initialized_size + blocksize - 1) >> blocksize_bits; 196 + read_unlock_irqrestore(&ni->size_lock, flags); 199 197 200 198 /* Loop through all the buffers in the page. */ 201 199 rl = NULL; ··· 264 258 goto lock_retry_remap; 265 259 rl = NULL; 266 260 lcn = err; 267 - } 261 + } else if (!rl) 262 + up_read(&ni->runlist.lock); 268 263 /* Hard error, zero out region. */ 269 264 bh->b_blocknr = -1; 270 265 SetPageError(page); ··· 348 341 */ 349 342 static int ntfs_readpage(struct file *file, struct page *page) 350 343 { 351 - loff_t i_size; 352 344 ntfs_inode *ni, *base_ni; 353 345 u8 *kaddr; 354 346 ntfs_attr_search_ctx *ctx; 355 347 MFT_RECORD *mrec; 348 + unsigned long flags; 356 349 u32 attr_len; 357 350 int err = 0; 358 351 352 + retry_readpage: 359 353 BUG_ON(!PageLocked(page)); 360 354 /* 361 355 * This can potentially happen because we clear PageUptodate() during ··· 391 383 * Attribute is resident, implying it is not compressed or encrypted. 392 384 * This also means the attribute is smaller than an mft record and 393 385 * hence smaller than a page, so can simply zero out any pages with 394 - * index above 0. We can also do this if the file size is 0. 386 + * index above 0. 395 387 */ 396 - if (unlikely(page->index > 0 || !i_size_read(VFS_I(ni)))) { 388 + if (unlikely(page->index > 0)) { 397 389 kaddr = kmap_atomic(page, KM_USER0); 398 390 memset(kaddr, 0, PAGE_CACHE_SIZE); 399 391 flush_dcache_page(page); ··· 410 402 err = PTR_ERR(mrec); 411 403 goto err_out; 412 404 } 405 + /* 406 + * If a parallel write made the attribute non-resident, drop the mft 407 + * record and retry the readpage. 408 + */ 409 + if (unlikely(NInoNonResident(ni))) { 410 + unmap_mft_record(base_ni); 411 + goto retry_readpage; 412 + } 413 413 ctx = ntfs_attr_get_search_ctx(base_ni, mrec); 414 414 if (unlikely(!ctx)) { 415 415 err = -ENOMEM; ··· 428 412 if (unlikely(err)) 429 413 goto put_unm_err_out; 430 414 attr_len = le32_to_cpu(ctx->attr->data.resident.value_length); 431 - i_size = i_size_read(VFS_I(ni)); 432 - if (unlikely(attr_len > i_size)) 433 - attr_len = i_size; 415 + read_lock_irqsave(&ni->size_lock, flags); 416 + if (unlikely(attr_len > ni->initialized_size)) 417 + attr_len = ni->initialized_size; 418 + read_unlock_irqrestore(&ni->size_lock, flags); 434 419 kaddr = kmap_atomic(page, KM_USER0); 435 420 /* Copy the data to the page. */ 436 421 memcpy(kaddr, (u8*)ctx->attr + ··· 480 463 { 481 464 VCN vcn; 482 465 LCN lcn; 466 + s64 initialized_size; 467 + loff_t i_size; 483 468 sector_t block, dblock, iblock; 484 469 struct inode *vi; 485 470 ntfs_inode *ni; 486 471 ntfs_volume *vol; 487 472 runlist_element *rl; 488 473 struct buffer_head *bh, *head; 474 + unsigned long flags; 489 475 unsigned int blocksize, vcn_ofs; 490 476 int err; 491 477 BOOL need_end_writeback; ··· 530 510 /* The first block in the page. */ 531 511 block = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits); 532 512 513 + read_lock_irqsave(&ni->size_lock, flags); 514 + i_size = i_size_read(vi); 515 + initialized_size = ni->initialized_size; 516 + read_unlock_irqrestore(&ni->size_lock, flags); 517 + 533 518 /* The first out of bounds block for the data size. */ 534 - dblock = (vi->i_size + blocksize - 1) >> blocksize_bits; 519 + dblock = (i_size + blocksize - 1) >> blocksize_bits; 535 520 536 521 /* The last (fully or partially) initialized block. */ 537 - iblock = ni->initialized_size >> blocksize_bits; 522 + iblock = initialized_size >> blocksize_bits; 538 523 539 524 /* 540 525 * Be very careful. We have no exclusion from __set_page_dirty_buffers ··· 584 559 585 560 /* Make sure we have enough initialized size. */ 586 561 if (unlikely((block >= iblock) && 587 - (ni->initialized_size < vi->i_size))) { 562 + (initialized_size < i_size))) { 588 563 /* 589 564 * If this page is fully outside initialized size, zero 590 565 * out all pages between the current initialized size ··· 691 666 goto lock_retry_remap; 692 667 rl = NULL; 693 668 lcn = err; 694 - } 669 + } else if (!rl) 670 + up_read(&ni->runlist.lock); 695 671 /* Failed to map the buffer, even after retrying. */ 696 672 bh->b_blocknr = -1; 697 673 ntfs_error(vol->sb, "Failed to write to inode 0x%lx, " ··· 827 801 ntfs_inode *ni = NTFS_I(vi); 828 802 ntfs_volume *vol = ni->vol; 829 803 u8 *kaddr; 830 - unsigned char bh_size_bits = vi->i_blkbits; 831 - unsigned int bh_size = 1 << bh_size_bits; 832 804 unsigned int rec_size = ni->itype.index.block_size; 833 805 ntfs_inode *locked_nis[PAGE_CACHE_SIZE / rec_size]; 834 806 struct buffer_head *bh, *head, *tbh, *rec_start_bh; 835 - int max_bhs = PAGE_CACHE_SIZE / bh_size; 836 - struct buffer_head *bhs[max_bhs]; 807 + struct buffer_head *bhs[MAX_BUF_PER_PAGE]; 837 808 runlist_element *rl; 838 - int i, nr_locked_nis, nr_recs, nr_bhs, bhs_per_rec, err, err2; 839 - unsigned rec_size_bits; 809 + int i, nr_locked_nis, nr_recs, nr_bhs, max_bhs, bhs_per_rec, err, err2; 810 + unsigned bh_size, rec_size_bits; 840 811 BOOL sync, is_mft, page_is_dirty, rec_is_dirty; 812 + unsigned char bh_size_bits; 841 813 842 814 ntfs_debug("Entering for inode 0x%lx, attribute type 0x%x, page index " 843 815 "0x%lx.", vi->i_ino, ni->type, page->index); ··· 850 826 */ 851 827 BUG_ON(!(is_mft || S_ISDIR(vi->i_mode) || 852 828 (NInoAttr(ni) && ni->type == AT_INDEX_ALLOCATION))); 829 + bh_size_bits = vi->i_blkbits; 830 + bh_size = 1 << bh_size_bits; 831 + max_bhs = PAGE_CACHE_SIZE / bh_size; 853 832 BUG_ON(!max_bhs); 833 + BUG_ON(max_bhs > MAX_BUF_PER_PAGE); 854 834 855 835 /* Were we called for sync purposes? */ 856 836 sync = (wbc->sync_mode == WB_SYNC_ALL); ··· 874 846 (PAGE_CACHE_SHIFT - bh_size_bits); 875 847 876 848 /* The first out of bounds block for the data size. */ 877 - dblock = (vi->i_size + bh_size - 1) >> bh_size_bits; 849 + dblock = (i_size_read(vi) + bh_size - 1) >> bh_size_bits; 878 850 879 851 rl = NULL; 880 852 err = err2 = nr_bhs = nr_recs = nr_locked_nis = 0; ··· 886 858 if (likely(block < rec_block)) { 887 859 if (unlikely(block >= dblock)) { 888 860 clear_buffer_dirty(bh); 861 + set_buffer_uptodate(bh); 889 862 continue; 890 863 } 891 864 /* ··· 967 938 if (err2 == -ENOMEM) 968 939 page_is_dirty = TRUE; 969 940 lcn = err2; 970 - } else 941 + } else { 971 942 err2 = -EIO; 943 + if (!rl) 944 + up_read(&ni->runlist.lock); 945 + } 972 946 /* Hard error. Abort writing this record. */ 973 947 if (!err || err == -ENOMEM) 974 948 err = err2; ··· 981 949 "attribute type 0x%x) because " 982 950 "its location on disk could " 983 951 "not be determined (error " 984 - "code %lli).", (s64)block << 952 + "code %lli).", 953 + (long long)block << 985 954 bh_size_bits >> 986 955 vol->mft_record_size_bits, 987 956 ni->mft_no, ni->type, ··· 1256 1223 static int ntfs_writepage(struct page *page, struct writeback_control *wbc) 1257 1224 { 1258 1225 loff_t i_size; 1259 - struct inode *vi; 1260 - ntfs_inode *ni, *base_ni; 1226 + struct inode *vi = page->mapping->host; 1227 + ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi); 1261 1228 char *kaddr; 1262 - ntfs_attr_search_ctx *ctx; 1263 - MFT_RECORD *m; 1229 + ntfs_attr_search_ctx *ctx = NULL; 1230 + MFT_RECORD *m = NULL; 1264 1231 u32 attr_len; 1265 1232 int err; 1266 1233 1234 + retry_writepage: 1267 1235 BUG_ON(!PageLocked(page)); 1268 - 1269 - vi = page->mapping->host; 1270 1236 i_size = i_size_read(vi); 1271 - 1272 1237 /* Is the page fully outside i_size? (truncate in progress) */ 1273 1238 if (unlikely(page->index >= (i_size + PAGE_CACHE_SIZE - 1) >> 1274 1239 PAGE_CACHE_SHIFT)) { ··· 1279 1248 ntfs_debug("Write outside i_size - truncated?"); 1280 1249 return 0; 1281 1250 } 1282 - ni = NTFS_I(vi); 1283 - 1284 1251 /* NInoNonResident() == NInoIndexAllocPresent() */ 1285 1252 if (NInoNonResident(ni)) { 1286 1253 /* ··· 1355 1326 ctx = NULL; 1356 1327 goto err_out; 1357 1328 } 1329 + /* 1330 + * If a parallel write made the attribute non-resident, drop the mft 1331 + * record and retry the writepage. 1332 + */ 1333 + if (unlikely(NInoNonResident(ni))) { 1334 + unmap_mft_record(base_ni); 1335 + goto retry_writepage; 1336 + } 1358 1337 ctx = ntfs_attr_get_search_ctx(base_ni, m); 1359 1338 if (unlikely(!ctx)) { 1360 1339 err = -ENOMEM; ··· 1404 1367 */ 1405 1368 1406 1369 attr_len = le32_to_cpu(ctx->attr->data.resident.value_length); 1407 - i_size = i_size_read(VFS_I(ni)); 1408 - kaddr = kmap_atomic(page, KM_USER0); 1370 + i_size = i_size_read(vi); 1409 1371 if (unlikely(attr_len > i_size)) { 1410 - /* Zero out of bounds area in the mft record. */ 1411 - memset((u8*)ctx->attr + le16_to_cpu( 1412 - ctx->attr->data.resident.value_offset) + 1413 - i_size, 0, attr_len - i_size); 1414 1372 attr_len = i_size; 1373 + ctx->attr->data.resident.value_length = cpu_to_le32(attr_len); 1415 1374 } 1375 + kaddr = kmap_atomic(page, KM_USER0); 1416 1376 /* Copy the data from the page to the mft record. */ 1417 1377 memcpy((u8*)ctx->attr + 1418 1378 le16_to_cpu(ctx->attr->data.resident.value_offset), ··· 1439 1405 err = 0; 1440 1406 } else { 1441 1407 ntfs_error(vi->i_sb, "Resident attribute write failed with " 1442 - "error %i. Setting page error flag.", err); 1408 + "error %i.", err); 1443 1409 SetPageError(page); 1410 + NVolSetErrors(ni->vol); 1411 + make_bad_inode(vi); 1444 1412 } 1445 1413 unlock_page(page); 1446 1414 if (ctx) ··· 1461 1425 { 1462 1426 VCN vcn; 1463 1427 LCN lcn; 1428 + s64 initialized_size; 1429 + loff_t i_size; 1464 1430 sector_t block, ablock, iblock; 1465 1431 struct inode *vi; 1466 1432 ntfs_inode *ni; 1467 1433 ntfs_volume *vol; 1468 1434 runlist_element *rl; 1469 1435 struct buffer_head *bh, *head, *wait[2], **wait_bh = wait; 1436 + unsigned long flags; 1470 1437 unsigned int vcn_ofs, block_start, block_end, blocksize; 1471 1438 int err; 1472 1439 BOOL is_retry; ··· 1501 1462 /* The first block in the page. */ 1502 1463 block = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits); 1503 1464 1465 + read_lock_irqsave(&ni->size_lock, flags); 1504 1466 /* 1505 - * The first out of bounds block for the allocated size. No need to 1467 + * The first out of bounds block for the allocated size. No need to 1506 1468 * round up as allocated_size is in multiples of cluster size and the 1507 1469 * minimum cluster size is 512 bytes, which is equal to the smallest 1508 1470 * blocksize. 1509 1471 */ 1510 1472 ablock = ni->allocated_size >> blocksize_bits; 1473 + i_size = i_size_read(vi); 1474 + initialized_size = ni->initialized_size; 1475 + read_unlock_irqrestore(&ni->size_lock, flags); 1511 1476 1512 1477 /* The last (fully or partially) initialized block. */ 1513 - iblock = ni->initialized_size >> blocksize_bits; 1478 + iblock = initialized_size >> blocksize_bits; 1514 1479 1515 1480 /* Loop through all the buffers in the page. */ 1516 1481 block_start = 0; ··· 1561 1518 * request, i.e. block < ablock is true. 1562 1519 */ 1563 1520 if (unlikely((block >= iblock) && 1564 - (ni->initialized_size < vi->i_size))) { 1521 + (initialized_size < i_size))) { 1565 1522 /* 1566 1523 * If this page is fully outside initialized size, zero 1567 1524 * out all pages between the current initialized size ··· 1665 1622 "not supported yet. " 1666 1623 "Sorry."); 1667 1624 err = -EOPNOTSUPP; 1625 + if (!rl) 1626 + up_read(&ni->runlist.lock); 1668 1627 goto err_out; 1669 1628 } else if (!is_retry && 1670 1629 lcn == LCN_RL_NOT_MAPPED) { ··· 1681 1636 goto lock_retry_remap; 1682 1637 rl = NULL; 1683 1638 lcn = err; 1684 - } 1639 + } else if (!rl) 1640 + up_read(&ni->runlist.lock); 1685 1641 /* 1686 1642 * Failed to map the buffer, even after 1687 1643 * retrying. ··· 1843 1797 unsigned from, unsigned to) 1844 1798 { 1845 1799 s64 new_size; 1800 + loff_t i_size; 1846 1801 struct inode *vi = page->mapping->host; 1847 1802 ntfs_inode *base_ni = NULL, *ni = NTFS_I(vi); 1848 1803 ntfs_volume *vol = ni->vol; ··· 1915 1868 BUG_ON(page_has_buffers(page)); 1916 1869 new_size = ((s64)page->index << PAGE_CACHE_SHIFT) + to; 1917 1870 /* If we do not need to resize the attribute allocation we are done. */ 1918 - if (new_size <= vi->i_size) 1871 + if (new_size <= i_size_read(vi)) 1919 1872 goto done; 1920 - 1921 - // FIXME: We abort for now as this code is not safe. 1922 - ntfs_error(vi->i_sb, "Changing the file size is not supported yet. " 1923 - "Sorry."); 1924 - return -EOPNOTSUPP; 1925 - 1926 1873 /* Map, pin, and lock the (base) mft record. */ 1927 1874 if (!NInoAttr(ni)) 1928 1875 base_ni = ni; ··· 1945 1904 a = ctx->attr; 1946 1905 /* The total length of the attribute value. */ 1947 1906 attr_len = le32_to_cpu(a->data.resident.value_length); 1948 - BUG_ON(vi->i_size != attr_len); 1907 + /* Fix an eventual previous failure of ntfs_commit_write(). */ 1908 + i_size = i_size_read(vi); 1909 + if (unlikely(attr_len > i_size)) { 1910 + attr_len = i_size; 1911 + a->data.resident.value_length = cpu_to_le32(attr_len); 1912 + } 1913 + /* If we do not need to resize the attribute allocation we are done. */ 1914 + if (new_size <= attr_len) 1915 + goto done_unm; 1949 1916 /* Check if new size is allowed in $AttrDef. */ 1950 1917 err = ntfs_attr_size_bounds_check(vol, ni->type, new_size); 1951 1918 if (unlikely(err)) { ··· 2011 1962 } 2012 1963 flush_dcache_mft_record_page(ctx->ntfs_ino); 2013 1964 mark_mft_record_dirty(ctx->ntfs_ino); 1965 + done_unm: 2014 1966 ntfs_attr_put_search_ctx(ctx); 2015 1967 unmap_mft_record(base_ni); 2016 1968 /* ··· 2097 2047 * now we know ntfs_prepare_write() would have failed in the write 2098 2048 * exceeds i_size case, so this will never trigger which is fine. 2099 2049 */ 2100 - if (pos > vi->i_size) { 2050 + if (pos > i_size_read(vi)) { 2101 2051 ntfs_error(vi->i_sb, "Writing beyond the existing file size is " 2102 2052 "not supported yet. Sorry."); 2103 2053 return -EOPNOTSUPP; ··· 2233 2183 } 2234 2184 kunmap_atomic(kaddr, KM_USER0); 2235 2185 /* Update i_size if necessary. */ 2236 - if (vi->i_size < attr_len) { 2186 + if (i_size_read(vi) < attr_len) { 2187 + unsigned long flags; 2188 + 2189 + write_lock_irqsave(&ni->size_lock, flags); 2237 2190 ni->allocated_size = ni->initialized_size = attr_len; 2238 2191 i_size_write(vi, attr_len); 2192 + write_unlock_irqrestore(&ni->size_lock, flags); 2239 2193 } 2240 2194 /* Mark the mft record dirty, so it gets written back. */ 2241 2195 flush_dcache_mft_record_page(ctx->ntfs_ino);
+557 -99
fs/ntfs/attrib.c
··· 1 1 /** 2 2 * attrib.c - NTFS attribute operations. Part of the Linux-NTFS project. 3 3 * 4 - * Copyright (c) 2001-2004 Anton Altaparmakov 4 + * Copyright (c) 2001-2005 Anton Altaparmakov 5 5 * Copyright (c) 2002 Richard Russon 6 6 * 7 7 * This program/include file is free software; you can redistribute it and/or ··· 21 21 */ 22 22 23 23 #include <linux/buffer_head.h> 24 + #include <linux/swap.h> 24 25 25 26 #include "attrib.h" 26 27 #include "debug.h" 27 28 #include "layout.h" 29 + #include "lcnalloc.h" 30 + #include "malloc.h" 28 31 #include "mft.h" 29 32 #include "ntfs.h" 30 33 #include "types.h" 34 + 35 + /** 36 + * ntfs_map_runlist_nolock - map (a part of) a runlist of an ntfs inode 37 + * @ni: ntfs inode for which to map (part of) a runlist 38 + * @vcn: map runlist part containing this vcn 39 + * 40 + * Map the part of a runlist containing the @vcn of the ntfs inode @ni. 41 + * 42 + * Return 0 on success and -errno on error. There is one special error code 43 + * which is not an error as such. This is -ENOENT. It means that @vcn is out 44 + * of bounds of the runlist. 45 + * 46 + * Locking: - The runlist must be locked for writing. 47 + * - This function modifies the runlist. 48 + */ 49 + int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn) 50 + { 51 + VCN end_vcn; 52 + ntfs_inode *base_ni; 53 + MFT_RECORD *m; 54 + ATTR_RECORD *a; 55 + ntfs_attr_search_ctx *ctx; 56 + runlist_element *rl; 57 + int err = 0; 58 + 59 + ntfs_debug("Mapping runlist part containing vcn 0x%llx.", 60 + (unsigned long long)vcn); 61 + if (!NInoAttr(ni)) 62 + base_ni = ni; 63 + else 64 + base_ni = ni->ext.base_ntfs_ino; 65 + m = map_mft_record(base_ni); 66 + if (IS_ERR(m)) 67 + return PTR_ERR(m); 68 + ctx = ntfs_attr_get_search_ctx(base_ni, m); 69 + if (unlikely(!ctx)) { 70 + err = -ENOMEM; 71 + goto err_out; 72 + } 73 + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, 74 + CASE_SENSITIVE, vcn, NULL, 0, ctx); 75 + if (unlikely(err)) { 76 + if (err == -ENOENT) 77 + err = -EIO; 78 + goto err_out; 79 + } 80 + a = ctx->attr; 81 + /* 82 + * Only decompress the mapping pairs if @vcn is inside it. Otherwise 83 + * we get into problems when we try to map an out of bounds vcn because 84 + * we then try to map the already mapped runlist fragment and 85 + * ntfs_mapping_pairs_decompress() fails. 86 + */ 87 + end_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn) + 1; 88 + if (unlikely(!a->data.non_resident.lowest_vcn && end_vcn <= 1)) 89 + end_vcn = ni->allocated_size >> ni->vol->cluster_size_bits; 90 + if (unlikely(vcn >= end_vcn)) { 91 + err = -ENOENT; 92 + goto err_out; 93 + } 94 + rl = ntfs_mapping_pairs_decompress(ni->vol, a, ni->runlist.rl); 95 + if (IS_ERR(rl)) 96 + err = PTR_ERR(rl); 97 + else 98 + ni->runlist.rl = rl; 99 + err_out: 100 + if (likely(ctx)) 101 + ntfs_attr_put_search_ctx(ctx); 102 + unmap_mft_record(base_ni); 103 + return err; 104 + } 31 105 32 106 /** 33 107 * ntfs_map_runlist - map (a part of) a runlist of an ntfs inode ··· 110 36 * 111 37 * Map the part of a runlist containing the @vcn of the ntfs inode @ni. 112 38 * 113 - * Return 0 on success and -errno on error. 39 + * Return 0 on success and -errno on error. There is one special error code 40 + * which is not an error as such. This is -ENOENT. It means that @vcn is out 41 + * of bounds of the runlist. 114 42 * 115 43 * Locking: - The runlist must be unlocked on entry and is unlocked on return. 116 - * - This function takes the lock for writing and modifies the runlist. 44 + * - This function takes the runlist lock for writing and modifies the 45 + * runlist. 117 46 */ 118 47 int ntfs_map_runlist(ntfs_inode *ni, VCN vcn) 119 48 { 120 - ntfs_inode *base_ni; 121 - ntfs_attr_search_ctx *ctx; 122 - MFT_RECORD *mrec; 123 49 int err = 0; 124 - 125 - ntfs_debug("Mapping runlist part containing vcn 0x%llx.", 126 - (unsigned long long)vcn); 127 - 128 - if (!NInoAttr(ni)) 129 - base_ni = ni; 130 - else 131 - base_ni = ni->ext.base_ntfs_ino; 132 - 133 - mrec = map_mft_record(base_ni); 134 - if (IS_ERR(mrec)) 135 - return PTR_ERR(mrec); 136 - ctx = ntfs_attr_get_search_ctx(base_ni, mrec); 137 - if (unlikely(!ctx)) { 138 - err = -ENOMEM; 139 - goto err_out; 140 - } 141 - err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, 142 - CASE_SENSITIVE, vcn, NULL, 0, ctx); 143 - if (unlikely(err)) 144 - goto put_err_out; 145 50 146 51 down_write(&ni->runlist.lock); 147 52 /* Make sure someone else didn't do the work while we were sleeping. */ 148 53 if (likely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) <= 149 - LCN_RL_NOT_MAPPED)) { 150 - runlist_element *rl; 151 - 152 - rl = ntfs_mapping_pairs_decompress(ni->vol, ctx->attr, 153 - ni->runlist.rl); 154 - if (IS_ERR(rl)) 155 - err = PTR_ERR(rl); 156 - else 157 - ni->runlist.rl = rl; 158 - } 54 + LCN_RL_NOT_MAPPED)) 55 + err = ntfs_map_runlist_nolock(ni, vcn); 159 56 up_write(&ni->runlist.lock); 160 - 161 - put_err_out: 162 - ntfs_attr_put_search_ctx(ctx); 163 - err_out: 164 - unmap_mft_record(base_ni); 165 57 return err; 166 58 } 167 59 168 60 /** 169 - * ntfs_find_vcn - find a vcn in the runlist described by an ntfs inode 170 - * @ni: ntfs inode describing the runlist to search 171 - * @vcn: vcn to find 172 - * @need_write: if false, lock for reading and if true, lock for writing 61 + * ntfs_attr_vcn_to_lcn_nolock - convert a vcn into a lcn given an ntfs inode 62 + * @ni: ntfs inode of the attribute whose runlist to search 63 + * @vcn: vcn to convert 64 + * @write_locked: true if the runlist is locked for writing 65 + * 66 + * Find the virtual cluster number @vcn in the runlist of the ntfs attribute 67 + * described by the ntfs inode @ni and return the corresponding logical cluster 68 + * number (lcn). 69 + * 70 + * If the @vcn is not mapped yet, the attempt is made to map the attribute 71 + * extent containing the @vcn and the vcn to lcn conversion is retried. 72 + * 73 + * If @write_locked is true the caller has locked the runlist for writing and 74 + * if false for reading. 75 + * 76 + * Since lcns must be >= 0, we use negative return codes with special meaning: 77 + * 78 + * Return code Meaning / Description 79 + * ========================================== 80 + * LCN_HOLE Hole / not allocated on disk. 81 + * LCN_ENOENT There is no such vcn in the runlist, i.e. @vcn is out of bounds. 82 + * LCN_ENOMEM Not enough memory to map runlist. 83 + * LCN_EIO Critical error (runlist/file is corrupt, i/o error, etc). 84 + * 85 + * Locking: - The runlist must be locked on entry and is left locked on return. 86 + * - If @write_locked is FALSE, i.e. the runlist is locked for reading, 87 + * the lock may be dropped inside the function so you cannot rely on 88 + * the runlist still being the same when this function returns. 89 + */ 90 + LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn, 91 + const BOOL write_locked) 92 + { 93 + LCN lcn; 94 + BOOL is_retry = FALSE; 95 + 96 + ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.", 97 + ni->mft_no, (unsigned long long)vcn, 98 + write_locked ? "write" : "read"); 99 + BUG_ON(!ni); 100 + BUG_ON(!NInoNonResident(ni)); 101 + BUG_ON(vcn < 0); 102 + retry_remap: 103 + /* Convert vcn to lcn. If that fails map the runlist and retry once. */ 104 + lcn = ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn); 105 + if (likely(lcn >= LCN_HOLE)) { 106 + ntfs_debug("Done, lcn 0x%llx.", (long long)lcn); 107 + return lcn; 108 + } 109 + if (lcn != LCN_RL_NOT_MAPPED) { 110 + if (lcn != LCN_ENOENT) 111 + lcn = LCN_EIO; 112 + } else if (!is_retry) { 113 + int err; 114 + 115 + if (!write_locked) { 116 + up_read(&ni->runlist.lock); 117 + down_write(&ni->runlist.lock); 118 + if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) != 119 + LCN_RL_NOT_MAPPED)) { 120 + up_write(&ni->runlist.lock); 121 + down_read(&ni->runlist.lock); 122 + goto retry_remap; 123 + } 124 + } 125 + err = ntfs_map_runlist_nolock(ni, vcn); 126 + if (!write_locked) { 127 + up_write(&ni->runlist.lock); 128 + down_read(&ni->runlist.lock); 129 + } 130 + if (likely(!err)) { 131 + is_retry = TRUE; 132 + goto retry_remap; 133 + } 134 + if (err == -ENOENT) 135 + lcn = LCN_ENOENT; 136 + else if (err == -ENOMEM) 137 + lcn = LCN_ENOMEM; 138 + else 139 + lcn = LCN_EIO; 140 + } 141 + if (lcn != LCN_ENOENT) 142 + ntfs_error(ni->vol->sb, "Failed with error code %lli.", 143 + (long long)lcn); 144 + return lcn; 145 + } 146 + 147 + /** 148 + * ntfs_attr_find_vcn_nolock - find a vcn in the runlist of an ntfs inode 149 + * @ni: ntfs inode describing the runlist to search 150 + * @vcn: vcn to find 151 + * @write_locked: true if the runlist is locked for writing 173 152 * 174 153 * Find the virtual cluster number @vcn in the runlist described by the ntfs 175 154 * inode @ni and return the address of the runlist element containing the @vcn. 176 - * The runlist is left locked and the caller has to unlock it. If @need_write 177 - * is true, the runlist is locked for writing and if @need_write is false, the 178 - * runlist is locked for reading. In the error case, the runlist is not left 179 - * locked. 155 + * 156 + * If the @vcn is not mapped yet, the attempt is made to map the attribute 157 + * extent containing the @vcn and the vcn to lcn conversion is retried. 158 + * 159 + * If @write_locked is true the caller has locked the runlist for writing and 160 + * if false for reading. 180 161 * 181 162 * Note you need to distinguish between the lcn of the returned runlist element 182 163 * being >= 0 and LCN_HOLE. In the later case you have to return zeroes on ··· 247 118 * -ENOMEM - Not enough memory to map runlist. 248 119 * -EIO - Critical error (runlist/file is corrupt, i/o error, etc). 249 120 * 250 - * Locking: - The runlist must be unlocked on entry. 251 - * - On failing return, the runlist is unlocked. 252 - * - On successful return, the runlist is locked. If @need_write us 253 - * true, it is locked for writing. Otherwise is is locked for 254 - * reading. 121 + * Locking: - The runlist must be locked on entry and is left locked on return. 122 + * - If @write_locked is FALSE, i.e. the runlist is locked for reading, 123 + * the lock may be dropped inside the function so you cannot rely on 124 + * the runlist still being the same when this function returns. 255 125 */ 256 - runlist_element *ntfs_find_vcn(ntfs_inode *ni, const VCN vcn, 257 - const BOOL need_write) 126 + runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, const VCN vcn, 127 + const BOOL write_locked) 258 128 { 259 129 runlist_element *rl; 260 130 int err = 0; 261 131 BOOL is_retry = FALSE; 262 132 263 - ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, lock for %sing.", 133 + ntfs_debug("Entering for i_ino 0x%lx, vcn 0x%llx, %s_locked.", 264 134 ni->mft_no, (unsigned long long)vcn, 265 - !need_write ? "read" : "writ"); 135 + write_locked ? "write" : "read"); 266 136 BUG_ON(!ni); 267 137 BUG_ON(!NInoNonResident(ni)); 268 138 BUG_ON(vcn < 0); 269 - lock_retry_remap: 270 - if (!need_write) 271 - down_read(&ni->runlist.lock); 272 - else 273 - down_write(&ni->runlist.lock); 139 + retry_remap: 274 140 rl = ni->runlist.rl; 275 141 if (likely(rl && vcn >= rl[0].vcn)) { 276 142 while (likely(rl->length)) { 277 - if (likely(vcn < rl[1].vcn)) { 143 + if (unlikely(vcn < rl[1].vcn)) { 278 144 if (likely(rl->lcn >= LCN_HOLE)) { 279 145 ntfs_debug("Done."); 280 146 return rl; ··· 285 161 err = -EIO; 286 162 } 287 163 } 288 - if (!need_write) 289 - up_read(&ni->runlist.lock); 290 - else 291 - up_write(&ni->runlist.lock); 292 164 if (!err && !is_retry) { 293 165 /* 294 166 * The @vcn is in an unmapped region, map the runlist and 295 167 * retry. 296 168 */ 297 - err = ntfs_map_runlist(ni, vcn); 169 + if (!write_locked) { 170 + up_read(&ni->runlist.lock); 171 + down_write(&ni->runlist.lock); 172 + if (unlikely(ntfs_rl_vcn_to_lcn(ni->runlist.rl, vcn) != 173 + LCN_RL_NOT_MAPPED)) { 174 + up_write(&ni->runlist.lock); 175 + down_read(&ni->runlist.lock); 176 + goto retry_remap; 177 + } 178 + } 179 + err = ntfs_map_runlist_nolock(ni, vcn); 180 + if (!write_locked) { 181 + up_write(&ni->runlist.lock); 182 + down_read(&ni->runlist.lock); 183 + } 298 184 if (likely(!err)) { 299 185 is_retry = TRUE; 300 - goto lock_retry_remap; 186 + goto retry_remap; 301 187 } 302 188 /* 303 - * -EINVAL and -ENOENT coming from a failed mapping attempt are 304 - * equivalent to i/o errors for us as they should not happen in 305 - * our code paths. 189 + * -EINVAL coming from a failed mapping attempt is equivalent 190 + * to i/o error for us as it should not happen in our code 191 + * paths. 306 192 */ 307 - if (err == -EINVAL || err == -ENOENT) 193 + if (err == -EINVAL) 308 194 err = -EIO; 309 195 } else if (!err) 310 196 err = -EIO; 311 - ntfs_error(ni->vol->sb, "Failed with error code %i.", err); 197 + if (err != -ENOENT) 198 + ntfs_error(ni->vol->sb, "Failed with error code %i.", err); 312 199 return ERR_PTR(err); 313 200 } 314 201 ··· 1005 870 static inline void ntfs_attr_init_search_ctx(ntfs_attr_search_ctx *ctx, 1006 871 ntfs_inode *ni, MFT_RECORD *mrec) 1007 872 { 1008 - ctx->mrec = mrec; 1009 - /* Sanity checks are performed elsewhere. */ 1010 - ctx->attr = (ATTR_RECORD*)((u8*)mrec + le16_to_cpu(mrec->attrs_offset)); 1011 - ctx->is_first = TRUE; 1012 - ctx->ntfs_ino = ni; 1013 - ctx->al_entry = NULL; 1014 - ctx->base_ntfs_ino = NULL; 1015 - ctx->base_mrec = NULL; 1016 - ctx->base_attr = NULL; 873 + *ctx = (ntfs_attr_search_ctx) { 874 + .mrec = mrec, 875 + /* Sanity checks are performed elsewhere. */ 876 + .attr = (ATTR_RECORD*)((u8*)mrec + 877 + le16_to_cpu(mrec->attrs_offset)), 878 + .is_first = TRUE, 879 + .ntfs_ino = ni, 880 + }; 1017 881 } 1018 882 1019 883 /** ··· 1078 944 kmem_cache_free(ntfs_attr_ctx_cache, ctx); 1079 945 return; 1080 946 } 947 + 948 + #ifdef NTFS_RW 1081 949 1082 950 /** 1083 951 * ntfs_attr_find_in_attrdef - find an attribute in the $AttrDef system file ··· 1160 1024 * Check whether the attribute of @type on the ntfs volume @vol is allowed to 1161 1025 * be non-resident. This information is obtained from $AttrDef system file. 1162 1026 * 1163 - * Return 0 if the attribute is allowed to be non-resident, -EPERM if not, or 1027 + * Return 0 if the attribute is allowed to be non-resident, -EPERM if not, and 1164 1028 * -ENOENT if the attribute is not listed in $AttrDef. 1165 1029 */ 1166 1030 int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, const ATTR_TYPE type) 1167 1031 { 1168 1032 ATTR_DEF *ad; 1169 1033 1170 - /* 1171 - * $DATA is always allowed to be non-resident even if $AttrDef does not 1172 - * specify this in the flags of the $DATA attribute definition record. 1173 - */ 1174 - if (type == AT_DATA) 1175 - return 0; 1176 1034 /* Find the attribute definition record in $AttrDef. */ 1177 1035 ad = ntfs_attr_find_in_attrdef(vol, type); 1178 1036 if (unlikely(!ad)) 1179 1037 return -ENOENT; 1180 1038 /* Check the flags and return the result. */ 1181 - if (ad->flags & CAN_BE_NON_RESIDENT) 1182 - return 0; 1183 - return -EPERM; 1039 + if (ad->flags & ATTR_DEF_RESIDENT) 1040 + return -EPERM; 1041 + return 0; 1184 1042 } 1185 1043 1186 1044 /** ··· 1197 1067 */ 1198 1068 int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPE type) 1199 1069 { 1200 - if (type != AT_INDEX_ALLOCATION && type != AT_EA) 1201 - return 0; 1202 - return -EPERM; 1070 + if (type == AT_INDEX_ALLOCATION || type == AT_EA) 1071 + return -EPERM; 1072 + return 0; 1203 1073 } 1204 1074 1205 1075 /** ··· 1247 1117 } 1248 1118 1249 1119 /** 1120 + * ntfs_attr_make_non_resident - convert a resident to a non-resident attribute 1121 + * @ni: ntfs inode describing the attribute to convert 1122 + * 1123 + * Convert the resident ntfs attribute described by the ntfs inode @ni to a 1124 + * non-resident one. 1125 + * 1126 + * Return 0 on success and -errno on error. The following error return codes 1127 + * are defined: 1128 + * -EPERM - The attribute is not allowed to be non-resident. 1129 + * -ENOMEM - Not enough memory. 1130 + * -ENOSPC - Not enough disk space. 1131 + * -EINVAL - Attribute not defined on the volume. 1132 + * -EIO - I/o error or other error. 1133 + * Note that -ENOSPC is also returned in the case that there is not enough 1134 + * space in the mft record to do the conversion. This can happen when the mft 1135 + * record is already very full. The caller is responsible for trying to make 1136 + * space in the mft record and trying again. FIXME: Do we need a separate 1137 + * error return code for this kind of -ENOSPC or is it always worth trying 1138 + * again in case the attribute may then fit in a resident state so no need to 1139 + * make it non-resident at all? Ho-hum... (AIA) 1140 + * 1141 + * NOTE to self: No changes in the attribute list are required to move from 1142 + * a resident to a non-resident attribute. 1143 + * 1144 + * Locking: - The caller must hold i_sem on the inode. 1145 + */ 1146 + int ntfs_attr_make_non_resident(ntfs_inode *ni) 1147 + { 1148 + s64 new_size; 1149 + struct inode *vi = VFS_I(ni); 1150 + ntfs_volume *vol = ni->vol; 1151 + ntfs_inode *base_ni; 1152 + MFT_RECORD *m; 1153 + ATTR_RECORD *a; 1154 + ntfs_attr_search_ctx *ctx; 1155 + struct page *page; 1156 + runlist_element *rl; 1157 + u8 *kaddr; 1158 + unsigned long flags; 1159 + int mp_size, mp_ofs, name_ofs, arec_size, err, err2; 1160 + u32 attr_size; 1161 + u8 old_res_attr_flags; 1162 + 1163 + /* Check that the attribute is allowed to be non-resident. */ 1164 + err = ntfs_attr_can_be_non_resident(vol, ni->type); 1165 + if (unlikely(err)) { 1166 + if (err == -EPERM) 1167 + ntfs_debug("Attribute is not allowed to be " 1168 + "non-resident."); 1169 + else 1170 + ntfs_debug("Attribute not defined on the NTFS " 1171 + "volume!"); 1172 + return err; 1173 + } 1174 + /* 1175 + * The size needs to be aligned to a cluster boundary for allocation 1176 + * purposes. 1177 + */ 1178 + new_size = (i_size_read(vi) + vol->cluster_size - 1) & 1179 + ~(vol->cluster_size - 1); 1180 + if (new_size > 0) { 1181 + runlist_element *rl2; 1182 + 1183 + /* 1184 + * Will need the page later and since the page lock nests 1185 + * outside all ntfs locks, we need to get the page now. 1186 + */ 1187 + page = find_or_create_page(vi->i_mapping, 0, 1188 + mapping_gfp_mask(vi->i_mapping)); 1189 + if (unlikely(!page)) 1190 + return -ENOMEM; 1191 + /* Start by allocating clusters to hold the attribute value. */ 1192 + rl = ntfs_cluster_alloc(vol, 0, new_size >> 1193 + vol->cluster_size_bits, -1, DATA_ZONE); 1194 + if (IS_ERR(rl)) { 1195 + err = PTR_ERR(rl); 1196 + ntfs_debug("Failed to allocate cluster%s, error code " 1197 + "%i.", (new_size >> 1198 + vol->cluster_size_bits) > 1 ? "s" : "", 1199 + err); 1200 + goto page_err_out; 1201 + } 1202 + /* Change the runlist terminator to LCN_ENOENT. */ 1203 + rl2 = rl; 1204 + while (rl2->length) 1205 + rl2++; 1206 + BUG_ON(rl2->lcn != LCN_RL_NOT_MAPPED); 1207 + rl2->lcn = LCN_ENOENT; 1208 + } else { 1209 + rl = NULL; 1210 + page = NULL; 1211 + } 1212 + /* Determine the size of the mapping pairs array. */ 1213 + mp_size = ntfs_get_size_for_mapping_pairs(vol, rl, 0, -1); 1214 + if (unlikely(mp_size < 0)) { 1215 + err = mp_size; 1216 + ntfs_debug("Failed to get size for mapping pairs array, error " 1217 + "code %i.", err); 1218 + goto rl_err_out; 1219 + } 1220 + down_write(&ni->runlist.lock); 1221 + if (!NInoAttr(ni)) 1222 + base_ni = ni; 1223 + else 1224 + base_ni = ni->ext.base_ntfs_ino; 1225 + m = map_mft_record(base_ni); 1226 + if (IS_ERR(m)) { 1227 + err = PTR_ERR(m); 1228 + m = NULL; 1229 + ctx = NULL; 1230 + goto err_out; 1231 + } 1232 + ctx = ntfs_attr_get_search_ctx(base_ni, m); 1233 + if (unlikely(!ctx)) { 1234 + err = -ENOMEM; 1235 + goto err_out; 1236 + } 1237 + err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, 1238 + CASE_SENSITIVE, 0, NULL, 0, ctx); 1239 + if (unlikely(err)) { 1240 + if (err == -ENOENT) 1241 + err = -EIO; 1242 + goto err_out; 1243 + } 1244 + m = ctx->mrec; 1245 + a = ctx->attr; 1246 + BUG_ON(NInoNonResident(ni)); 1247 + BUG_ON(a->non_resident); 1248 + /* 1249 + * Calculate new offsets for the name and the mapping pairs array. 1250 + * We assume the attribute is not compressed or sparse. 1251 + */ 1252 + name_ofs = (offsetof(ATTR_REC, 1253 + data.non_resident.compressed_size) + 7) & ~7; 1254 + mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7; 1255 + /* 1256 + * Determine the size of the resident part of the now non-resident 1257 + * attribute record. 1258 + */ 1259 + arec_size = (mp_ofs + mp_size + 7) & ~7; 1260 + /* 1261 + * If the page is not uptodate bring it uptodate by copying from the 1262 + * attribute value. 1263 + */ 1264 + attr_size = le32_to_cpu(a->data.resident.value_length); 1265 + BUG_ON(attr_size != i_size_read(vi)); 1266 + if (page && !PageUptodate(page)) { 1267 + kaddr = kmap_atomic(page, KM_USER0); 1268 + memcpy(kaddr, (u8*)a + 1269 + le16_to_cpu(a->data.resident.value_offset), 1270 + attr_size); 1271 + memset(kaddr + attr_size, 0, PAGE_CACHE_SIZE - attr_size); 1272 + kunmap_atomic(kaddr, KM_USER0); 1273 + flush_dcache_page(page); 1274 + SetPageUptodate(page); 1275 + } 1276 + /* Backup the attribute flag. */ 1277 + old_res_attr_flags = a->data.resident.flags; 1278 + /* Resize the resident part of the attribute record. */ 1279 + err = ntfs_attr_record_resize(m, a, arec_size); 1280 + if (unlikely(err)) 1281 + goto err_out; 1282 + /* 1283 + * Convert the resident part of the attribute record to describe a 1284 + * non-resident attribute. 1285 + */ 1286 + a->non_resident = 1; 1287 + /* Move the attribute name if it exists and update the offset. */ 1288 + if (a->name_length) 1289 + memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset), 1290 + a->name_length * sizeof(ntfschar)); 1291 + a->name_offset = cpu_to_le16(name_ofs); 1292 + /* 1293 + * FIXME: For now just clear all of these as we do not support them 1294 + * when writing. 1295 + */ 1296 + a->flags &= cpu_to_le16(0xffff & ~le16_to_cpu(ATTR_IS_SPARSE | 1297 + ATTR_IS_ENCRYPTED | ATTR_COMPRESSION_MASK)); 1298 + /* Setup the fields specific to non-resident attributes. */ 1299 + a->data.non_resident.lowest_vcn = 0; 1300 + a->data.non_resident.highest_vcn = cpu_to_sle64((new_size - 1) >> 1301 + vol->cluster_size_bits); 1302 + a->data.non_resident.mapping_pairs_offset = cpu_to_le16(mp_ofs); 1303 + a->data.non_resident.compression_unit = 0; 1304 + memset(&a->data.non_resident.reserved, 0, 1305 + sizeof(a->data.non_resident.reserved)); 1306 + a->data.non_resident.allocated_size = cpu_to_sle64(new_size); 1307 + a->data.non_resident.data_size = 1308 + a->data.non_resident.initialized_size = 1309 + cpu_to_sle64(attr_size); 1310 + /* Generate the mapping pairs array into the attribute record. */ 1311 + err = ntfs_mapping_pairs_build(vol, (u8*)a + mp_ofs, 1312 + arec_size - mp_ofs, rl, 0, -1, NULL); 1313 + if (unlikely(err)) { 1314 + ntfs_debug("Failed to build mapping pairs, error code %i.", 1315 + err); 1316 + goto undo_err_out; 1317 + } 1318 + /* Setup the in-memory attribute structure to be non-resident. */ 1319 + /* 1320 + * FIXME: For now just clear all of these as we do not support them 1321 + * when writing. 1322 + */ 1323 + NInoClearSparse(ni); 1324 + NInoClearEncrypted(ni); 1325 + NInoClearCompressed(ni); 1326 + ni->runlist.rl = rl; 1327 + write_lock_irqsave(&ni->size_lock, flags); 1328 + ni->allocated_size = new_size; 1329 + write_unlock_irqrestore(&ni->size_lock, flags); 1330 + /* 1331 + * This needs to be last since the address space operations ->readpage 1332 + * and ->writepage can run concurrently with us as they are not 1333 + * serialized on i_sem. Note, we are not allowed to fail once we flip 1334 + * this switch, which is another reason to do this last. 1335 + */ 1336 + NInoSetNonResident(ni); 1337 + /* Mark the mft record dirty, so it gets written back. */ 1338 + flush_dcache_mft_record_page(ctx->ntfs_ino); 1339 + mark_mft_record_dirty(ctx->ntfs_ino); 1340 + ntfs_attr_put_search_ctx(ctx); 1341 + unmap_mft_record(base_ni); 1342 + up_write(&ni->runlist.lock); 1343 + if (page) { 1344 + set_page_dirty(page); 1345 + unlock_page(page); 1346 + mark_page_accessed(page); 1347 + page_cache_release(page); 1348 + } 1349 + ntfs_debug("Done."); 1350 + return 0; 1351 + undo_err_out: 1352 + /* Convert the attribute back into a resident attribute. */ 1353 + a->non_resident = 0; 1354 + /* Move the attribute name if it exists and update the offset. */ 1355 + name_ofs = (offsetof(ATTR_RECORD, data.resident.reserved) + 1356 + sizeof(a->data.resident.reserved) + 7) & ~7; 1357 + if (a->name_length) 1358 + memmove((u8*)a + name_ofs, (u8*)a + le16_to_cpu(a->name_offset), 1359 + a->name_length * sizeof(ntfschar)); 1360 + mp_ofs = (name_ofs + a->name_length * sizeof(ntfschar) + 7) & ~7; 1361 + a->name_offset = cpu_to_le16(name_ofs); 1362 + arec_size = (mp_ofs + attr_size + 7) & ~7; 1363 + /* Resize the resident part of the attribute record. */ 1364 + err2 = ntfs_attr_record_resize(m, a, arec_size); 1365 + if (unlikely(err2)) { 1366 + /* 1367 + * This cannot happen (well if memory corruption is at work it 1368 + * could happen in theory), but deal with it as well as we can. 1369 + * If the old size is too small, truncate the attribute, 1370 + * otherwise simply give it a larger allocated size. 1371 + * FIXME: Should check whether chkdsk complains when the 1372 + * allocated size is much bigger than the resident value size. 1373 + */ 1374 + arec_size = le32_to_cpu(a->length); 1375 + if ((mp_ofs + attr_size) > arec_size) { 1376 + err2 = attr_size; 1377 + attr_size = arec_size - mp_ofs; 1378 + ntfs_error(vol->sb, "Failed to undo partial resident " 1379 + "to non-resident attribute " 1380 + "conversion. Truncating inode 0x%lx, " 1381 + "attribute type 0x%x from %i bytes to " 1382 + "%i bytes to maintain metadata " 1383 + "consistency. THIS MEANS YOU ARE " 1384 + "LOSING %i BYTES DATA FROM THIS %s.", 1385 + vi->i_ino, 1386 + (unsigned)le32_to_cpu(ni->type), 1387 + err2, attr_size, err2 - attr_size, 1388 + ((ni->type == AT_DATA) && 1389 + !ni->name_len) ? "FILE": "ATTRIBUTE"); 1390 + write_lock_irqsave(&ni->size_lock, flags); 1391 + ni->initialized_size = attr_size; 1392 + i_size_write(vi, attr_size); 1393 + write_unlock_irqrestore(&ni->size_lock, flags); 1394 + } 1395 + } 1396 + /* Setup the fields specific to resident attributes. */ 1397 + a->data.resident.value_length = cpu_to_le32(attr_size); 1398 + a->data.resident.value_offset = cpu_to_le16(mp_ofs); 1399 + a->data.resident.flags = old_res_attr_flags; 1400 + memset(&a->data.resident.reserved, 0, 1401 + sizeof(a->data.resident.reserved)); 1402 + /* Copy the data from the page back to the attribute value. */ 1403 + if (page) { 1404 + kaddr = kmap_atomic(page, KM_USER0); 1405 + memcpy((u8*)a + mp_ofs, kaddr, attr_size); 1406 + kunmap_atomic(kaddr, KM_USER0); 1407 + } 1408 + /* Setup the allocated size in the ntfs inode in case it changed. */ 1409 + write_lock_irqsave(&ni->size_lock, flags); 1410 + ni->allocated_size = arec_size - mp_ofs; 1411 + write_unlock_irqrestore(&ni->size_lock, flags); 1412 + /* Mark the mft record dirty, so it gets written back. */ 1413 + flush_dcache_mft_record_page(ctx->ntfs_ino); 1414 + mark_mft_record_dirty(ctx->ntfs_ino); 1415 + err_out: 1416 + if (ctx) 1417 + ntfs_attr_put_search_ctx(ctx); 1418 + if (m) 1419 + unmap_mft_record(base_ni); 1420 + ni->runlist.rl = NULL; 1421 + up_write(&ni->runlist.lock); 1422 + rl_err_out: 1423 + if (rl) { 1424 + if (ntfs_cluster_free_from_rl(vol, rl) < 0) { 1425 + ntfs_error(vol->sb, "Failed to release allocated " 1426 + "cluster(s) in error code path. Run " 1427 + "chkdsk to recover the lost " 1428 + "cluster(s)."); 1429 + NVolSetErrors(vol); 1430 + } 1431 + ntfs_free(rl); 1432 + page_err_out: 1433 + unlock_page(page); 1434 + page_cache_release(page); 1435 + } 1436 + if (err == -EINVAL) 1437 + err = -EIO; 1438 + return err; 1439 + } 1440 + 1441 + /** 1250 1442 * ntfs_attr_set - fill (a part of) an attribute with a byte 1251 1443 * @ni: ntfs inode describing the attribute to fill 1252 1444 * @ofs: offset inside the attribute at which to start to fill ··· 1579 1127 * byte offset @ofs inside the attribute with the constant byte @val. 1580 1128 * 1581 1129 * This function is effectively like memset() applied to an ntfs attribute. 1130 + * Note thie function actually only operates on the page cache pages belonging 1131 + * to the ntfs attribute and it marks them dirty after doing the memset(). 1132 + * Thus it relies on the vm dirty page write code paths to cause the modified 1133 + * pages to be written to the mft record/disk. 1582 1134 * 1583 1135 * Return 0 on success and -errno on error. An error code of -ESPIPE means 1584 1136 * that @ofs + @cnt were outside the end of the attribute and no write was ··· 1611 1155 end = ofs + cnt; 1612 1156 end_ofs = end & ~PAGE_CACHE_MASK; 1613 1157 /* If the end is outside the inode size return -ESPIPE. */ 1614 - if (unlikely(end > VFS_I(ni)->i_size)) { 1158 + if (unlikely(end > i_size_read(VFS_I(ni)))) { 1615 1159 ntfs_error(vol->sb, "Request exceeds end of attribute."); 1616 1160 return -ESPIPE; 1617 1161 } ··· 1712 1256 ntfs_debug("Done."); 1713 1257 return 0; 1714 1258 } 1259 + 1260 + #endif /* NTFS_RW */
+13 -3
fs/ntfs/attrib.h
··· 2 2 * attrib.h - Defines for attribute handling in NTFS Linux kernel driver. 3 3 * Part of the Linux-NTFS project. 4 4 * 5 - * Copyright (c) 2001-2004 Anton Altaparmakov 5 + * Copyright (c) 2001-2005 Anton Altaparmakov 6 6 * Copyright (c) 2002 Richard Russon 7 7 * 8 8 * This program/include file is free software; you can redistribute it and/or ··· 60 60 ATTR_RECORD *base_attr; 61 61 } ntfs_attr_search_ctx; 62 62 63 + extern int ntfs_map_runlist_nolock(ntfs_inode *ni, VCN vcn); 63 64 extern int ntfs_map_runlist(ntfs_inode *ni, VCN vcn); 64 65 65 - extern runlist_element *ntfs_find_vcn(ntfs_inode *ni, const VCN vcn, 66 - const BOOL need_write); 66 + extern LCN ntfs_attr_vcn_to_lcn_nolock(ntfs_inode *ni, const VCN vcn, 67 + const BOOL write_locked); 68 + 69 + extern runlist_element *ntfs_attr_find_vcn_nolock(ntfs_inode *ni, 70 + const VCN vcn, const BOOL write_locked); 67 71 68 72 int ntfs_attr_lookup(const ATTR_TYPE type, const ntfschar *name, 69 73 const u32 name_len, const IGNORE_CASE_BOOL ic, ··· 89 85 MFT_RECORD *mrec); 90 86 extern void ntfs_attr_put_search_ctx(ntfs_attr_search_ctx *ctx); 91 87 88 + #ifdef NTFS_RW 89 + 92 90 extern int ntfs_attr_size_bounds_check(const ntfs_volume *vol, 93 91 const ATTR_TYPE type, const s64 size); 94 92 extern int ntfs_attr_can_be_non_resident(const ntfs_volume *vol, ··· 100 94 101 95 extern int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size); 102 96 97 + extern int ntfs_attr_make_non_resident(ntfs_inode *ni); 98 + 103 99 extern int ntfs_attr_set(ntfs_inode *ni, const s64 ofs, const s64 cnt, 104 100 const u8 val); 101 + 102 + #endif /* NTFS_RW */ 105 103 106 104 #endif /* _LINUX_NTFS_ATTRIB_H */
+28 -18
fs/ntfs/compress.c
··· 96 96 /** 97 97 * zero_partial_compressed_page - zero out of bounds compressed page region 98 98 */ 99 - static void zero_partial_compressed_page(ntfs_inode *ni, struct page *page) 99 + static void zero_partial_compressed_page(struct page *page, 100 + const s64 initialized_size) 100 101 { 101 102 u8 *kp = page_address(page); 102 103 unsigned int kp_ofs; 103 104 104 105 ntfs_debug("Zeroing page region outside initialized size."); 105 - if (((s64)page->index << PAGE_CACHE_SHIFT) >= ni->initialized_size) { 106 + if (((s64)page->index << PAGE_CACHE_SHIFT) >= initialized_size) { 106 107 /* 107 108 * FIXME: Using clear_page() will become wrong when we get 108 109 * PAGE_CACHE_SIZE != PAGE_SIZE but for now there is no problem. ··· 111 110 clear_page(kp); 112 111 return; 113 112 } 114 - kp_ofs = ni->initialized_size & ~PAGE_CACHE_MASK; 113 + kp_ofs = initialized_size & ~PAGE_CACHE_MASK; 115 114 memset(kp + kp_ofs, 0, PAGE_CACHE_SIZE - kp_ofs); 116 115 return; 117 116 } ··· 119 118 /** 120 119 * handle_bounds_compressed_page - test for&handle out of bounds compressed page 121 120 */ 122 - static inline void handle_bounds_compressed_page(ntfs_inode *ni, 123 - struct page *page) 121 + static inline void handle_bounds_compressed_page(struct page *page, 122 + const loff_t i_size, const s64 initialized_size) 124 123 { 125 - if ((page->index >= (ni->initialized_size >> PAGE_CACHE_SHIFT)) && 126 - (ni->initialized_size < VFS_I(ni)->i_size)) 127 - zero_partial_compressed_page(ni, page); 124 + if ((page->index >= (initialized_size >> PAGE_CACHE_SHIFT)) && 125 + (initialized_size < i_size)) 126 + zero_partial_compressed_page(page, initialized_size); 128 127 return; 129 128 } 130 129 ··· 139 138 * @xpage_done: set to 1 if xpage was completed successfully (IN/OUT) 140 139 * @cb_start: compression block to decompress (IN) 141 140 * @cb_size: size of compression block @cb_start in bytes (IN) 141 + * @i_size: file size when we started the read (IN) 142 + * @initialized_size: initialized file size when we started the read (IN) 142 143 * 143 144 * The caller must have disabled preemption. ntfs_decompress() reenables it when 144 145 * the critical section is finished. ··· 168 165 static int ntfs_decompress(struct page *dest_pages[], int *dest_index, 169 166 int *dest_ofs, const int dest_max_index, const int dest_max_ofs, 170 167 const int xpage, char *xpage_done, u8 *const cb_start, 171 - const u32 cb_size) 168 + const u32 cb_size, const loff_t i_size, 169 + const s64 initialized_size) 172 170 { 173 171 /* 174 172 * Pointers into the compressed data, i.e. the compression block (cb), ··· 223 219 spin_unlock(&ntfs_cb_lock); 224 220 /* Second stage: finalize completed pages. */ 225 221 if (nr_completed_pages > 0) { 226 - struct page *page = dest_pages[completed_pages[0]]; 227 - ntfs_inode *ni = NTFS_I(page->mapping->host); 228 - 229 222 for (i = 0; i < nr_completed_pages; i++) { 230 223 int di = completed_pages[i]; 231 224 ··· 231 230 * If we are outside the initialized size, zero 232 231 * the out of bounds page range. 233 232 */ 234 - handle_bounds_compressed_page(ni, dp); 233 + handle_bounds_compressed_page(dp, i_size, 234 + initialized_size); 235 235 flush_dcache_page(dp); 236 236 kunmap(dp); 237 237 SetPageUptodate(dp); ··· 480 478 */ 481 479 int ntfs_read_compressed_block(struct page *page) 482 480 { 481 + loff_t i_size; 482 + s64 initialized_size; 483 483 struct address_space *mapping = page->mapping; 484 484 ntfs_inode *ni = NTFS_I(mapping->host); 485 485 ntfs_volume *vol = ni->vol; 486 486 struct super_block *sb = vol->sb; 487 487 runlist_element *rl; 488 - unsigned long block_size = sb->s_blocksize; 488 + unsigned long flags, block_size = sb->s_blocksize; 489 489 unsigned char block_size_bits = sb->s_blocksize_bits; 490 490 u8 *cb, *cb_pos, *cb_end; 491 491 struct buffer_head **bhs; ··· 556 552 * The remaining pages need to be allocated and inserted into the page 557 553 * cache, alignment guarantees keep all the below much simpler. (-8 558 554 */ 559 - max_page = ((VFS_I(ni)->i_size + PAGE_CACHE_SIZE - 1) >> 560 - PAGE_CACHE_SHIFT) - offset; 555 + read_lock_irqsave(&ni->size_lock, flags); 556 + i_size = i_size_read(VFS_I(ni)); 557 + initialized_size = ni->initialized_size; 558 + read_unlock_irqrestore(&ni->size_lock, flags); 559 + max_page = ((i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) - 560 + offset; 561 561 if (nr_pages < max_page) 562 562 max_page = nr_pages; 563 563 for (i = 0; i < max_page; i++, offset++) { ··· 832 824 * If we are outside the initialized size, zero 833 825 * the out of bounds page range. 834 826 */ 835 - handle_bounds_compressed_page(ni, page); 827 + handle_bounds_compressed_page(page, i_size, 828 + initialized_size); 836 829 flush_dcache_page(page); 837 830 kunmap(page); 838 831 SetPageUptodate(page); ··· 856 847 ntfs_debug("Found compressed compression block."); 857 848 err = ntfs_decompress(pages, &cur_page, &cur_ofs, 858 849 cb_max_page, cb_max_ofs, xpage, &xpage_done, 859 - cb_pos, cb_size - (cb_pos - cb)); 850 + cb_pos, cb_size - (cb_pos - cb), i_size, 851 + initialized_size); 860 852 /* 861 853 * We can sleep from now on, lock already dropped by 862 854 * ntfs_decompress().
+9 -6
fs/ntfs/debug.c
··· 164 164 if (index > -LCN_ENOENT - 1) 165 165 index = 3; 166 166 printk(KERN_DEBUG "%-16Lx %s %-16Lx%s\n", 167 - (rl + i)->vcn, lcn_str[index], 168 - (rl + i)->length, (rl + i)->length ? 169 - "" : " (runlist end)"); 167 + (long long)(rl + i)->vcn, lcn_str[index], 168 + (long long)(rl + i)->length, 169 + (rl + i)->length ? "" : 170 + " (runlist end)"); 170 171 } else 171 172 printk(KERN_DEBUG "%-16Lx %-16Lx %-16Lx%s\n", 172 - (rl + i)->vcn, (rl + i)->lcn, 173 - (rl + i)->length, (rl + i)->length ? 174 - "" : " (runlist end)"); 173 + (long long)(rl + i)->vcn, 174 + (long long)(rl + i)->lcn, 175 + (long long)(rl + i)->length, 176 + (rl + i)->length ? "" : 177 + " (runlist end)"); 175 178 if (!(rl + i)->length) 176 179 break; 177 180 }
+15 -17
fs/ntfs/dir.c
··· 1 1 /** 2 2 * dir.c - NTFS kernel directory operations. Part of the Linux-NTFS project. 3 3 * 4 - * Copyright (c) 2001-2004 Anton Altaparmakov 4 + * Copyright (c) 2001-2005 Anton Altaparmakov 5 5 * Copyright (c) 2002 Richard Russon 6 6 * 7 7 * This program/include file is free software; you can redistribute it and/or ··· 183 183 name->len = 0; 184 184 *res = name; 185 185 } else { 186 - if (name) 187 - kfree(name); 186 + kfree(name); 188 187 *res = NULL; 189 188 } 190 189 mref = le64_to_cpu(ie->data.dir.indexed_file); ··· 443 444 name->len = 0; 444 445 *res = name; 445 446 } else { 446 - if (name) 447 - kfree(name); 447 + kfree(name); 448 448 *res = NULL; 449 449 } 450 450 mref = le64_to_cpu(ie->data.dir.indexed_file); ··· 608 610 // TODO: (AIA) 609 611 // The algorithm embedded in this code will be required for the time when we 610 612 // want to support adding of entries to directories, where we require correct 611 - // collation of file names in order not to cause corruption of the file system. 613 + // collation of file names in order not to cause corruption of the filesystem. 612 614 613 615 /** 614 616 * ntfs_lookup_inode_by_name - find an inode in a directory given its name ··· 1099 1101 static int ntfs_readdir(struct file *filp, void *dirent, filldir_t filldir) 1100 1102 { 1101 1103 s64 ia_pos, ia_start, prev_ia_pos, bmp_pos; 1102 - loff_t fpos; 1104 + loff_t fpos, i_size; 1103 1105 struct inode *bmp_vi, *vdir = filp->f_dentry->d_inode; 1104 1106 struct super_block *sb = vdir->i_sb; 1105 1107 ntfs_inode *ndir = NTFS_I(vdir); ··· 1120 1122 vdir->i_ino, fpos); 1121 1123 rc = err = 0; 1122 1124 /* Are we at end of dir yet? */ 1123 - if (fpos >= vdir->i_size + vol->mft_record_size) 1125 + i_size = i_size_read(vdir); 1126 + if (fpos >= i_size + vol->mft_record_size) 1124 1127 goto done; 1125 1128 /* Emulate . and .. for all directories. */ 1126 1129 if (!fpos) { ··· 1263 1264 bmp_mapping = bmp_vi->i_mapping; 1264 1265 /* Get the starting bitmap bit position and sanity check it. */ 1265 1266 bmp_pos = ia_pos >> ndir->itype.index.block_size_bits; 1266 - if (unlikely(bmp_pos >> 3 >= bmp_vi->i_size)) { 1267 + if (unlikely(bmp_pos >> 3 >= i_size_read(bmp_vi))) { 1267 1268 ntfs_error(sb, "Current index allocation position exceeds " 1268 1269 "index bitmap size."); 1269 1270 goto err_out; ··· 1300 1301 goto get_next_bmp_page; 1301 1302 } 1302 1303 /* If we have reached the end of the bitmap, we are done. */ 1303 - if (unlikely(((bmp_pos + cur_bmp_pos) >> 3) >= vdir->i_size)) 1304 + if (unlikely(((bmp_pos + cur_bmp_pos) >> 3) >= i_size)) 1304 1305 goto unm_EOD; 1305 1306 ia_pos = (bmp_pos + cur_bmp_pos) << 1306 1307 ndir->itype.index.block_size_bits; ··· 1308 1309 ntfs_debug("Handling index buffer 0x%llx.", 1309 1310 (unsigned long long)bmp_pos + cur_bmp_pos); 1310 1311 /* If the current index buffer is in the same page we reuse the page. */ 1311 - if ((prev_ia_pos & PAGE_CACHE_MASK) != (ia_pos & PAGE_CACHE_MASK)) { 1312 + if ((prev_ia_pos & (s64)PAGE_CACHE_MASK) != 1313 + (ia_pos & (s64)PAGE_CACHE_MASK)) { 1312 1314 prev_ia_pos = ia_pos; 1313 1315 if (likely(ia_page != NULL)) { 1314 1316 unlock_page(ia_page); ··· 1441 1441 ntfs_unmap_page(bmp_page); 1442 1442 EOD: 1443 1443 /* We are finished, set fpos to EOD. */ 1444 - fpos = vdir->i_size + vol->mft_record_size; 1444 + fpos = i_size + vol->mft_record_size; 1445 1445 abort: 1446 1446 kfree(name); 1447 1447 done: ··· 1461 1461 unlock_page(ia_page); 1462 1462 ntfs_unmap_page(ia_page); 1463 1463 } 1464 - if (ir) 1465 - kfree(ir); 1466 - if (name) 1467 - kfree(name); 1464 + kfree(ir); 1465 + kfree(name); 1468 1466 if (ctx) 1469 1467 ntfs_attr_put_search_ctx(ctx); 1470 1468 if (m) ··· 1493 1495 static int ntfs_dir_open(struct inode *vi, struct file *filp) 1494 1496 { 1495 1497 if (sizeof(unsigned long) < 8) { 1496 - if (vi->i_size > MAX_LFS_FILESIZE) 1498 + if (i_size_read(vi) > MAX_LFS_FILESIZE) 1497 1499 return -EFBIG; 1498 1500 } 1499 1501 return 0;
+1 -1
fs/ntfs/file.c
··· 47 47 static int ntfs_file_open(struct inode *vi, struct file *filp) 48 48 { 49 49 if (sizeof(unsigned long) < 8) { 50 - if (vi->i_size > MAX_LFS_FILESIZE) 50 + if (i_size_read(vi) > MAX_LFS_FILESIZE) 51 51 return -EFBIG; 52 52 } 53 53 return generic_file_open(vi, filp);
+3 -13
fs/ntfs/index.c
··· 1 1 /* 2 2 * index.c - NTFS kernel index handling. Part of the Linux-NTFS project. 3 3 * 4 - * Copyright (c) 2004 Anton Altaparmakov 4 + * Copyright (c) 2004-2005 Anton Altaparmakov 5 5 * 6 6 * This program/include file is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as published ··· 39 39 ntfs_index_context *ictx; 40 40 41 41 ictx = kmem_cache_alloc(ntfs_index_ctx_cache, SLAB_NOFS); 42 - if (ictx) { 43 - ictx->idx_ni = idx_ni; 44 - ictx->entry = NULL; 45 - ictx->data = NULL; 46 - ictx->data_len = 0; 47 - ictx->is_in_root = 0; 48 - ictx->ir = NULL; 49 - ictx->actx = NULL; 50 - ictx->base_ni = NULL; 51 - ictx->ia = NULL; 52 - ictx->page = NULL; 53 - } 42 + if (ictx) 43 + *ictx = (ntfs_index_context){ .idx_ni = idx_ni }; 54 44 return ictx; 55 45 } 56 46
+262 -268
fs/ntfs/inode.c
··· 1 1 /** 2 2 * inode.c - NTFS kernel inode handling. Part of the Linux-NTFS project. 3 3 * 4 - * Copyright (c) 2001-2004 Anton Altaparmakov 4 + * Copyright (c) 2001-2005 Anton Altaparmakov 5 5 * 6 6 * This program/include file is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as published ··· 174 174 175 175 vi = iget5_locked(sb, mft_no, (test_t)ntfs_test_inode, 176 176 (set_t)ntfs_init_locked_inode, &na); 177 - if (!vi) 177 + if (unlikely(!vi)) 178 178 return ERR_PTR(-ENOMEM); 179 179 180 180 err = 0; ··· 188 188 * There is no point in keeping bad inodes around if the failure was 189 189 * due to ENOMEM. We want to be able to retry again later. 190 190 */ 191 - if (err == -ENOMEM) { 191 + if (unlikely(err == -ENOMEM)) { 192 192 iput(vi); 193 193 vi = ERR_PTR(err); 194 194 } ··· 235 235 236 236 vi = iget5_locked(base_vi->i_sb, na.mft_no, (test_t)ntfs_test_inode, 237 237 (set_t)ntfs_init_locked_inode, &na); 238 - if (!vi) 238 + if (unlikely(!vi)) 239 239 return ERR_PTR(-ENOMEM); 240 240 241 241 err = 0; ··· 250 250 * simplifies things in that we never need to check for bad attribute 251 251 * inodes elsewhere. 252 252 */ 253 - if (err) { 253 + if (unlikely(err)) { 254 254 iput(vi); 255 255 vi = ERR_PTR(err); 256 256 } ··· 290 290 291 291 vi = iget5_locked(base_vi->i_sb, na.mft_no, (test_t)ntfs_test_inode, 292 292 (set_t)ntfs_init_locked_inode, &na); 293 - if (!vi) 293 + if (unlikely(!vi)) 294 294 return ERR_PTR(-ENOMEM); 295 295 296 296 err = 0; ··· 305 305 * simplifies things in that we never need to check for bad index 306 306 * inodes elsewhere. 307 307 */ 308 - if (err) { 308 + if (unlikely(err)) { 309 309 iput(vi); 310 310 vi = ERR_PTR(err); 311 311 } ··· 317 317 ntfs_inode *ni; 318 318 319 319 ntfs_debug("Entering."); 320 - ni = (ntfs_inode *)kmem_cache_alloc(ntfs_big_inode_cache, 321 - SLAB_NOFS); 320 + ni = kmem_cache_alloc(ntfs_big_inode_cache, SLAB_NOFS); 322 321 if (likely(ni != NULL)) { 323 322 ni->state = 0; 324 323 return VFS_I(ni); ··· 342 343 ntfs_inode *ni; 343 344 344 345 ntfs_debug("Entering."); 345 - ni = (ntfs_inode *)kmem_cache_alloc(ntfs_inode_cache, SLAB_NOFS); 346 + ni = kmem_cache_alloc(ntfs_inode_cache, SLAB_NOFS); 346 347 if (likely(ni != NULL)) { 347 348 ni->state = 0; 348 349 return ni; ··· 375 376 void __ntfs_init_inode(struct super_block *sb, ntfs_inode *ni) 376 377 { 377 378 ntfs_debug("Entering."); 379 + rwlock_init(&ni->size_lock); 378 380 ni->initialized_size = ni->allocated_size = 0; 379 381 ni->seq_no = 0; 380 382 atomic_set(&ni->count, 1); ··· 524 524 ntfs_volume *vol = NTFS_SB(vi->i_sb); 525 525 ntfs_inode *ni; 526 526 MFT_RECORD *m; 527 + ATTR_RECORD *a; 527 528 STANDARD_INFORMATION *si; 528 529 ntfs_attr_search_ctx *ctx; 529 530 int err = 0; ··· 633 632 } 634 633 goto unm_err_out; 635 634 } 635 + a = ctx->attr; 636 636 /* Get the standard information attribute value. */ 637 - si = (STANDARD_INFORMATION*)((char*)ctx->attr + 638 - le16_to_cpu(ctx->attr->data.resident.value_offset)); 637 + si = (STANDARD_INFORMATION*)((u8*)a + 638 + le16_to_cpu(a->data.resident.value_offset)); 639 639 640 640 /* Transfer information from the standard information into vi. */ 641 641 /* ··· 675 673 goto skip_attr_list_load; 676 674 ntfs_debug("Attribute list found in inode 0x%lx.", vi->i_ino); 677 675 NInoSetAttrList(ni); 678 - if (ctx->attr->flags & ATTR_IS_ENCRYPTED || 679 - ctx->attr->flags & ATTR_COMPRESSION_MASK || 680 - ctx->attr->flags & ATTR_IS_SPARSE) { 676 + a = ctx->attr; 677 + if (a->flags & ATTR_IS_ENCRYPTED || 678 + a->flags & ATTR_COMPRESSION_MASK || 679 + a->flags & ATTR_IS_SPARSE) { 681 680 ntfs_error(vi->i_sb, "Attribute list attribute is " 682 681 "compressed/encrypted/sparse."); 683 682 goto unm_err_out; 684 683 } 685 684 /* Now allocate memory for the attribute list. */ 686 - ni->attr_list_size = (u32)ntfs_attr_size(ctx->attr); 685 + ni->attr_list_size = (u32)ntfs_attr_size(a); 687 686 ni->attr_list = ntfs_malloc_nofs(ni->attr_list_size); 688 687 if (!ni->attr_list) { 689 688 ntfs_error(vi->i_sb, "Not enough memory to allocate " ··· 692 689 err = -ENOMEM; 693 690 goto unm_err_out; 694 691 } 695 - if (ctx->attr->non_resident) { 692 + if (a->non_resident) { 696 693 NInoSetAttrListNonResident(ni); 697 - if (ctx->attr->data.non_resident.lowest_vcn) { 694 + if (a->data.non_resident.lowest_vcn) { 698 695 ntfs_error(vi->i_sb, "Attribute list has non " 699 696 "zero lowest_vcn."); 700 697 goto unm_err_out; ··· 704 701 * exclusive access to the inode at this time. 705 702 */ 706 703 ni->attr_list_rl.rl = ntfs_mapping_pairs_decompress(vol, 707 - ctx->attr, NULL); 704 + a, NULL); 708 705 if (IS_ERR(ni->attr_list_rl.rl)) { 709 706 err = PTR_ERR(ni->attr_list_rl.rl); 710 707 ni->attr_list_rl.rl = NULL; ··· 715 712 /* Now load the attribute list. */ 716 713 if ((err = load_attribute_list(vol, &ni->attr_list_rl, 717 714 ni->attr_list, ni->attr_list_size, 718 - sle64_to_cpu(ctx->attr->data. 719 - non_resident.initialized_size)))) { 715 + sle64_to_cpu(a->data.non_resident. 716 + initialized_size)))) { 720 717 ntfs_error(vi->i_sb, "Failed to load " 721 718 "attribute list attribute."); 722 719 goto unm_err_out; 723 720 } 724 - } else /* if (!ctx.attr->non_resident) */ { 725 - if ((u8*)ctx->attr + le16_to_cpu( 726 - ctx->attr->data.resident.value_offset) + 727 - le32_to_cpu( 728 - ctx->attr->data.resident.value_length) > 721 + } else /* if (!a->non_resident) */ { 722 + if ((u8*)a + le16_to_cpu(a->data.resident.value_offset) 723 + + le32_to_cpu( 724 + a->data.resident.value_length) > 729 725 (u8*)ctx->mrec + vol->mft_record_size) { 730 726 ntfs_error(vi->i_sb, "Corrupt attribute list " 731 727 "in inode."); 732 728 goto unm_err_out; 733 729 } 734 730 /* Now copy the attribute list. */ 735 - memcpy(ni->attr_list, (u8*)ctx->attr + le16_to_cpu( 736 - ctx->attr->data.resident.value_offset), 731 + memcpy(ni->attr_list, (u8*)a + le16_to_cpu( 732 + a->data.resident.value_offset), 737 733 le32_to_cpu( 738 - ctx->attr->data.resident.value_length)); 734 + a->data.resident.value_length)); 739 735 } 740 736 } 741 737 skip_attr_list_load: ··· 743 741 * in ntfs_ino->attr_list and it is ntfs_ino->attr_list_size bytes. 744 742 */ 745 743 if (S_ISDIR(vi->i_mode)) { 744 + loff_t bvi_size; 746 745 struct inode *bvi; 747 746 ntfs_inode *bni; 748 747 INDEX_ROOT *ir; 749 - char *ir_end, *index_end; 748 + u8 *ir_end, *index_end; 750 749 751 750 /* It is a directory, find index root attribute. */ 752 751 ntfs_attr_reinit_search_ctx(ctx); ··· 763 760 } 764 761 goto unm_err_out; 765 762 } 763 + a = ctx->attr; 766 764 /* Set up the state. */ 767 - if (unlikely(ctx->attr->non_resident)) { 765 + if (unlikely(a->non_resident)) { 768 766 ntfs_error(vol->sb, "$INDEX_ROOT attribute is not " 769 767 "resident."); 770 768 goto unm_err_out; 771 769 } 772 770 /* Ensure the attribute name is placed before the value. */ 773 - if (unlikely(ctx->attr->name_length && 774 - (le16_to_cpu(ctx->attr->name_offset) >= 775 - le16_to_cpu(ctx->attr->data.resident. 776 - value_offset)))) { 771 + if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >= 772 + le16_to_cpu(a->data.resident.value_offset)))) { 777 773 ntfs_error(vol->sb, "$INDEX_ROOT attribute name is " 778 774 "placed after the attribute value."); 779 775 goto unm_err_out; ··· 783 781 * encrypted. However index root cannot be both compressed and 784 782 * encrypted. 785 783 */ 786 - if (ctx->attr->flags & ATTR_COMPRESSION_MASK) 784 + if (a->flags & ATTR_COMPRESSION_MASK) 787 785 NInoSetCompressed(ni); 788 - if (ctx->attr->flags & ATTR_IS_ENCRYPTED) { 789 - if (ctx->attr->flags & ATTR_COMPRESSION_MASK) { 786 + if (a->flags & ATTR_IS_ENCRYPTED) { 787 + if (a->flags & ATTR_COMPRESSION_MASK) { 790 788 ntfs_error(vi->i_sb, "Found encrypted and " 791 789 "compressed attribute."); 792 790 goto unm_err_out; 793 791 } 794 792 NInoSetEncrypted(ni); 795 793 } 796 - if (ctx->attr->flags & ATTR_IS_SPARSE) 794 + if (a->flags & ATTR_IS_SPARSE) 797 795 NInoSetSparse(ni); 798 - ir = (INDEX_ROOT*)((char*)ctx->attr + le16_to_cpu( 799 - ctx->attr->data.resident.value_offset)); 800 - ir_end = (char*)ir + le32_to_cpu( 801 - ctx->attr->data.resident.value_length); 802 - if (ir_end > (char*)ctx->mrec + vol->mft_record_size) { 796 + ir = (INDEX_ROOT*)((u8*)a + 797 + le16_to_cpu(a->data.resident.value_offset)); 798 + ir_end = (u8*)ir + le32_to_cpu(a->data.resident.value_length); 799 + if (ir_end > (u8*)ctx->mrec + vol->mft_record_size) { 803 800 ntfs_error(vi->i_sb, "$INDEX_ROOT attribute is " 804 801 "corrupt."); 805 802 goto unm_err_out; 806 803 } 807 - index_end = (char*)&ir->index + 804 + index_end = (u8*)&ir->index + 808 805 le32_to_cpu(ir->index.index_length); 809 806 if (index_end > ir_end) { 810 807 ntfs_error(vi->i_sb, "Directory index is corrupt."); ··· 890 889 "attribute."); 891 890 goto unm_err_out; 892 891 } 893 - if (!ctx->attr->non_resident) { 892 + a = ctx->attr; 893 + if (!a->non_resident) { 894 894 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute " 895 895 "is resident."); 896 896 goto unm_err_out; ··· 900 898 * Ensure the attribute name is placed before the mapping pairs 901 899 * array. 902 900 */ 903 - if (unlikely(ctx->attr->name_length && 904 - (le16_to_cpu(ctx->attr->name_offset) >= 905 - le16_to_cpu(ctx->attr->data.non_resident. 906 - mapping_pairs_offset)))) { 901 + if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >= 902 + le16_to_cpu( 903 + a->data.non_resident.mapping_pairs_offset)))) { 907 904 ntfs_error(vol->sb, "$INDEX_ALLOCATION attribute name " 908 905 "is placed after the mapping pairs " 909 906 "array."); 910 907 goto unm_err_out; 911 908 } 912 - if (ctx->attr->flags & ATTR_IS_ENCRYPTED) { 909 + if (a->flags & ATTR_IS_ENCRYPTED) { 913 910 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute " 914 911 "is encrypted."); 915 912 goto unm_err_out; 916 913 } 917 - if (ctx->attr->flags & ATTR_IS_SPARSE) { 914 + if (a->flags & ATTR_IS_SPARSE) { 918 915 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute " 919 916 "is sparse."); 920 917 goto unm_err_out; 921 918 } 922 - if (ctx->attr->flags & ATTR_COMPRESSION_MASK) { 919 + if (a->flags & ATTR_COMPRESSION_MASK) { 923 920 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute " 924 921 "is compressed."); 925 922 goto unm_err_out; 926 923 } 927 - if (ctx->attr->data.non_resident.lowest_vcn) { 924 + if (a->data.non_resident.lowest_vcn) { 928 925 ntfs_error(vi->i_sb, "First extent of " 929 926 "$INDEX_ALLOCATION attribute has non " 930 927 "zero lowest_vcn."); 931 928 goto unm_err_out; 932 929 } 933 - vi->i_size = sle64_to_cpu( 934 - ctx->attr->data.non_resident.data_size); 930 + vi->i_size = sle64_to_cpu(a->data.non_resident.data_size); 935 931 ni->initialized_size = sle64_to_cpu( 936 - ctx->attr->data.non_resident.initialized_size); 932 + a->data.non_resident.initialized_size); 937 933 ni->allocated_size = sle64_to_cpu( 938 - ctx->attr->data.non_resident.allocated_size); 934 + a->data.non_resident.allocated_size); 939 935 /* 940 936 * We are done with the mft record, so we release it. Otherwise 941 937 * we would deadlock in ntfs_attr_iget(). ··· 958 958 goto unm_err_out; 959 959 } 960 960 /* Consistency check bitmap size vs. index allocation size. */ 961 - if ((bvi->i_size << 3) < (vi->i_size >> 961 + bvi_size = i_size_read(bvi); 962 + if ((bvi_size << 3) < (vi->i_size >> 962 963 ni->itype.index.block_size_bits)) { 963 964 ntfs_error(vi->i_sb, "Index bitmap too small (0x%llx) " 964 965 "for index allocation (0x%llx).", 965 - bvi->i_size << 3, vi->i_size); 966 + bvi_size << 3, vi->i_size); 966 967 goto unm_err_out; 967 968 } 968 969 skip_large_dir_stuff: ··· 1011 1010 ntfs_error(vi->i_sb, "$DATA attribute is missing."); 1012 1011 goto unm_err_out; 1013 1012 } 1013 + a = ctx->attr; 1014 1014 /* Setup the state. */ 1015 - if (ctx->attr->non_resident) { 1015 + if (a->non_resident) { 1016 1016 NInoSetNonResident(ni); 1017 - if (ctx->attr->flags & ATTR_COMPRESSION_MASK) { 1018 - NInoSetCompressed(ni); 1019 - if (vol->cluster_size > 4096) { 1020 - ntfs_error(vi->i_sb, "Found " 1021 - "compressed data but " 1022 - "compression is disabled due " 1023 - "to cluster size (%i) > 4kiB.", 1024 - vol->cluster_size); 1025 - goto unm_err_out; 1017 + if (a->flags & (ATTR_COMPRESSION_MASK | 1018 + ATTR_IS_SPARSE)) { 1019 + if (a->flags & ATTR_COMPRESSION_MASK) { 1020 + NInoSetCompressed(ni); 1021 + if (vol->cluster_size > 4096) { 1022 + ntfs_error(vi->i_sb, "Found " 1023 + "compressed data but " 1024 + "compression is " 1025 + "disabled due to " 1026 + "cluster size (%i) > " 1027 + "4kiB.", 1028 + vol->cluster_size); 1029 + goto unm_err_out; 1030 + } 1031 + if ((a->flags & ATTR_COMPRESSION_MASK) 1032 + != ATTR_IS_COMPRESSED) { 1033 + ntfs_error(vi->i_sb, "Found " 1034 + "unknown compression " 1035 + "method or corrupt " 1036 + "file."); 1037 + goto unm_err_out; 1038 + } 1026 1039 } 1027 - if ((ctx->attr->flags & ATTR_COMPRESSION_MASK) 1028 - != ATTR_IS_COMPRESSED) { 1029 - ntfs_error(vi->i_sb, "Found " 1030 - "unknown compression method or " 1031 - "corrupt file."); 1032 - goto unm_err_out; 1033 - } 1034 - ni->itype.compressed.block_clusters = 1U << 1035 - ctx->attr->data.non_resident. 1036 - compression_unit; 1037 - if (ctx->attr->data.non_resident. 1038 - compression_unit != 4) { 1040 + if (a->flags & ATTR_IS_SPARSE) 1041 + NInoSetSparse(ni); 1042 + if (a->data.non_resident.compression_unit != 1043 + 4) { 1039 1044 ntfs_error(vi->i_sb, "Found " 1040 1045 "nonstandard compression unit " 1041 1046 "(%u instead of 4). Cannot " 1042 1047 "handle this.", 1043 - ctx->attr->data.non_resident. 1048 + a->data.non_resident. 1044 1049 compression_unit); 1045 1050 err = -EOPNOTSUPP; 1046 1051 goto unm_err_out; 1047 1052 } 1053 + ni->itype.compressed.block_clusters = 1U << 1054 + a->data.non_resident. 1055 + compression_unit; 1048 1056 ni->itype.compressed.block_size = 1U << ( 1049 - ctx->attr->data.non_resident. 1057 + a->data.non_resident. 1050 1058 compression_unit + 1051 1059 vol->cluster_size_bits); 1052 1060 ni->itype.compressed.block_size_bits = ffs( 1053 - ni->itype.compressed.block_size) - 1; 1061 + ni->itype.compressed. 1062 + block_size) - 1; 1063 + ni->itype.compressed.size = sle64_to_cpu( 1064 + a->data.non_resident. 1065 + compressed_size); 1054 1066 } 1055 - if (ctx->attr->flags & ATTR_IS_ENCRYPTED) { 1056 - if (ctx->attr->flags & ATTR_COMPRESSION_MASK) { 1067 + if (a->flags & ATTR_IS_ENCRYPTED) { 1068 + if (a->flags & ATTR_COMPRESSION_MASK) { 1057 1069 ntfs_error(vi->i_sb, "Found encrypted " 1058 1070 "and compressed data."); 1059 1071 goto unm_err_out; 1060 1072 } 1061 1073 NInoSetEncrypted(ni); 1062 1074 } 1063 - if (ctx->attr->flags & ATTR_IS_SPARSE) 1064 - NInoSetSparse(ni); 1065 - if (ctx->attr->data.non_resident.lowest_vcn) { 1075 + if (a->data.non_resident.lowest_vcn) { 1066 1076 ntfs_error(vi->i_sb, "First extent of $DATA " 1067 1077 "attribute has non zero " 1068 1078 "lowest_vcn."); 1069 1079 goto unm_err_out; 1070 1080 } 1071 - /* Setup all the sizes. */ 1072 1081 vi->i_size = sle64_to_cpu( 1073 - ctx->attr->data.non_resident.data_size); 1082 + a->data.non_resident.data_size); 1074 1083 ni->initialized_size = sle64_to_cpu( 1075 - ctx->attr->data.non_resident. 1076 - initialized_size); 1084 + a->data.non_resident.initialized_size); 1077 1085 ni->allocated_size = sle64_to_cpu( 1078 - ctx->attr->data.non_resident. 1079 - allocated_size); 1080 - if (NInoCompressed(ni)) { 1081 - ni->itype.compressed.size = sle64_to_cpu( 1082 - ctx->attr->data.non_resident. 1083 - compressed_size); 1084 - } 1086 + a->data.non_resident.allocated_size); 1085 1087 } else { /* Resident attribute. */ 1086 - /* 1087 - * Make all sizes equal for simplicity in read code 1088 - * paths. FIXME: Need to keep this in mind when 1089 - * converting to non-resident attribute in write code 1090 - * path. (Probably only affects truncate().) 1091 - */ 1092 - vi->i_size = ni->initialized_size = ni->allocated_size = 1093 - le32_to_cpu( 1094 - ctx->attr->data.resident.value_length); 1088 + vi->i_size = ni->initialized_size = le32_to_cpu( 1089 + a->data.resident.value_length); 1090 + ni->allocated_size = le32_to_cpu(a->length) - 1091 + le16_to_cpu( 1092 + a->data.resident.value_offset); 1093 + if (vi->i_size > ni->allocated_size) { 1094 + ntfs_error(vi->i_sb, "Resident data attribute " 1095 + "is corrupt (size exceeds " 1096 + "allocation)."); 1097 + goto unm_err_out; 1098 + } 1095 1099 } 1096 1100 no_data_attr_special_case: 1097 1101 /* We are done with the mft record, so we release it. */ ··· 1123 1117 * sizes of all non-resident attributes present to give us the Linux 1124 1118 * correct size that should go into i_blocks (after division by 512). 1125 1119 */ 1126 - if (S_ISDIR(vi->i_mode) || !NInoCompressed(ni)) 1127 - vi->i_blocks = ni->allocated_size >> 9; 1128 - else 1120 + if (S_ISREG(vi->i_mode) && (NInoCompressed(ni) || NInoSparse(ni))) 1129 1121 vi->i_blocks = ni->itype.compressed.size >> 9; 1130 - 1122 + else 1123 + vi->i_blocks = ni->allocated_size >> 9; 1131 1124 ntfs_debug("Done."); 1132 1125 return 0; 1133 1126 ··· 1171 1166 ntfs_volume *vol = NTFS_SB(vi->i_sb); 1172 1167 ntfs_inode *ni, *base_ni; 1173 1168 MFT_RECORD *m; 1169 + ATTR_RECORD *a; 1174 1170 ntfs_attr_search_ctx *ctx; 1175 1171 int err = 0; 1176 1172 ··· 1206 1200 err = -ENOMEM; 1207 1201 goto unm_err_out; 1208 1202 } 1209 - 1210 1203 /* Find the attribute. */ 1211 1204 err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len, 1212 1205 CASE_SENSITIVE, 0, NULL, 0, ctx); 1213 1206 if (unlikely(err)) 1214 1207 goto unm_err_out; 1215 - 1216 - if (!ctx->attr->non_resident) { 1208 + a = ctx->attr; 1209 + if (!a->non_resident) { 1217 1210 /* Ensure the attribute name is placed before the value. */ 1218 - if (unlikely(ctx->attr->name_length && 1219 - (le16_to_cpu(ctx->attr->name_offset) >= 1220 - le16_to_cpu(ctx->attr->data.resident. 1221 - value_offset)))) { 1211 + if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >= 1212 + le16_to_cpu(a->data.resident.value_offset)))) { 1222 1213 ntfs_error(vol->sb, "Attribute name is placed after " 1223 1214 "the attribute value."); 1224 1215 goto unm_err_out; 1225 1216 } 1226 - if (NInoMstProtected(ni) || ctx->attr->flags) { 1217 + if (NInoMstProtected(ni) || a->flags) { 1227 1218 ntfs_error(vi->i_sb, "Found mst protected attribute " 1228 1219 "or attribute with non-zero flags but " 1229 1220 "the attribute is resident. Please " ··· 1228 1225 "linux-ntfs-dev@lists.sourceforge.net"); 1229 1226 goto unm_err_out; 1230 1227 } 1231 - /* 1232 - * Resident attribute. Make all sizes equal for simplicity in 1233 - * read code paths. 1234 - */ 1235 - vi->i_size = ni->initialized_size = ni->allocated_size = 1236 - le32_to_cpu(ctx->attr->data.resident.value_length); 1228 + vi->i_size = ni->initialized_size = le32_to_cpu( 1229 + a->data.resident.value_length); 1230 + ni->allocated_size = le32_to_cpu(a->length) - 1231 + le16_to_cpu(a->data.resident.value_offset); 1232 + if (vi->i_size > ni->allocated_size) { 1233 + ntfs_error(vi->i_sb, "Resident attribute is corrupt " 1234 + "(size exceeds allocation)."); 1235 + goto unm_err_out; 1236 + } 1237 1237 } else { 1238 1238 NInoSetNonResident(ni); 1239 1239 /* 1240 1240 * Ensure the attribute name is placed before the mapping pairs 1241 1241 * array. 1242 1242 */ 1243 - if (unlikely(ctx->attr->name_length && 1244 - (le16_to_cpu(ctx->attr->name_offset) >= 1245 - le16_to_cpu(ctx->attr->data.non_resident. 1246 - mapping_pairs_offset)))) { 1243 + if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >= 1244 + le16_to_cpu( 1245 + a->data.non_resident.mapping_pairs_offset)))) { 1247 1246 ntfs_error(vol->sb, "Attribute name is placed after " 1248 1247 "the mapping pairs array."); 1249 1248 goto unm_err_out; 1250 1249 } 1251 - if (ctx->attr->flags & ATTR_COMPRESSION_MASK) { 1250 + if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_SPARSE)) { 1251 + if (a->flags & ATTR_COMPRESSION_MASK) { 1252 + NInoSetCompressed(ni); 1253 + if ((ni->type != AT_DATA) || (ni->type == 1254 + AT_DATA && ni->name_len)) { 1255 + ntfs_error(vi->i_sb, "Found compressed " 1256 + "non-data or named " 1257 + "data attribute. " 1258 + "Please report you " 1259 + "saw this message to " 1260 + "linux-ntfs-dev@lists." 1261 + "sourceforge.net"); 1262 + goto unm_err_out; 1263 + } 1264 + if (vol->cluster_size > 4096) { 1265 + ntfs_error(vi->i_sb, "Found compressed " 1266 + "attribute but " 1267 + "compression is " 1268 + "disabled due to " 1269 + "cluster size (%i) > " 1270 + "4kiB.", 1271 + vol->cluster_size); 1272 + goto unm_err_out; 1273 + } 1274 + if ((a->flags & ATTR_COMPRESSION_MASK) != 1275 + ATTR_IS_COMPRESSED) { 1276 + ntfs_error(vi->i_sb, "Found unknown " 1277 + "compression method."); 1278 + goto unm_err_out; 1279 + } 1280 + } 1252 1281 if (NInoMstProtected(ni)) { 1253 1282 ntfs_error(vi->i_sb, "Found mst protected " 1254 1283 "attribute but the attribute " 1255 - "is compressed. Please report " 1256 - "you saw this message to " 1284 + "is %s. Please report you " 1285 + "saw this message to " 1257 1286 "linux-ntfs-dev@lists." 1258 - "sourceforge.net"); 1287 + "sourceforge.net", 1288 + NInoCompressed(ni) ? 1289 + "compressed" : "sparse"); 1259 1290 goto unm_err_out; 1260 1291 } 1261 - NInoSetCompressed(ni); 1262 - if ((ni->type != AT_DATA) || (ni->type == AT_DATA && 1263 - ni->name_len)) { 1264 - ntfs_error(vi->i_sb, "Found compressed " 1265 - "non-data or named data " 1266 - "attribute. Please report " 1267 - "you saw this message to " 1268 - "linux-ntfs-dev@lists." 1269 - "sourceforge.net"); 1270 - goto unm_err_out; 1271 - } 1272 - if (vol->cluster_size > 4096) { 1273 - ntfs_error(vi->i_sb, "Found compressed " 1274 - "attribute but compression is " 1275 - "disabled due to cluster size " 1276 - "(%i) > 4kiB.", 1277 - vol->cluster_size); 1278 - goto unm_err_out; 1279 - } 1280 - if ((ctx->attr->flags & ATTR_COMPRESSION_MASK) 1281 - != ATTR_IS_COMPRESSED) { 1282 - ntfs_error(vi->i_sb, "Found unknown " 1283 - "compression method."); 1284 - goto unm_err_out; 1285 - } 1286 - ni->itype.compressed.block_clusters = 1U << 1287 - ctx->attr->data.non_resident. 1288 - compression_unit; 1289 - if (ctx->attr->data.non_resident.compression_unit != 1290 - 4) { 1292 + if (a->flags & ATTR_IS_SPARSE) 1293 + NInoSetSparse(ni); 1294 + if (a->data.non_resident.compression_unit != 4) { 1291 1295 ntfs_error(vi->i_sb, "Found nonstandard " 1292 1296 "compression unit (%u instead " 1293 1297 "of 4). Cannot handle this.", 1294 - ctx->attr->data.non_resident. 1298 + a->data.non_resident. 1295 1299 compression_unit); 1296 1300 err = -EOPNOTSUPP; 1297 1301 goto unm_err_out; 1298 1302 } 1303 + ni->itype.compressed.block_clusters = 1U << 1304 + a->data.non_resident.compression_unit; 1299 1305 ni->itype.compressed.block_size = 1U << ( 1300 - ctx->attr->data.non_resident. 1301 - compression_unit + 1306 + a->data.non_resident.compression_unit + 1302 1307 vol->cluster_size_bits); 1303 1308 ni->itype.compressed.block_size_bits = ffs( 1304 - ni->itype.compressed.block_size) - 1; 1309 + ni->itype.compressed.block_size) - 1; 1310 + ni->itype.compressed.size = sle64_to_cpu( 1311 + a->data.non_resident.compressed_size); 1305 1312 } 1306 - if (ctx->attr->flags & ATTR_IS_ENCRYPTED) { 1307 - if (ctx->attr->flags & ATTR_COMPRESSION_MASK) { 1308 - ntfs_error(vi->i_sb, "Found encrypted " 1309 - "and compressed data."); 1313 + if (a->flags & ATTR_IS_ENCRYPTED) { 1314 + if (a->flags & ATTR_COMPRESSION_MASK) { 1315 + ntfs_error(vi->i_sb, "Found encrypted and " 1316 + "compressed data."); 1310 1317 goto unm_err_out; 1311 1318 } 1312 1319 if (NInoMstProtected(ni)) { ··· 1330 1317 } 1331 1318 NInoSetEncrypted(ni); 1332 1319 } 1333 - if (ctx->attr->flags & ATTR_IS_SPARSE) { 1334 - if (NInoMstProtected(ni)) { 1335 - ntfs_error(vi->i_sb, "Found mst protected " 1336 - "attribute but the attribute " 1337 - "is sparse. Please report " 1338 - "you saw this message to " 1339 - "linux-ntfs-dev@lists." 1340 - "sourceforge.net"); 1341 - goto unm_err_out; 1342 - } 1343 - NInoSetSparse(ni); 1344 - } 1345 - if (ctx->attr->data.non_resident.lowest_vcn) { 1320 + if (a->data.non_resident.lowest_vcn) { 1346 1321 ntfs_error(vi->i_sb, "First extent of attribute has " 1347 1322 "non-zero lowest_vcn."); 1348 1323 goto unm_err_out; 1349 1324 } 1350 - /* Setup all the sizes. */ 1351 - vi->i_size = sle64_to_cpu( 1352 - ctx->attr->data.non_resident.data_size); 1325 + vi->i_size = sle64_to_cpu(a->data.non_resident.data_size); 1353 1326 ni->initialized_size = sle64_to_cpu( 1354 - ctx->attr->data.non_resident.initialized_size); 1327 + a->data.non_resident.initialized_size); 1355 1328 ni->allocated_size = sle64_to_cpu( 1356 - ctx->attr->data.non_resident.allocated_size); 1357 - if (NInoCompressed(ni)) { 1358 - ni->itype.compressed.size = sle64_to_cpu( 1359 - ctx->attr->data.non_resident. 1360 - compressed_size); 1361 - } 1329 + a->data.non_resident.allocated_size); 1362 1330 } 1363 - 1364 1331 /* Setup the operations for this attribute inode. */ 1365 1332 vi->i_op = NULL; 1366 1333 vi->i_fop = NULL; ··· 1348 1355 vi->i_mapping->a_ops = &ntfs_mst_aops; 1349 1356 else 1350 1357 vi->i_mapping->a_ops = &ntfs_aops; 1351 - 1352 - if (!NInoCompressed(ni)) 1353 - vi->i_blocks = ni->allocated_size >> 9; 1354 - else 1358 + if (NInoCompressed(ni) || NInoSparse(ni)) 1355 1359 vi->i_blocks = ni->itype.compressed.size >> 9; 1356 - 1360 + else 1361 + vi->i_blocks = ni->allocated_size >> 9; 1357 1362 /* 1358 1363 * Make sure the base inode doesn't go away and attach it to the 1359 1364 * attribute inode. ··· 1420 1429 */ 1421 1430 static int ntfs_read_locked_index_inode(struct inode *base_vi, struct inode *vi) 1422 1431 { 1432 + loff_t bvi_size; 1423 1433 ntfs_volume *vol = NTFS_SB(vi->i_sb); 1424 1434 ntfs_inode *ni, *base_ni, *bni; 1425 1435 struct inode *bvi; 1426 1436 MFT_RECORD *m; 1437 + ATTR_RECORD *a; 1427 1438 ntfs_attr_search_ctx *ctx; 1428 1439 INDEX_ROOT *ir; 1429 1440 u8 *ir_end, *index_end; ··· 1467 1474 "missing."); 1468 1475 goto unm_err_out; 1469 1476 } 1477 + a = ctx->attr; 1470 1478 /* Set up the state. */ 1471 - if (unlikely(ctx->attr->non_resident)) { 1479 + if (unlikely(a->non_resident)) { 1472 1480 ntfs_error(vol->sb, "$INDEX_ROOT attribute is not resident."); 1473 1481 goto unm_err_out; 1474 1482 } 1475 1483 /* Ensure the attribute name is placed before the value. */ 1476 - if (unlikely(ctx->attr->name_length && 1477 - (le16_to_cpu(ctx->attr->name_offset) >= 1478 - le16_to_cpu(ctx->attr->data.resident. 1479 - value_offset)))) { 1484 + if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >= 1485 + le16_to_cpu(a->data.resident.value_offset)))) { 1480 1486 ntfs_error(vol->sb, "$INDEX_ROOT attribute name is placed " 1481 1487 "after the attribute value."); 1482 1488 goto unm_err_out; 1483 1489 } 1484 1490 /* Compressed/encrypted/sparse index root is not allowed. */ 1485 - if (ctx->attr->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_ENCRYPTED | 1491 + if (a->flags & (ATTR_COMPRESSION_MASK | ATTR_IS_ENCRYPTED | 1486 1492 ATTR_IS_SPARSE)) { 1487 1493 ntfs_error(vi->i_sb, "Found compressed/encrypted/sparse index " 1488 1494 "root attribute."); 1489 1495 goto unm_err_out; 1490 1496 } 1491 - ir = (INDEX_ROOT*)((u8*)ctx->attr + 1492 - le16_to_cpu(ctx->attr->data.resident.value_offset)); 1493 - ir_end = (u8*)ir + le32_to_cpu(ctx->attr->data.resident.value_length); 1497 + ir = (INDEX_ROOT*)((u8*)a + le16_to_cpu(a->data.resident.value_offset)); 1498 + ir_end = (u8*)ir + le32_to_cpu(a->data.resident.value_length); 1494 1499 if (ir_end > (u8*)ctx->mrec + vol->mft_record_size) { 1495 1500 ntfs_error(vi->i_sb, "$INDEX_ROOT attribute is corrupt."); 1496 1501 goto unm_err_out; ··· 1561 1570 "$INDEX_ALLOCATION attribute."); 1562 1571 goto unm_err_out; 1563 1572 } 1564 - if (!ctx->attr->non_resident) { 1573 + if (!a->non_resident) { 1565 1574 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is " 1566 1575 "resident."); 1567 1576 goto unm_err_out; ··· 1569 1578 /* 1570 1579 * Ensure the attribute name is placed before the mapping pairs array. 1571 1580 */ 1572 - if (unlikely(ctx->attr->name_length && (le16_to_cpu( 1573 - ctx->attr->name_offset) >= le16_to_cpu( 1574 - ctx->attr->data.non_resident.mapping_pairs_offset)))) { 1581 + if (unlikely(a->name_length && (le16_to_cpu(a->name_offset) >= 1582 + le16_to_cpu( 1583 + a->data.non_resident.mapping_pairs_offset)))) { 1575 1584 ntfs_error(vol->sb, "$INDEX_ALLOCATION attribute name is " 1576 1585 "placed after the mapping pairs array."); 1577 1586 goto unm_err_out; 1578 1587 } 1579 - if (ctx->attr->flags & ATTR_IS_ENCRYPTED) { 1588 + if (a->flags & ATTR_IS_ENCRYPTED) { 1580 1589 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is " 1581 1590 "encrypted."); 1582 1591 goto unm_err_out; 1583 1592 } 1584 - if (ctx->attr->flags & ATTR_IS_SPARSE) { 1593 + if (a->flags & ATTR_IS_SPARSE) { 1585 1594 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is sparse."); 1586 1595 goto unm_err_out; 1587 1596 } 1588 - if (ctx->attr->flags & ATTR_COMPRESSION_MASK) { 1597 + if (a->flags & ATTR_COMPRESSION_MASK) { 1589 1598 ntfs_error(vi->i_sb, "$INDEX_ALLOCATION attribute is " 1590 1599 "compressed."); 1591 1600 goto unm_err_out; 1592 1601 } 1593 - if (ctx->attr->data.non_resident.lowest_vcn) { 1602 + if (a->data.non_resident.lowest_vcn) { 1594 1603 ntfs_error(vi->i_sb, "First extent of $INDEX_ALLOCATION " 1595 1604 "attribute has non zero lowest_vcn."); 1596 1605 goto unm_err_out; 1597 1606 } 1598 - vi->i_size = sle64_to_cpu(ctx->attr->data.non_resident.data_size); 1607 + vi->i_size = sle64_to_cpu(a->data.non_resident.data_size); 1599 1608 ni->initialized_size = sle64_to_cpu( 1600 - ctx->attr->data.non_resident.initialized_size); 1601 - ni->allocated_size = sle64_to_cpu( 1602 - ctx->attr->data.non_resident.allocated_size); 1609 + a->data.non_resident.initialized_size); 1610 + ni->allocated_size = sle64_to_cpu(a->data.non_resident.allocated_size); 1603 1611 /* 1604 1612 * We are done with the mft record, so we release it. Otherwise 1605 1613 * we would deadlock in ntfs_attr_iget(). ··· 1622 1632 goto iput_unm_err_out; 1623 1633 } 1624 1634 /* Consistency check bitmap size vs. index allocation size. */ 1625 - if ((bvi->i_size << 3) < (vi->i_size >> 1626 - ni->itype.index.block_size_bits)) { 1635 + bvi_size = i_size_read(bvi); 1636 + if ((bvi_size << 3) < (vi->i_size >> ni->itype.index.block_size_bits)) { 1627 1637 ntfs_error(vi->i_sb, "Index bitmap too small (0x%llx) for " 1628 - "index allocation (0x%llx).", bvi->i_size << 3, 1638 + "index allocation (0x%llx).", bvi_size << 3, 1629 1639 vi->i_size); 1630 1640 goto iput_unm_err_out; 1631 1641 } ··· 1636 1646 vi->i_fop = NULL; 1637 1647 vi->i_mapping->a_ops = &ntfs_mst_aops; 1638 1648 vi->i_blocks = ni->allocated_size >> 9; 1639 - 1640 1649 /* 1641 1650 * Make sure the base inode doesn't go away and attach it to the 1642 1651 * index inode. ··· 1701 1712 struct buffer_head *bh; 1702 1713 ntfs_inode *ni; 1703 1714 MFT_RECORD *m = NULL; 1704 - ATTR_RECORD *attr; 1715 + ATTR_RECORD *a; 1705 1716 ntfs_attr_search_ctx *ctx; 1706 1717 unsigned int i, nr_blocks; 1707 1718 int err; ··· 1716 1727 /* Setup the data attribute. It is special as it is mst protected. */ 1717 1728 NInoSetNonResident(ni); 1718 1729 NInoSetMstProtected(ni); 1730 + NInoSetSparseDisabled(ni); 1719 1731 ni->type = AT_DATA; 1720 1732 ni->name = NULL; 1721 1733 ni->name_len = 0; 1722 - 1723 1734 /* 1724 1735 * This sets up our little cheat allowing us to reuse the async read io 1725 1736 * completion handler for directories. ··· 1797 1808 1798 1809 ntfs_debug("Attribute list attribute found in $MFT."); 1799 1810 NInoSetAttrList(ni); 1800 - if (ctx->attr->flags & ATTR_IS_ENCRYPTED || 1801 - ctx->attr->flags & ATTR_COMPRESSION_MASK || 1802 - ctx->attr->flags & ATTR_IS_SPARSE) { 1811 + a = ctx->attr; 1812 + if (a->flags & ATTR_IS_ENCRYPTED || 1813 + a->flags & ATTR_COMPRESSION_MASK || 1814 + a->flags & ATTR_IS_SPARSE) { 1803 1815 ntfs_error(sb, "Attribute list attribute is " 1804 1816 "compressed/encrypted/sparse. Not " 1805 1817 "allowed. $MFT is corrupt. You should " ··· 1808 1818 goto put_err_out; 1809 1819 } 1810 1820 /* Now allocate memory for the attribute list. */ 1811 - ni->attr_list_size = (u32)ntfs_attr_size(ctx->attr); 1821 + ni->attr_list_size = (u32)ntfs_attr_size(a); 1812 1822 ni->attr_list = ntfs_malloc_nofs(ni->attr_list_size); 1813 1823 if (!ni->attr_list) { 1814 1824 ntfs_error(sb, "Not enough memory to allocate buffer " 1815 1825 "for attribute list."); 1816 1826 goto put_err_out; 1817 1827 } 1818 - if (ctx->attr->non_resident) { 1828 + if (a->non_resident) { 1819 1829 NInoSetAttrListNonResident(ni); 1820 - if (ctx->attr->data.non_resident.lowest_vcn) { 1830 + if (a->data.non_resident.lowest_vcn) { 1821 1831 ntfs_error(sb, "Attribute list has non zero " 1822 1832 "lowest_vcn. $MFT is corrupt. " 1823 1833 "You should run chkdsk."); ··· 1825 1835 } 1826 1836 /* Setup the runlist. */ 1827 1837 ni->attr_list_rl.rl = ntfs_mapping_pairs_decompress(vol, 1828 - ctx->attr, NULL); 1838 + a, NULL); 1829 1839 if (IS_ERR(ni->attr_list_rl.rl)) { 1830 1840 err = PTR_ERR(ni->attr_list_rl.rl); 1831 1841 ni->attr_list_rl.rl = NULL; ··· 1837 1847 /* Now load the attribute list. */ 1838 1848 if ((err = load_attribute_list(vol, &ni->attr_list_rl, 1839 1849 ni->attr_list, ni->attr_list_size, 1840 - sle64_to_cpu(ctx->attr->data. 1850 + sle64_to_cpu(a->data. 1841 1851 non_resident.initialized_size)))) { 1842 1852 ntfs_error(sb, "Failed to load attribute list " 1843 1853 "attribute with error code %i.", ··· 1845 1855 goto put_err_out; 1846 1856 } 1847 1857 } else /* if (!ctx.attr->non_resident) */ { 1848 - if ((u8*)ctx->attr + le16_to_cpu( 1849 - ctx->attr->data.resident.value_offset) + 1858 + if ((u8*)a + le16_to_cpu( 1859 + a->data.resident.value_offset) + 1850 1860 le32_to_cpu( 1851 - ctx->attr->data.resident.value_length) > 1861 + a->data.resident.value_length) > 1852 1862 (u8*)ctx->mrec + vol->mft_record_size) { 1853 1863 ntfs_error(sb, "Corrupt attribute list " 1854 1864 "attribute."); 1855 1865 goto put_err_out; 1856 1866 } 1857 1867 /* Now copy the attribute list. */ 1858 - memcpy(ni->attr_list, (u8*)ctx->attr + le16_to_cpu( 1859 - ctx->attr->data.resident.value_offset), 1868 + memcpy(ni->attr_list, (u8*)a + le16_to_cpu( 1869 + a->data.resident.value_offset), 1860 1870 le32_to_cpu( 1861 - ctx->attr->data.resident.value_length)); 1871 + a->data.resident.value_length)); 1862 1872 } 1863 1873 /* The attribute list is now setup in memory. */ 1864 1874 /* ··· 1924 1934 ntfs_attr_reinit_search_ctx(ctx); 1925 1935 1926 1936 /* Now load all attribute extents. */ 1927 - attr = NULL; 1937 + a = NULL; 1928 1938 next_vcn = last_vcn = highest_vcn = 0; 1929 1939 while (!(err = ntfs_attr_lookup(AT_DATA, NULL, 0, 0, next_vcn, NULL, 0, 1930 1940 ctx))) { 1931 1941 runlist_element *nrl; 1932 1942 1933 1943 /* Cache the current attribute. */ 1934 - attr = ctx->attr; 1944 + a = ctx->attr; 1935 1945 /* $MFT must be non-resident. */ 1936 - if (!attr->non_resident) { 1946 + if (!a->non_resident) { 1937 1947 ntfs_error(sb, "$MFT must be non-resident but a " 1938 1948 "resident extent was found. $MFT is " 1939 1949 "corrupt. Run chkdsk."); 1940 1950 goto put_err_out; 1941 1951 } 1942 1952 /* $MFT must be uncompressed and unencrypted. */ 1943 - if (attr->flags & ATTR_COMPRESSION_MASK || 1944 - attr->flags & ATTR_IS_ENCRYPTED || 1945 - attr->flags & ATTR_IS_SPARSE) { 1953 + if (a->flags & ATTR_COMPRESSION_MASK || 1954 + a->flags & ATTR_IS_ENCRYPTED || 1955 + a->flags & ATTR_IS_SPARSE) { 1946 1956 ntfs_error(sb, "$MFT must be uncompressed, " 1947 1957 "non-sparse, and unencrypted but a " 1948 1958 "compressed/sparse/encrypted extent " ··· 1956 1966 * as we have exclusive access to the inode at this time and we 1957 1967 * are a mount in progress task, too. 1958 1968 */ 1959 - nrl = ntfs_mapping_pairs_decompress(vol, attr, ni->runlist.rl); 1969 + nrl = ntfs_mapping_pairs_decompress(vol, a, ni->runlist.rl); 1960 1970 if (IS_ERR(nrl)) { 1961 1971 ntfs_error(sb, "ntfs_mapping_pairs_decompress() " 1962 1972 "failed with error code %ld. $MFT is " ··· 1967 1977 1968 1978 /* Are we in the first extent? */ 1969 1979 if (!next_vcn) { 1970 - if (attr->data.non_resident.lowest_vcn) { 1980 + if (a->data.non_resident.lowest_vcn) { 1971 1981 ntfs_error(sb, "First extent of $DATA " 1972 1982 "attribute has non zero " 1973 1983 "lowest_vcn. $MFT is corrupt. " ··· 1976 1986 } 1977 1987 /* Get the last vcn in the $DATA attribute. */ 1978 1988 last_vcn = sle64_to_cpu( 1979 - attr->data.non_resident.allocated_size) 1989 + a->data.non_resident.allocated_size) 1980 1990 >> vol->cluster_size_bits; 1981 1991 /* Fill in the inode size. */ 1982 1992 vi->i_size = sle64_to_cpu( 1983 - attr->data.non_resident.data_size); 1984 - ni->initialized_size = sle64_to_cpu(attr->data. 1985 - non_resident.initialized_size); 1993 + a->data.non_resident.data_size); 1994 + ni->initialized_size = sle64_to_cpu( 1995 + a->data.non_resident.initialized_size); 1986 1996 ni->allocated_size = sle64_to_cpu( 1987 - attr->data.non_resident.allocated_size); 1997 + a->data.non_resident.allocated_size); 1988 1998 /* 1989 1999 * Verify the number of mft records does not exceed 1990 2000 * 2^32 - 1. ··· 2041 2051 } 2042 2052 2043 2053 /* Get the lowest vcn for the next extent. */ 2044 - highest_vcn = sle64_to_cpu(attr->data.non_resident.highest_vcn); 2054 + highest_vcn = sle64_to_cpu(a->data.non_resident.highest_vcn); 2045 2055 next_vcn = highest_vcn + 1; 2046 2056 2047 2057 /* Only one extent or error, which we catch below. */ ··· 2050 2060 2051 2061 /* Avoid endless loops due to corruption. */ 2052 2062 if (next_vcn < sle64_to_cpu( 2053 - attr->data.non_resident.lowest_vcn)) { 2063 + a->data.non_resident.lowest_vcn)) { 2054 2064 ntfs_error(sb, "$MFT has corrupt attribute list " 2055 2065 "attribute. Run chkdsk."); 2056 2066 goto put_err_out; ··· 2061 2071 "$MFT is corrupt. Run chkdsk."); 2062 2072 goto put_err_out; 2063 2073 } 2064 - if (!attr) { 2074 + if (!a) { 2065 2075 ntfs_error(sb, "$MFT/$DATA attribute not found. $MFT is " 2066 2076 "corrupt. Run chkdsk."); 2067 2077 goto put_err_out; ··· 2265 2275 seq_printf(sf, ",case_sensitive"); 2266 2276 if (NVolShowSystemFiles(vol)) 2267 2277 seq_printf(sf, ",show_sys_files"); 2278 + if (!NVolSparseEnabled(vol)) 2279 + seq_printf(sf, ",disable_sparse"); 2268 2280 for (i = 0; on_errors_arr[i].val; i++) { 2269 2281 if (on_errors_arr[i].val & vol->on_errors) 2270 2282 seq_printf(sf, ",errors=%s", on_errors_arr[i].str); ··· 2303 2311 ntfs_volume *vol = ni->vol; 2304 2312 ntfs_attr_search_ctx *ctx; 2305 2313 MFT_RECORD *m; 2314 + ATTR_RECORD *a; 2306 2315 const char *te = " Leaving file length out of sync with i_size."; 2307 2316 int err; 2308 2317 ··· 2340 2347 vi->i_ino, err); 2341 2348 goto err_out; 2342 2349 } 2350 + a = ctx->attr; 2343 2351 /* If the size has not changed there is nothing to do. */ 2344 - if (ntfs_attr_size(ctx->attr) == i_size_read(vi)) 2352 + if (ntfs_attr_size(a) == i_size_read(vi)) 2345 2353 goto done; 2346 2354 // TODO: Implement the truncate... 2347 2355 ntfs_error(vi->i_sb, "Inode size has changed but this is not " 2348 2356 "implemented yet. Resetting inode size to old value. " 2349 2357 " This is most likely a bug in the ntfs driver!"); 2350 - i_size_write(vi, ntfs_attr_size(ctx->attr)); 2358 + i_size_write(vi, ntfs_attr_size(a)); 2351 2359 done: 2352 2360 ntfs_attr_put_search_ctx(ctx); 2353 2361 unmap_mft_record(ni); ··· 2509 2515 nt = utc2ntfs(vi->i_mtime); 2510 2516 if (si->last_data_change_time != nt) { 2511 2517 ntfs_debug("Updating mtime for inode 0x%lx: old = 0x%llx, " 2512 - "new = 0x%llx", vi->i_ino, 2518 + "new = 0x%llx", vi->i_ino, (long long) 2513 2519 sle64_to_cpu(si->last_data_change_time), 2514 - sle64_to_cpu(nt)); 2520 + (long long)sle64_to_cpu(nt)); 2515 2521 si->last_data_change_time = nt; 2516 2522 modified = TRUE; 2517 2523 } 2518 2524 nt = utc2ntfs(vi->i_ctime); 2519 2525 if (si->last_mft_change_time != nt) { 2520 2526 ntfs_debug("Updating ctime for inode 0x%lx: old = 0x%llx, " 2521 - "new = 0x%llx", vi->i_ino, 2527 + "new = 0x%llx", vi->i_ino, (long long) 2522 2528 sle64_to_cpu(si->last_mft_change_time), 2523 - sle64_to_cpu(nt)); 2529 + (long long)sle64_to_cpu(nt)); 2524 2530 si->last_mft_change_time = nt; 2525 2531 modified = TRUE; 2526 2532 } ··· 2528 2534 if (si->last_access_time != nt) { 2529 2535 ntfs_debug("Updating atime for inode 0x%lx: old = 0x%llx, " 2530 2536 "new = 0x%llx", vi->i_ino, 2531 - sle64_to_cpu(si->last_access_time), 2532 - sle64_to_cpu(nt)); 2537 + (long long)sle64_to_cpu(si->last_access_time), 2538 + (long long)sle64_to_cpu(nt)); 2533 2539 si->last_access_time = nt; 2534 2540 modified = TRUE; 2535 2541 }
+5 -2
fs/ntfs/inode.h
··· 2 2 * inode.h - Defines for inode structures NTFS Linux kernel driver. Part of 3 3 * the Linux-NTFS project. 4 4 * 5 - * Copyright (c) 2001-2004 Anton Altaparmakov 5 + * Copyright (c) 2001-2005 Anton Altaparmakov 6 6 * Copyright (c) 2002 Richard Russon 7 7 * 8 8 * This program/include file is free software; you can redistribute it and/or ··· 44 44 * fields already provided in the VFS inode. 45 45 */ 46 46 struct _ntfs_inode { 47 + rwlock_t size_lock; /* Lock serializing access to inode sizes. */ 47 48 s64 initialized_size; /* Copy from the attribute record. */ 48 49 s64 allocated_size; /* Copy from the attribute record. */ 49 50 unsigned long state; /* NTFS specific flags describing this inode. ··· 110 109 u8 block_size_bits; /* Log2 of the above. */ 111 110 u8 vcn_size_bits; /* Log2 of the above. */ 112 111 } index; 113 - struct { /* It is a compressed file or an attribute inode. */ 112 + struct { /* It is a compressed/sparse file/attribute inode. */ 114 113 s64 size; /* Copy of compressed_size from 115 114 $DATA. */ 116 115 u32 block_size; /* Size of a compression block ··· 166 165 NI_Sparse, /* 1: Unnamed data attr is sparse (f). 167 166 1: Create sparse files by default (d). 168 167 1: Attribute is sparse (a). */ 168 + NI_SparseDisabled, /* 1: May not create sparse regions. */ 169 169 NI_TruncateFailed, /* 1: Last ntfs_truncate() call failed. */ 170 170 } ntfs_inode_state_bits; 171 171 ··· 219 217 NINO_FNS(Compressed) 220 218 NINO_FNS(Encrypted) 221 219 NINO_FNS(Sparse) 220 + NINO_FNS(SparseDisabled) 222 221 NINO_FNS(TruncateFailed) 223 222 224 223 /*
+47 -36
fs/ntfs/layout.h
··· 2 2 * layout.h - All NTFS associated on-disk structures. Part of the Linux-NTFS 3 3 * project. 4 4 * 5 - * Copyright (c) 2001-2004 Anton Altaparmakov 5 + * Copyright (c) 2001-2005 Anton Altaparmakov 6 6 * Copyright (c) 2002 Richard Russon 7 7 * 8 8 * This program/include file is free software; you can redistribute it and/or ··· 547 547 COLLATION_NTOFS_ULONG = const_cpu_to_le32(0x10), 548 548 COLLATION_NTOFS_SID = const_cpu_to_le32(0x11), 549 549 COLLATION_NTOFS_SECURITY_HASH = const_cpu_to_le32(0x12), 550 - COLLATION_NTOFS_ULONGS = const_cpu_to_le32(0x13) 550 + COLLATION_NTOFS_ULONGS = const_cpu_to_le32(0x13), 551 551 }; 552 552 553 553 typedef le32 COLLATION_RULE; 554 554 555 555 /* 556 556 * The flags (32-bit) describing attribute properties in the attribute 557 - * definition structure. FIXME: This information is from Regis's information 558 - * and, according to him, it is not certain and probably incomplete. 559 - * The INDEXABLE flag is fairly certainly correct as only the file name 560 - * attribute has this flag set and this is the only attribute indexed in NT4. 557 + * definition structure. FIXME: This information is based on Regis's 558 + * information and, according to him, it is not certain and probably 559 + * incomplete. The INDEXABLE flag is fairly certainly correct as only the file 560 + * name attribute has this flag set and this is the only attribute indexed in 561 + * NT4. 561 562 */ 562 563 enum { 563 - INDEXABLE = const_cpu_to_le32(0x02), /* Attribute can be 564 - indexed. */ 565 - NEED_TO_REGENERATE = const_cpu_to_le32(0x40), /* Need to regenerate 566 - during regeneration 567 - phase. */ 568 - CAN_BE_NON_RESIDENT = const_cpu_to_le32(0x80), /* Attribute can be 569 - non-resident. */ 564 + ATTR_DEF_INDEXABLE = const_cpu_to_le32(0x02), /* Attribute can be 565 + indexed. */ 566 + ATTR_DEF_MULTIPLE = const_cpu_to_le32(0x04), /* Attribute type 567 + can be present multiple times in the 568 + mft records of an inode. */ 569 + ATTR_DEF_NOT_ZERO = const_cpu_to_le32(0x08), /* Attribute value 570 + must contain at least one non-zero 571 + byte. */ 572 + ATTR_DEF_INDEXED_UNIQUE = const_cpu_to_le32(0x10), /* Attribute must be 573 + indexed and the attribute value must be 574 + unique for the attribute type in all of 575 + the mft records of an inode. */ 576 + ATTR_DEF_NAMED_UNIQUE = const_cpu_to_le32(0x20), /* Attribute must be 577 + named and the name must be unique for 578 + the attribute type in all of the mft 579 + records of an inode. */ 580 + ATTR_DEF_RESIDENT = const_cpu_to_le32(0x40), /* Attribute must be 581 + resident. */ 582 + ATTR_DEF_ALWAYS_LOG = const_cpu_to_le32(0x80), /* Always log 583 + modifications to this attribute, 584 + regardless of whether it is resident or 585 + non-resident. Without this, only log 586 + modifications if the attribute is 587 + resident. */ 570 588 }; 571 589 572 590 typedef le32 ATTR_DEF_FLAGS; ··· 767 749 record header aligned to 8-byte boundary. */ 768 750 /* 34*/ u8 compression_unit; /* The compression unit expressed 769 751 as the log to the base 2 of the number of 770 - clusters in a compression unit. 0 means not 771 - compressed. (This effectively limits the 752 + clusters in a compression unit. 0 means not 753 + compressed. (This effectively limits the 772 754 compression unit size to be a power of two 773 - clusters.) WinNT4 only uses a value of 4. */ 755 + clusters.) WinNT4 only uses a value of 4. 756 + Sparse files also have this set to 4. */ 774 757 /* 35*/ u8 reserved[5]; /* Align to 8-byte boundary. */ 775 758 /* The sizes below are only used when lowest_vcn is zero, as otherwise it would 776 759 be difficult to keep them up-to-date.*/ ··· 791 772 data_size. */ 792 773 /* sizeof(uncompressed attr) = 64*/ 793 774 /* 64*/ sle64 compressed_size; /* Byte size of the attribute 794 - value after compression. Only present when 795 - compressed. Always is a multiple of the 796 - cluster size. Represents the actual amount of 797 - disk space being used on the disk. */ 775 + value after compression. Only present when 776 + compressed or sparse. Always is a multiple of 777 + the cluster size. Represents the actual amount 778 + of disk space being used on the disk. */ 798 779 /* sizeof(compressed attr) = 72*/ 799 780 } __attribute__ ((__packed__)) non_resident; 800 781 } __attribute__ ((__packed__)) data; ··· 853 834 /* Note, this is a copy of the corresponding bit from the mft record, 854 835 telling us whether this file has a view index present (eg. object id 855 836 index, quota index, one of the security indexes or the encrypting 856 - file system related indexes). */ 837 + filesystem related indexes). */ 857 838 }; 858 839 859 840 typedef le32 FILE_ATTR_FLAGS; ··· 936 917 /* 56*/ le64 quota_charged; /* Byte size of the charge to 937 918 the quota for all streams of the file. Note: Is 938 919 zero if quotas are disabled. */ 939 - /* 64*/ le64 usn; /* Last update sequence number 940 - of the file. This is a direct index into the 941 - change (aka usn) journal file. It is zero if 942 - the usn journal is disabled. 943 - NOTE: To disable the journal need to delete 944 - the journal file itself and to then walk the 945 - whole mft and set all Usn entries in all mft 946 - records to zero! (This can take a while!) 947 - The journal is FILE_Extend/$UsnJrnl. Win2k 948 - will recreate the journal and initiate 949 - logging if necessary when mounting the 950 - partition. This, in contrast to disabling the 951 - journal is a very fast process, so the user 952 - won't even notice it. */ 920 + /* 64*/ leUSN usn; /* Last update sequence number 921 + of the file. This is a direct index into the 922 + transaction log file ($UsnJrnl). It is zero if 923 + the usn journal is disabled or this file has 924 + not been subject to logging yet. See usnjrnl.h 925 + for details. */ 953 926 } __attribute__ ((__packed__)) v3; 954 927 /* sizeof() = 72 bytes (NTFS 3.x) */ 955 928 } __attribute__ ((__packed__)) ver; ··· 1904 1893 VOLUME_FLAGS_MASK = const_cpu_to_le16(0x803f), 1905 1894 1906 1895 /* To make our life easier when checking if we must mount read-only. */ 1907 - VOLUME_MUST_MOUNT_RO_MASK = const_cpu_to_le16(0x8037), 1896 + VOLUME_MUST_MOUNT_RO_MASK = const_cpu_to_le16(0x8027), 1908 1897 } __attribute__ ((__packed__)); 1909 1898 1910 1899 typedef le16 VOLUME_FLAGS;
+29 -43
fs/ntfs/lcnalloc.c
··· 1 1 /* 2 2 * lcnalloc.c - Cluster (de)allocation code. Part of the Linux-NTFS project. 3 3 * 4 - * Copyright (c) 2004 Anton Altaparmakov 4 + * Copyright (c) 2004-2005 Anton Altaparmakov 5 5 * 6 6 * This program/include file is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as published ··· 60 60 if (rl->lcn < 0) 61 61 continue; 62 62 err = ntfs_bitmap_clear_run(lcnbmp_vi, rl->lcn, rl->length); 63 - if (unlikely(err && (!ret || ret == ENOMEM) && ret != err)) 63 + if (unlikely(err && (!ret || ret == -ENOMEM) && ret != err)) 64 64 ret = err; 65 65 } 66 66 ntfs_debug("Done."); ··· 140 140 LCN zone_start, zone_end, bmp_pos, bmp_initial_pos, last_read_pos, lcn; 141 141 LCN prev_lcn = 0, prev_run_len = 0, mft_zone_size; 142 142 s64 clusters; 143 + loff_t i_size; 143 144 struct inode *lcnbmp_vi; 144 145 runlist_element *rl = NULL; 145 146 struct address_space *mapping; ··· 250 249 clusters = count; 251 250 rlpos = rlsize = 0; 252 251 mapping = lcnbmp_vi->i_mapping; 252 + i_size = i_size_read(lcnbmp_vi); 253 253 while (1) { 254 254 ntfs_debug("Start of outer while loop: done_zones 0x%x, " 255 255 "search_zone %i, pass %i, zone_start 0x%llx, " ··· 265 263 last_read_pos = bmp_pos >> 3; 266 264 ntfs_debug("last_read_pos 0x%llx.", 267 265 (unsigned long long)last_read_pos); 268 - if (last_read_pos > lcnbmp_vi->i_size) { 266 + if (last_read_pos > i_size) { 269 267 ntfs_debug("End of attribute reached. " 270 268 "Skipping to zone_pass_done."); 271 269 goto zone_pass_done; ··· 289 287 buf_size = last_read_pos & ~PAGE_CACHE_MASK; 290 288 buf = page_address(page) + buf_size; 291 289 buf_size = PAGE_CACHE_SIZE - buf_size; 292 - if (unlikely(last_read_pos + buf_size > lcnbmp_vi->i_size)) 293 - buf_size = lcnbmp_vi->i_size - last_read_pos; 290 + if (unlikely(last_read_pos + buf_size > i_size)) 291 + buf_size = i_size - last_read_pos; 294 292 buf_size <<= 3; 295 293 lcn = bmp_pos & 7; 296 - bmp_pos &= ~7; 294 + bmp_pos &= ~(LCN)7; 297 295 ntfs_debug("Before inner while loop: buf_size %i, lcn 0x%llx, " 298 296 "bmp_pos 0x%llx, need_writeback %i.", buf_size, 299 297 (unsigned long long)lcn, ··· 311 309 (unsigned int)*byte); 312 310 /* Skip full bytes. */ 313 311 if (*byte == 0xff) { 314 - lcn = (lcn + 8) & ~7; 312 + lcn = (lcn + 8) & ~(LCN)7; 315 313 ntfs_debug("Continuing while loop 1."); 316 314 continue; 317 315 } ··· 693 691 if (zone == MFT_ZONE || mft_zone_size <= 0) { 694 692 ntfs_debug("No free clusters left, going to out."); 695 693 /* Really no more space left on device. */ 696 - err = ENOSPC; 694 + err = -ENOSPC; 697 695 goto out; 698 696 } /* zone == DATA_ZONE && mft_zone_size > 0 */ 699 697 ntfs_debug("Shrinking mft zone."); ··· 757 755 if (rl) { 758 756 int err2; 759 757 760 - if (err == ENOSPC) 758 + if (err == -ENOSPC) 761 759 ntfs_debug("Not enough space to complete allocation, " 762 - "err ENOSPC, first free lcn 0x%llx, " 760 + "err -ENOSPC, first free lcn 0x%llx, " 763 761 "could allocate up to 0x%llx " 764 762 "clusters.", 765 763 (unsigned long long)rl[0].lcn, 766 - (unsigned long long)count - clusters); 764 + (unsigned long long)(count - clusters)); 767 765 /* Deallocate all allocated clusters. */ 768 766 ntfs_debug("Attempting rollback..."); 769 767 err2 = ntfs_cluster_free_from_rl_nolock(vol, rl); ··· 775 773 } 776 774 /* Free the runlist. */ 777 775 ntfs_free(rl); 778 - } else if (err == ENOSPC) 779 - ntfs_debug("No space left at all, err = ENOSPC, " 780 - "first free lcn = 0x%llx.", 781 - (unsigned long long)vol->data1_zone_pos); 776 + } else if (err == -ENOSPC) 777 + ntfs_debug("No space left at all, err = -ENOSPC, first free " 778 + "lcn = 0x%llx.", 779 + (long long)vol->data1_zone_pos); 782 780 up_write(&vol->lcnbmp_lock); 783 781 return ERR_PTR(err); 784 782 } ··· 848 846 849 847 total_freed = real_freed = 0; 850 848 851 - /* This returns with ni->runlist locked for reading on success. */ 852 - rl = ntfs_find_vcn(ni, start_vcn, FALSE); 849 + down_read(&ni->runlist.lock); 850 + rl = ntfs_attr_find_vcn_nolock(ni, start_vcn, FALSE); 853 851 if (IS_ERR(rl)) { 854 852 if (!is_rollback) 855 853 ntfs_error(vol->sb, "Failed to find first runlist " ··· 863 861 ntfs_error(vol->sb, "First runlist element has " 864 862 "invalid lcn, aborting."); 865 863 err = -EIO; 866 - goto unl_err_out; 864 + goto err_out; 867 865 } 868 866 /* Find the starting cluster inside the run that needs freeing. */ 869 867 delta = start_vcn - rl->vcn; ··· 881 879 if (!is_rollback) 882 880 ntfs_error(vol->sb, "Failed to clear first run " 883 881 "(error %i), aborting.", err); 884 - goto unl_err_out; 882 + goto err_out; 885 883 } 886 884 /* We have freed @to_free real clusters. */ 887 885 real_freed = to_free; ··· 901 899 if (unlikely(rl->lcn < LCN_HOLE)) { 902 900 VCN vcn; 903 901 904 - /* 905 - * Attempt to map runlist, dropping runlist lock for 906 - * the duration. 907 - */ 902 + /* Attempt to map runlist. */ 908 903 vcn = rl->vcn; 909 - up_read(&ni->runlist.lock); 910 - err = ntfs_map_runlist(ni, vcn); 911 - if (err) { 912 - if (!is_rollback) 913 - ntfs_error(vol->sb, "Failed to map " 914 - "runlist fragment."); 915 - if (err == -EINVAL || err == -ENOENT) 916 - err = -EIO; 917 - goto err_out; 918 - } 919 - /* 920 - * This returns with ni->runlist locked for reading on 921 - * success. 922 - */ 923 - rl = ntfs_find_vcn(ni, vcn, FALSE); 904 + rl = ntfs_attr_find_vcn_nolock(ni, vcn, FALSE); 924 905 if (IS_ERR(rl)) { 925 906 err = PTR_ERR(rl); 926 907 if (!is_rollback) 927 - ntfs_error(vol->sb, "Failed to find " 908 + ntfs_error(vol->sb, "Failed to map " 909 + "runlist fragment or " 910 + "failed to find " 928 911 "subsequent runlist " 929 912 "element."); 930 913 goto err_out; ··· 922 935 (unsigned long long) 923 936 rl->lcn); 924 937 err = -EIO; 925 - goto unl_err_out; 938 + goto err_out; 926 939 } 927 940 } 928 941 /* The number of clusters in this run that need freeing. */ ··· 938 951 if (!is_rollback) 939 952 ntfs_error(vol->sb, "Failed to clear " 940 953 "subsequent run."); 941 - goto unl_err_out; 954 + goto err_out; 942 955 } 943 956 /* We have freed @to_free real clusters. */ 944 957 real_freed += to_free; ··· 959 972 /* We are done. Return the number of actually freed clusters. */ 960 973 ntfs_debug("Done."); 961 974 return real_freed; 962 - unl_err_out: 963 - up_read(&ni->runlist.lock); 964 975 err_out: 976 + up_read(&ni->runlist.lock); 965 977 if (is_rollback) 966 978 return err; 967 979 /* If no real clusters were freed, no need to rollback. */
+6 -5
fs/ntfs/logfile.c
··· 1 1 /* 2 2 * logfile.c - NTFS kernel journal handling. Part of the Linux-NTFS project. 3 3 * 4 - * Copyright (c) 2002-2004 Anton Altaparmakov 4 + * Copyright (c) 2002-2005 Anton Altaparmakov 5 5 * 6 6 * This program/include file is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as published ··· 410 410 } 411 411 412 412 /** 413 - * ntfs_ckeck_logfile - check in the journal if the volume is consistent 413 + * ntfs_check_logfile - check the journal for consistency 414 414 * @log_vi: struct inode of loaded journal $LogFile to check 415 415 * 416 416 * Check the $LogFile journal for consistency and return TRUE if it is ··· 443 443 /* An empty $LogFile must have been clean before it got emptied. */ 444 444 if (NVolLogFileEmpty(vol)) 445 445 goto is_empty; 446 - size = log_vi->i_size; 446 + size = i_size_read(log_vi); 447 447 /* Make sure the file doesn't exceed the maximum allowed size. */ 448 448 if (size > MaxLogFileSize) 449 449 size = MaxLogFileSize; ··· 464 464 * optimize log_page_size and log_page_bits into constants. 465 465 */ 466 466 log_page_bits = generic_ffs(log_page_size) - 1; 467 - size &= ~(log_page_size - 1); 467 + size &= ~(s64)(log_page_size - 1); 468 468 /* 469 469 * Ensure the log file is big enough to store at least the two restart 470 470 * pages and the minimum number of log record pages. ··· 689 689 if (!NVolLogFileEmpty(vol)) { 690 690 int err; 691 691 692 - err = ntfs_attr_set(NTFS_I(log_vi), 0, log_vi->i_size, 0xff); 692 + err = ntfs_attr_set(NTFS_I(log_vi), 0, i_size_read(log_vi), 693 + 0xff); 693 694 if (unlikely(err)) { 694 695 ntfs_error(vol->sb, "Failed to fill $LogFile with " 695 696 "0xff bytes (error code %i).", err);
+155 -72
fs/ntfs/mft.c
··· 1 1 /** 2 2 * mft.c - NTFS kernel mft record operations. Part of the Linux-NTFS project. 3 3 * 4 - * Copyright (c) 2001-2004 Anton Altaparmakov 4 + * Copyright (c) 2001-2005 Anton Altaparmakov 5 5 * Copyright (c) 2002 Richard Russon 6 6 * 7 7 * This program/include file is free software; you can redistribute it and/or ··· 45 45 */ 46 46 static inline MFT_RECORD *map_mft_record_page(ntfs_inode *ni) 47 47 { 48 + loff_t i_size; 48 49 ntfs_volume *vol = ni->vol; 49 50 struct inode *mft_vi = vol->mft_ino; 50 51 struct page *page; ··· 61 60 index = ni->mft_no << vol->mft_record_size_bits >> PAGE_CACHE_SHIFT; 62 61 ofs = (ni->mft_no << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK; 63 62 63 + i_size = i_size_read(mft_vi); 64 64 /* The maximum valid index into the page cache for $MFT's data. */ 65 - end_index = mft_vi->i_size >> PAGE_CACHE_SHIFT; 65 + end_index = i_size >> PAGE_CACHE_SHIFT; 66 66 67 67 /* If the wanted index is out of bounds the mft record doesn't exist. */ 68 68 if (unlikely(index >= end_index)) { 69 - if (index > end_index || (mft_vi->i_size & ~PAGE_CACHE_MASK) < 70 - ofs + vol->mft_record_size) { 69 + if (index > end_index || (i_size & ~PAGE_CACHE_MASK) < ofs + 70 + vol->mft_record_size) { 71 71 page = ERR_PTR(-ENOENT); 72 72 ntfs_error(vol->sb, "Attemt to read mft record 0x%lx, " 73 73 "which is beyond the end of the mft. " ··· 287 285 } 288 286 unmap_mft_record(ni); 289 287 ntfs_error(base_ni->vol->sb, "Found stale extent mft " 290 - "reference! Corrupt file system. " 288 + "reference! Corrupt filesystem. " 291 289 "Run chkdsk."); 292 290 return ERR_PTR(-EIO); 293 291 } ··· 318 316 /* Verify the sequence number if it is present. */ 319 317 if (seq_no && (le16_to_cpu(m->sequence_number) != seq_no)) { 320 318 ntfs_error(base_ni->vol->sb, "Found stale extent mft " 321 - "reference! Corrupt file system. Run chkdsk."); 319 + "reference! Corrupt filesystem. Run chkdsk."); 322 320 destroy_ni = TRUE; 323 321 m = ERR_PTR(-EIO); 324 322 goto unm_err_out; ··· 948 946 na.name_len = 0; 949 947 na.type = AT_UNUSED; 950 948 /* 951 - * For inode 0, i.e. $MFT itself, we cannot use ilookup5() from here or 952 - * we deadlock because the inode is already locked by the kernel 953 - * (fs/fs-writeback.c::__sync_single_inode()) and ilookup5() waits 954 - * until the inode is unlocked before returning it and it never gets 955 - * unlocked because ntfs_should_write_mft_record() never returns. )-: 956 - * Fortunately, we have inode 0 pinned in icache for the duration of 957 - * the mount so we can access it directly. 949 + * Optimize inode 0, i.e. $MFT itself, since we have it in memory and 950 + * we get here for it rather often. 958 951 */ 959 952 if (!mft_no) { 960 953 /* Balance the below iput(). */ 961 954 vi = igrab(mft_vi); 962 955 BUG_ON(vi != mft_vi); 963 - } else 964 - vi = ilookup5(sb, mft_no, (test_t)ntfs_test_inode, &na); 956 + } else { 957 + /* 958 + * Have to use ilookup5_nowait() since ilookup5() waits for the 959 + * inode lock which causes ntfs to deadlock when a concurrent 960 + * inode write via the inode dirty code paths and the page 961 + * dirty code path of the inode dirty code path when writing 962 + * $MFT occurs. 963 + */ 964 + vi = ilookup5_nowait(sb, mft_no, (test_t)ntfs_test_inode, &na); 965 + } 965 966 if (vi) { 966 967 ntfs_debug("Base inode 0x%lx is in icache.", mft_no); 967 968 /* The inode is in icache. */ ··· 1019 1014 na.mft_no = MREF_LE(m->base_mft_record); 1020 1015 ntfs_debug("Mft record 0x%lx is an extent record. Looking for base " 1021 1016 "inode 0x%lx in icache.", mft_no, na.mft_no); 1022 - vi = ilookup5(sb, na.mft_no, (test_t)ntfs_test_inode, &na); 1017 + if (!na.mft_no) { 1018 + /* Balance the below iput(). */ 1019 + vi = igrab(mft_vi); 1020 + BUG_ON(vi != mft_vi); 1021 + } else 1022 + vi = ilookup5_nowait(sb, na.mft_no, (test_t)ntfs_test_inode, 1023 + &na); 1023 1024 if (!vi) { 1024 1025 /* 1025 1026 * The base inode is not in icache, write this extent mft ··· 1132 1121 ntfs_inode *base_ni) 1133 1122 { 1134 1123 s64 pass_end, ll, data_pos, pass_start, ofs, bit; 1124 + unsigned long flags; 1135 1125 struct address_space *mftbmp_mapping; 1136 1126 u8 *buf, *byte; 1137 1127 struct page *page; ··· 1146 1134 * Set the end of the pass making sure we do not overflow the mft 1147 1135 * bitmap. 1148 1136 */ 1137 + read_lock_irqsave(&NTFS_I(vol->mft_ino)->size_lock, flags); 1149 1138 pass_end = NTFS_I(vol->mft_ino)->allocated_size >> 1150 1139 vol->mft_record_size_bits; 1140 + read_unlock_irqrestore(&NTFS_I(vol->mft_ino)->size_lock, flags); 1141 + read_lock_irqsave(&NTFS_I(vol->mftbmp_ino)->size_lock, flags); 1151 1142 ll = NTFS_I(vol->mftbmp_ino)->initialized_size << 3; 1143 + read_unlock_irqrestore(&NTFS_I(vol->mftbmp_ino)->size_lock, flags); 1152 1144 if (pass_end > ll) 1153 1145 pass_end = ll; 1154 1146 pass = 1; ··· 1279 1263 { 1280 1264 LCN lcn; 1281 1265 s64 ll; 1266 + unsigned long flags; 1282 1267 struct page *page; 1283 1268 ntfs_inode *mft_ni, *mftbmp_ni; 1284 1269 runlist_element *rl, *rl2 = NULL; ··· 1301 1284 /* 1302 1285 * Determine the last lcn of the mft bitmap. The allocated size of the 1303 1286 * mft bitmap cannot be zero so we are ok to do this. 1304 - * ntfs_find_vcn() returns the runlist locked on success. 1305 1287 */ 1306 - rl = ntfs_find_vcn(mftbmp_ni, (mftbmp_ni->allocated_size - 1) >> 1307 - vol->cluster_size_bits, TRUE); 1288 + down_write(&mftbmp_ni->runlist.lock); 1289 + read_lock_irqsave(&mftbmp_ni->size_lock, flags); 1290 + ll = mftbmp_ni->allocated_size; 1291 + read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); 1292 + rl = ntfs_attr_find_vcn_nolock(mftbmp_ni, 1293 + (ll - 1) >> vol->cluster_size_bits, TRUE); 1308 1294 if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) { 1295 + up_write(&mftbmp_ni->runlist.lock); 1309 1296 ntfs_error(vol->sb, "Failed to determine last allocated " 1310 1297 "cluster of mft bitmap attribute."); 1311 - if (!IS_ERR(rl)) { 1312 - up_write(&mftbmp_ni->runlist.lock); 1298 + if (!IS_ERR(rl)) 1313 1299 ret = -EIO; 1314 - } else 1300 + else 1315 1301 ret = PTR_ERR(rl); 1316 1302 return ret; 1317 1303 } ··· 1416 1396 BUG_ON(ll < rl2->vcn); 1417 1397 BUG_ON(ll >= rl2->vcn + rl2->length); 1418 1398 /* Get the size for the new mapping pairs array for this extent. */ 1419 - mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll); 1399 + mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1); 1420 1400 if (unlikely(mp_size <= 0)) { 1421 1401 ntfs_error(vol->sb, "Get size for mapping pairs failed for " 1422 1402 "mft bitmap attribute extent."); ··· 1438 1418 // TODO: Deal with this by moving this extent to a new mft 1439 1419 // record or by starting a new extent in a new mft record or by 1440 1420 // moving other attributes out of this mft record. 1421 + // Note: It will need to be a special mft record and if none of 1422 + // those are available it gets rather complicated... 1441 1423 ntfs_error(vol->sb, "Not enough space in this mft record to " 1442 1424 "accomodate extended mft bitmap attribute " 1443 1425 "extent. Cannot handle this yet."); ··· 1450 1428 /* Generate the mapping pairs array directly into the attr record. */ 1451 1429 ret = ntfs_mapping_pairs_build(vol, (u8*)a + 1452 1430 le16_to_cpu(a->data.non_resident.mapping_pairs_offset), 1453 - mp_size, rl2, ll, NULL); 1431 + mp_size, rl2, ll, -1, NULL); 1454 1432 if (unlikely(ret)) { 1455 1433 ntfs_error(vol->sb, "Failed to build mapping pairs array for " 1456 1434 "mft bitmap attribute."); ··· 1480 1458 } 1481 1459 a = ctx->attr; 1482 1460 } 1461 + write_lock_irqsave(&mftbmp_ni->size_lock, flags); 1483 1462 mftbmp_ni->allocated_size += vol->cluster_size; 1484 1463 a->data.non_resident.allocated_size = 1485 1464 cpu_to_sle64(mftbmp_ni->allocated_size); 1465 + write_unlock_irqrestore(&mftbmp_ni->size_lock, flags); 1486 1466 /* Ensure the changes make it to disk. */ 1487 1467 flush_dcache_mft_record_page(ctx->ntfs_ino); 1488 1468 mark_mft_record_dirty(ctx->ntfs_ino); ··· 1500 1476 0, ctx)) { 1501 1477 ntfs_error(vol->sb, "Failed to find last attribute extent of " 1502 1478 "mft bitmap attribute.%s", es); 1479 + write_lock_irqsave(&mftbmp_ni->size_lock, flags); 1503 1480 mftbmp_ni->allocated_size += vol->cluster_size; 1481 + write_unlock_irqrestore(&mftbmp_ni->size_lock, flags); 1504 1482 ntfs_attr_put_search_ctx(ctx); 1505 1483 unmap_mft_record(mft_ni); 1506 1484 up_write(&mftbmp_ni->runlist.lock); ··· 1538 1512 a->data.non_resident.mapping_pairs_offset), 1539 1513 old_alen - le16_to_cpu( 1540 1514 a->data.non_resident.mapping_pairs_offset), 1541 - rl2, ll, NULL)) { 1515 + rl2, ll, -1, NULL)) { 1542 1516 ntfs_error(vol->sb, "Failed to restore mapping pairs " 1543 1517 "array.%s", es); 1544 1518 NVolSetErrors(vol); ··· 1576 1550 static int ntfs_mft_bitmap_extend_initialized_nolock(ntfs_volume *vol) 1577 1551 { 1578 1552 s64 old_data_size, old_initialized_size; 1553 + unsigned long flags; 1579 1554 struct inode *mftbmp_vi; 1580 1555 ntfs_inode *mft_ni, *mftbmp_ni; 1581 1556 ntfs_attr_search_ctx *ctx; ··· 1610 1583 goto put_err_out; 1611 1584 } 1612 1585 a = ctx->attr; 1613 - old_data_size = mftbmp_vi->i_size; 1586 + write_lock_irqsave(&mftbmp_ni->size_lock, flags); 1587 + old_data_size = i_size_read(mftbmp_vi); 1614 1588 old_initialized_size = mftbmp_ni->initialized_size; 1615 1589 /* 1616 1590 * We can simply update the initialized_size before filling the space ··· 1621 1593 mftbmp_ni->initialized_size += 8; 1622 1594 a->data.non_resident.initialized_size = 1623 1595 cpu_to_sle64(mftbmp_ni->initialized_size); 1624 - if (mftbmp_ni->initialized_size > mftbmp_vi->i_size) { 1625 - mftbmp_vi->i_size = mftbmp_ni->initialized_size; 1596 + if (mftbmp_ni->initialized_size > old_data_size) { 1597 + i_size_write(mftbmp_vi, mftbmp_ni->initialized_size); 1626 1598 a->data.non_resident.data_size = 1627 - cpu_to_sle64(mftbmp_vi->i_size); 1599 + cpu_to_sle64(mftbmp_ni->initialized_size); 1628 1600 } 1601 + write_unlock_irqrestore(&mftbmp_ni->size_lock, flags); 1629 1602 /* Ensure the changes make it to disk. */ 1630 1603 flush_dcache_mft_record_page(ctx->ntfs_ino); 1631 1604 mark_mft_record_dirty(ctx->ntfs_ino); ··· 1665 1636 goto err_out; 1666 1637 } 1667 1638 a = ctx->attr; 1639 + write_lock_irqsave(&mftbmp_ni->size_lock, flags); 1668 1640 mftbmp_ni->initialized_size = old_initialized_size; 1669 1641 a->data.non_resident.initialized_size = 1670 1642 cpu_to_sle64(old_initialized_size); 1671 - if (mftbmp_vi->i_size != old_data_size) { 1672 - mftbmp_vi->i_size = old_data_size; 1643 + if (i_size_read(mftbmp_vi) != old_data_size) { 1644 + i_size_write(mftbmp_vi, old_data_size); 1673 1645 a->data.non_resident.data_size = cpu_to_sle64(old_data_size); 1674 1646 } 1647 + write_unlock_irqrestore(&mftbmp_ni->size_lock, flags); 1675 1648 flush_dcache_mft_record_page(ctx->ntfs_ino); 1676 1649 mark_mft_record_dirty(ctx->ntfs_ino); 1677 1650 ntfs_attr_put_search_ctx(ctx); 1678 1651 unmap_mft_record(mft_ni); 1652 + #ifdef DEBUG 1653 + read_lock_irqsave(&mftbmp_ni->size_lock, flags); 1679 1654 ntfs_debug("Restored status of mftbmp: allocated_size 0x%llx, " 1680 1655 "data_size 0x%llx, initialized_size 0x%llx.", 1681 1656 (long long)mftbmp_ni->allocated_size, 1682 - (long long)mftbmp_vi->i_size, 1657 + (long long)i_size_read(mftbmp_vi), 1683 1658 (long long)mftbmp_ni->initialized_size); 1659 + read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); 1660 + #endif /* DEBUG */ 1684 1661 err_out: 1685 1662 return ret; 1686 1663 } ··· 1714 1679 { 1715 1680 LCN lcn; 1716 1681 VCN old_last_vcn; 1717 - s64 min_nr, nr, ll = 0; 1682 + s64 min_nr, nr, ll; 1683 + unsigned long flags; 1718 1684 ntfs_inode *mft_ni; 1719 1685 runlist_element *rl, *rl2; 1720 1686 ntfs_attr_search_ctx *ctx = NULL; ··· 1731 1695 * Determine the preferred allocation location, i.e. the last lcn of 1732 1696 * the mft data attribute. The allocated size of the mft data 1733 1697 * attribute cannot be zero so we are ok to do this. 1734 - * ntfs_find_vcn() returns the runlist locked on success. 1735 1698 */ 1736 - rl = ntfs_find_vcn(mft_ni, (mft_ni->allocated_size - 1) >> 1737 - vol->cluster_size_bits, TRUE); 1699 + down_write(&mft_ni->runlist.lock); 1700 + read_lock_irqsave(&mft_ni->size_lock, flags); 1701 + ll = mft_ni->allocated_size; 1702 + read_unlock_irqrestore(&mft_ni->size_lock, flags); 1703 + rl = ntfs_attr_find_vcn_nolock(mft_ni, 1704 + (ll - 1) >> vol->cluster_size_bits, TRUE); 1738 1705 if (unlikely(IS_ERR(rl) || !rl->length || rl->lcn < 0)) { 1706 + up_write(&mft_ni->runlist.lock); 1739 1707 ntfs_error(vol->sb, "Failed to determine last allocated " 1740 1708 "cluster of mft data attribute."); 1741 - if (!IS_ERR(rl)) { 1742 - up_write(&mft_ni->runlist.lock); 1709 + if (!IS_ERR(rl)) 1743 1710 ret = -EIO; 1744 - } else 1711 + else 1745 1712 ret = PTR_ERR(rl); 1746 1713 return ret; 1747 1714 } 1748 1715 lcn = rl->lcn + rl->length; 1749 - ntfs_debug("Last lcn of mft data attribute is 0x%llx.", 1750 - (long long)lcn); 1716 + ntfs_debug("Last lcn of mft data attribute is 0x%llx.", (long long)lcn); 1751 1717 /* Minimum allocation is one mft record worth of clusters. */ 1752 1718 min_nr = vol->mft_record_size >> vol->cluster_size_bits; 1753 1719 if (!min_nr) ··· 1759 1721 if (!nr) 1760 1722 nr = min_nr; 1761 1723 /* Ensure we do not go above 2^32-1 mft records. */ 1762 - if (unlikely((mft_ni->allocated_size + 1763 - (nr << vol->cluster_size_bits)) >> 1724 + read_lock_irqsave(&mft_ni->size_lock, flags); 1725 + ll = mft_ni->allocated_size; 1726 + read_unlock_irqrestore(&mft_ni->size_lock, flags); 1727 + if (unlikely((ll + (nr << vol->cluster_size_bits)) >> 1764 1728 vol->mft_record_size_bits >= (1ll << 32))) { 1765 1729 nr = min_nr; 1766 - if (unlikely((mft_ni->allocated_size + 1767 - (nr << vol->cluster_size_bits)) >> 1730 + if (unlikely((ll + (nr << vol->cluster_size_bits)) >> 1768 1731 vol->mft_record_size_bits >= (1ll << 32))) { 1769 1732 ntfs_warning(vol->sb, "Cannot allocate mft record " 1770 1733 "because the maximum number of inodes " ··· 1811 1772 return PTR_ERR(rl); 1812 1773 } 1813 1774 mft_ni->runlist.rl = rl; 1814 - ntfs_debug("Allocated %lli clusters.", nr); 1775 + ntfs_debug("Allocated %lli clusters.", (long long)nr); 1815 1776 /* Find the last run in the new runlist. */ 1816 1777 for (; rl[1].length; rl++) 1817 1778 ; ··· 1847 1808 BUG_ON(ll < rl2->vcn); 1848 1809 BUG_ON(ll >= rl2->vcn + rl2->length); 1849 1810 /* Get the size for the new mapping pairs array for this extent. */ 1850 - mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll); 1811 + mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1); 1851 1812 if (unlikely(mp_size <= 0)) { 1852 1813 ntfs_error(vol->sb, "Get size for mapping pairs failed for " 1853 1814 "mft data attribute extent."); ··· 1871 1832 // moving other attributes out of this mft record. 1872 1833 // Note: Use the special reserved mft records and ensure that 1873 1834 // this extent is not required to find the mft record in 1874 - // question. 1835 + // question. If no free special records left we would need to 1836 + // move an existing record away, insert ours in its place, and 1837 + // then place the moved record into the newly allocated space 1838 + // and we would then need to update all references to this mft 1839 + // record appropriately. This is rather complicated... 1875 1840 ntfs_error(vol->sb, "Not enough space in this mft record to " 1876 1841 "accomodate extended mft data attribute " 1877 1842 "extent. Cannot handle this yet."); ··· 1886 1843 /* Generate the mapping pairs array directly into the attr record. */ 1887 1844 ret = ntfs_mapping_pairs_build(vol, (u8*)a + 1888 1845 le16_to_cpu(a->data.non_resident.mapping_pairs_offset), 1889 - mp_size, rl2, ll, NULL); 1846 + mp_size, rl2, ll, -1, NULL); 1890 1847 if (unlikely(ret)) { 1891 1848 ntfs_error(vol->sb, "Failed to build mapping pairs array of " 1892 1849 "mft data attribute."); ··· 1918 1875 } 1919 1876 a = ctx->attr; 1920 1877 } 1878 + write_lock_irqsave(&mft_ni->size_lock, flags); 1921 1879 mft_ni->allocated_size += nr << vol->cluster_size_bits; 1922 1880 a->data.non_resident.allocated_size = 1923 1881 cpu_to_sle64(mft_ni->allocated_size); 1882 + write_unlock_irqrestore(&mft_ni->size_lock, flags); 1924 1883 /* Ensure the changes make it to disk. */ 1925 1884 flush_dcache_mft_record_page(ctx->ntfs_ino); 1926 1885 mark_mft_record_dirty(ctx->ntfs_ino); ··· 1937 1892 CASE_SENSITIVE, rl[1].vcn, NULL, 0, ctx)) { 1938 1893 ntfs_error(vol->sb, "Failed to find last attribute extent of " 1939 1894 "mft data attribute.%s", es); 1895 + write_lock_irqsave(&mft_ni->size_lock, flags); 1940 1896 mft_ni->allocated_size += nr << vol->cluster_size_bits; 1897 + write_unlock_irqrestore(&mft_ni->size_lock, flags); 1941 1898 ntfs_attr_put_search_ctx(ctx); 1942 1899 unmap_mft_record(mft_ni); 1943 1900 up_write(&mft_ni->runlist.lock); ··· 1968 1921 a->data.non_resident.mapping_pairs_offset), 1969 1922 old_alen - le16_to_cpu( 1970 1923 a->data.non_resident.mapping_pairs_offset), 1971 - rl2, ll, NULL)) { 1924 + rl2, ll, -1, NULL)) { 1972 1925 ntfs_error(vol->sb, "Failed to restore mapping pairs " 1973 1926 "array.%s", es); 1974 1927 NVolSetErrors(vol); ··· 2038 1991 "reports this as corruption, please email " 2039 1992 "linux-ntfs-dev@lists.sourceforge.net stating " 2040 1993 "that you saw this message and that the " 2041 - "modified file system created was corrupt. " 1994 + "modified filesystem created was corrupt. " 2042 1995 "Thank you."); 2043 1996 } 2044 1997 /* Set the update sequence number to 1. */ ··· 2083 2036 */ 2084 2037 static int ntfs_mft_record_format(const ntfs_volume *vol, const s64 mft_no) 2085 2038 { 2039 + loff_t i_size; 2086 2040 struct inode *mft_vi = vol->mft_ino; 2087 2041 struct page *page; 2088 2042 MFT_RECORD *m; ··· 2099 2051 index = mft_no << vol->mft_record_size_bits >> PAGE_CACHE_SHIFT; 2100 2052 ofs = (mft_no << vol->mft_record_size_bits) & ~PAGE_CACHE_MASK; 2101 2053 /* The maximum valid index into the page cache for $MFT's data. */ 2102 - end_index = mft_vi->i_size >> PAGE_CACHE_SHIFT; 2054 + i_size = i_size_read(mft_vi); 2055 + end_index = i_size >> PAGE_CACHE_SHIFT; 2103 2056 if (unlikely(index >= end_index)) { 2104 2057 if (unlikely(index > end_index || ofs + vol->mft_record_size >= 2105 - (mft_vi->i_size & ~PAGE_CACHE_MASK))) { 2058 + (i_size & ~PAGE_CACHE_MASK))) { 2106 2059 ntfs_error(vol->sb, "Tried to format non-existing mft " 2107 2060 "record 0x%llx.", (long long)mft_no); 2108 2061 return -ENOENT; ··· 2237 2188 ntfs_inode *base_ni, MFT_RECORD **mrec) 2238 2189 { 2239 2190 s64 ll, bit, old_data_initialized, old_data_size; 2191 + unsigned long flags; 2240 2192 struct inode *vi; 2241 2193 struct page *page; 2242 2194 ntfs_inode *mft_ni, *mftbmp_ni, *ni; ··· 2287 2237 * the first 24 mft records as they are special and whilst they may not 2288 2238 * be in use, we do not allocate from them. 2289 2239 */ 2240 + read_lock_irqsave(&mft_ni->size_lock, flags); 2290 2241 ll = mft_ni->initialized_size >> vol->mft_record_size_bits; 2291 - if (mftbmp_ni->initialized_size << 3 > ll && 2292 - mftbmp_ni->initialized_size > 3) { 2242 + read_unlock_irqrestore(&mft_ni->size_lock, flags); 2243 + read_lock_irqsave(&mftbmp_ni->size_lock, flags); 2244 + old_data_initialized = mftbmp_ni->initialized_size; 2245 + read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); 2246 + if (old_data_initialized << 3 > ll && old_data_initialized > 3) { 2293 2247 bit = ll; 2294 2248 if (bit < 24) 2295 2249 bit = 24; ··· 2308 2254 * mft record that we can allocate. 2309 2255 * Note: The smallest mft record we allocate is mft record 24. 2310 2256 */ 2311 - bit = mftbmp_ni->initialized_size << 3; 2257 + bit = old_data_initialized << 3; 2312 2258 if (unlikely(bit >= (1ll << 32))) 2313 2259 goto max_err_out; 2260 + read_lock_irqsave(&mftbmp_ni->size_lock, flags); 2261 + old_data_size = mftbmp_ni->allocated_size; 2314 2262 ntfs_debug("Status of mftbmp before extension: allocated_size 0x%llx, " 2315 2263 "data_size 0x%llx, initialized_size 0x%llx.", 2316 - (long long)mftbmp_ni->allocated_size, 2317 - (long long)vol->mftbmp_ino->i_size, 2318 - (long long)mftbmp_ni->initialized_size); 2319 - if (mftbmp_ni->initialized_size + 8 > mftbmp_ni->allocated_size) { 2264 + (long long)old_data_size, 2265 + (long long)i_size_read(vol->mftbmp_ino), 2266 + (long long)old_data_initialized); 2267 + read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); 2268 + if (old_data_initialized + 8 > old_data_size) { 2320 2269 /* Need to extend bitmap by one more cluster. */ 2321 2270 ntfs_debug("mftbmp: initialized_size + 8 > allocated_size."); 2322 2271 err = ntfs_mft_bitmap_extend_allocation_nolock(vol); ··· 2327 2270 up_write(&vol->mftbmp_lock); 2328 2271 goto err_out; 2329 2272 } 2273 + #ifdef DEBUG 2274 + read_lock_irqsave(&mftbmp_ni->size_lock, flags); 2330 2275 ntfs_debug("Status of mftbmp after allocation extension: " 2331 2276 "allocated_size 0x%llx, data_size 0x%llx, " 2332 2277 "initialized_size 0x%llx.", 2333 2278 (long long)mftbmp_ni->allocated_size, 2334 - (long long)vol->mftbmp_ino->i_size, 2279 + (long long)i_size_read(vol->mftbmp_ino), 2335 2280 (long long)mftbmp_ni->initialized_size); 2281 + read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); 2282 + #endif /* DEBUG */ 2336 2283 } 2337 2284 /* 2338 2285 * We now have sufficient allocated space, extend the initialized_size ··· 2348 2287 up_write(&vol->mftbmp_lock); 2349 2288 goto err_out; 2350 2289 } 2290 + #ifdef DEBUG 2291 + read_lock_irqsave(&mftbmp_ni->size_lock, flags); 2351 2292 ntfs_debug("Status of mftbmp after initialized extention: " 2352 2293 "allocated_size 0x%llx, data_size 0x%llx, " 2353 2294 "initialized_size 0x%llx.", 2354 2295 (long long)mftbmp_ni->allocated_size, 2355 - (long long)vol->mftbmp_ino->i_size, 2296 + (long long)i_size_read(vol->mftbmp_ino), 2356 2297 (long long)mftbmp_ni->initialized_size); 2298 + read_unlock_irqrestore(&mftbmp_ni->size_lock, flags); 2299 + #endif /* DEBUG */ 2357 2300 ntfs_debug("Found free record (#3), bit 0x%llx.", (long long)bit); 2358 2301 found_free_rec: 2359 2302 /* @bit is the found free mft record, allocate it in the mft bitmap. */ ··· 2379 2314 * parallel allocation could allocate the same mft record as this one. 2380 2315 */ 2381 2316 ll = (bit + 1) << vol->mft_record_size_bits; 2382 - if (ll <= mft_ni->initialized_size) { 2317 + read_lock_irqsave(&mft_ni->size_lock, flags); 2318 + old_data_initialized = mft_ni->initialized_size; 2319 + read_unlock_irqrestore(&mft_ni->size_lock, flags); 2320 + if (ll <= old_data_initialized) { 2383 2321 ntfs_debug("Allocated mft record already initialized."); 2384 2322 goto mft_rec_already_initialized; 2385 2323 } ··· 2393 2325 * actually traversed more than once when a freshly formatted volume is 2394 2326 * first written to so it optimizes away nicely in the common case. 2395 2327 */ 2328 + read_lock_irqsave(&mft_ni->size_lock, flags); 2396 2329 ntfs_debug("Status of mft data before extension: " 2397 2330 "allocated_size 0x%llx, data_size 0x%llx, " 2398 2331 "initialized_size 0x%llx.", 2399 2332 (long long)mft_ni->allocated_size, 2400 - (long long)vol->mft_ino->i_size, 2333 + (long long)i_size_read(vol->mft_ino), 2401 2334 (long long)mft_ni->initialized_size); 2402 2335 while (ll > mft_ni->allocated_size) { 2336 + read_unlock_irqrestore(&mft_ni->size_lock, flags); 2403 2337 err = ntfs_mft_data_extend_allocation_nolock(vol); 2404 2338 if (unlikely(err)) { 2405 2339 ntfs_error(vol->sb, "Failed to extend mft data " 2406 2340 "allocation."); 2407 2341 goto undo_mftbmp_alloc_nolock; 2408 2342 } 2343 + read_lock_irqsave(&mft_ni->size_lock, flags); 2409 2344 ntfs_debug("Status of mft data after allocation extension: " 2410 2345 "allocated_size 0x%llx, data_size 0x%llx, " 2411 2346 "initialized_size 0x%llx.", 2412 2347 (long long)mft_ni->allocated_size, 2413 - (long long)vol->mft_ino->i_size, 2348 + (long long)i_size_read(vol->mft_ino), 2414 2349 (long long)mft_ni->initialized_size); 2415 2350 } 2351 + read_unlock_irqrestore(&mft_ni->size_lock, flags); 2416 2352 /* 2417 2353 * Extend mft data initialized size (and data size of course) to reach 2418 2354 * the allocated mft record, formatting the mft records allong the way. ··· 2424 2352 * needed by ntfs_mft_record_format(). We will update the attribute 2425 2353 * record itself in one fell swoop later on. 2426 2354 */ 2355 + write_lock_irqsave(&mft_ni->size_lock, flags); 2427 2356 old_data_initialized = mft_ni->initialized_size; 2428 2357 old_data_size = vol->mft_ino->i_size; 2429 2358 while (ll > mft_ni->initialized_size) { ··· 2433 2360 new_initialized_size = mft_ni->initialized_size + 2434 2361 vol->mft_record_size; 2435 2362 mft_no = mft_ni->initialized_size >> vol->mft_record_size_bits; 2436 - if (new_initialized_size > vol->mft_ino->i_size) 2437 - vol->mft_ino->i_size = new_initialized_size; 2363 + if (new_initialized_size > i_size_read(vol->mft_ino)) 2364 + i_size_write(vol->mft_ino, new_initialized_size); 2365 + write_unlock_irqrestore(&mft_ni->size_lock, flags); 2438 2366 ntfs_debug("Initializing mft record 0x%llx.", 2439 2367 (long long)mft_no); 2440 2368 err = ntfs_mft_record_format(vol, mft_no); ··· 2443 2369 ntfs_error(vol->sb, "Failed to format mft record."); 2444 2370 goto undo_data_init; 2445 2371 } 2372 + write_lock_irqsave(&mft_ni->size_lock, flags); 2446 2373 mft_ni->initialized_size = new_initialized_size; 2447 2374 } 2375 + write_unlock_irqrestore(&mft_ni->size_lock, flags); 2448 2376 record_formatted = TRUE; 2449 2377 /* Update the mft data attribute record to reflect the new sizes. */ 2450 2378 m = map_mft_record(mft_ni); ··· 2472 2396 goto undo_data_init; 2473 2397 } 2474 2398 a = ctx->attr; 2399 + read_lock_irqsave(&mft_ni->size_lock, flags); 2475 2400 a->data.non_resident.initialized_size = 2476 2401 cpu_to_sle64(mft_ni->initialized_size); 2477 - a->data.non_resident.data_size = cpu_to_sle64(vol->mft_ino->i_size); 2402 + a->data.non_resident.data_size = 2403 + cpu_to_sle64(i_size_read(vol->mft_ino)); 2404 + read_unlock_irqrestore(&mft_ni->size_lock, flags); 2478 2405 /* Ensure the changes make it to disk. */ 2479 2406 flush_dcache_mft_record_page(ctx->ntfs_ino); 2480 2407 mark_mft_record_dirty(ctx->ntfs_ino); 2481 2408 ntfs_attr_put_search_ctx(ctx); 2482 2409 unmap_mft_record(mft_ni); 2410 + read_lock_irqsave(&mft_ni->size_lock, flags); 2483 2411 ntfs_debug("Status of mft data after mft record initialization: " 2484 2412 "allocated_size 0x%llx, data_size 0x%llx, " 2485 2413 "initialized_size 0x%llx.", 2486 2414 (long long)mft_ni->allocated_size, 2487 - (long long)vol->mft_ino->i_size, 2415 + (long long)i_size_read(vol->mft_ino), 2488 2416 (long long)mft_ni->initialized_size); 2489 - BUG_ON(vol->mft_ino->i_size > mft_ni->allocated_size); 2490 - BUG_ON(mft_ni->initialized_size > vol->mft_ino->i_size); 2417 + BUG_ON(i_size_read(vol->mft_ino) > mft_ni->allocated_size); 2418 + BUG_ON(mft_ni->initialized_size > i_size_read(vol->mft_ino)); 2419 + read_unlock_irqrestore(&mft_ni->size_lock, flags); 2491 2420 mft_rec_already_initialized: 2492 2421 /* 2493 2422 * We can finally drop the mft bitmap lock as the mft data attribute ··· 2733 2652 *mrec = m; 2734 2653 return ni; 2735 2654 undo_data_init: 2655 + write_lock_irqsave(&mft_ni->size_lock, flags); 2736 2656 mft_ni->initialized_size = old_data_initialized; 2737 - vol->mft_ino->i_size = old_data_size; 2657 + i_size_write(vol->mft_ino, old_data_size); 2658 + write_unlock_irqrestore(&mft_ni->size_lock, flags); 2738 2659 goto undo_mftbmp_alloc_nolock; 2739 2660 undo_mftbmp_alloc: 2740 2661 down_write(&vol->mftbmp_lock);
+30 -4
fs/ntfs/namei.c
··· 153 153 ntfs_error(vol->sb, "ntfs_iget(0x%lx) failed with " 154 154 "error code %li.", dent_ino, 155 155 PTR_ERR(dent_inode)); 156 - if (name) 157 - kfree(name); 156 + kfree(name); 158 157 /* Return the error code. */ 159 158 return (struct dentry *)dent_inode; 160 159 } ··· 379 380 * Return the dentry of the parent directory on success or the error code on 380 381 * error (IS_ERR() is true). 381 382 */ 382 - struct dentry *ntfs_get_parent(struct dentry *child_dent) 383 + static struct dentry *ntfs_get_parent(struct dentry *child_dent) 383 384 { 384 385 struct inode *vi = child_dent->d_inode; 385 386 ntfs_inode *ni = NTFS_I(vi); ··· 464 465 * 465 466 * Return the dentry on success or the error code on error (IS_ERR() is true). 466 467 */ 467 - struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh) 468 + static struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh) 468 469 { 469 470 struct inode *vi; 470 471 struct dentry *dent; ··· 495 496 ntfs_debug("Done for inode 0x%lx, generation 0x%x.", ino, gen); 496 497 return dent; 497 498 } 499 + 500 + /** 501 + * Export operations allowing NFS exporting of mounted NTFS partitions. 502 + * 503 + * We use the default ->decode_fh() and ->encode_fh() for now. Note that they 504 + * use 32 bits to store the inode number which is an unsigned long so on 64-bit 505 + * architectures is usually 64 bits so it would all fail horribly on huge 506 + * volumes. I guess we need to define our own encode and decode fh functions 507 + * that store 64-bit inode numbers at some point but for now we will ignore the 508 + * problem... 509 + * 510 + * We also use the default ->get_name() helper (used by ->decode_fh() via 511 + * fs/exportfs/expfs.c::find_exported_dentry()) as that is completely fs 512 + * independent. 513 + * 514 + * The default ->get_parent() just returns -EACCES so we have to provide our 515 + * own and the default ->get_dentry() is incompatible with NTFS due to not 516 + * allowing the inode number 0 which is used in NTFS for the system file $MFT 517 + * and due to using iget() whereas NTFS needs ntfs_iget(). 518 + */ 519 + struct export_operations ntfs_export_ops = { 520 + .get_parent = ntfs_get_parent, /* Find the parent of a given 521 + directory. */ 522 + .get_dentry = ntfs_get_dentry, /* Find a dentry for the inode 523 + given a file handle 524 + sub-fragment. */ 525 + };
+7 -1
fs/ntfs/ntfs.h
··· 2 2 * ntfs.h - Defines for NTFS Linux kernel driver. Part of the Linux-NTFS 3 3 * project. 4 4 * 5 - * Copyright (c) 2001-2004 Anton Altaparmakov 5 + * Copyright (c) 2001-2005 Anton Altaparmakov 6 6 * Copyright (C) 2002 Richard Russon 7 7 * 8 8 * This program/include file is free software; you can redistribute it and/or ··· 31 31 #include <linux/fs.h> 32 32 #include <linux/nls.h> 33 33 #include <linux/smp.h> 34 + #include <linux/pagemap.h> 34 35 35 36 #include "types.h" 36 37 #include "volume.h" ··· 42 41 NTFS_BLOCK_SIZE_BITS = 9, 43 42 NTFS_SB_MAGIC = 0x5346544e, /* 'NTFS' */ 44 43 NTFS_MAX_NAME_LEN = 255, 44 + NTFS_MAX_ATTR_NAME_LEN = 255, 45 + NTFS_MAX_CLUSTER_SIZE = 64 * 1024, /* 64kiB */ 46 + NTFS_MAX_PAGES_PER_CLUSTER = NTFS_MAX_CLUSTER_SIZE / PAGE_CACHE_SIZE, 45 47 } NTFS_CONSTANTS; 46 48 47 49 /* Global variables. */ ··· 68 64 69 65 extern struct file_operations ntfs_empty_file_ops; 70 66 extern struct inode_operations ntfs_empty_inode_ops; 67 + 68 + extern struct export_operations ntfs_export_ops; 71 69 72 70 /** 73 71 * NTFS_SB - return the ntfs volume given a vfs super block
+198 -80
fs/ntfs/runlist.c
··· 1 1 /** 2 2 * runlist.c - NTFS runlist handling code. Part of the Linux-NTFS project. 3 3 * 4 - * Copyright (c) 2001-2004 Anton Altaparmakov 4 + * Copyright (c) 2001-2005 Anton Altaparmakov 5 5 * Copyright (c) 2002 Richard Russon 6 6 * 7 7 * This program/include file is free software; you can redistribute it and/or ··· 59 59 * 60 60 * As the runlists grow, more memory will be required. To prevent the 61 61 * kernel having to allocate and reallocate large numbers of small bits of 62 - * memory, this function returns and entire page of memory. 62 + * memory, this function returns an entire page of memory. 63 63 * 64 64 * It is up to the caller to serialize access to the runlist @rl. 65 65 * ··· 113 113 BUG_ON(!dst); 114 114 BUG_ON(!src); 115 115 116 - if ((dst->lcn < 0) || (src->lcn < 0)) /* Are we merging holes? */ 116 + if ((dst->lcn < 0) || (src->lcn < 0)) { /* Are we merging holes? */ 117 + if (dst->lcn == LCN_HOLE && src->lcn == LCN_HOLE) 118 + return TRUE; 117 119 return FALSE; 120 + } 118 121 if ((dst->lcn + dst->length) != src->lcn) /* Are the runs contiguous? */ 119 122 return FALSE; 120 123 if ((dst->vcn + dst->length) != src->vcn) /* Are the runs misaligned? */ ··· 858 855 if (!attr->data.non_resident.lowest_vcn) { 859 856 VCN max_cluster; 860 857 861 - max_cluster = (sle64_to_cpu( 858 + max_cluster = ((sle64_to_cpu( 862 859 attr->data.non_resident.allocated_size) + 863 860 vol->cluster_size - 1) >> 864 - vol->cluster_size_bits; 861 + vol->cluster_size_bits) - 1; 865 862 /* 866 - * If there is a difference between the highest_vcn and the 867 - * highest cluster, the runlist is either corrupt or, more 868 - * likely, there are more extents following this one. 863 + * A highest_vcn of zero means this is a single extent 864 + * attribute so simply terminate the runlist with LCN_ENOENT). 869 865 */ 870 - if (deltaxcn < --max_cluster) { 871 - ntfs_debug("More extents to follow; deltaxcn = 0x%llx, " 872 - "max_cluster = 0x%llx", 873 - (unsigned long long)deltaxcn, 874 - (unsigned long long)max_cluster); 875 - rl[rlpos].vcn = vcn; 876 - vcn += rl[rlpos].length = max_cluster - deltaxcn; 877 - rl[rlpos].lcn = LCN_RL_NOT_MAPPED; 878 - rlpos++; 879 - } else if (unlikely(deltaxcn > max_cluster)) { 880 - ntfs_error(vol->sb, "Corrupt attribute. deltaxcn = " 881 - "0x%llx, max_cluster = 0x%llx", 882 - (unsigned long long)deltaxcn, 883 - (unsigned long long)max_cluster); 884 - goto mpa_err; 866 + if (deltaxcn) { 867 + /* 868 + * If there is a difference between the highest_vcn and 869 + * the highest cluster, the runlist is either corrupt 870 + * or, more likely, there are more extents following 871 + * this one. 872 + */ 873 + if (deltaxcn < max_cluster) { 874 + ntfs_debug("More extents to follow; deltaxcn " 875 + "= 0x%llx, max_cluster = " 876 + "0x%llx", 877 + (unsigned long long)deltaxcn, 878 + (unsigned long long) 879 + max_cluster); 880 + rl[rlpos].vcn = vcn; 881 + vcn += rl[rlpos].length = max_cluster - 882 + deltaxcn; 883 + rl[rlpos].lcn = LCN_RL_NOT_MAPPED; 884 + rlpos++; 885 + } else if (unlikely(deltaxcn > max_cluster)) { 886 + ntfs_error(vol->sb, "Corrupt attribute. " 887 + "deltaxcn = 0x%llx, " 888 + "max_cluster = 0x%llx", 889 + (unsigned long long)deltaxcn, 890 + (unsigned long long) 891 + max_cluster); 892 + goto mpa_err; 893 + } 885 894 } 886 895 rl[rlpos].lcn = LCN_ENOENT; 887 896 } else /* Not the base extent. There may be more extents to follow. */ ··· 933 918 * 934 919 * It is up to the caller to serialize access to the runlist @rl. 935 920 * 936 - * Since lcns must be >= 0, we use negative return values with special meaning: 921 + * Since lcns must be >= 0, we use negative return codes with special meaning: 937 922 * 938 - * Return value Meaning / Description 923 + * Return code Meaning / Description 939 924 * ================================================== 940 - * -1 = LCN_HOLE Hole / not allocated on disk. 941 - * -2 = LCN_RL_NOT_MAPPED This is part of the runlist which has not been 942 - * inserted into the runlist yet. 943 - * -3 = LCN_ENOENT There is no such vcn in the attribute. 925 + * LCN_HOLE Hole / not allocated on disk. 926 + * LCN_RL_NOT_MAPPED This is part of the runlist which has not been 927 + * inserted into the runlist yet. 928 + * LCN_ENOENT There is no such vcn in the attribute. 944 929 * 945 930 * Locking: - The caller must have locked the runlist (for reading or writing). 946 - * - This function does not touch the lock. 931 + * - This function does not touch the lock, nor does it modify the 932 + * runlist. 947 933 */ 948 934 LCN ntfs_rl_vcn_to_lcn(const runlist_element *rl, const VCN vcn) 949 935 { ··· 978 962 return rl[i].lcn; 979 963 /* Just in case... We could replace this with BUG() some day. */ 980 964 return LCN_ENOENT; 965 + } 966 + 967 + #ifdef NTFS_RW 968 + 969 + /** 970 + * ntfs_rl_find_vcn_nolock - find a vcn in a runlist 971 + * @rl: runlist to search 972 + * @vcn: vcn to find 973 + * 974 + * Find the virtual cluster number @vcn in the runlist @rl and return the 975 + * address of the runlist element containing the @vcn on success. 976 + * 977 + * Return NULL if @rl is NULL or @vcn is in an unmapped part/out of bounds of 978 + * the runlist. 979 + * 980 + * Locking: The runlist must be locked on entry. 981 + */ 982 + runlist_element *ntfs_rl_find_vcn_nolock(runlist_element *rl, const VCN vcn) 983 + { 984 + BUG_ON(vcn < 0); 985 + if (unlikely(!rl || vcn < rl[0].vcn)) 986 + return NULL; 987 + while (likely(rl->length)) { 988 + if (unlikely(vcn < rl[1].vcn)) { 989 + if (likely(rl->lcn >= LCN_HOLE)) 990 + return rl; 991 + return NULL; 992 + } 993 + rl++; 994 + } 995 + if (likely(rl->lcn == LCN_ENOENT)) 996 + return rl; 997 + return NULL; 981 998 } 982 999 983 1000 /** ··· 1048 999 * ntfs_get_size_for_mapping_pairs - get bytes needed for mapping pairs array 1049 1000 * @vol: ntfs volume (needed for the ntfs version) 1050 1001 * @rl: locked runlist to determine the size of the mapping pairs of 1051 - * @start_vcn: vcn at which to start the mapping pairs array 1002 + * @first_vcn: first vcn which to include in the mapping pairs array 1003 + * @last_vcn: last vcn which to include in the mapping pairs array 1052 1004 * 1053 1005 * Walk the locked runlist @rl and calculate the size in bytes of the mapping 1054 - * pairs array corresponding to the runlist @rl, starting at vcn @start_vcn. 1006 + * pairs array corresponding to the runlist @rl, starting at vcn @first_vcn and 1007 + * finishing with vcn @last_vcn. 1008 + * 1009 + * A @last_vcn of -1 means end of runlist and in that case the size of the 1010 + * mapping pairs array corresponding to the runlist starting at vcn @first_vcn 1011 + * and finishing at the end of the runlist is determined. 1012 + * 1055 1013 * This for example allows us to allocate a buffer of the right size when 1056 1014 * building the mapping pairs array. 1057 1015 * ··· 1074 1018 * remains locked throughout, and is left locked upon return. 1075 1019 */ 1076 1020 int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol, 1077 - const runlist_element *rl, const VCN start_vcn) 1021 + const runlist_element *rl, const VCN first_vcn, 1022 + const VCN last_vcn) 1078 1023 { 1079 1024 LCN prev_lcn; 1080 1025 int rls; 1026 + BOOL the_end = FALSE; 1081 1027 1082 - BUG_ON(start_vcn < 0); 1028 + BUG_ON(first_vcn < 0); 1029 + BUG_ON(last_vcn < -1); 1030 + BUG_ON(last_vcn >= 0 && first_vcn > last_vcn); 1083 1031 if (!rl) { 1084 - BUG_ON(start_vcn); 1032 + BUG_ON(first_vcn); 1033 + BUG_ON(last_vcn > 0); 1085 1034 return 1; 1086 1035 } 1087 - /* Skip to runlist element containing @start_vcn. */ 1088 - while (rl->length && start_vcn >= rl[1].vcn) 1036 + /* Skip to runlist element containing @first_vcn. */ 1037 + while (rl->length && first_vcn >= rl[1].vcn) 1089 1038 rl++; 1090 - if ((!rl->length && start_vcn > rl->vcn) || start_vcn < rl->vcn) 1039 + if (unlikely((!rl->length && first_vcn > rl->vcn) || 1040 + first_vcn < rl->vcn)) 1091 1041 return -EINVAL; 1092 1042 prev_lcn = 0; 1093 1043 /* Always need the termining zero byte. */ 1094 1044 rls = 1; 1095 1045 /* Do the first partial run if present. */ 1096 - if (start_vcn > rl->vcn) { 1097 - s64 delta; 1046 + if (first_vcn > rl->vcn) { 1047 + s64 delta, length = rl->length; 1098 1048 1099 1049 /* We know rl->length != 0 already. */ 1100 - if (rl->length < 0 || rl->lcn < LCN_HOLE) 1050 + if (unlikely(length < 0 || rl->lcn < LCN_HOLE)) 1101 1051 goto err_out; 1102 - delta = start_vcn - rl->vcn; 1052 + /* 1053 + * If @stop_vcn is given and finishes inside this run, cap the 1054 + * run length. 1055 + */ 1056 + if (unlikely(last_vcn >= 0 && rl[1].vcn > last_vcn)) { 1057 + s64 s1 = last_vcn + 1; 1058 + if (unlikely(rl[1].vcn > s1)) 1059 + length = s1 - rl->vcn; 1060 + the_end = TRUE; 1061 + } 1062 + delta = first_vcn - rl->vcn; 1103 1063 /* Header byte + length. */ 1104 - rls += 1 + ntfs_get_nr_significant_bytes(rl->length - delta); 1064 + rls += 1 + ntfs_get_nr_significant_bytes(length - delta); 1105 1065 /* 1106 1066 * If the logical cluster number (lcn) denotes a hole and we 1107 1067 * are on NTFS 3.0+, we don't store it at all, i.e. we need ··· 1125 1053 * Note: this assumes that on NTFS 1.2-, holes are stored with 1126 1054 * an lcn of -1 and not a delta_lcn of -1 (unless both are -1). 1127 1055 */ 1128 - if (rl->lcn >= 0 || vol->major_ver < 3) { 1056 + if (likely(rl->lcn >= 0 || vol->major_ver < 3)) { 1129 1057 prev_lcn = rl->lcn; 1130 - if (rl->lcn >= 0) 1058 + if (likely(rl->lcn >= 0)) 1131 1059 prev_lcn += delta; 1132 1060 /* Change in lcn. */ 1133 1061 rls += ntfs_get_nr_significant_bytes(prev_lcn); ··· 1136 1064 rl++; 1137 1065 } 1138 1066 /* Do the full runs. */ 1139 - for (; rl->length; rl++) { 1140 - if (rl->length < 0 || rl->lcn < LCN_HOLE) 1067 + for (; rl->length && !the_end; rl++) { 1068 + s64 length = rl->length; 1069 + 1070 + if (unlikely(length < 0 || rl->lcn < LCN_HOLE)) 1141 1071 goto err_out; 1072 + /* 1073 + * If @stop_vcn is given and finishes inside this run, cap the 1074 + * run length. 1075 + */ 1076 + if (unlikely(last_vcn >= 0 && rl[1].vcn > last_vcn)) { 1077 + s64 s1 = last_vcn + 1; 1078 + if (unlikely(rl[1].vcn > s1)) 1079 + length = s1 - rl->vcn; 1080 + the_end = TRUE; 1081 + } 1142 1082 /* Header byte + length. */ 1143 - rls += 1 + ntfs_get_nr_significant_bytes(rl->length); 1083 + rls += 1 + ntfs_get_nr_significant_bytes(length); 1144 1084 /* 1145 1085 * If the logical cluster number (lcn) denotes a hole and we 1146 1086 * are on NTFS 3.0+, we don't store it at all, i.e. we need ··· 1160 1076 * Note: this assumes that on NTFS 1.2-, holes are stored with 1161 1077 * an lcn of -1 and not a delta_lcn of -1 (unless both are -1). 1162 1078 */ 1163 - if (rl->lcn >= 0 || vol->major_ver < 3) { 1079 + if (likely(rl->lcn >= 0 || vol->major_ver < 3)) { 1164 1080 /* Change in lcn. */ 1165 1081 rls += ntfs_get_nr_significant_bytes(rl->lcn - 1166 1082 prev_lcn); ··· 1203 1119 1204 1120 i = 0; 1205 1121 do { 1206 - if (dst > dst_max) 1122 + if (unlikely(dst > dst_max)) 1207 1123 goto err_out; 1208 1124 *dst++ = l & 0xffll; 1209 1125 l >>= 8; ··· 1212 1128 j = (n >> 8 * (i - 1)) & 0xff; 1213 1129 /* If the sign bit is wrong, we need an extra byte. */ 1214 1130 if (n < 0 && j >= 0) { 1215 - if (dst > dst_max) 1131 + if (unlikely(dst > dst_max)) 1216 1132 goto err_out; 1217 1133 i++; 1218 1134 *dst = (s8)-1; 1219 1135 } else if (n > 0 && j < 0) { 1220 - if (dst > dst_max) 1136 + if (unlikely(dst > dst_max)) 1221 1137 goto err_out; 1222 1138 i++; 1223 1139 *dst = (s8)0; ··· 1233 1149 * @dst: destination buffer to which to write the mapping pairs array 1234 1150 * @dst_len: size of destination buffer @dst in bytes 1235 1151 * @rl: locked runlist for which to build the mapping pairs array 1236 - * @start_vcn: vcn at which to start the mapping pairs array 1152 + * @first_vcn: first vcn which to include in the mapping pairs array 1153 + * @last_vcn: last vcn which to include in the mapping pairs array 1237 1154 * @stop_vcn: first vcn outside destination buffer on success or -ENOSPC 1238 1155 * 1239 1156 * Create the mapping pairs array from the locked runlist @rl, starting at vcn 1240 - * @start_vcn and save the array in @dst. @dst_len is the size of @dst in 1241 - * bytes and it should be at least equal to the value obtained by calling 1242 - * ntfs_get_size_for_mapping_pairs(). 1157 + * @first_vcn and finishing with vcn @last_vcn and save the array in @dst. 1158 + * @dst_len is the size of @dst in bytes and it should be at least equal to the 1159 + * value obtained by calling ntfs_get_size_for_mapping_pairs(). 1160 + * 1161 + * A @last_vcn of -1 means end of runlist and in that case the mapping pairs 1162 + * array corresponding to the runlist starting at vcn @first_vcn and finishing 1163 + * at the end of the runlist is created. 1243 1164 * 1244 1165 * If @rl is NULL, just write a single terminator byte to @dst. 1245 1166 * ··· 1253 1164 * been filled with all the mapping pairs that will fit, thus it can be treated 1254 1165 * as partial success, in that a new attribute extent needs to be created or 1255 1166 * the next extent has to be used and the mapping pairs build has to be 1256 - * continued with @start_vcn set to *@stop_vcn. 1167 + * continued with @first_vcn set to *@stop_vcn. 1257 1168 * 1258 1169 * Return 0 on success and -errno on error. The following error codes are 1259 1170 * defined: ··· 1267 1178 */ 1268 1179 int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst, 1269 1180 const int dst_len, const runlist_element *rl, 1270 - const VCN start_vcn, VCN *const stop_vcn) 1181 + const VCN first_vcn, const VCN last_vcn, VCN *const stop_vcn) 1271 1182 { 1272 1183 LCN prev_lcn; 1273 1184 s8 *dst_max, *dst_next; 1274 1185 int err = -ENOSPC; 1186 + BOOL the_end = FALSE; 1275 1187 s8 len_len, lcn_len; 1276 1188 1277 - BUG_ON(start_vcn < 0); 1189 + BUG_ON(first_vcn < 0); 1190 + BUG_ON(last_vcn < -1); 1191 + BUG_ON(last_vcn >= 0 && first_vcn > last_vcn); 1278 1192 BUG_ON(dst_len < 1); 1279 1193 if (!rl) { 1280 - BUG_ON(start_vcn); 1194 + BUG_ON(first_vcn); 1195 + BUG_ON(last_vcn > 0); 1281 1196 if (stop_vcn) 1282 1197 *stop_vcn = 0; 1283 1198 /* Terminator byte. */ 1284 1199 *dst = 0; 1285 1200 return 0; 1286 1201 } 1287 - /* Skip to runlist element containing @start_vcn. */ 1288 - while (rl->length && start_vcn >= rl[1].vcn) 1202 + /* Skip to runlist element containing @first_vcn. */ 1203 + while (rl->length && first_vcn >= rl[1].vcn) 1289 1204 rl++; 1290 - if ((!rl->length && start_vcn > rl->vcn) || start_vcn < rl->vcn) 1205 + if (unlikely((!rl->length && first_vcn > rl->vcn) || 1206 + first_vcn < rl->vcn)) 1291 1207 return -EINVAL; 1292 1208 /* 1293 1209 * @dst_max is used for bounds checking in ··· 1301 1207 dst_max = dst + dst_len - 1; 1302 1208 prev_lcn = 0; 1303 1209 /* Do the first partial run if present. */ 1304 - if (start_vcn > rl->vcn) { 1305 - s64 delta; 1210 + if (first_vcn > rl->vcn) { 1211 + s64 delta, length = rl->length; 1306 1212 1307 1213 /* We know rl->length != 0 already. */ 1308 - if (rl->length < 0 || rl->lcn < LCN_HOLE) 1214 + if (unlikely(length < 0 || rl->lcn < LCN_HOLE)) 1309 1215 goto err_out; 1310 - delta = start_vcn - rl->vcn; 1216 + /* 1217 + * If @stop_vcn is given and finishes inside this run, cap the 1218 + * run length. 1219 + */ 1220 + if (unlikely(last_vcn >= 0 && rl[1].vcn > last_vcn)) { 1221 + s64 s1 = last_vcn + 1; 1222 + if (unlikely(rl[1].vcn > s1)) 1223 + length = s1 - rl->vcn; 1224 + the_end = TRUE; 1225 + } 1226 + delta = first_vcn - rl->vcn; 1311 1227 /* Write length. */ 1312 1228 len_len = ntfs_write_significant_bytes(dst + 1, dst_max, 1313 - rl->length - delta); 1314 - if (len_len < 0) 1229 + length - delta); 1230 + if (unlikely(len_len < 0)) 1315 1231 goto size_err; 1316 1232 /* 1317 1233 * If the logical cluster number (lcn) denotes a hole and we ··· 1332 1228 * case on NT4. - We assume that we just need to write the lcn 1333 1229 * change until someone tells us otherwise... (AIA) 1334 1230 */ 1335 - if (rl->lcn >= 0 || vol->major_ver < 3) { 1231 + if (likely(rl->lcn >= 0 || vol->major_ver < 3)) { 1336 1232 prev_lcn = rl->lcn; 1337 - if (rl->lcn >= 0) 1233 + if (likely(rl->lcn >= 0)) 1338 1234 prev_lcn += delta; 1339 1235 /* Write change in lcn. */ 1340 1236 lcn_len = ntfs_write_significant_bytes(dst + 1 + 1341 1237 len_len, dst_max, prev_lcn); 1342 - if (lcn_len < 0) 1238 + if (unlikely(lcn_len < 0)) 1343 1239 goto size_err; 1344 1240 } else 1345 1241 lcn_len = 0; 1346 1242 dst_next = dst + len_len + lcn_len + 1; 1347 - if (dst_next > dst_max) 1243 + if (unlikely(dst_next > dst_max)) 1348 1244 goto size_err; 1349 1245 /* Update header byte. */ 1350 1246 *dst = lcn_len << 4 | len_len; ··· 1354 1250 rl++; 1355 1251 } 1356 1252 /* Do the full runs. */ 1357 - for (; rl->length; rl++) { 1358 - if (rl->length < 0 || rl->lcn < LCN_HOLE) 1253 + for (; rl->length && !the_end; rl++) { 1254 + s64 length = rl->length; 1255 + 1256 + if (unlikely(length < 0 || rl->lcn < LCN_HOLE)) 1359 1257 goto err_out; 1258 + /* 1259 + * If @stop_vcn is given and finishes inside this run, cap the 1260 + * run length. 1261 + */ 1262 + if (unlikely(last_vcn >= 0 && rl[1].vcn > last_vcn)) { 1263 + s64 s1 = last_vcn + 1; 1264 + if (unlikely(rl[1].vcn > s1)) 1265 + length = s1 - rl->vcn; 1266 + the_end = TRUE; 1267 + } 1360 1268 /* Write length. */ 1361 1269 len_len = ntfs_write_significant_bytes(dst + 1, dst_max, 1362 - rl->length); 1363 - if (len_len < 0) 1270 + length); 1271 + if (unlikely(len_len < 0)) 1364 1272 goto size_err; 1365 1273 /* 1366 1274 * If the logical cluster number (lcn) denotes a hole and we ··· 1383 1267 * case on NT4. - We assume that we just need to write the lcn 1384 1268 * change until someone tells us otherwise... (AIA) 1385 1269 */ 1386 - if (rl->lcn >= 0 || vol->major_ver < 3) { 1270 + if (likely(rl->lcn >= 0 || vol->major_ver < 3)) { 1387 1271 /* Write change in lcn. */ 1388 1272 lcn_len = ntfs_write_significant_bytes(dst + 1 + 1389 1273 len_len, dst_max, rl->lcn - prev_lcn); 1390 - if (lcn_len < 0) 1274 + if (unlikely(lcn_len < 0)) 1391 1275 goto size_err; 1392 1276 prev_lcn = rl->lcn; 1393 1277 } else 1394 1278 lcn_len = 0; 1395 1279 dst_next = dst + len_len + lcn_len + 1; 1396 - if (dst_next > dst_max) 1280 + if (unlikely(dst_next > dst_max)) 1397 1281 goto size_err; 1398 1282 /* Update header byte. */ 1399 1283 *dst = lcn_len << 4 | len_len; ··· 1552 1436 ntfs_debug("Done."); 1553 1437 return 0; 1554 1438 } 1439 + 1440 + #endif /* NTFS_RW */
+13 -3
fs/ntfs/runlist.h
··· 2 2 * runlist.h - Defines for runlist handling in NTFS Linux kernel driver. 3 3 * Part of the Linux-NTFS project. 4 4 * 5 - * Copyright (c) 2001-2004 Anton Altaparmakov 5 + * Copyright (c) 2001-2005 Anton Altaparmakov 6 6 * Copyright (c) 2002 Richard Russon 7 7 * 8 8 * This program/include file is free software; you can redistribute it and/or ··· 66 66 LCN_HOLE = -1, /* Keep this as highest value or die! */ 67 67 LCN_RL_NOT_MAPPED = -2, 68 68 LCN_ENOENT = -3, 69 + LCN_ENOMEM = -4, 70 + LCN_EIO = -5, 69 71 } LCN_SPECIAL_VALUES; 70 72 71 73 extern runlist_element *ntfs_runlists_merge(runlist_element *drl, ··· 78 76 79 77 extern LCN ntfs_rl_vcn_to_lcn(const runlist_element *rl, const VCN vcn); 80 78 79 + #ifdef NTFS_RW 80 + 81 + extern runlist_element *ntfs_rl_find_vcn_nolock(runlist_element *rl, 82 + const VCN vcn); 83 + 81 84 extern int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol, 82 - const runlist_element *rl, const VCN start_vcn); 85 + const runlist_element *rl, const VCN first_vcn, 86 + const VCN last_vcn); 83 87 84 88 extern int ntfs_mapping_pairs_build(const ntfs_volume *vol, s8 *dst, 85 89 const int dst_len, const runlist_element *rl, 86 - const VCN start_vcn, VCN *const stop_vcn); 90 + const VCN first_vcn, const VCN last_vcn, VCN *const stop_vcn); 87 91 88 92 extern int ntfs_rl_truncate_nolock(const ntfs_volume *vol, 89 93 runlist *const runlist, const s64 new_length); 94 + 95 + #endif /* NTFS_RW */ 90 96 91 97 #endif /* _LINUX_NTFS_RUNLIST_H */
+542 -150
fs/ntfs/super.c
··· 1 1 /* 2 2 * super.c - NTFS kernel super block handling. Part of the Linux-NTFS project. 3 3 * 4 - * Copyright (c) 2001-2004 Anton Altaparmakov 4 + * Copyright (c) 2001-2005 Anton Altaparmakov 5 5 * Copyright (c) 2001,2002 Richard Russon 6 6 * 7 7 * This program/include file is free software; you can redistribute it and/or ··· 34 34 #include "sysctl.h" 35 35 #include "logfile.h" 36 36 #include "quota.h" 37 + #include "usnjrnl.h" 37 38 #include "dir.h" 38 39 #include "debug.h" 39 40 #include "index.h" 40 41 #include "aops.h" 42 + #include "layout.h" 41 43 #include "malloc.h" 42 44 #include "ntfs.h" 43 45 44 - /* Number of mounted file systems which have compression enabled. */ 46 + /* Number of mounted filesystems which have compression enabled. */ 45 47 static unsigned long ntfs_nr_compression_users; 46 48 47 49 /* A global default upcase table and a corresponding reference count. */ ··· 104 102 gid_t gid = (gid_t)-1; 105 103 mode_t fmask = (mode_t)-1, dmask = (mode_t)-1; 106 104 int mft_zone_multiplier = -1, on_errors = -1; 107 - int show_sys_files = -1, case_sensitive = -1; 105 + int show_sys_files = -1, case_sensitive = -1, disable_sparse = -1; 108 106 struct nls_table *nls_map = NULL, *old_nls; 109 107 110 108 /* I am lazy... (-8 */ ··· 164 162 else NTFS_GETOPT_WITH_DEFAULT("sloppy", sloppy, TRUE) 165 163 else NTFS_GETOPT_BOOL("show_sys_files", show_sys_files) 166 164 else NTFS_GETOPT_BOOL("case_sensitive", case_sensitive) 165 + else NTFS_GETOPT_BOOL("disable_sparse", disable_sparse) 167 166 else NTFS_GETOPT_OPTIONS_ARRAY("errors", on_errors, 168 167 on_errors_arr) 169 168 else if (!strcmp(p, "posix") || !strcmp(p, "show_inodes")) ··· 293 290 NVolSetCaseSensitive(vol); 294 291 else 295 292 NVolClearCaseSensitive(vol); 293 + } 294 + if (disable_sparse != -1) { 295 + if (disable_sparse) 296 + NVolClearSparseEnabled(vol); 297 + else { 298 + if (!NVolSparseEnabled(vol) && 299 + vol->major_ver && vol->major_ver < 3) 300 + ntfs_warning(vol->sb, "Not enabling sparse " 301 + "support due to NTFS volume " 302 + "version %i.%i (need at least " 303 + "version 3.0).", vol->major_ver, 304 + vol->minor_ver); 305 + else 306 + NVolSetSparseEnabled(vol); 307 + } 296 308 } 297 309 return TRUE; 298 310 needs_arg: ··· 498 480 NVolSetErrors(vol); 499 481 return -EROFS; 500 482 } 483 + if (!ntfs_stamp_usnjrnl(vol)) { 484 + ntfs_error(sb, "Failed to stamp transation log " 485 + "($UsnJrnl)%s", es); 486 + NVolSetErrors(vol); 487 + return -EROFS; 488 + } 501 489 } else if (!(sb->s_flags & MS_RDONLY) && (*flags & MS_RDONLY)) { 502 490 /* Remounting read-only. */ 503 491 if (!NVolErrors(vol)) { ··· 540 516 { 541 517 /* 542 518 * Check that checksum == sum of u32 values from b to the checksum 543 - * field. If checksum is zero, no checking is done. 519 + * field. If checksum is zero, no checking is done. We will work when 520 + * the checksum test fails, since some utilities update the boot sector 521 + * ignoring the checksum which leaves the checksum out-of-date. We 522 + * report a warning if this is the case. 544 523 */ 545 - if ((void*)b < (void*)&b->checksum && b->checksum) { 524 + if ((void*)b < (void*)&b->checksum && b->checksum && !silent) { 546 525 le32 *u; 547 526 u32 i; 548 527 549 528 for (i = 0, u = (le32*)b; u < (le32*)(&b->checksum); ++u) 550 529 i += le32_to_cpup(u); 551 530 if (le32_to_cpu(b->checksum) != i) 552 - goto not_ntfs; 531 + ntfs_warning(sb, "Invalid boot sector checksum."); 553 532 } 554 533 /* Check OEMidentifier is "NTFS " */ 555 534 if (b->oem_id != magicNTFS) ··· 568 541 default: 569 542 goto not_ntfs; 570 543 } 571 - /* Check the cluster size is not above 65536 bytes. */ 544 + /* Check the cluster size is not above the maximum (64kiB). */ 572 545 if ((u32)le16_to_cpu(b->bpb.bytes_per_sector) * 573 - b->bpb.sectors_per_cluster > 0x10000) 546 + b->bpb.sectors_per_cluster > NTFS_MAX_CLUSTER_SIZE) 574 547 goto not_ntfs; 575 548 /* Check reserved/unused fields are really zero. */ 576 549 if (le16_to_cpu(b->bpb.reserved_sectors) || ··· 602 575 * many BIOSes will refuse to boot from a bootsector if the magic is 603 576 * incorrect, so we emit a warning. 604 577 */ 605 - if (!silent && b->end_of_sector_marker != cpu_to_le16(0xaa55)) 578 + if (!silent && b->end_of_sector_marker != const_cpu_to_le16(0xaa55)) 606 579 ntfs_warning(sb, "Invalid end of sector marker."); 607 580 return TRUE; 608 581 not_ntfs: ··· 994 967 tmp_ni = NTFS_I(tmp_ino); 995 968 /* The $MFTMirr, like the $MFT is multi sector transfer protected. */ 996 969 NInoSetMstProtected(tmp_ni); 970 + NInoSetSparseDisabled(tmp_ni); 997 971 /* 998 972 * Set up our little cheat allowing us to reuse the async read io 999 973 * completion handler for directories. ··· 1018 990 */ 1019 991 static BOOL check_mft_mirror(ntfs_volume *vol) 1020 992 { 1021 - unsigned long index; 1022 993 struct super_block *sb = vol->sb; 1023 994 ntfs_inode *mirr_ni; 1024 995 struct page *mft_page, *mirr_page; 1025 996 u8 *kmft, *kmirr; 1026 997 runlist_element *rl, rl2[2]; 998 + pgoff_t index; 1027 999 int mrecs_per_page, i; 1028 1000 1029 1001 ntfs_debug("Entering."); ··· 1150 1122 /* ntfs_check_logfile() will have displayed error output. */ 1151 1123 return FALSE; 1152 1124 } 1125 + NInoSetSparseDisabled(NTFS_I(tmp_ino)); 1153 1126 vol->logfile_ino = tmp_ino; 1154 1127 ntfs_debug("Done."); 1155 1128 return TRUE; 1129 + } 1130 + 1131 + #define NTFS_HIBERFIL_HEADER_SIZE 4096 1132 + 1133 + /** 1134 + * check_windows_hibernation_status - check if Windows is suspended on a volume 1135 + * @vol: ntfs super block of device to check 1136 + * 1137 + * Check if Windows is hibernated on the ntfs volume @vol. This is done by 1138 + * looking for the file hiberfil.sys in the root directory of the volume. If 1139 + * the file is not present Windows is definitely not suspended. 1140 + * 1141 + * If hiberfil.sys exists and is less than 4kiB in size it means Windows is 1142 + * definitely suspended (this volume is not the system volume). Caveat: on a 1143 + * system with many volumes it is possible that the < 4kiB check is bogus but 1144 + * for now this should do fine. 1145 + * 1146 + * If hiberfil.sys exists and is larger than 4kiB in size, we need to read the 1147 + * hiberfil header (which is the first 4kiB). If this begins with "hibr", 1148 + * Windows is definitely suspended. If it is completely full of zeroes, 1149 + * Windows is definitely not hibernated. Any other case is treated as if 1150 + * Windows is suspended. This caters for the above mentioned caveat of a 1151 + * system with many volumes where no "hibr" magic would be present and there is 1152 + * no zero header. 1153 + * 1154 + * Return 0 if Windows is not hibernated on the volume, >0 if Windows is 1155 + * hibernated on the volume, and -errno on error. 1156 + */ 1157 + static int check_windows_hibernation_status(ntfs_volume *vol) 1158 + { 1159 + MFT_REF mref; 1160 + struct inode *vi; 1161 + ntfs_inode *ni; 1162 + struct page *page; 1163 + u32 *kaddr, *kend; 1164 + ntfs_name *name = NULL; 1165 + int ret = 1; 1166 + static const ntfschar hiberfil[13] = { const_cpu_to_le16('h'), 1167 + const_cpu_to_le16('i'), const_cpu_to_le16('b'), 1168 + const_cpu_to_le16('e'), const_cpu_to_le16('r'), 1169 + const_cpu_to_le16('f'), const_cpu_to_le16('i'), 1170 + const_cpu_to_le16('l'), const_cpu_to_le16('.'), 1171 + const_cpu_to_le16('s'), const_cpu_to_le16('y'), 1172 + const_cpu_to_le16('s'), 0 }; 1173 + 1174 + ntfs_debug("Entering."); 1175 + /* 1176 + * Find the inode number for the hibernation file by looking up the 1177 + * filename hiberfil.sys in the root directory. 1178 + */ 1179 + down(&vol->root_ino->i_sem); 1180 + mref = ntfs_lookup_inode_by_name(NTFS_I(vol->root_ino), hiberfil, 12, 1181 + &name); 1182 + up(&vol->root_ino->i_sem); 1183 + if (IS_ERR_MREF(mref)) { 1184 + ret = MREF_ERR(mref); 1185 + /* If the file does not exist, Windows is not hibernated. */ 1186 + if (ret == -ENOENT) { 1187 + ntfs_debug("hiberfil.sys not present. Windows is not " 1188 + "hibernated on the volume."); 1189 + return 0; 1190 + } 1191 + /* A real error occured. */ 1192 + ntfs_error(vol->sb, "Failed to find inode number for " 1193 + "hiberfil.sys."); 1194 + return ret; 1195 + } 1196 + /* We do not care for the type of match that was found. */ 1197 + kfree(name); 1198 + /* Get the inode. */ 1199 + vi = ntfs_iget(vol->sb, MREF(mref)); 1200 + if (IS_ERR(vi) || is_bad_inode(vi)) { 1201 + if (!IS_ERR(vi)) 1202 + iput(vi); 1203 + ntfs_error(vol->sb, "Failed to load hiberfil.sys."); 1204 + return IS_ERR(vi) ? PTR_ERR(vi) : -EIO; 1205 + } 1206 + if (unlikely(i_size_read(vi) < NTFS_HIBERFIL_HEADER_SIZE)) { 1207 + ntfs_debug("hiberfil.sys is smaller than 4kiB (0x%llx). " 1208 + "Windows is hibernated on the volume. This " 1209 + "is not the system volume.", i_size_read(vi)); 1210 + goto iput_out; 1211 + } 1212 + ni = NTFS_I(vi); 1213 + page = ntfs_map_page(vi->i_mapping, 0); 1214 + if (IS_ERR(page)) { 1215 + ntfs_error(vol->sb, "Failed to read from hiberfil.sys."); 1216 + ret = PTR_ERR(page); 1217 + goto iput_out; 1218 + } 1219 + kaddr = (u32*)page_address(page); 1220 + if (*(le32*)kaddr == const_cpu_to_le32(0x72626968)/*'hibr'*/) { 1221 + ntfs_debug("Magic \"hibr\" found in hiberfil.sys. Windows is " 1222 + "hibernated on the volume. This is the " 1223 + "system volume."); 1224 + goto unm_iput_out; 1225 + } 1226 + kend = kaddr + NTFS_HIBERFIL_HEADER_SIZE/sizeof(*kaddr); 1227 + do { 1228 + if (unlikely(*kaddr)) { 1229 + ntfs_debug("hiberfil.sys is larger than 4kiB " 1230 + "(0x%llx), does not contain the " 1231 + "\"hibr\" magic, and does not have a " 1232 + "zero header. Windows is hibernated " 1233 + "on the volume. This is not the " 1234 + "system volume.", i_size_read(vi)); 1235 + goto unm_iput_out; 1236 + } 1237 + } while (++kaddr < kend); 1238 + ntfs_debug("hiberfil.sys contains a zero header. Windows is not " 1239 + "hibernated on the volume. This is the system " 1240 + "volume."); 1241 + ret = 0; 1242 + unm_iput_out: 1243 + ntfs_unmap_page(page); 1244 + iput_out: 1245 + iput(vi); 1246 + return ret; 1156 1247 } 1157 1248 1158 1249 /** ··· 1322 1175 return FALSE; 1323 1176 } 1324 1177 /* We do not care for the type of match that was found. */ 1325 - if (name) 1326 - kfree(name); 1178 + kfree(name); 1327 1179 /* Get the inode. */ 1328 1180 tmp_ino = ntfs_iget(vol->sb, MREF(mref)); 1329 1181 if (IS_ERR(tmp_ino) || is_bad_inode(tmp_ino)) { ··· 1344 1198 } 1345 1199 1346 1200 /** 1201 + * load_and_init_usnjrnl - load and setup the transaction log if present 1202 + * @vol: ntfs super block describing device whose usnjrnl file to load 1203 + * 1204 + * Return TRUE on success or FALSE on error. 1205 + * 1206 + * If $UsnJrnl is not present or in the process of being disabled, we set 1207 + * NVolUsnJrnlStamped() and return success. 1208 + * 1209 + * If the $UsnJrnl $DATA/$J attribute has a size equal to the lowest valid usn, 1210 + * i.e. transaction logging has only just been enabled or the journal has been 1211 + * stamped and nothing has been logged since, we also set NVolUsnJrnlStamped() 1212 + * and return success. 1213 + */ 1214 + static BOOL load_and_init_usnjrnl(ntfs_volume *vol) 1215 + { 1216 + MFT_REF mref; 1217 + struct inode *tmp_ino; 1218 + ntfs_inode *tmp_ni; 1219 + struct page *page; 1220 + ntfs_name *name = NULL; 1221 + USN_HEADER *uh; 1222 + static const ntfschar UsnJrnl[9] = { const_cpu_to_le16('$'), 1223 + const_cpu_to_le16('U'), const_cpu_to_le16('s'), 1224 + const_cpu_to_le16('n'), const_cpu_to_le16('J'), 1225 + const_cpu_to_le16('r'), const_cpu_to_le16('n'), 1226 + const_cpu_to_le16('l'), 0 }; 1227 + static ntfschar Max[5] = { const_cpu_to_le16('$'), 1228 + const_cpu_to_le16('M'), const_cpu_to_le16('a'), 1229 + const_cpu_to_le16('x'), 0 }; 1230 + static ntfschar J[3] = { const_cpu_to_le16('$'), 1231 + const_cpu_to_le16('J'), 0 }; 1232 + 1233 + ntfs_debug("Entering."); 1234 + /* 1235 + * Find the inode number for the transaction log file by looking up the 1236 + * filename $UsnJrnl in the extended system files directory $Extend. 1237 + */ 1238 + down(&vol->extend_ino->i_sem); 1239 + mref = ntfs_lookup_inode_by_name(NTFS_I(vol->extend_ino), UsnJrnl, 8, 1240 + &name); 1241 + up(&vol->extend_ino->i_sem); 1242 + if (IS_ERR_MREF(mref)) { 1243 + /* 1244 + * If the file does not exist, transaction logging is disabled, 1245 + * just return success. 1246 + */ 1247 + if (MREF_ERR(mref) == -ENOENT) { 1248 + ntfs_debug("$UsnJrnl not present. Volume does not " 1249 + "have transaction logging enabled."); 1250 + not_enabled: 1251 + /* 1252 + * No need to try to stamp the transaction log if 1253 + * transaction logging is not enabled. 1254 + */ 1255 + NVolSetUsnJrnlStamped(vol); 1256 + return TRUE; 1257 + } 1258 + /* A real error occured. */ 1259 + ntfs_error(vol->sb, "Failed to find inode number for " 1260 + "$UsnJrnl."); 1261 + return FALSE; 1262 + } 1263 + /* We do not care for the type of match that was found. */ 1264 + kfree(name); 1265 + /* Get the inode. */ 1266 + tmp_ino = ntfs_iget(vol->sb, MREF(mref)); 1267 + if (unlikely(IS_ERR(tmp_ino) || is_bad_inode(tmp_ino))) { 1268 + if (!IS_ERR(tmp_ino)) 1269 + iput(tmp_ino); 1270 + ntfs_error(vol->sb, "Failed to load $UsnJrnl."); 1271 + return FALSE; 1272 + } 1273 + vol->usnjrnl_ino = tmp_ino; 1274 + /* 1275 + * If the transaction log is in the process of being deleted, we can 1276 + * ignore it. 1277 + */ 1278 + if (unlikely(vol->vol_flags & VOLUME_DELETE_USN_UNDERWAY)) { 1279 + ntfs_debug("$UsnJrnl in the process of being disabled. " 1280 + "Volume does not have transaction logging " 1281 + "enabled."); 1282 + goto not_enabled; 1283 + } 1284 + /* Get the $DATA/$Max attribute. */ 1285 + tmp_ino = ntfs_attr_iget(vol->usnjrnl_ino, AT_DATA, Max, 4); 1286 + if (IS_ERR(tmp_ino)) { 1287 + ntfs_error(vol->sb, "Failed to load $UsnJrnl/$DATA/$Max " 1288 + "attribute."); 1289 + return FALSE; 1290 + } 1291 + vol->usnjrnl_max_ino = tmp_ino; 1292 + if (unlikely(i_size_read(tmp_ino) < sizeof(USN_HEADER))) { 1293 + ntfs_error(vol->sb, "Found corrupt $UsnJrnl/$DATA/$Max " 1294 + "attribute (size is 0x%llx but should be at " 1295 + "least 0x%x bytes).", i_size_read(tmp_ino), 1296 + sizeof(USN_HEADER)); 1297 + return FALSE; 1298 + } 1299 + /* Get the $DATA/$J attribute. */ 1300 + tmp_ino = ntfs_attr_iget(vol->usnjrnl_ino, AT_DATA, J, 2); 1301 + if (IS_ERR(tmp_ino)) { 1302 + ntfs_error(vol->sb, "Failed to load $UsnJrnl/$DATA/$J " 1303 + "attribute."); 1304 + return FALSE; 1305 + } 1306 + vol->usnjrnl_j_ino = tmp_ino; 1307 + /* Verify $J is non-resident and sparse. */ 1308 + tmp_ni = NTFS_I(vol->usnjrnl_j_ino); 1309 + if (unlikely(!NInoNonResident(tmp_ni) || !NInoSparse(tmp_ni))) { 1310 + ntfs_error(vol->sb, "$UsnJrnl/$DATA/$J attribute is resident " 1311 + "and/or not sparse."); 1312 + return FALSE; 1313 + } 1314 + /* Read the USN_HEADER from $DATA/$Max. */ 1315 + page = ntfs_map_page(vol->usnjrnl_max_ino->i_mapping, 0); 1316 + if (IS_ERR(page)) { 1317 + ntfs_error(vol->sb, "Failed to read from $UsnJrnl/$DATA/$Max " 1318 + "attribute."); 1319 + return FALSE; 1320 + } 1321 + uh = (USN_HEADER*)page_address(page); 1322 + /* Sanity check the $Max. */ 1323 + if (unlikely(sle64_to_cpu(uh->allocation_delta) > 1324 + sle64_to_cpu(uh->maximum_size))) { 1325 + ntfs_error(vol->sb, "Allocation delta (0x%llx) exceeds " 1326 + "maximum size (0x%llx). $UsnJrnl is corrupt.", 1327 + (long long)sle64_to_cpu(uh->allocation_delta), 1328 + (long long)sle64_to_cpu(uh->maximum_size)); 1329 + ntfs_unmap_page(page); 1330 + return FALSE; 1331 + } 1332 + /* 1333 + * If the transaction log has been stamped and nothing has been written 1334 + * to it since, we do not need to stamp it. 1335 + */ 1336 + if (unlikely(sle64_to_cpu(uh->lowest_valid_usn) >= 1337 + i_size_read(vol->usnjrnl_j_ino))) { 1338 + if (likely(sle64_to_cpu(uh->lowest_valid_usn) == 1339 + i_size_read(vol->usnjrnl_j_ino))) { 1340 + ntfs_unmap_page(page); 1341 + ntfs_debug("$UsnJrnl is enabled but nothing has been " 1342 + "logged since it was last stamped. " 1343 + "Treating this as if the volume does " 1344 + "not have transaction logging " 1345 + "enabled."); 1346 + goto not_enabled; 1347 + } 1348 + ntfs_error(vol->sb, "$UsnJrnl has lowest valid usn (0x%llx) " 1349 + "which is out of bounds (0x%llx). $UsnJrnl " 1350 + "is corrupt.", 1351 + (long long)sle64_to_cpu(uh->lowest_valid_usn), 1352 + i_size_read(vol->usnjrnl_j_ino)); 1353 + ntfs_unmap_page(page); 1354 + return FALSE; 1355 + } 1356 + ntfs_unmap_page(page); 1357 + ntfs_debug("Done."); 1358 + return TRUE; 1359 + } 1360 + 1361 + /** 1347 1362 * load_and_init_attrdef - load the attribute definitions table for a volume 1348 1363 * @vol: ntfs super block describing device whose attrdef to load 1349 1364 * ··· 1512 1205 */ 1513 1206 static BOOL load_and_init_attrdef(ntfs_volume *vol) 1514 1207 { 1208 + loff_t i_size; 1515 1209 struct super_block *sb = vol->sb; 1516 1210 struct inode *ino; 1517 1211 struct page *page; 1518 - unsigned long index, max_index; 1212 + pgoff_t index, max_index; 1519 1213 unsigned int size; 1520 1214 1521 1215 ntfs_debug("Entering."); ··· 1527 1219 iput(ino); 1528 1220 goto failed; 1529 1221 } 1222 + NInoSetSparseDisabled(NTFS_I(ino)); 1530 1223 /* The size of FILE_AttrDef must be above 0 and fit inside 31 bits. */ 1531 - if (!ino->i_size || ino->i_size > 0x7fffffff) 1224 + i_size = i_size_read(ino); 1225 + if (i_size <= 0 || i_size > 0x7fffffff) 1532 1226 goto iput_failed; 1533 - vol->attrdef = (ATTR_DEF*)ntfs_malloc_nofs(ino->i_size); 1227 + vol->attrdef = (ATTR_DEF*)ntfs_malloc_nofs(i_size); 1534 1228 if (!vol->attrdef) 1535 1229 goto iput_failed; 1536 1230 index = 0; 1537 - max_index = ino->i_size >> PAGE_CACHE_SHIFT; 1231 + max_index = i_size >> PAGE_CACHE_SHIFT; 1538 1232 size = PAGE_CACHE_SIZE; 1539 1233 while (index < max_index) { 1540 1234 /* Read the attrdef table and copy it into the linear buffer. */ ··· 1549 1239 ntfs_unmap_page(page); 1550 1240 }; 1551 1241 if (size == PAGE_CACHE_SIZE) { 1552 - size = ino->i_size & ~PAGE_CACHE_MASK; 1242 + size = i_size & ~PAGE_CACHE_MASK; 1553 1243 if (size) 1554 1244 goto read_partial_attrdef_page; 1555 1245 } 1556 - vol->attrdef_size = ino->i_size; 1557 - ntfs_debug("Read %llu bytes from $AttrDef.", ino->i_size); 1246 + vol->attrdef_size = i_size; 1247 + ntfs_debug("Read %llu bytes from $AttrDef.", i_size); 1558 1248 iput(ino); 1559 1249 return TRUE; 1560 1250 free_iput_failed: ··· 1577 1267 */ 1578 1268 static BOOL load_and_init_upcase(ntfs_volume *vol) 1579 1269 { 1270 + loff_t i_size; 1580 1271 struct super_block *sb = vol->sb; 1581 1272 struct inode *ino; 1582 1273 struct page *page; 1583 - unsigned long index, max_index; 1274 + pgoff_t index, max_index; 1584 1275 unsigned int size; 1585 1276 int i, max; 1586 1277 ··· 1597 1286 * The upcase size must not be above 64k Unicode characters, must not 1598 1287 * be zero and must be a multiple of sizeof(ntfschar). 1599 1288 */ 1600 - if (!ino->i_size || ino->i_size & (sizeof(ntfschar) - 1) || 1601 - ino->i_size > 64ULL * 1024 * sizeof(ntfschar)) 1289 + i_size = i_size_read(ino); 1290 + if (!i_size || i_size & (sizeof(ntfschar) - 1) || 1291 + i_size > 64ULL * 1024 * sizeof(ntfschar)) 1602 1292 goto iput_upcase_failed; 1603 - vol->upcase = (ntfschar*)ntfs_malloc_nofs(ino->i_size); 1293 + vol->upcase = (ntfschar*)ntfs_malloc_nofs(i_size); 1604 1294 if (!vol->upcase) 1605 1295 goto iput_upcase_failed; 1606 1296 index = 0; 1607 - max_index = ino->i_size >> PAGE_CACHE_SHIFT; 1297 + max_index = i_size >> PAGE_CACHE_SHIFT; 1608 1298 size = PAGE_CACHE_SIZE; 1609 1299 while (index < max_index) { 1610 1300 /* Read the upcase table and copy it into the linear buffer. */ ··· 1618 1306 ntfs_unmap_page(page); 1619 1307 }; 1620 1308 if (size == PAGE_CACHE_SIZE) { 1621 - size = ino->i_size & ~PAGE_CACHE_MASK; 1309 + size = i_size & ~PAGE_CACHE_MASK; 1622 1310 if (size) 1623 1311 goto read_partial_upcase_page; 1624 1312 } 1625 - vol->upcase_len = ino->i_size >> UCHAR_T_SIZE_BITS; 1313 + vol->upcase_len = i_size >> UCHAR_T_SIZE_BITS; 1626 1314 ntfs_debug("Read %llu bytes from $UpCase (expected %zu bytes).", 1627 - ino->i_size, 64 * 1024 * sizeof(ntfschar)); 1315 + i_size, 64 * 1024 * sizeof(ntfschar)); 1628 1316 iput(ino); 1629 1317 down(&ntfs_lock); 1630 1318 if (!default_upcase) { ··· 1688 1376 MFT_RECORD *m; 1689 1377 VOLUME_INFORMATION *vi; 1690 1378 ntfs_attr_search_ctx *ctx; 1379 + #ifdef NTFS_RW 1380 + int err; 1381 + #endif /* NTFS_RW */ 1691 1382 1692 1383 ntfs_debug("Entering."); 1693 1384 #ifdef NTFS_RW ··· 1750 1435 iput(vol->lcnbmp_ino); 1751 1436 goto bitmap_failed; 1752 1437 } 1753 - if ((vol->nr_clusters + 7) >> 3 > vol->lcnbmp_ino->i_size) { 1438 + NInoSetSparseDisabled(NTFS_I(vol->lcnbmp_ino)); 1439 + if ((vol->nr_clusters + 7) >> 3 > i_size_read(vol->lcnbmp_ino)) { 1754 1440 iput(vol->lcnbmp_ino); 1755 1441 bitmap_failed: 1756 1442 ntfs_error(sb, "Failed to load $Bitmap."); ··· 1802 1486 unmap_mft_record(NTFS_I(vol->vol_ino)); 1803 1487 printk(KERN_INFO "NTFS volume version %i.%i.\n", vol->major_ver, 1804 1488 vol->minor_ver); 1489 + if (vol->major_ver < 3 && NVolSparseEnabled(vol)) { 1490 + ntfs_warning(vol->sb, "Disabling sparse support due to NTFS " 1491 + "volume version %i.%i (need at least version " 1492 + "3.0).", vol->major_ver, vol->minor_ver); 1493 + NVolClearSparseEnabled(vol); 1494 + } 1805 1495 #ifdef NTFS_RW 1806 1496 /* Make sure that no unsupported volume flags are set. */ 1807 1497 if (vol->vol_flags & VOLUME_MUST_MOUNT_RO_MASK) { ··· 1867 1545 /* This will prevent a read-write remount. */ 1868 1546 NVolSetErrors(vol); 1869 1547 } 1548 + #endif /* NTFS_RW */ 1549 + /* Get the root directory inode so we can do path lookups. */ 1550 + vol->root_ino = ntfs_iget(sb, FILE_root); 1551 + if (IS_ERR(vol->root_ino) || is_bad_inode(vol->root_ino)) { 1552 + if (!IS_ERR(vol->root_ino)) 1553 + iput(vol->root_ino); 1554 + ntfs_error(sb, "Failed to load root directory."); 1555 + goto iput_logfile_err_out; 1556 + } 1557 + #ifdef NTFS_RW 1558 + /* 1559 + * Check if Windows is suspended to disk on the target volume. If it 1560 + * is hibernated, we must not write *anything* to the disk so set 1561 + * NVolErrors() without setting the dirty volume flag and mount 1562 + * read-only. This will prevent read-write remounting and it will also 1563 + * prevent all writes. 1564 + */ 1565 + err = check_windows_hibernation_status(vol); 1566 + if (unlikely(err)) { 1567 + static const char *es1a = "Failed to determine if Windows is " 1568 + "hibernated"; 1569 + static const char *es1b = "Windows is hibernated"; 1570 + static const char *es2 = ". Run chkdsk."; 1571 + const char *es1; 1572 + 1573 + es1 = err < 0 ? es1a : es1b; 1574 + /* If a read-write mount, convert it to a read-only mount. */ 1575 + if (!(sb->s_flags & MS_RDONLY)) { 1576 + if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO | 1577 + ON_ERRORS_CONTINUE))) { 1578 + ntfs_error(sb, "%s and neither on_errors=" 1579 + "continue nor on_errors=" 1580 + "remount-ro was specified%s", 1581 + es1, es2); 1582 + goto iput_root_err_out; 1583 + } 1584 + sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; 1585 + ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); 1586 + } else 1587 + ntfs_warning(sb, "%s. Will not be able to remount " 1588 + "read-write%s", es1, es2); 1589 + /* This will prevent a read-write remount. */ 1590 + NVolSetErrors(vol); 1591 + } 1870 1592 /* If (still) a read-write mount, mark the volume dirty. */ 1871 1593 if (!(sb->s_flags & MS_RDONLY) && 1872 1594 ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY)) { ··· 1924 1558 ntfs_error(sb, "%s and neither on_errors=continue nor " 1925 1559 "on_errors=remount-ro was specified%s", 1926 1560 es1, es2); 1927 - goto iput_logfile_err_out; 1561 + goto iput_root_err_out; 1928 1562 } 1929 1563 ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); 1930 1564 sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; ··· 1951 1585 ntfs_error(sb, "%s and neither on_errors=continue nor " 1952 1586 "on_errors=remount-ro was specified%s", 1953 1587 es1, es2); 1954 - goto iput_logfile_err_out; 1588 + goto iput_root_err_out; 1955 1589 } 1956 1590 ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); 1957 1591 sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; ··· 1970 1604 ntfs_error(sb, "%s and neither on_errors=continue nor " 1971 1605 "on_errors=remount-ro was specified%s", 1972 1606 es1, es2); 1973 - goto iput_logfile_err_out; 1607 + goto iput_root_err_out; 1974 1608 } 1975 1609 ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); 1976 1610 sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; 1977 1611 NVolSetErrors(vol); 1978 1612 } 1979 1613 #endif /* NTFS_RW */ 1980 - /* Get the root directory inode. */ 1981 - vol->root_ino = ntfs_iget(sb, FILE_root); 1982 - if (IS_ERR(vol->root_ino) || is_bad_inode(vol->root_ino)) { 1983 - if (!IS_ERR(vol->root_ino)) 1984 - iput(vol->root_ino); 1985 - ntfs_error(sb, "Failed to load root directory."); 1986 - goto iput_logfile_err_out; 1987 - } 1988 1614 /* If on NTFS versions before 3.0, we are done. */ 1989 - if (vol->major_ver < 3) 1615 + if (unlikely(vol->major_ver < 3)) 1990 1616 return TRUE; 1991 1617 /* NTFS 3.0+ specific initialization. */ 1992 1618 /* Get the security descriptors inode. */ ··· 1989 1631 ntfs_error(sb, "Failed to load $Secure."); 1990 1632 goto iput_root_err_out; 1991 1633 } 1992 - // FIXME: Initialize security. 1634 + // TODO: Initialize security. 1993 1635 /* Get the extended system files' directory inode. */ 1994 1636 vol->extend_ino = ntfs_iget(sb, FILE_Extend); 1995 1637 if (IS_ERR(vol->extend_ino) || is_bad_inode(vol->extend_ino)) { ··· 2040 1682 sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; 2041 1683 NVolSetErrors(vol); 2042 1684 } 2043 - // TODO: Delete or checkpoint the $UsnJrnl if it exists. 1685 + /* 1686 + * Find the transaction log file ($UsnJrnl), load it if present, check 1687 + * it, and set it up. 1688 + */ 1689 + if (!load_and_init_usnjrnl(vol)) { 1690 + static const char *es1 = "Failed to load $UsnJrnl"; 1691 + static const char *es2 = ". Run chkdsk."; 1692 + 1693 + /* If a read-write mount, convert it to a read-only mount. */ 1694 + if (!(sb->s_flags & MS_RDONLY)) { 1695 + if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO | 1696 + ON_ERRORS_CONTINUE))) { 1697 + ntfs_error(sb, "%s and neither on_errors=" 1698 + "continue nor on_errors=" 1699 + "remount-ro was specified%s", 1700 + es1, es2); 1701 + goto iput_usnjrnl_err_out; 1702 + } 1703 + sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; 1704 + ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); 1705 + } else 1706 + ntfs_warning(sb, "%s. Will not be able to remount " 1707 + "read-write%s", es1, es2); 1708 + /* This will prevent a read-write remount. */ 1709 + NVolSetErrors(vol); 1710 + } 1711 + /* If (still) a read-write mount, stamp the transaction log. */ 1712 + if (!(sb->s_flags & MS_RDONLY) && !ntfs_stamp_usnjrnl(vol)) { 1713 + static const char *es1 = "Failed to stamp transaction log " 1714 + "($UsnJrnl)"; 1715 + static const char *es2 = ". Run chkdsk."; 1716 + 1717 + /* Convert to a read-only mount. */ 1718 + if (!(vol->on_errors & (ON_ERRORS_REMOUNT_RO | 1719 + ON_ERRORS_CONTINUE))) { 1720 + ntfs_error(sb, "%s and neither on_errors=continue nor " 1721 + "on_errors=remount-ro was specified%s", 1722 + es1, es2); 1723 + goto iput_usnjrnl_err_out; 1724 + } 1725 + ntfs_error(sb, "%s. Mounting read-only%s", es1, es2); 1726 + sb->s_flags |= MS_RDONLY | MS_NOATIME | MS_NODIRATIME; 1727 + NVolSetErrors(vol); 1728 + } 2044 1729 #endif /* NTFS_RW */ 2045 1730 return TRUE; 2046 1731 #ifdef NTFS_RW 1732 + iput_usnjrnl_err_out: 1733 + if (vol->usnjrnl_j_ino) 1734 + iput(vol->usnjrnl_j_ino); 1735 + if (vol->usnjrnl_max_ino) 1736 + iput(vol->usnjrnl_max_ino); 1737 + if (vol->usnjrnl_ino) 1738 + iput(vol->usnjrnl_ino); 2047 1739 iput_quota_err_out: 2048 1740 if (vol->quota_q_ino) 2049 1741 iput(vol->quota_q_ino); ··· 2167 1759 2168 1760 /* NTFS 3.0+ specific. */ 2169 1761 if (vol->major_ver >= 3) { 1762 + if (vol->usnjrnl_j_ino) 1763 + ntfs_commit_inode(vol->usnjrnl_j_ino); 1764 + if (vol->usnjrnl_max_ino) 1765 + ntfs_commit_inode(vol->usnjrnl_max_ino); 1766 + if (vol->usnjrnl_ino) 1767 + ntfs_commit_inode(vol->usnjrnl_ino); 2170 1768 if (vol->quota_q_ino) 2171 1769 ntfs_commit_inode(vol->quota_q_ino); 2172 1770 if (vol->quota_ino) ··· 2228 1814 /* NTFS 3.0+ specific clean up. */ 2229 1815 if (vol->major_ver >= 3) { 2230 1816 #ifdef NTFS_RW 1817 + if (vol->usnjrnl_j_ino) { 1818 + iput(vol->usnjrnl_j_ino); 1819 + vol->usnjrnl_j_ino = NULL; 1820 + } 1821 + if (vol->usnjrnl_max_ino) { 1822 + iput(vol->usnjrnl_max_ino); 1823 + vol->usnjrnl_max_ino = NULL; 1824 + } 1825 + if (vol->usnjrnl_ino) { 1826 + iput(vol->usnjrnl_ino); 1827 + vol->usnjrnl_ino = NULL; 1828 + } 2231 1829 if (vol->quota_q_ino) { 2232 1830 iput(vol->quota_q_ino); 2233 1831 vol->quota_q_ino = NULL; ··· 2385 1959 struct address_space *mapping = vol->lcnbmp_ino->i_mapping; 2386 1960 filler_t *readpage = (filler_t*)mapping->a_ops->readpage; 2387 1961 struct page *page; 2388 - unsigned long index, max_index; 2389 - unsigned int max_size; 1962 + pgoff_t index, max_index; 2390 1963 2391 1964 ntfs_debug("Entering."); 2392 1965 /* Serialize accesses to the cluster bitmap. */ ··· 2397 1972 */ 2398 1973 max_index = (((vol->nr_clusters + 7) >> 3) + PAGE_CACHE_SIZE - 1) >> 2399 1974 PAGE_CACHE_SHIFT; 2400 - /* Use multiples of 4 bytes. */ 2401 - max_size = PAGE_CACHE_SIZE >> 2; 2402 - ntfs_debug("Reading $Bitmap, max_index = 0x%lx, max_size = 0x%x.", 2403 - max_index, max_size); 2404 - for (index = 0UL; index < max_index; index++) { 1975 + /* Use multiples of 4 bytes, thus max_size is PAGE_CACHE_SIZE / 4. */ 1976 + ntfs_debug("Reading $Bitmap, max_index = 0x%lx, max_size = 0x%lx.", 1977 + max_index, PAGE_CACHE_SIZE / 4); 1978 + for (index = 0; index < max_index; index++) { 2405 1979 unsigned int i; 2406 1980 /* 2407 1981 * Read the page from page cache, getting it from backing store ··· 2432 2008 * the result as all out of range bytes are set to zero by 2433 2009 * ntfs_readpage(). 2434 2010 */ 2435 - for (i = 0; i < max_size; i++) 2011 + for (i = 0; i < PAGE_CACHE_SIZE / 4; i++) 2436 2012 nr_free -= (s64)hweight32(kaddr[i]); 2437 2013 kunmap_atomic(kaddr, KM_USER0); 2438 2014 page_cache_release(page); ··· 2455 2031 /** 2456 2032 * __get_nr_free_mft_records - return the number of free inodes on a volume 2457 2033 * @vol: ntfs volume for which to obtain free inode count 2034 + * @nr_free: number of mft records in filesystem 2035 + * @max_index: maximum number of pages containing set bits 2458 2036 * 2459 2037 * Calculate the number of free mft records (inodes) on the mounted NTFS 2460 2038 * volume @vol. We actually calculate the number of mft records in use instead ··· 2469 2043 * 2470 2044 * NOTE: Caller must hold mftbmp_lock rw_semaphore for reading or writing. 2471 2045 */ 2472 - static unsigned long __get_nr_free_mft_records(ntfs_volume *vol) 2046 + static unsigned long __get_nr_free_mft_records(ntfs_volume *vol, 2047 + s64 nr_free, const pgoff_t max_index) 2473 2048 { 2474 - s64 nr_free; 2475 2049 u32 *kaddr; 2476 2050 struct address_space *mapping = vol->mftbmp_ino->i_mapping; 2477 2051 filler_t *readpage = (filler_t*)mapping->a_ops->readpage; 2478 2052 struct page *page; 2479 - unsigned long index, max_index; 2480 - unsigned int max_size; 2053 + pgoff_t index; 2481 2054 2482 2055 ntfs_debug("Entering."); 2483 - /* Number of mft records in file system (at this point in time). */ 2484 - nr_free = vol->mft_ino->i_size >> vol->mft_record_size_bits; 2485 - /* 2486 - * Convert the maximum number of set bits into bytes rounded up, then 2487 - * convert into multiples of PAGE_CACHE_SIZE, rounding up so that if we 2488 - * have one full and one partial page max_index = 2. 2489 - */ 2490 - max_index = ((((NTFS_I(vol->mft_ino)->initialized_size >> 2491 - vol->mft_record_size_bits) + 7) >> 3) + 2492 - PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; 2493 - /* Use multiples of 4 bytes. */ 2494 - max_size = PAGE_CACHE_SIZE >> 2; 2056 + /* Use multiples of 4 bytes, thus max_size is PAGE_CACHE_SIZE / 4. */ 2495 2057 ntfs_debug("Reading $MFT/$BITMAP, max_index = 0x%lx, max_size = " 2496 - "0x%x.", max_index, max_size); 2497 - for (index = 0UL; index < max_index; index++) { 2058 + "0x%lx.", max_index, PAGE_CACHE_SIZE / 4); 2059 + for (index = 0; index < max_index; index++) { 2498 2060 unsigned int i; 2499 2061 /* 2500 2062 * Read the page from page cache, getting it from backing store ··· 2514 2100 * the result as all out of range bytes are set to zero by 2515 2101 * ntfs_readpage(). 2516 2102 */ 2517 - for (i = 0; i < max_size; i++) 2103 + for (i = 0; i < PAGE_CACHE_SIZE / 4; i++) 2518 2104 nr_free -= (s64)hweight32(kaddr[i]); 2519 2105 kunmap_atomic(kaddr, KM_USER0); 2520 2106 page_cache_release(page); ··· 2548 2134 */ 2549 2135 static int ntfs_statfs(struct super_block *sb, struct kstatfs *sfs) 2550 2136 { 2551 - ntfs_volume *vol = NTFS_SB(sb); 2552 2137 s64 size; 2138 + ntfs_volume *vol = NTFS_SB(sb); 2139 + ntfs_inode *mft_ni = NTFS_I(vol->mft_ino); 2140 + pgoff_t max_index; 2141 + unsigned long flags; 2553 2142 2554 2143 ntfs_debug("Entering."); 2555 2144 /* Type of filesystem. */ ··· 2560 2143 /* Optimal transfer block size. */ 2561 2144 sfs->f_bsize = PAGE_CACHE_SIZE; 2562 2145 /* 2563 - * Total data blocks in file system in units of f_bsize and since 2146 + * Total data blocks in filesystem in units of f_bsize and since 2564 2147 * inodes are also stored in data blocs ($MFT is a file) this is just 2565 2148 * the total clusters. 2566 2149 */ 2567 2150 sfs->f_blocks = vol->nr_clusters << vol->cluster_size_bits >> 2568 2151 PAGE_CACHE_SHIFT; 2569 - /* Free data blocks in file system in units of f_bsize. */ 2152 + /* Free data blocks in filesystem in units of f_bsize. */ 2570 2153 size = get_nr_free_clusters(vol) << vol->cluster_size_bits >> 2571 2154 PAGE_CACHE_SHIFT; 2572 2155 if (size < 0LL) ··· 2575 2158 sfs->f_bavail = sfs->f_bfree = size; 2576 2159 /* Serialize accesses to the inode bitmap. */ 2577 2160 down_read(&vol->mftbmp_lock); 2578 - /* Number of inodes in file system (at this point in time). */ 2579 - sfs->f_files = vol->mft_ino->i_size >> vol->mft_record_size_bits; 2161 + read_lock_irqsave(&mft_ni->size_lock, flags); 2162 + size = i_size_read(vol->mft_ino) >> vol->mft_record_size_bits; 2163 + /* 2164 + * Convert the maximum number of set bits into bytes rounded up, then 2165 + * convert into multiples of PAGE_CACHE_SIZE, rounding up so that if we 2166 + * have one full and one partial page max_index = 2. 2167 + */ 2168 + max_index = ((((mft_ni->initialized_size >> vol->mft_record_size_bits) 2169 + + 7) >> 3) + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; 2170 + read_unlock_irqrestore(&mft_ni->size_lock, flags); 2171 + /* Number of inodes in filesystem (at this point in time). */ 2172 + sfs->f_files = size; 2580 2173 /* Free inodes in fs (based on current total count). */ 2581 - sfs->f_ffree = __get_nr_free_mft_records(vol); 2174 + sfs->f_ffree = __get_nr_free_mft_records(vol, size, max_index); 2582 2175 up_read(&vol->mftbmp_lock); 2583 2176 /* 2584 2177 * File system id. This is extremely *nix flavour dependent and even 2585 2178 * within Linux itself all fs do their own thing. I interpret this to 2586 2179 * mean a unique id associated with the mounted fs and not the id 2587 - * associated with the file system driver, the latter is already given 2588 - * by the file system type in sfs->f_type. Thus we use the 64-bit 2180 + * associated with the filesystem driver, the latter is already given 2181 + * by the filesystem type in sfs->f_type. Thus we use the 64-bit 2589 2182 * volume serial number splitting it into two 32-bit parts. We enter 2590 2183 * the least significant 32-bits in f_fsid[0] and the most significant 2591 2184 * 32-bits in f_fsid[1]. ··· 2646 2219 proc. */ 2647 2220 }; 2648 2221 2649 - 2650 2222 /** 2651 - * Declarations for NTFS specific export operations (fs/ntfs/namei.c). 2652 - */ 2653 - extern struct dentry *ntfs_get_parent(struct dentry *child_dent); 2654 - extern struct dentry *ntfs_get_dentry(struct super_block *sb, void *fh); 2655 - 2656 - /** 2657 - * Export operations allowing NFS exporting of mounted NTFS partitions. 2658 - * 2659 - * We use the default ->decode_fh() and ->encode_fh() for now. Note that they 2660 - * use 32 bits to store the inode number which is an unsigned long so on 64-bit 2661 - * architectures is usually 64 bits so it would all fail horribly on huge 2662 - * volumes. I guess we need to define our own encode and decode fh functions 2663 - * that store 64-bit inode numbers at some point but for now we will ignore the 2664 - * problem... 2665 - * 2666 - * We also use the default ->get_name() helper (used by ->decode_fh() via 2667 - * fs/exportfs/expfs.c::find_exported_dentry()) as that is completely fs 2668 - * independent. 2669 - * 2670 - * The default ->get_parent() just returns -EACCES so we have to provide our 2671 - * own and the default ->get_dentry() is incompatible with NTFS due to not 2672 - * allowing the inode number 0 which is used in NTFS for the system file $MFT 2673 - * and due to using iget() whereas NTFS needs ntfs_iget(). 2674 - */ 2675 - static struct export_operations ntfs_export_ops = { 2676 - .get_parent = ntfs_get_parent, /* Find the parent of a given 2677 - directory. */ 2678 - .get_dentry = ntfs_get_dentry, /* Find a dentry for the inode 2679 - given a file handle 2680 - sub-fragment. */ 2681 - }; 2682 - 2683 - /** 2684 - * ntfs_fill_super - mount an ntfs files system 2685 - * @sb: super block of ntfs file system to mount 2223 + * ntfs_fill_super - mount an ntfs filesystem 2224 + * @sb: super block of ntfs filesystem to mount 2686 2225 * @opt: string containing the mount options 2687 2226 * @silent: silence error output 2688 2227 * 2689 2228 * ntfs_fill_super() is called by the VFS to mount the device described by @sb 2690 - * with the mount otions in @data with the NTFS file system. 2229 + * with the mount otions in @data with the NTFS filesystem. 2691 2230 * 2692 2231 * If @silent is true, remain silent even if errors are detected. This is used 2693 - * during bootup, when the kernel tries to mount the root file system with all 2694 - * registered file systems one after the other until one succeeds. This implies 2695 - * that all file systems except the correct one will quite correctly and 2232 + * during bootup, when the kernel tries to mount the root filesystem with all 2233 + * registered filesystems one after the other until one succeeds. This implies 2234 + * that all filesystems except the correct one will quite correctly and 2696 2235 * expectedly return an error, but nobody wants to see error messages when in 2697 2236 * fact this is what is supposed to happen. 2698 2237 * ··· 2685 2292 return -ENOMEM; 2686 2293 } 2687 2294 /* Initialize ntfs_volume structure. */ 2688 - memset(vol, 0, sizeof(ntfs_volume)); 2689 - vol->sb = sb; 2690 - vol->upcase = NULL; 2691 - vol->attrdef = NULL; 2692 - vol->mft_ino = NULL; 2693 - vol->mftbmp_ino = NULL; 2295 + *vol = (ntfs_volume) { 2296 + .sb = sb, 2297 + /* 2298 + * Default is group and other don't have any access to files or 2299 + * directories while owner has full access. Further, files by 2300 + * default are not executable but directories are of course 2301 + * browseable. 2302 + */ 2303 + .fmask = 0177, 2304 + .dmask = 0077, 2305 + }; 2694 2306 init_rwsem(&vol->mftbmp_lock); 2695 - #ifdef NTFS_RW 2696 - vol->mftmirr_ino = NULL; 2697 - vol->logfile_ino = NULL; 2698 - #endif /* NTFS_RW */ 2699 - vol->lcnbmp_ino = NULL; 2700 2307 init_rwsem(&vol->lcnbmp_lock); 2701 - vol->vol_ino = NULL; 2702 - vol->root_ino = NULL; 2703 - vol->secure_ino = NULL; 2704 - vol->extend_ino = NULL; 2705 - #ifdef NTFS_RW 2706 - vol->quota_ino = NULL; 2707 - vol->quota_q_ino = NULL; 2708 - #endif /* NTFS_RW */ 2709 - vol->nls_map = NULL; 2710 - 2711 - /* 2712 - * Default is group and other don't have any access to files or 2713 - * directories while owner has full access. Further, files by default 2714 - * are not executable but directories are of course browseable. 2715 - */ 2716 - vol->fmask = 0177; 2717 - vol->dmask = 0077; 2718 2308 2719 2309 unlock_kernel(); 2310 + 2311 + /* By default, enable sparse support. */ 2312 + NVolSetSparseEnabled(vol); 2720 2313 2721 2314 /* Important to get the mount options dealt with now. */ 2722 2315 if (!parse_options(vol, (char*)opt)) ··· 2726 2347 } 2727 2348 2728 2349 /* Get the size of the device in units of NTFS_BLOCK_SIZE bytes. */ 2729 - vol->nr_blocks = sb->s_bdev->bd_inode->i_size >> NTFS_BLOCK_SIZE_BITS; 2350 + vol->nr_blocks = i_size_read(sb->s_bdev->bd_inode) >> 2351 + NTFS_BLOCK_SIZE_BITS; 2730 2352 2731 2353 /* Read the boot sector and return unlocked buffer head to it. */ 2732 2354 if (!(bh = read_ntfs_boot_sector(sb, silent))) { ··· 2856 2476 /* NTFS 3.0+ specific clean up. */ 2857 2477 if (vol->major_ver >= 3) { 2858 2478 #ifdef NTFS_RW 2479 + if (vol->usnjrnl_j_ino) { 2480 + iput(vol->usnjrnl_j_ino); 2481 + vol->usnjrnl_j_ino = NULL; 2482 + } 2483 + if (vol->usnjrnl_max_ino) { 2484 + iput(vol->usnjrnl_max_ino); 2485 + vol->usnjrnl_max_ino = NULL; 2486 + } 2487 + if (vol->usnjrnl_ino) { 2488 + iput(vol->usnjrnl_ino); 2489 + vol->usnjrnl_ino = NULL; 2490 + } 2859 2491 if (vol->quota_q_ino) { 2860 2492 iput(vol->quota_q_ino); 2861 2493 vol->quota_q_ino = NULL; ··· 2973 2581 */ 2974 2582 kmem_cache_t *ntfs_name_cache; 2975 2583 2976 - /* Slab caches for efficient allocation/deallocation of of inodes. */ 2584 + /* Slab caches for efficient allocation/deallocation of inodes. */ 2977 2585 kmem_cache_t *ntfs_inode_cache; 2978 2586 kmem_cache_t *ntfs_big_inode_cache; 2979 2587 ··· 3097 2705 ntfs_debug("NTFS driver registered successfully."); 3098 2706 return 0; /* Success! */ 3099 2707 } 3100 - printk(KERN_CRIT "NTFS: Failed to register NTFS file system driver!\n"); 2708 + printk(KERN_CRIT "NTFS: Failed to register NTFS filesystem driver!\n"); 3101 2709 3102 2710 sysctl_err_out: 3103 2711 kmem_cache_destroy(ntfs_big_inode_cache); ··· 3111 2719 kmem_cache_destroy(ntfs_index_ctx_cache); 3112 2720 ictx_err_out: 3113 2721 if (!err) { 3114 - printk(KERN_CRIT "NTFS: Aborting NTFS file system driver " 2722 + printk(KERN_CRIT "NTFS: Aborting NTFS filesystem driver " 3115 2723 "registration...\n"); 3116 2724 err = -ENOMEM; 3117 2725 } ··· 3151 2759 } 3152 2760 3153 2761 MODULE_AUTHOR("Anton Altaparmakov <aia21@cantab.net>"); 3154 - MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2004 Anton Altaparmakov"); 2762 + MODULE_DESCRIPTION("NTFS 1.2/3.x driver - Copyright (c) 2001-2005 Anton Altaparmakov"); 3155 2763 MODULE_VERSION(NTFS_VERSION); 3156 2764 MODULE_LICENSE("GPL"); 3157 2765 #ifdef DEBUG
+2 -2
fs/ntfs/sysctl.c
··· 3 3 * the Linux-NTFS project. Adapted from the old NTFS driver, 4 4 * Copyright (C) 1997 Martin von L�wis, R�gis Duchesne 5 5 * 6 - * Copyright (c) 2002-2004 Anton Altaparmakov 6 + * Copyright (c) 2002-2005 Anton Altaparmakov 7 7 * 8 8 * This program/include file is free software; you can redistribute it and/or 9 9 * modify it under the terms of the GNU General Public License as published ··· 67 67 return -ENOMEM; 68 68 #ifdef CONFIG_PROC_FS 69 69 /* 70 - * If the proc file system is in use and we are a module, need 70 + * If the proc filesystem is in use and we are a module, need 71 71 * to set the owner of our proc entry to our module. In the 72 72 * non-modular case, THIS_MODULE is NULL, so this is ok. 73 73 */
+2 -2
fs/ntfs/time.h
··· 1 1 /* 2 2 * time.h - NTFS time conversion functions. Part of the Linux-NTFS project. 3 3 * 4 - * Copyright (c) 2001-2004 Anton Altaparmakov 4 + * Copyright (c) 2001-2005 Anton Altaparmakov 5 5 * 6 6 * This program/include file is free software; you can redistribute it and/or 7 7 * modify it under the terms of the GNU General Public License as published ··· 87 87 struct timespec ts; 88 88 89 89 /* Subtract the NTFS time offset. */ 90 - s64 t = sle64_to_cpu(time) - NTFS_TIME_OFFSET; 90 + u64 t = (u64)(sle64_to_cpu(time) - NTFS_TIME_OFFSET); 91 91 /* 92 92 * Convert the time to 1-second intervals and the remainder to 93 93 * 1-nano-second intervals.
+9 -1
fs/ntfs/types.h
··· 2 2 * types.h - Defines for NTFS Linux kernel driver specific types. 3 3 * Part of the Linux-NTFS project. 4 4 * 5 - * Copyright (c) 2001-2004 Anton Altaparmakov 5 + * Copyright (c) 2001-2005 Anton Altaparmakov 6 6 * 7 7 * This program/include file is free software; you can redistribute it and/or 8 8 * modify it under the terms of the GNU General Public License as published ··· 52 52 */ 53 53 typedef s64 LSN; 54 54 typedef sle64 leLSN; 55 + 56 + /* 57 + * The NTFS transaction log $UsnJrnl uses usn which are signed 64-bit values. 58 + * We define our own type USN, to allow for type checking and better code 59 + * readability. 60 + */ 61 + typedef s64 USN; 62 + typedef sle64 leUSN; 55 63 56 64 typedef enum { 57 65 FALSE = 0,
+1 -1
fs/ntfs/unistr.c
··· 264 264 265 265 /* We don't trust outside sources. */ 266 266 if (ins) { 267 - ucs = (ntfschar*)kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS); 267 + ucs = kmem_cache_alloc(ntfs_name_cache, SLAB_NOFS); 268 268 if (ucs) { 269 269 for (i = o = 0; i < ins_len; i += wc_len) { 270 270 wc_len = nls->char2uni(ins + i, ins_len - i,
+84
fs/ntfs/usnjrnl.c
··· 1 + /* 2 + * usnjrnl.h - NTFS kernel transaction log ($UsnJrnl) handling. Part of the 3 + * Linux-NTFS project. 4 + * 5 + * Copyright (c) 2005 Anton Altaparmakov 6 + * 7 + * This program/include file is free software; you can redistribute it and/or 8 + * modify it under the terms of the GNU General Public License as published 9 + * by the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program/include file is distributed in the hope that it will be 13 + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 14 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program (in the main directory of the Linux-NTFS 19 + * distribution in the file COPYING); if not, write to the Free Software 20 + * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 + */ 22 + 23 + #ifdef NTFS_RW 24 + 25 + #include <linux/fs.h> 26 + #include <linux/highmem.h> 27 + #include <linux/mm.h> 28 + 29 + #include "aops.h" 30 + #include "debug.h" 31 + #include "endian.h" 32 + #include "time.h" 33 + #include "types.h" 34 + #include "usnjrnl.h" 35 + #include "volume.h" 36 + 37 + /** 38 + * ntfs_stamp_usnjrnl - stamp the transaction log ($UsnJrnl) on an ntfs volume 39 + * @vol: ntfs volume on which to stamp the transaction log 40 + * 41 + * Stamp the transaction log ($UsnJrnl) on the ntfs volume @vol and return 42 + * TRUE on success and FALSE on error. 43 + * 44 + * This function assumes that the transaction log has already been loaded and 45 + * consistency checked by a call to fs/ntfs/super.c::load_and_init_usnjrnl(). 46 + */ 47 + BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol) 48 + { 49 + ntfs_debug("Entering."); 50 + if (likely(!NVolUsnJrnlStamped(vol))) { 51 + sle64 stamp; 52 + struct page *page; 53 + USN_HEADER *uh; 54 + 55 + page = ntfs_map_page(vol->usnjrnl_max_ino->i_mapping, 0); 56 + if (IS_ERR(page)) { 57 + ntfs_error(vol->sb, "Failed to read from " 58 + "$UsnJrnl/$DATA/$Max attribute."); 59 + return FALSE; 60 + } 61 + uh = (USN_HEADER*)page_address(page); 62 + stamp = get_current_ntfs_time(); 63 + ntfs_debug("Stamping transaction log ($UsnJrnl): old " 64 + "journal_id 0x%llx, old lowest_valid_usn " 65 + "0x%llx, new journal_id 0x%llx, new " 66 + "lowest_valid_usn 0x%llx.", 67 + (long long)sle64_to_cpu(uh->journal_id), 68 + (long long)sle64_to_cpu(uh->lowest_valid_usn), 69 + (long long)sle64_to_cpu(stamp), 70 + i_size_read(vol->usnjrnl_j_ino)); 71 + uh->lowest_valid_usn = 72 + cpu_to_sle64(i_size_read(vol->usnjrnl_j_ino)); 73 + uh->journal_id = stamp; 74 + flush_dcache_page(page); 75 + set_page_dirty(page); 76 + ntfs_unmap_page(page); 77 + /* Set the flag so we do not have to do it again on remount. */ 78 + NVolSetUsnJrnlStamped(vol); 79 + } 80 + ntfs_debug("Done."); 81 + return TRUE; 82 + } 83 + 84 + #endif /* NTFS_RW */
+205
fs/ntfs/usnjrnl.h
··· 1 + /* 2 + * usnjrnl.h - Defines for NTFS kernel transaction log ($UsnJrnl) handling. 3 + * Part of the Linux-NTFS project. 4 + * 5 + * Copyright (c) 2005 Anton Altaparmakov 6 + * 7 + * This program/include file is free software; you can redistribute it and/or 8 + * modify it under the terms of the GNU General Public License as published 9 + * by the Free Software Foundation; either version 2 of the License, or 10 + * (at your option) any later version. 11 + * 12 + * This program/include file is distributed in the hope that it will be 13 + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty 14 + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + * GNU General Public License for more details. 16 + * 17 + * You should have received a copy of the GNU General Public License 18 + * along with this program (in the main directory of the Linux-NTFS 19 + * distribution in the file COPYING); if not, write to the Free Software 20 + * Foundation,Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 + */ 22 + 23 + #ifndef _LINUX_NTFS_USNJRNL_H 24 + #define _LINUX_NTFS_USNJRNL_H 25 + 26 + #ifdef NTFS_RW 27 + 28 + #include "types.h" 29 + #include "endian.h" 30 + #include "layout.h" 31 + #include "volume.h" 32 + 33 + /* 34 + * Transaction log ($UsnJrnl) organization: 35 + * 36 + * The transaction log records whenever a file is modified in any way. So for 37 + * example it will record that file "blah" was written to at a particular time 38 + * but not what was written. If will record that a file was deleted or 39 + * created, that a file was truncated, etc. See below for all the reason 40 + * codes used. 41 + * 42 + * The transaction log is in the $Extend directory which is in the root 43 + * directory of each volume. If it is not present it means transaction 44 + * logging is disabled. If it is present it means transaction logging is 45 + * either enabled or in the process of being disabled in which case we can 46 + * ignore it as it will go away as soon as Windows gets its hands on it. 47 + * 48 + * To determine whether the transaction logging is enabled or in the process 49 + * of being disabled, need to check the volume flags in the 50 + * $VOLUME_INFORMATION attribute in the $Volume system file (which is present 51 + * in the root directory and has a fixed mft record number, see layout.h). 52 + * If the flag VOLUME_DELETE_USN_UNDERWAY is set it means the transaction log 53 + * is in the process of being disabled and if this flag is clear it means the 54 + * transaction log is enabled. 55 + * 56 + * The transaction log consists of two parts; the $DATA/$Max attribute as well 57 + * as the $DATA/$J attribute. $Max is a header describing the transaction 58 + * log whilst $J is the transaction log data itself as a sequence of variable 59 + * sized USN_RECORDs (see below for all the structures). 60 + * 61 + * We do not care about transaction logging at this point in time but we still 62 + * need to let windows know that the transaction log is out of date. To do 63 + * this we need to stamp the transaction log. This involves setting the 64 + * lowest_valid_usn field in the $DATA/$Max attribute to the usn to be used 65 + * for the next added USN_RECORD to the $DATA/$J attribute as well as 66 + * generating a new journal_id in $DATA/$Max. 67 + * 68 + * The journal_id is as of the current version (2.0) of the transaction log 69 + * simply the 64-bit timestamp of when the journal was either created or last 70 + * stamped. 71 + * 72 + * To determine the next usn there are two ways. The first is to parse 73 + * $DATA/$J and to find the last USN_RECORD in it and to add its record_length 74 + * to its usn (which is the byte offset in the $DATA/$J attribute). The 75 + * second is simply to take the data size of the attribute. Since the usns 76 + * are simply byte offsets into $DATA/$J, this is exactly the next usn. For 77 + * obvious reasons we use the second method as it is much simpler and faster. 78 + * 79 + * As an aside, note that to actually disable the transaction log, one would 80 + * need to set the VOLUME_DELETE_USN_UNDERWAY flag (see above), then go 81 + * through all the mft records on the volume and set the usn field in their 82 + * $STANDARD_INFORMATION attribute to zero. Once that is done, one would need 83 + * to delete the transaction log file, i.e. \$Extent\$UsnJrnl, and finally, 84 + * one would need to clear the VOLUME_DELETE_USN_UNDERWAY flag. 85 + * 86 + * Note that if a volume is unmounted whilst the transaction log is being 87 + * disabled, the process will continue the next time the volume is mounted. 88 + * This is why we can safely mount read-write when we see a transaction log 89 + * in the process of being deleted. 90 + */ 91 + 92 + /* Some $UsnJrnl related constants. */ 93 + #define UsnJrnlMajorVer 2 94 + #define UsnJrnlMinorVer 0 95 + 96 + /* 97 + * $DATA/$Max attribute. This is (always?) resident and has a fixed size of 98 + * 32 bytes. It contains the header describing the transaction log. 99 + */ 100 + typedef struct { 101 + /*Ofs*/ 102 + /* 0*/sle64 maximum_size; /* The maximum on-disk size of the $DATA/$J 103 + attribute. */ 104 + /* 8*/sle64 allocation_delta; /* Number of bytes by which to increase the 105 + size of the $DATA/$J attribute. */ 106 + /*0x10*/sle64 journal_id; /* Current id of the transaction log. */ 107 + /*0x18*/leUSN lowest_valid_usn; /* Lowest valid usn in $DATA/$J for the 108 + current journal_id. */ 109 + /* sizeof() = 32 (0x20) bytes */ 110 + } __attribute__ ((__packed__)) USN_HEADER; 111 + 112 + /* 113 + * Reason flags (32-bit). Cumulative flags describing the change(s) to the 114 + * file since it was last opened. I think the names speak for themselves but 115 + * if you disagree check out the descriptions in the Linux NTFS project NTFS 116 + * documentation: http://linux-ntfs.sourceforge.net/ntfs/files/usnjrnl.html 117 + */ 118 + enum { 119 + USN_REASON_DATA_OVERWRITE = const_cpu_to_le32(0x00000001), 120 + USN_REASON_DATA_EXTEND = const_cpu_to_le32(0x00000002), 121 + USN_REASON_DATA_TRUNCATION = const_cpu_to_le32(0x00000004), 122 + USN_REASON_NAMED_DATA_OVERWRITE = const_cpu_to_le32(0x00000010), 123 + USN_REASON_NAMED_DATA_EXTEND = const_cpu_to_le32(0x00000020), 124 + USN_REASON_NAMED_DATA_TRUNCATION= const_cpu_to_le32(0x00000040), 125 + USN_REASON_FILE_CREATE = const_cpu_to_le32(0x00000100), 126 + USN_REASON_FILE_DELETE = const_cpu_to_le32(0x00000200), 127 + USN_REASON_EA_CHANGE = const_cpu_to_le32(0x00000400), 128 + USN_REASON_SECURITY_CHANGE = const_cpu_to_le32(0x00000800), 129 + USN_REASON_RENAME_OLD_NAME = const_cpu_to_le32(0x00001000), 130 + USN_REASON_RENAME_NEW_NAME = const_cpu_to_le32(0x00002000), 131 + USN_REASON_INDEXABLE_CHANGE = const_cpu_to_le32(0x00004000), 132 + USN_REASON_BASIC_INFO_CHANGE = const_cpu_to_le32(0x00008000), 133 + USN_REASON_HARD_LINK_CHANGE = const_cpu_to_le32(0x00010000), 134 + USN_REASON_COMPRESSION_CHANGE = const_cpu_to_le32(0x00020000), 135 + USN_REASON_ENCRYPTION_CHANGE = const_cpu_to_le32(0x00040000), 136 + USN_REASON_OBJECT_ID_CHANGE = const_cpu_to_le32(0x00080000), 137 + USN_REASON_REPARSE_POINT_CHANGE = const_cpu_to_le32(0x00100000), 138 + USN_REASON_STREAM_CHANGE = const_cpu_to_le32(0x00200000), 139 + USN_REASON_CLOSE = const_cpu_to_le32(0x80000000), 140 + }; 141 + 142 + typedef le32 USN_REASON_FLAGS; 143 + 144 + /* 145 + * Source info flags (32-bit). Information about the source of the change(s) 146 + * to the file. For detailed descriptions of what these mean, see the Linux 147 + * NTFS project NTFS documentation: 148 + * http://linux-ntfs.sourceforge.net/ntfs/files/usnjrnl.html 149 + */ 150 + enum { 151 + USN_SOURCE_DATA_MANAGEMENT = const_cpu_to_le32(0x00000001), 152 + USN_SOURCE_AUXILIARY_DATA = const_cpu_to_le32(0x00000002), 153 + USN_SOURCE_REPLICATION_MANAGEMENT = const_cpu_to_le32(0x00000004), 154 + }; 155 + 156 + typedef le32 USN_SOURCE_INFO_FLAGS; 157 + 158 + /* 159 + * $DATA/$J attribute. This is always non-resident, is marked as sparse, and 160 + * is of variabled size. It consists of a sequence of variable size 161 + * USN_RECORDS. The minimum allocated_size is allocation_delta as 162 + * specified in $DATA/$Max. When the maximum_size specified in $DATA/$Max is 163 + * exceeded by more than allocation_delta bytes, allocation_delta bytes are 164 + * allocated and appended to the $DATA/$J attribute and an equal number of 165 + * bytes at the beginning of the attribute are freed and made sparse. Note the 166 + * making sparse only happens at volume checkpoints and hence the actual 167 + * $DATA/$J size can exceed maximum_size + allocation_delta temporarily. 168 + */ 169 + typedef struct { 170 + /*Ofs*/ 171 + /* 0*/le32 length; /* Byte size of this record (8-byte 172 + aligned). */ 173 + /* 4*/le16 major_ver; /* Major version of the transaction log used 174 + for this record. */ 175 + /* 6*/le16 minor_ver; /* Minor version of the transaction log used 176 + for this record. */ 177 + /* 8*/leMFT_REF mft_reference;/* The mft reference of the file (or 178 + directory) described by this record. */ 179 + /*0x10*/leMFT_REF parent_directory;/* The mft reference of the parent 180 + directory of the file described by this 181 + record. */ 182 + /*0x18*/leUSN usn; /* The usn of this record. Equals the offset 183 + within the $DATA/$J attribute. */ 184 + /*0x20*/sle64 time; /* Time when this record was created. */ 185 + /*0x28*/USN_REASON_FLAGS reason;/* Reason flags (see above). */ 186 + /*0x2c*/USN_SOURCE_INFO_FLAGS source_info;/* Source info flags (see above). */ 187 + /*0x30*/le32 security_id; /* File security_id copied from 188 + $STANDARD_INFORMATION. */ 189 + /*0x34*/FILE_ATTR_FLAGS file_attributes; /* File attributes copied from 190 + $STANDARD_INFORMATION or $FILE_NAME (not 191 + sure which). */ 192 + /*0x38*/le16 file_name_size; /* Size of the file name in bytes. */ 193 + /*0x3a*/le16 file_name_offset; /* Offset to the file name in bytes from the 194 + start of this record. */ 195 + /*0x3c*/ntfschar file_name[0]; /* Use when creating only. When reading use 196 + file_name_offset to determine the location 197 + of the name. */ 198 + /* sizeof() = 60 (0x3c) bytes */ 199 + } __attribute__ ((__packed__)) USN_RECORD; 200 + 201 + extern BOOL ntfs_stamp_usnjrnl(ntfs_volume *vol); 202 + 203 + #endif /* NTFS_RW */ 204 + 205 + #endif /* _LINUX_NTFS_USNJRNL_H */
+10 -2
fs/ntfs/volume.h
··· 2 2 * volume.h - Defines for volume structures in NTFS Linux kernel driver. Part 3 3 * of the Linux-NTFS project. 4 4 * 5 - * Copyright (c) 2001-2004 Anton Altaparmakov 5 + * Copyright (c) 2001-2005 Anton Altaparmakov 6 6 * Copyright (c) 2002 Richard Russon 7 7 * 8 8 * This program/include file is free software; you can redistribute it and/or ··· 54 54 mode_t dmask; /* The mask for directory 55 55 permissions. */ 56 56 u8 mft_zone_multiplier; /* Initial mft zone multiplier. */ 57 - u8 on_errors; /* What to do on file system errors. */ 57 + u8 on_errors; /* What to do on filesystem errors. */ 58 58 /* NTFS bootsector provided information. */ 59 59 u16 sector_size; /* in bytes */ 60 60 u8 sector_size_bits; /* log2(sector_size) */ ··· 125 125 /* $Quota stuff is NTFS3.0+ specific. Unused/NULL otherwise. */ 126 126 struct inode *quota_ino; /* The VFS inode of $Quota. */ 127 127 struct inode *quota_q_ino; /* Attribute inode for $Quota/$Q. */ 128 + /* $UsnJrnl stuff is NTFS3.0+ specific. Unused/NULL otherwise. */ 129 + struct inode *usnjrnl_ino; /* The VFS inode of $UsnJrnl. */ 130 + struct inode *usnjrnl_max_ino; /* Attribute inode for $UsnJrnl/$Max. */ 131 + struct inode *usnjrnl_j_ino; /* Attribute inode for $UsnJrnl/$J. */ 128 132 #endif /* NTFS_RW */ 129 133 struct nls_table *nls_map; 130 134 } ntfs_volume; ··· 145 141 file names in WIN32 namespace. */ 146 142 NV_LogFileEmpty, /* 1: $LogFile journal is empty. */ 147 143 NV_QuotaOutOfDate, /* 1: $Quota is out of date. */ 144 + NV_UsnJrnlStamped, /* 1: $UsnJrnl has been stamped. */ 145 + NV_SparseEnabled, /* 1: May create sparse files. */ 148 146 } ntfs_volume_flags; 149 147 150 148 /* ··· 173 167 NVOL_FNS(CaseSensitive) 174 168 NVOL_FNS(LogFileEmpty) 175 169 NVOL_FNS(QuotaOutOfDate) 170 + NVOL_FNS(UsnJrnlStamped) 171 + NVOL_FNS(SparseEnabled) 176 172 177 173 #endif /* _LINUX_NTFS_VOLUME_H */