summaryrefslogtreecommitdiffstats
path: root/fs/afs
diff options
context:
space:
mode:
authorNick Piggin <npiggin@suse.de>2007-05-06 14:49:04 -0700
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-07 12:12:51 -0700
commit6fe6900e1e5b6fa9e5c59aa5061f244fe3f467e2 (patch)
tree8bbfe5072279227cc50a941ad4813908082426a1 /fs/afs
parent714b8171af9c930a59a0da8f6fe50518e70ab035 (diff)
downloadlinux-stable-6fe6900e1e5b6fa9e5c59aa5061f244fe3f467e2.tar.gz
linux-stable-6fe6900e1e5b6fa9e5c59aa5061f244fe3f467e2.tar.bz2
linux-stable-6fe6900e1e5b6fa9e5c59aa5061f244fe3f467e2.zip
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 <npiggin@suse.de> Cc: Hugh Dickins <hugh@veritas.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/afs')
-rw-r--r--fs/afs/dir.c3
-rw-r--r--fs/afs/mntpt.c11
2 files changed, 4 insertions, 10 deletions
diff --git a/fs/afs/dir.c b/fs/afs/dir.c
index dac5b990c0cd..0c1e902f17a3 100644
--- a/fs/afs/dir.c
+++ b/fs/afs/dir.c
@@ -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))
diff --git a/fs/afs/mntpt.c b/fs/afs/mntpt.c
index b905ae37f912..034fcfd4e330 100644
--- a/fs/afs/mntpt.c
+++ b/fs/afs/mntpt.c
@@ -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);