From ebab89909e0dc716282d5e7f6e73a3155fe66d4a Mon Sep 17 00:00:00 2001 From: Anton Altaparmakov Date: Sat, 3 Nov 2007 07:38:59 +0000 Subject: 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 Tested-by: Mike Galbraith Signed-off-by: Linus Torvalds --- fs/ntfs/aops.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'fs/ntfs/aops.c') 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) retry_readpage: BUG_ON(!PageLocked(page)); + vi = page->mapping->host; + i_size = i_size_read(vi); + /* Is the page fully outside i_size? (truncate in progress) */ + if (unlikely(page->index >= (i_size + PAGE_CACHE_SIZE - 1) >> + PAGE_CACHE_SHIFT)) { + zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); + ntfs_debug("Read outside i_size - truncated?"); + goto done; + } /* * This can potentially happen because we clear PageUptodate() during * ntfs_writepage() of MstProtected() attributes. @@ -413,7 +422,6 @@ retry_readpage: unlock_page(page); return 0; } - vi = page->mapping->host; ni = NTFS_I(vi); /* * Only $DATA attributes can be encrypted and only unnamed $DATA -- cgit v1.2.1