diff options
Diffstat (limited to 'fs/ntfs/aops.c')
| -rw-r--r-- | fs/ntfs/aops.c | 294 |
1 files changed, 170 insertions, 124 deletions
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c index 78adad7a988d..b6cc8cf24626 100644 --- a/fs/ntfs/aops.c +++ b/fs/ntfs/aops.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/swap.h> | 27 | #include <linux/swap.h> |
| 28 | #include <linux/buffer_head.h> | 28 | #include <linux/buffer_head.h> |
| 29 | #include <linux/writeback.h> | 29 | #include <linux/writeback.h> |
| 30 | #include <linux/bit_spinlock.h> | ||
| 30 | 31 | ||
| 31 | #include "aops.h" | 32 | #include "aops.h" |
| 32 | #include "attrib.h" | 33 | #include "attrib.h" |
| @@ -55,9 +56,8 @@ | |||
| 55 | */ | 56 | */ |
| 56 | static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) | 57 | static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) |
| 57 | { | 58 | { |
| 58 | static DEFINE_SPINLOCK(page_uptodate_lock); | ||
| 59 | unsigned long flags; | 59 | unsigned long flags; |
| 60 | struct buffer_head *tmp; | 60 | struct buffer_head *first, *tmp; |
| 61 | struct page *page; | 61 | struct page *page; |
| 62 | ntfs_inode *ni; | 62 | ntfs_inode *ni; |
| 63 | int page_uptodate = 1; | 63 | int page_uptodate = 1; |
| @@ -89,11 +89,13 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) | |||
| 89 | } | 89 | } |
| 90 | } else { | 90 | } else { |
| 91 | clear_buffer_uptodate(bh); | 91 | clear_buffer_uptodate(bh); |
| 92 | SetPageError(page); | ||
| 92 | ntfs_error(ni->vol->sb, "Buffer I/O error, logical block %llu.", | 93 | ntfs_error(ni->vol->sb, "Buffer I/O error, logical block %llu.", |
| 93 | (unsigned long long)bh->b_blocknr); | 94 | (unsigned long long)bh->b_blocknr); |
| 94 | SetPageError(page); | ||
| 95 | } | 95 | } |
| 96 | spin_lock_irqsave(&page_uptodate_lock, flags); | 96 | first = page_buffers(page); |
| 97 | local_irq_save(flags); | ||
| 98 | bit_spin_lock(BH_Uptodate_Lock, &first->b_state); | ||
| 97 | clear_buffer_async_read(bh); | 99 | clear_buffer_async_read(bh); |
| 98 | unlock_buffer(bh); | 100 | unlock_buffer(bh); |
| 99 | tmp = bh; | 101 | tmp = bh; |
| @@ -108,7 +110,8 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) | |||
| 108 | } | 110 | } |
| 109 | tmp = tmp->b_this_page; | 111 | tmp = tmp->b_this_page; |
| 110 | } while (tmp != bh); | 112 | } while (tmp != bh); |
| 111 | spin_unlock_irqrestore(&page_uptodate_lock, flags); | 113 | bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); |
| 114 | local_irq_restore(flags); | ||
| 112 | /* | 115 | /* |
| 113 | * If none of the buffers had errors then we can set the page uptodate, | 116 | * If none of the buffers had errors then we can set the page uptodate, |
| 114 | * but we first have to perform the post read mst fixups, if the | 117 | * but we first have to perform the post read mst fixups, if the |
| @@ -141,7 +144,8 @@ static void ntfs_end_buffer_async_read(struct buffer_head *bh, int uptodate) | |||
| 141 | unlock_page(page); | 144 | unlock_page(page); |
| 142 | return; | 145 | return; |
| 143 | still_busy: | 146 | still_busy: |
| 144 | spin_unlock_irqrestore(&page_uptodate_lock, flags); | 147 | bit_spin_unlock(BH_Uptodate_Lock, &first->b_state); |
| 148 | local_irq_restore(flags); | ||
| 145 | return; | 149 | return; |
| 146 | } | 150 | } |
| 147 | 151 | ||
| @@ -185,13 +189,15 @@ static int ntfs_read_block(struct page *page) | |||
| 185 | blocksize_bits = VFS_I(ni)->i_blkbits; | 189 | blocksize_bits = VFS_I(ni)->i_blkbits; |
| 186 | blocksize = 1 << blocksize_bits; | 190 | blocksize = 1 << blocksize_bits; |
| 187 | 191 | ||
| 188 | if (!page_has_buffers(page)) | 192 | if (!page_has_buffers(page)) { |
| 189 | create_empty_buffers(page, blocksize, 0); | 193 | create_empty_buffers(page, blocksize, 0); |
| 190 | bh = head = page_buffers(page); | 194 | if (unlikely(!page_has_buffers(page))) { |
| 191 | if (unlikely(!bh)) { | 195 | unlock_page(page); |
| 192 | unlock_page(page); | 196 | return -ENOMEM; |
| 193 | return -ENOMEM; | 197 | } |
| 194 | } | 198 | } |
| 199 | bh = head = page_buffers(page); | ||
| 200 | BUG_ON(!bh); | ||
| 195 | 201 | ||
| 196 | iblock = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits); | 202 | iblock = (s64)page->index << (PAGE_CACHE_SHIFT - blocksize_bits); |
| 197 | read_lock_irqsave(&ni->size_lock, flags); | 203 | read_lock_irqsave(&ni->size_lock, flags); |
| @@ -204,6 +210,7 @@ static int ntfs_read_block(struct page *page) | |||
| 204 | nr = i = 0; | 210 | nr = i = 0; |
| 205 | do { | 211 | do { |
| 206 | u8 *kaddr; | 212 | u8 *kaddr; |
| 213 | int err; | ||
| 207 | 214 | ||
| 208 | if (unlikely(buffer_uptodate(bh))) | 215 | if (unlikely(buffer_uptodate(bh))) |
| 209 | continue; | 216 | continue; |
| @@ -211,6 +218,7 @@ static int ntfs_read_block(struct page *page) | |||
| 211 | arr[nr++] = bh; | 218 | arr[nr++] = bh; |
| 212 | continue; | 219 | continue; |
| 213 | } | 220 | } |
| 221 | err = 0; | ||
| 214 | bh->b_bdev = vol->sb->s_bdev; | 222 | bh->b_bdev = vol->sb->s_bdev; |
| 215 | /* Is the block within the allowed limits? */ | 223 | /* Is the block within the allowed limits? */ |
| 216 | if (iblock < lblock) { | 224 | if (iblock < lblock) { |
| @@ -252,7 +260,6 @@ lock_retry_remap: | |||
| 252 | goto handle_hole; | 260 | goto handle_hole; |
| 253 | /* If first try and runlist unmapped, map and retry. */ | 261 | /* If first try and runlist unmapped, map and retry. */ |
| 254 | if (!is_retry && lcn == LCN_RL_NOT_MAPPED) { | 262 | if (!is_retry && lcn == LCN_RL_NOT_MAPPED) { |
| 255 | int err; | ||
| 256 | is_retry = TRUE; | 263 | is_retry = TRUE; |
| 257 | /* | 264 | /* |
| 258 | * Attempt to map runlist, dropping lock for | 265 | * Attempt to map runlist, dropping lock for |
| @@ -263,20 +270,30 @@ lock_retry_remap: | |||
| 263 | if (likely(!err)) | 270 | if (likely(!err)) |
| 264 | goto lock_retry_remap; | 271 | goto lock_retry_remap; |
| 265 | rl = NULL; | 272 | rl = NULL; |
| 266 | lcn = err; | ||
| 267 | } else if (!rl) | 273 | } else if (!rl) |
| 268 | up_read(&ni->runlist.lock); | 274 | up_read(&ni->runlist.lock); |
| 275 | /* | ||
| 276 | * If buffer is outside the runlist, treat it as a | ||
| 277 | * hole. This can happen due to concurrent truncate | ||
| 278 | * for example. | ||
| 279 | */ | ||
| 280 | if (err == -ENOENT || lcn == LCN_ENOENT) { | ||
| 281 | err = 0; | ||
| 282 | goto handle_hole; | ||
| 283 | } | ||
| 269 | /* Hard error, zero out region. */ | 284 | /* Hard error, zero out region. */ |
| 285 | if (!err) | ||
| 286 | err = -EIO; | ||
| 270 | bh->b_blocknr = -1; | 287 | bh->b_blocknr = -1; |
| 271 | SetPageError(page); | 288 | SetPageError(page); |
| 272 | ntfs_error(vol->sb, "Failed to read from inode 0x%lx, " | 289 | ntfs_error(vol->sb, "Failed to read from inode 0x%lx, " |
| 273 | "attribute type 0x%x, vcn 0x%llx, " | 290 | "attribute type 0x%x, vcn 0x%llx, " |
| 274 | "offset 0x%x because its location on " | 291 | "offset 0x%x because its location on " |
| 275 | "disk could not be determined%s " | 292 | "disk could not be determined%s " |
| 276 | "(error code %lli).", ni->mft_no, | 293 | "(error code %i).", ni->mft_no, |
| 277 | ni->type, (unsigned long long)vcn, | 294 | ni->type, (unsigned long long)vcn, |
| 278 | vcn_ofs, is_retry ? " even after " | 295 | vcn_ofs, is_retry ? " even after " |
| 279 | "retrying" : "", (long long)lcn); | 296 | "retrying" : "", err); |
| 280 | } | 297 | } |
| 281 | /* | 298 | /* |
| 282 | * Either iblock was outside lblock limits or | 299 | * Either iblock was outside lblock limits or |
| @@ -289,9 +306,10 @@ handle_hole: | |||
| 289 | handle_zblock: | 306 | handle_zblock: |
| 290 | kaddr = kmap_atomic(page, KM_USER0); | 307 | kaddr = kmap_atomic(page, KM_USER0); |
| 291 | memset(kaddr + i * blocksize, 0, blocksize); | 308 | memset(kaddr + i * blocksize, 0, blocksize); |
| 292 | flush_dcache_page(page); | ||
| 293 | kunmap_atomic(kaddr, KM_USER0); | 309 | kunmap_atomic(kaddr, KM_USER0); |
| 294 | set_buffer_uptodate(bh); | 310 | flush_dcache_page(page); |
| 311 | if (likely(!err)) | ||
| 312 | set_buffer_uptodate(bh); | ||
| 295 | } while (i++, iblock++, (bh = bh->b_this_page) != head); | 313 | } while (i++, iblock++, (bh = bh->b_this_page) != head); |
| 296 | 314 | ||
| 297 | /* Release the lock if we took it. */ | 315 | /* Release the lock if we took it. */ |
| @@ -367,31 +385,38 @@ retry_readpage: | |||
| 367 | return 0; | 385 | return 0; |
| 368 | } | 386 | } |
| 369 | ni = NTFS_I(page->mapping->host); | 387 | ni = NTFS_I(page->mapping->host); |
| 370 | 388 | /* | |
| 389 | * Only $DATA attributes can be encrypted and only unnamed $DATA | ||
| 390 | * attributes can be compressed. Index root can have the flags set but | ||
| 391 | * this means to create compressed/encrypted files, not that the | ||
| 392 | * attribute is compressed/encrypted. | ||
| 393 | */ | ||
| 394 | if (ni->type != AT_INDEX_ROOT) { | ||
| 395 | /* If attribute is encrypted, deny access, just like NT4. */ | ||
| 396 | if (NInoEncrypted(ni)) { | ||
| 397 | BUG_ON(ni->type != AT_DATA); | ||
| 398 | err = -EACCES; | ||
| 399 | goto err_out; | ||
| 400 | } | ||
| 401 | /* Compressed data streams are handled in compress.c. */ | ||
| 402 | if (NInoNonResident(ni) && NInoCompressed(ni)) { | ||
| 403 | BUG_ON(ni->type != AT_DATA); | ||
| 404 | BUG_ON(ni->name_len); | ||
| 405 | return ntfs_read_compressed_block(page); | ||
| 406 | } | ||
| 407 | } | ||
| 371 | /* NInoNonResident() == NInoIndexAllocPresent() */ | 408 | /* NInoNonResident() == NInoIndexAllocPresent() */ |
| 372 | if (NInoNonResident(ni)) { | 409 | if (NInoNonResident(ni)) { |
| 373 | /* | 410 | /* Normal, non-resident data stream. */ |
| 374 | * Only unnamed $DATA attributes can be compressed or | ||
| 375 | * encrypted. | ||
| 376 | */ | ||
| 377 | if (ni->type == AT_DATA && !ni->name_len) { | ||
| 378 | /* If file is encrypted, deny access, just like NT4. */ | ||
| 379 | if (NInoEncrypted(ni)) { | ||
| 380 | err = -EACCES; | ||
| 381 | goto err_out; | ||
| 382 | } | ||
| 383 | /* Compressed data streams are handled in compress.c. */ | ||
| 384 | if (NInoCompressed(ni)) | ||
| 385 | return ntfs_read_compressed_block(page); | ||
| 386 | } | ||
| 387 | /* Normal data stream. */ | ||
| 388 | return ntfs_read_block(page); | 411 | return ntfs_read_block(page); |
| 389 | } | 412 | } |
| 390 | /* | 413 | /* |
| 391 | * Attribute is resident, implying it is not compressed or encrypted. | 414 | * Attribute is resident, implying it is not compressed or encrypted. |
| 392 | * This also means the attribute is smaller than an mft record and | 415 | * This also means the attribute is smaller than an mft record and |
| 393 | * hence smaller than a page, so can simply zero out any pages with | 416 | * hence smaller than a page, so can simply zero out any pages with |
| 394 | * index above 0. | 417 | * index above 0. Note the attribute can actually be marked compressed |
| 418 | * but if it is resident the actual data is not compressed so we are | ||
| 419 | * ok to ignore the compressed flag here. | ||
| 395 | */ | 420 | */ |
| 396 | if (unlikely(page->index > 0)) { | 421 | if (unlikely(page->index > 0)) { |
| 397 | kaddr = kmap_atomic(page, KM_USER0); | 422 | kaddr = kmap_atomic(page, KM_USER0); |
| @@ -511,19 +536,21 @@ static int ntfs_write_block(struct page *page, struct writeback_control *wbc) | |||
| 511 | BUG_ON(!PageUptodate(page)); | 536 | BUG_ON(!PageUptodate(page)); |
| 512 | create_empty_buffers(page, blocksize, | 537 | create_empty_buffers(page, blocksize, |
| 513 | (1 << BH_Uptodate) | (1 << BH_Dirty)); | 538 | (1 << BH_Uptodate) | (1 << BH_Dirty)); |
| 539 | if (unlikely(!page_has_buffers(page))) { | ||
| 540 | ntfs_warning(vol->sb, "Error allocating page " | ||
| 541 | "buffers. Redirtying page so we try " | ||
| 542 | "again later."); | ||
| 543 | /* | ||
| 544 | * Put the page back on mapping->dirty_pages, but leave | ||
| 545 | * its buffers' dirty state as-is. | ||
| 546 | */ | ||
| 547 | redirty_page_for_writepage(wbc, page); | ||
| 548 | unlock_page(page); | ||
| 549 | return 0; | ||
| 550 | } | ||
| 514 | } | 551 | } |
| 515 | bh = head = page_buffers(page); | 552 | bh = head = page_buffers(page); |
| 516 | if (unlikely(!bh)) { | 553 | BUG_ON(!bh); |
| 517 | ntfs_warning(vol->sb, "Error allocating page buffers. " | ||
| 518 | "Redirtying page so we try again later."); | ||
| 519 | /* | ||
| 520 | * Put the page back on mapping->dirty_pages, but leave its | ||
| 521 | * buffer's dirty state as-is. | ||
| 522 | */ | ||
| 523 | redirty_page_for_writepage(wbc, page); | ||
| 524 | unlock_page(page); | ||
| 525 | return 0; | ||
| 526 | } | ||
| 527 | 554 | ||
| 528 | /* NOTE: Different naming scheme to ntfs_read_block()! */ | 555 | /* NOTE: Different naming scheme to ntfs_read_block()! */ |
| 529 | 556 | ||
| @@ -670,6 +697,27 @@ lock_retry_remap: | |||
| 670 | } | 697 | } |
| 671 | /* It is a hole, need to instantiate it. */ | 698 | /* It is a hole, need to instantiate it. */ |
| 672 | if (lcn == LCN_HOLE) { | 699 | if (lcn == LCN_HOLE) { |
| 700 | u8 *kaddr; | ||
| 701 | unsigned long *bpos, *bend; | ||
| 702 | |||
| 703 | /* Check if the buffer is zero. */ | ||
| 704 | kaddr = kmap_atomic(page, KM_USER0); | ||
| 705 | bpos = (unsigned long *)(kaddr + bh_offset(bh)); | ||
| 706 | bend = (unsigned long *)((u8*)bpos + blocksize); | ||
| 707 | do { | ||
| 708 | if (unlikely(*bpos)) | ||
| 709 | break; | ||
| 710 | } while (likely(++bpos < bend)); | ||
| 711 | kunmap_atomic(kaddr, KM_USER0); | ||
| 712 | if (bpos == bend) { | ||
| 713 | /* | ||
| 714 | * Buffer is zero and sparse, no need to write | ||
| 715 | * it. | ||
| 716 | */ | ||
| 717 | bh->b_blocknr = -1; | ||
| 718 | clear_buffer_dirty(bh); | ||
| 719 | continue; | ||
| 720 | } | ||
| 673 | // TODO: Instantiate the hole. | 721 | // TODO: Instantiate the hole. |
| 674 | // clear_buffer_new(bh); | 722 | // clear_buffer_new(bh); |
| 675 | // unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr); | 723 | // unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr); |
| @@ -690,20 +738,37 @@ lock_retry_remap: | |||
| 690 | if (likely(!err)) | 738 | if (likely(!err)) |
| 691 | goto lock_retry_remap; | 739 | goto lock_retry_remap; |
| 692 | rl = NULL; | 740 | rl = NULL; |
| 693 | lcn = err; | ||
| 694 | } else if (!rl) | 741 | } else if (!rl) |
| 695 | up_read(&ni->runlist.lock); | 742 | up_read(&ni->runlist.lock); |
| 743 | /* | ||
| 744 | * If buffer is outside the runlist, truncate has cut it out | ||
| 745 | * of the runlist. Just clean and clear the buffer and set it | ||
| 746 | * uptodate so it can get discarded by the VM. | ||
| 747 | */ | ||
| 748 | if (err == -ENOENT || lcn == LCN_ENOENT) { | ||
| 749 | u8 *kaddr; | ||
| 750 | |||
| 751 | bh->b_blocknr = -1; | ||
| 752 | clear_buffer_dirty(bh); | ||
| 753 | kaddr = kmap_atomic(page, KM_USER0); | ||
| 754 | memset(kaddr + bh_offset(bh), 0, blocksize); | ||
| 755 | kunmap_atomic(kaddr, KM_USER0); | ||
| 756 | flush_dcache_page(page); | ||
| 757 | set_buffer_uptodate(bh); | ||
| 758 | err = 0; | ||
| 759 | continue; | ||
| 760 | } | ||
| 696 | /* Failed to map the buffer, even after retrying. */ | 761 | /* Failed to map the buffer, even after retrying. */ |
| 762 | if (!err) | ||
| 763 | err = -EIO; | ||
| 697 | bh->b_blocknr = -1; | 764 | bh->b_blocknr = -1; |
| 698 | ntfs_error(vol->sb, "Failed to write to inode 0x%lx, " | 765 | ntfs_error(vol->sb, "Failed to write to inode 0x%lx, " |
| 699 | "attribute type 0x%x, vcn 0x%llx, offset 0x%x " | 766 | "attribute type 0x%x, vcn 0x%llx, offset 0x%x " |
| 700 | "because its location on disk could not be " | 767 | "because its location on disk could not be " |
| 701 | "determined%s (error code %lli).", ni->mft_no, | 768 | "determined%s (error code %i).", ni->mft_no, |
| 702 | ni->type, (unsigned long long)vcn, | 769 | ni->type, (unsigned long long)vcn, |
| 703 | vcn_ofs, is_retry ? " even after " | 770 | vcn_ofs, is_retry ? " even after " |
| 704 | "retrying" : "", (long long)lcn); | 771 | "retrying" : "", err); |
| 705 | if (!err) | ||
| 706 | err = -EIO; | ||
| 707 | break; | 772 | break; |
| 708 | } while (block++, (bh = bh->b_this_page) != head); | 773 | } while (block++, (bh = bh->b_this_page) != head); |
| 709 | 774 | ||
| @@ -714,7 +779,7 @@ lock_retry_remap: | |||
| 714 | /* For the error case, need to reset bh to the beginning. */ | 779 | /* For the error case, need to reset bh to the beginning. */ |
| 715 | bh = head; | 780 | bh = head; |
| 716 | 781 | ||
| 717 | /* Just an optimization, so ->readpage() isn't called later. */ | 782 | /* Just an optimization, so ->readpage() is not called later. */ |
| 718 | if (unlikely(!PageUptodate(page))) { | 783 | if (unlikely(!PageUptodate(page))) { |
| 719 | int uptodate = 1; | 784 | int uptodate = 1; |
| 720 | do { | 785 | do { |
| @@ -730,7 +795,6 @@ lock_retry_remap: | |||
| 730 | 795 | ||
| 731 | /* Setup all mapped, dirty buffers for async write i/o. */ | 796 | /* Setup all mapped, dirty buffers for async write i/o. */ |
| 732 | do { | 797 | do { |
| 733 | get_bh(bh); | ||
| 734 | if (buffer_mapped(bh) && buffer_dirty(bh)) { | 798 | if (buffer_mapped(bh) && buffer_dirty(bh)) { |
| 735 | lock_buffer(bh); | 799 | lock_buffer(bh); |
| 736 | if (test_clear_buffer_dirty(bh)) { | 800 | if (test_clear_buffer_dirty(bh)) { |
| @@ -768,14 +832,8 @@ lock_retry_remap: | |||
| 768 | 832 | ||
| 769 | BUG_ON(PageWriteback(page)); | 833 | BUG_ON(PageWriteback(page)); |
| 770 | set_page_writeback(page); /* Keeps try_to_free_buffers() away. */ | 834 | set_page_writeback(page); /* Keeps try_to_free_buffers() away. */ |
| 771 | unlock_page(page); | ||
| 772 | 835 | ||
| 773 | /* | 836 | /* Submit the prepared buffers for i/o. */ |
| 774 | * Submit the prepared buffers for i/o. Note the page is unlocked, | ||
| 775 | * and the async write i/o completion handler can end_page_writeback() | ||
| 776 | * at any time after the *first* submit_bh(). So the buffers can then | ||
| 777 | * disappear... | ||
| 778 | */ | ||
| 779 | need_end_writeback = TRUE; | 837 | need_end_writeback = TRUE; |
| 780 | do { | 838 | do { |
| 781 | struct buffer_head *next = bh->b_this_page; | 839 | struct buffer_head *next = bh->b_this_page; |
| @@ -783,9 +841,9 @@ lock_retry_remap: | |||
| 783 | submit_bh(WRITE, bh); | 841 | submit_bh(WRITE, bh); |
| 784 | need_end_writeback = FALSE; | 842 | need_end_writeback = FALSE; |
| 785 | } | 843 | } |
| 786 | put_bh(bh); | ||
| 787 | bh = next; | 844 | bh = next; |
| 788 | } while (bh != head); | 845 | } while (bh != head); |
| 846 | unlock_page(page); | ||
| 789 | 847 | ||
| 790 | /* If no i/o was started, need to end_page_writeback(). */ | 848 | /* If no i/o was started, need to end_page_writeback(). */ |
| 791 | if (unlikely(need_end_writeback)) | 849 | if (unlikely(need_end_writeback)) |
| @@ -860,7 +918,6 @@ static int ntfs_write_mst_block(struct page *page, | |||
| 860 | sync = (wbc->sync_mode == WB_SYNC_ALL); | 918 | sync = (wbc->sync_mode == WB_SYNC_ALL); |
| 861 | 919 | ||
| 862 | /* Make sure we have mapped buffers. */ | 920 | /* Make sure we have mapped buffers. */ |
| 863 | BUG_ON(!page_has_buffers(page)); | ||
| 864 | bh = head = page_buffers(page); | 921 | bh = head = page_buffers(page); |
| 865 | BUG_ON(!bh); | 922 | BUG_ON(!bh); |
| 866 | 923 | ||
| @@ -1280,38 +1337,42 @@ retry_writepage: | |||
| 1280 | ntfs_debug("Write outside i_size - truncated?"); | 1337 | ntfs_debug("Write outside i_size - truncated?"); |
| 1281 | return 0; | 1338 | return 0; |
| 1282 | } | 1339 | } |
| 1340 | /* | ||
| 1341 | * Only $DATA attributes can be encrypted and only unnamed $DATA | ||
| 1342 | * attributes can be compressed. Index root can have the flags set but | ||
| 1343 | * this means to create compressed/encrypted files, not that the | ||
| 1344 | * attribute is compressed/encrypted. | ||
| 1345 | */ | ||
| 1346 | if (ni->type != AT_INDEX_ROOT) { | ||
| 1347 | /* If file is encrypted, deny access, just like NT4. */ | ||
| 1348 | if (NInoEncrypted(ni)) { | ||
| 1349 | unlock_page(page); | ||
| 1350 | BUG_ON(ni->type != AT_DATA); | ||
| 1351 | ntfs_debug("Denying write access to encrypted " | ||
| 1352 | "file."); | ||
| 1353 | return -EACCES; | ||
| 1354 | } | ||
| 1355 | /* Compressed data streams are handled in compress.c. */ | ||
| 1356 | if (NInoNonResident(ni) && NInoCompressed(ni)) { | ||
| 1357 | BUG_ON(ni->type != AT_DATA); | ||
| 1358 | BUG_ON(ni->name_len); | ||
| 1359 | // TODO: Implement and replace this with | ||
| 1360 | // return ntfs_write_compressed_block(page); | ||
| 1361 | unlock_page(page); | ||
| 1362 | ntfs_error(vi->i_sb, "Writing to compressed files is " | ||
| 1363 | "not supported yet. Sorry."); | ||
| 1364 | return -EOPNOTSUPP; | ||
| 1365 | } | ||
| 1366 | // TODO: Implement and remove this check. | ||
| 1367 | if (NInoNonResident(ni) && NInoSparse(ni)) { | ||
| 1368 | unlock_page(page); | ||
| 1369 | ntfs_error(vi->i_sb, "Writing to sparse files is not " | ||
| 1370 | "supported yet. Sorry."); | ||
| 1371 | return -EOPNOTSUPP; | ||
| 1372 | } | ||
| 1373 | } | ||
| 1283 | /* NInoNonResident() == NInoIndexAllocPresent() */ | 1374 | /* NInoNonResident() == NInoIndexAllocPresent() */ |
| 1284 | if (NInoNonResident(ni)) { | 1375 | if (NInoNonResident(ni)) { |
| 1285 | /* | ||
| 1286 | * Only unnamed $DATA attributes can be compressed, encrypted, | ||
| 1287 | * and/or sparse. | ||
| 1288 | */ | ||
| 1289 | if (ni->type == AT_DATA && !ni->name_len) { | ||
| 1290 | /* If file is encrypted, deny access, just like NT4. */ | ||
| 1291 | if (NInoEncrypted(ni)) { | ||
| 1292 | unlock_page(page); | ||
| 1293 | ntfs_debug("Denying write access to encrypted " | ||
| 1294 | "file."); | ||
| 1295 | return -EACCES; | ||
| 1296 | } | ||
| 1297 | /* Compressed data streams are handled in compress.c. */ | ||
| 1298 | if (NInoCompressed(ni)) { | ||
| 1299 | // TODO: Implement and replace this check with | ||
| 1300 | // return ntfs_write_compressed_block(page); | ||
| 1301 | unlock_page(page); | ||
| 1302 | ntfs_error(vi->i_sb, "Writing to compressed " | ||
| 1303 | "files is not supported yet. " | ||
| 1304 | "Sorry."); | ||
| 1305 | return -EOPNOTSUPP; | ||
| 1306 | } | ||
| 1307 | // TODO: Implement and remove this check. | ||
| 1308 | if (NInoSparse(ni)) { | ||
| 1309 | unlock_page(page); | ||
| 1310 | ntfs_error(vi->i_sb, "Writing to sparse files " | ||
| 1311 | "is not supported yet. Sorry."); | ||
| 1312 | return -EOPNOTSUPP; | ||
| 1313 | } | ||
| 1314 | } | ||
| 1315 | /* We have to zero every time due to mmap-at-end-of-file. */ | 1376 | /* We have to zero every time due to mmap-at-end-of-file. */ |
| 1316 | if (page->index >= (i_size >> PAGE_CACHE_SHIFT)) { | 1377 | if (page->index >= (i_size >> PAGE_CACHE_SHIFT)) { |
| 1317 | /* The page straddles i_size. */ | 1378 | /* The page straddles i_size. */ |
| @@ -1324,14 +1385,16 @@ retry_writepage: | |||
| 1324 | /* Handle mst protected attributes. */ | 1385 | /* Handle mst protected attributes. */ |
| 1325 | if (NInoMstProtected(ni)) | 1386 | if (NInoMstProtected(ni)) |
| 1326 | return ntfs_write_mst_block(page, wbc); | 1387 | return ntfs_write_mst_block(page, wbc); |
| 1327 | /* Normal data stream. */ | 1388 | /* Normal, non-resident data stream. */ |
| 1328 | return ntfs_write_block(page, wbc); | 1389 | return ntfs_write_block(page, wbc); |
| 1329 | } | 1390 | } |
| 1330 | /* | 1391 | /* |
| 1331 | * Attribute is resident, implying it is not compressed, encrypted, | 1392 | * Attribute is resident, implying it is not compressed, encrypted, or |
| 1332 | * sparse, or mst protected. This also means the attribute is smaller | 1393 | * mst protected. This also means the attribute is smaller than an mft |
| 1333 | * than an mft record and hence smaller than a page, so can simply | 1394 | * record and hence smaller than a page, so can simply return error on |
| 1334 | * return error on any pages with index above 0. | 1395 | * any pages with index above 0. Note the attribute can actually be |
| 1396 | * marked compressed but if it is resident the actual data is not | ||
| 1397 | * compressed so we are ok to ignore the compressed flag here. | ||
| 1335 | */ | 1398 | */ |
| 1336 | BUG_ON(page_has_buffers(page)); | 1399 | BUG_ON(page_has_buffers(page)); |
| 1337 | BUG_ON(!PageUptodate(page)); | 1400 | BUG_ON(!PageUptodate(page)); |
| @@ -1380,30 +1443,14 @@ retry_writepage: | |||
| 1380 | BUG_ON(PageWriteback(page)); | 1443 | BUG_ON(PageWriteback(page)); |
| 1381 | set_page_writeback(page); | 1444 | set_page_writeback(page); |
| 1382 | unlock_page(page); | 1445 | unlock_page(page); |
| 1383 | |||
| 1384 | /* | 1446 | /* |
| 1385 | * Here, we don't need to zero the out of bounds area everytime because | 1447 | * Here, we do not need to zero the out of bounds area everytime |
| 1386 | * the below memcpy() already takes care of the mmap-at-end-of-file | 1448 | * because the below memcpy() already takes care of the |
| 1387 | * requirements. If the file is converted to a non-resident one, then | 1449 | * mmap-at-end-of-file requirements. If the file is converted to a |
| 1388 | * the code path use is switched to the non-resident one where the | 1450 | * non-resident one, then the code path use is switched to the |
| 1389 | * zeroing happens on each ntfs_writepage() invocation. | 1451 | * non-resident one where the zeroing happens on each ntfs_writepage() |
| 1390 | * | 1452 | * invocation. |
| 1391 | * The above also applies nicely when i_size is decreased. | ||
| 1392 | * | ||
| 1393 | * When i_size is increased, the memory between the old and new i_size | ||
| 1394 | * _must_ be zeroed (or overwritten with new data). Otherwise we will | ||
| 1395 | * expose data to userspace/disk which should never have been exposed. | ||
| 1396 | * | ||
| 1397 | * FIXME: Ensure that i_size increases do the zeroing/overwriting and | ||
| 1398 | * if we cannot guarantee that, then enable the zeroing below. If the | ||
| 1399 | * zeroing below is enabled, we MUST move the unlock_page() from above | ||
| 1400 | * to after the kunmap_atomic(), i.e. just before the | ||
| 1401 | * end_page_writeback(). | ||
| 1402 | * UPDATE: ntfs_prepare/commit_write() do the zeroing on i_size | ||
| 1403 | * increases for resident attributes so those are ok. | ||
| 1404 | * TODO: ntfs_truncate(), others? | ||
| 1405 | */ | 1453 | */ |
| 1406 | |||
| 1407 | attr_len = le32_to_cpu(ctx->attr->data.resident.value_length); | 1454 | attr_len = le32_to_cpu(ctx->attr->data.resident.value_length); |
| 1408 | i_size = i_size_read(vi); | 1455 | i_size = i_size_read(vi); |
| 1409 | if (unlikely(attr_len > i_size)) { | 1456 | if (unlikely(attr_len > i_size)) { |
| @@ -1681,27 +1728,25 @@ lock_retry_remap: | |||
| 1681 | if (likely(!err)) | 1728 | if (likely(!err)) |
| 1682 | goto lock_retry_remap; | 1729 | goto lock_retry_remap; |
| 1683 | rl = NULL; | 1730 | rl = NULL; |
| 1684 | lcn = err; | ||
| 1685 | } else if (!rl) | 1731 | } else if (!rl) |
| 1686 | up_read(&ni->runlist.lock); | 1732 | up_read(&ni->runlist.lock); |
| 1687 | /* | 1733 | /* |
| 1688 | * Failed to map the buffer, even after | 1734 | * Failed to map the buffer, even after |
| 1689 | * retrying. | 1735 | * retrying. |
| 1690 | */ | 1736 | */ |
| 1737 | if (!err) | ||
| 1738 | err = -EIO; | ||
| 1691 | bh->b_blocknr = -1; | 1739 | bh->b_blocknr = -1; |
| 1692 | ntfs_error(vol->sb, "Failed to write to inode " | 1740 | ntfs_error(vol->sb, "Failed to write to inode " |
| 1693 | "0x%lx, attribute type 0x%x, " | 1741 | "0x%lx, attribute type 0x%x, " |
| 1694 | "vcn 0x%llx, offset 0x%x " | 1742 | "vcn 0x%llx, offset 0x%x " |
| 1695 | "because its location on disk " | 1743 | "because its location on disk " |
| 1696 | "could not be determined%s " | 1744 | "could not be determined%s " |
| 1697 | "(error code %lli).", | 1745 | "(error code %i).", |
| 1698 | ni->mft_no, ni->type, | 1746 | ni->mft_no, ni->type, |
| 1699 | (unsigned long long)vcn, | 1747 | (unsigned long long)vcn, |
| 1700 | vcn_ofs, is_retry ? " even " | 1748 | vcn_ofs, is_retry ? " even " |
| 1701 | "after retrying" : "", | 1749 | "after retrying" : "", err); |
| 1702 | (long long)lcn); | ||
| 1703 | if (!err) | ||
| 1704 | err = -EIO; | ||
| 1705 | goto err_out; | 1750 | goto err_out; |
| 1706 | } | 1751 | } |
| 1707 | /* We now have a successful remap, i.e. lcn >= 0. */ | 1752 | /* We now have a successful remap, i.e. lcn >= 0. */ |
| @@ -2357,6 +2402,7 @@ void mark_ntfs_record_dirty(struct page *page, const unsigned int ofs) { | |||
| 2357 | buffers_to_free = bh; | 2402 | buffers_to_free = bh; |
| 2358 | } | 2403 | } |
| 2359 | bh = head = page_buffers(page); | 2404 | bh = head = page_buffers(page); |
| 2405 | BUG_ON(!bh); | ||
| 2360 | do { | 2406 | do { |
| 2361 | bh_ofs = bh_offset(bh); | 2407 | bh_ofs = bh_offset(bh); |
| 2362 | if (bh_ofs + bh_size <= ofs) | 2408 | if (bh_ofs + bh_size <= ofs) |
