diff options
author | Anton Altaparmakov <aia21@cam.ac.uk> | 2007-11-03 03:38:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-11-03 15:27:21 -0400 |
commit | ebab89909e0dc716282d5e7f6e73a3155fe66d4a (patch) | |
tree | 8cee9ff6f9e0a08c6f08853e38e563514e92a99e /fs/ntfs/aops.c | |
parent | 74521c28e550c4ec265cda14114bd9b908e9de34 (diff) |
NTFS: Fix read regression.
The regression was caused by:
commit[a32ea1e1f925399e0d81ca3f7394a44a6dafa12c] Fix read/truncate race
This causes ntfs_readpage() to be called for a zero i_size inode, which
failed when the file was compressed and non-resident.
Thanks a lot to Mike Galbraith for reporting the issue and tracking down
the commit that caused the regression.
Looking into it I found three bugs which the patch fixes.
Signed-off-by: Anton Altaparmakov <aia21@cantab.net>
Tested-by: Mike Galbraith <efault@gmx.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ntfs/aops.c')
-rw-r--r-- | fs/ntfs/aops.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/fs/ntfs/aops.c b/fs/ntfs/aops.c index cfdc7900d271..ad87cb01299b 100644 --- a/fs/ntfs/aops.c +++ b/fs/ntfs/aops.c | |||
@@ -405,6 +405,15 @@ static int ntfs_readpage(struct file *file, struct page *page) | |||
405 | 405 | ||
406 | retry_readpage: | 406 | retry_readpage: |
407 | BUG_ON(!PageLocked(page)); | 407 | BUG_ON(!PageLocked(page)); |
408 | vi = page->mapping->host; | ||
409 | i_size = i_size_read(vi); | ||
410 | /* Is the page fully outside i_size? (truncate in progress) */ | ||
411 | if (unlikely(page->index >= (i_size + PAGE_CACHE_SIZE - 1) >> | ||
412 | PAGE_CACHE_SHIFT)) { | ||
413 | zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); | ||
414 | ntfs_debug("Read outside i_size - truncated?"); | ||
415 | goto done; | ||
416 | } | ||
408 | /* | 417 | /* |
409 | * This can potentially happen because we clear PageUptodate() during | 418 | * This can potentially happen because we clear PageUptodate() during |
410 | * ntfs_writepage() of MstProtected() attributes. | 419 | * ntfs_writepage() of MstProtected() attributes. |
@@ -413,7 +422,6 @@ retry_readpage: | |||
413 | unlock_page(page); | 422 | unlock_page(page); |
414 | return 0; | 423 | return 0; |
415 | } | 424 | } |
416 | vi = page->mapping->host; | ||
417 | ni = NTFS_I(vi); | 425 | ni = NTFS_I(vi); |
418 | /* | 426 | /* |
419 | * Only $DATA attributes can be encrypted and only unnamed $DATA | 427 | * Only $DATA attributes can be encrypted and only unnamed $DATA |