提交 01b7c7ae 编写于 作者: S Steven Whitehouse

[GFS2] Revise readpage locking

The previous attempt to fix the locking in readpage failed due
to the use of a "try lock" which resulted in occasional high
cpu usage during testing (due to repeated tries) and also it
did not resolve all the ordering problems wrt the transaction
lock (although it did solve all the inode lock ordering problems).

This patch avoids the problem by unlocking the page and getting the
locks in the correct order. This means that we have to retest the
page to ensure that it hasn't changed when we relock the page.

This now passes the tests which were previously failing.
Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
上级 80274737
...@@ -499,31 +499,34 @@ static int __gfs2_readpage(void *file, struct page *page) ...@@ -499,31 +499,34 @@ static int __gfs2_readpage(void *file, struct page *page)
* @file: The file to read * @file: The file to read
* @page: The page of the file * @page: The page of the file
* *
* This deals with the locking required. We use a trylock in order to * This deals with the locking required. We have to unlock and
* avoid the page lock / glock ordering problems returning AOP_TRUNCATED_PAGE * relock the page in order to get the locking in the right
* in the event that we are unable to get the lock. * order.
*/ */
static int gfs2_readpage(struct file *file, struct page *page) static int gfs2_readpage(struct file *file, struct page *page)
{ {
struct gfs2_inode *ip = GFS2_I(page->mapping->host); struct address_space *mapping = page->mapping;
struct gfs2_inode *ip = GFS2_I(mapping->host);
struct gfs2_holder gh; struct gfs2_holder gh;
int error; int error;
gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|LM_FLAG_TRY_1CB, &gh); unlock_page(page);
gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh);
error = gfs2_glock_nq_atime(&gh); error = gfs2_glock_nq_atime(&gh);
if (unlikely(error)) { if (unlikely(error))
unlock_page(page);
goto out; goto out;
} error = AOP_TRUNCATED_PAGE;
error = __gfs2_readpage(file, page); lock_page(page);
if (page->mapping == mapping && !PageUptodate(page))
error = __gfs2_readpage(file, page);
else
unlock_page(page);
gfs2_glock_dq(&gh); gfs2_glock_dq(&gh);
out: out:
gfs2_holder_uninit(&gh); gfs2_holder_uninit(&gh);
if (error == GLR_TRYFAILED) { if (error && error != AOP_TRUNCATED_PAGE)
yield(); lock_page(page);
return AOP_TRUNCATED_PAGE;
}
return error; return error;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册