]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/gfs2/ops_address.c
AMD IOMMU: avoid unnecessary low zone allocation in alloc_coherent
[linux-2.6-omap-h63xx.git] / fs / gfs2 / ops_address.c
index f55394e57cb28facf0e8928053064f8b70ad7f37..e64a1b04117ad5b27bb5fc1efd98ffe6295056a8 100644 (file)
@@ -499,34 +499,34 @@ static int __gfs2_readpage(void *file, struct page *page)
  * @file: The file to read
  * @page: The page of the file
  *
- * This deals with the locking required. We use a trylock in order to
- * avoid the page lock / glock ordering problems returning AOP_TRUNCATED_PAGE
- * in the event that we are unable to get the lock.
+ * This deals with the locking required. We have to unlock and
+ * relock the page in order to get the locking in the right
+ * order.
  */
 
 static int gfs2_readpage(struct file *file, struct page *page)
 {
-       struct gfs2_inode *ip = GFS2_I(page->mapping->host);
-       struct gfs2_holder *gh;
+       struct address_space *mapping = page->mapping;
+       struct gfs2_inode *ip = GFS2_I(mapping->host);
+       struct gfs2_holder gh;
        int error;
 
-       gh = gfs2_glock_is_locked_by_me(ip->i_gl);
-       if (!gh) {
-               gh = kmalloc(sizeof(struct gfs2_holder), GFP_NOFS);
-               if (!gh)
-                       return -ENOBUFS;
-               gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, gh);
+       unlock_page(page);
+       gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh);
+       error = gfs2_glock_nq_atime(&gh);
+       if (unlikely(error))
+               goto out;
+       error = AOP_TRUNCATED_PAGE;
+       lock_page(page);
+       if (page->mapping == mapping && !PageUptodate(page))
+               error = __gfs2_readpage(file, page);
+       else
                unlock_page(page);
-               error = gfs2_glock_nq_atime(gh);
-               if (likely(error != 0))
-                       goto out;
-               return AOP_TRUNCATED_PAGE;
-       }
-       error = __gfs2_readpage(file, page);
-       gfs2_glock_dq(gh);
+       gfs2_glock_dq(&gh);
 out:
-       gfs2_holder_uninit(gh);
-       kfree(gh);
+       gfs2_holder_uninit(&gh);
+       if (error && error != AOP_TRUNCATED_PAGE)
+               lock_page(page);
        return error;
 }