aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/gfs2/ops_address.c29
1 files changed, 16 insertions, 13 deletions
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 2b556dd034bb..e64a1b04117a 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -499,31 +499,34 @@ static int __gfs2_readpage(void *file, struct page *page)
499 * @file: The file to read 499 * @file: The file to read
500 * @page: The page of the file 500 * @page: The page of the file
501 * 501 *
502 * This deals with the locking required. We use a trylock in order to 502 * This deals with the locking required. We have to unlock and
503 * avoid the page lock / glock ordering problems returning AOP_TRUNCATED_PAGE 503 * relock the page in order to get the locking in the right
504 * in the event that we are unable to get the lock. 504 * order.
505 */ 505 */
506 506
507static int gfs2_readpage(struct file *file, struct page *page) 507static int gfs2_readpage(struct file *file, struct page *page)
508{ 508{
509 struct gfs2_inode *ip = GFS2_I(page->mapping->host); 509 struct address_space *mapping = page->mapping;
510 struct gfs2_inode *ip = GFS2_I(mapping->host);
510 struct gfs2_holder gh; 511 struct gfs2_holder gh;
511 int error; 512 int error;
512 513
513 gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|LM_FLAG_TRY_1CB, &gh); 514 unlock_page(page);
515 gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh);
514 error = gfs2_glock_nq_atime(&gh); 516 error = gfs2_glock_nq_atime(&gh);
515 if (unlikely(error)) { 517 if (unlikely(error))
516 unlock_page(page);
517 goto out; 518 goto out;
518 } 519 error = AOP_TRUNCATED_PAGE;
519 error = __gfs2_readpage(file, page); 520 lock_page(page);
521 if (page->mapping == mapping && !PageUptodate(page))
522 error = __gfs2_readpage(file, page);
523 else
524 unlock_page(page);
520 gfs2_glock_dq(&gh); 525 gfs2_glock_dq(&gh);
521out: 526out:
522 gfs2_holder_uninit(&gh); 527 gfs2_holder_uninit(&gh);
523 if (error == GLR_TRYFAILED) { 528 if (error && error != AOP_TRUNCATED_PAGE)
524 yield(); 529 lock_page(page);
525 return AOP_TRUNCATED_PAGE;
526 }
527 return error; 530 return error;
528} 531}
529 532