summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMark Fasheh <mark.fasheh@oracle.com>2007-05-14 20:38:51 +0200
committerMark Fasheh <mark.fasheh@oracle.com>2007-05-25 20:00:23 +0200
commite9dfc0b2bc42761410e8db6c252c6c5889e178b8 (patch)
treed42beb9d6b2c54bc205e48bc75cdf26ec0eeddc3 /fs
parentMerge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/ne... (diff)
downloadlinux-e9dfc0b2bc42761410e8db6c252c6c5889e178b8.tar.xz
linux-e9dfc0b2bc42761410e8db6c252c6c5889e178b8.zip
ocfs2: trylock in ocfs2_readpage()
Similarly to the page lock / cluster lock inversion in ocfs2_readpage, we can deadlock on ip_alloc_sem. We can down_read_trylock() instead and just return AOP_TRUNCATED_PAGE if the operation fails. Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/aops.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 8e7cafb5fc6c..30306707b2ca 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -222,7 +222,10 @@ static int ocfs2_readpage(struct file *file, struct page *page)
goto out;
}
- down_read(&OCFS2_I(inode)->ip_alloc_sem);
+ if (down_read_trylock(&OCFS2_I(inode)->ip_alloc_sem) == 0) {
+ ret = AOP_TRUNCATED_PAGE;
+ goto out_meta_unlock;
+ }
/*
* i_size might have just been updated as we grabed the meta lock. We
@@ -258,6 +261,7 @@ static int ocfs2_readpage(struct file *file, struct page *page)
ocfs2_data_unlock(inode, 0);
out_alloc:
up_read(&OCFS2_I(inode)->ip_alloc_sem);
+out_meta_unlock:
ocfs2_meta_unlock(inode, 0);
out:
if (unlock)