mm: make read_cache_page synchronous

Ensure pages are uptodate after returning from read_cache_page, which allows
us to cut out most of the filesystem-internal PageUptodate calls.

I didn't have a great look down the call chains, but this appears to fixes 7
possible use-before uptodate in hfs, 2 in hfsplus, 1 in jfs, a few in
ecryptfs, 1 in jffs2, and a possible cleared data overwritten with readpage in
block2mtd.  All depending on whether the filler is async and/or can return
with a !uptodate page.

Signed-off-by: Nick Piggin <[email protected]>
Cc: Hugh Dickins <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Linus Torvalds <[email protected]>
This commit is contained in:
Nick Piggin 2007-05-06 14:49:04 -07:00 • committed by Linus Torvalds
commit 6fe6900e1e
24 changed files with 71 additions and 146 deletions

View file

@ -194,10 +194,7 @@ static struct page *afs_dir_get_page(struct inode *dir, unsigned long index,
page = read_mapping_page(dir->i_mapping, index, &file);
if (!IS_ERR(page)) {
wait_on_page_locked(page);
kmap(page);
if (!PageUptodate(page))
goto fail;
if (!PageChecked(page))
afs_dir_check_page(dir, page);
if (PageError(page))

View file

@ -68,13 +68,11 @@ int afs_mntpt_check_symlink(struct afs_vnode *vnode, struct key *key)
}
ret = -EIO;
wait_on_page_locked(page);
buf = kmap(page);
if (!PageUptodate(page))
goto out_free;
if (PageError(page))
goto out_free;
buf = kmap(page);
/* examine the symlink's contents */
size = vnode->status.size;
_debug("symlink to %*.*s", (int) size, (int) size, buf);
@ -91,8 +89,8 @@ int afs_mntpt_check_symlink(struct afs_vnode *vnode, struct key *key)
ret = 0;
out_free:
kunmap(page);
out_free:
page_cache_release(page);
out:
_leave(" = %d", ret);
@ -171,8 +169,7 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
}
ret = -EIO;
wait_on_page_locked(page);
if (!PageUptodate(page) || PageError(page))
if (PageError(page))
goto error;
buf = kmap(page);