diff options
Diffstat (limited to 'fs/gfs2/ops_address.c')
-rw-r--r-- | fs/gfs2/ops_address.c | 40 |
1 files changed, 20 insertions, 20 deletions
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c index f55394e57cb2..e64a1b04117a 100644 --- a/fs/gfs2/ops_address.c +++ b/fs/gfs2/ops_address.c | |||
@@ -499,34 +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 | ||
507 | static int gfs2_readpage(struct file *file, struct page *page) | 507 | static 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_holder *gh; | 510 | struct gfs2_inode *ip = GFS2_I(mapping->host); |
511 | struct gfs2_holder gh; | ||
511 | int error; | 512 | int error; |
512 | 513 | ||
513 | gh = gfs2_glock_is_locked_by_me(ip->i_gl); | 514 | unlock_page(page); |
514 | if (!gh) { | 515 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh); |
515 | gh = kmalloc(sizeof(struct gfs2_holder), GFP_NOFS); | 516 | error = gfs2_glock_nq_atime(&gh); |
516 | if (!gh) | 517 | if (unlikely(error)) |
517 | return -ENOBUFS; | 518 | goto out; |
518 | gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, gh); | 519 | error = AOP_TRUNCATED_PAGE; |
520 | lock_page(page); | ||
521 | if (page->mapping == mapping && !PageUptodate(page)) | ||
522 | error = __gfs2_readpage(file, page); | ||
523 | else | ||
519 | unlock_page(page); | 524 | unlock_page(page); |
520 | error = gfs2_glock_nq_atime(gh); | 525 | gfs2_glock_dq(&gh); |
521 | if (likely(error != 0)) | ||
522 | goto out; | ||
523 | return AOP_TRUNCATED_PAGE; | ||
524 | } | ||
525 | error = __gfs2_readpage(file, page); | ||
526 | gfs2_glock_dq(gh); | ||
527 | out: | 526 | out: |
528 | gfs2_holder_uninit(gh); | 527 | gfs2_holder_uninit(&gh); |
529 | kfree(gh); | 528 | if (error && error != AOP_TRUNCATED_PAGE) |
529 | lock_page(page); | ||
530 | return error; | 530 | return error; |
531 | } | 531 | } |
532 | 532 | ||