mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-29 19:21:31 -04:00
make ext2_get_page() and friends work without external serialization
Right now ext2_get_page() (and its analogues in a bunch of other filesystems) relies upon the directory being locked - the way it sets and tests Checked and Error bits would be racy without that. Switch to a slightly different scheme, _not_ setting Checked in case of failure. That way the logics becomes if Checked => OK else if Error => fail else if !validate => fail else => OK with validation setting Checked or Error on success and failure resp. and returning which one had happened. Equivalent to the current logics, but unlike the current logics not sensitive to the order of set_bit, test_bit getting reordered by CPU, etc. Signed-off-by: Al Viro <[email protected]>
This commit is contained in:
parent
b9e1d435fd
commit
be5b82dbfe
5 changed files with 35 additions and 35 deletions
14
fs/afs/dir.c
14
fs/afs/dir.c
|
|
@ -128,7 +128,7 @@ struct afs_lookup_cookie {
|
|||
/*
|
||||
* check that a directory page is valid
|
||||
*/
|
||||
static inline void afs_dir_check_page(struct inode *dir, struct page *page)
|
||||
static inline bool afs_dir_check_page(struct inode *dir, struct page *page)
|
||||
{
|
||||
struct afs_dir_page *dbuf;
|
||||
loff_t latter;
|
||||
|
|
@ -168,11 +168,11 @@ static inline void afs_dir_check_page(struct inode *dir, struct page *page)
|
|||
}
|
||||
|
||||
SetPageChecked(page);
|
||||
return;
|
||||
return true;
|
||||
|
||||
error:
|
||||
SetPageChecked(page);
|
||||
SetPageError(page);
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -196,10 +196,10 @@ static struct page *afs_dir_get_page(struct inode *dir, unsigned long index,
|
|||
page = read_cache_page(dir->i_mapping, index, afs_page_filler, key);
|
||||
if (!IS_ERR(page)) {
|
||||
kmap(page);
|
||||
if (!PageChecked(page))
|
||||
afs_dir_check_page(dir, page);
|
||||
if (PageError(page))
|
||||
goto fail;
|
||||
if (unlikely(!PageChecked(page))) {
|
||||
if (PageError(page) || !afs_dir_check_page(dir, page))
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
return page;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue