gfs2: Fix iomap write page reclaim deadlock
[sfrench/cifs-2.6.git] / fs / gfs2 / aops.c
index 8afbb35559b9f1094981a664bd92b97551778640..6210d4429d8454030f7a82b4f5c373ca56ccb986 100644 (file)
@@ -649,7 +649,7 @@ out_uninit:
  */
 void adjust_fs_space(struct inode *inode)
 {
-       struct gfs2_sbd *sdp = inode->i_sb->s_fs_info;
+       struct gfs2_sbd *sdp = GFS2_SB(inode);
        struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
        struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
        struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
@@ -657,10 +657,13 @@ void adjust_fs_space(struct inode *inode)
        struct buffer_head *m_bh, *l_bh;
        u64 fs_total, new_free;
 
+       if (gfs2_trans_begin(sdp, 2 * RES_STATFS, 0) != 0)
+               return;
+
        /* Total up the file system space, according to the latest rindex. */
        fs_total = gfs2_ri_total(sdp);
        if (gfs2_meta_inode_buffer(m_ip, &m_bh) != 0)
-               return;
+               goto out;
 
        spin_lock(&sdp->sd_statfs_spin);
        gfs2_statfs_change_in(m_sc, m_bh->b_data +
@@ -675,11 +678,14 @@ void adjust_fs_space(struct inode *inode)
        gfs2_statfs_change(sdp, new_free, new_free, 0);
 
        if (gfs2_meta_inode_buffer(l_ip, &l_bh) != 0)
-               goto out;
+               goto out2;
        update_statfs(sdp, m_bh, l_bh);
        brelse(l_bh);
-out:
+out2:
        brelse(m_bh);
+out:
+       sdp->sd_rindex_uptodate = 0;
+       gfs2_trans_end(sdp);
 }
 
 /**
@@ -820,10 +826,10 @@ out:
  * @page: the page that's being released
  * @gfp_mask: passed from Linux VFS, ignored by us
  *
- * Call try_to_free_buffers() if the buffers in this page can be
- * released.
+ * Calls try_to_free_buffers() to free the buffers and put the page if the
+ * buffers can be released.
  *
- * Returns: 0
+ * Returns: 1 if the page was put or else 0
  */
 
 int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
@@ -930,14 +936,14 @@ static const struct address_space_operations gfs2_jdata_aops = {
 void gfs2_set_aops(struct inode *inode)
 {
        struct gfs2_inode *ip = GFS2_I(inode);
+       struct gfs2_sbd *sdp = GFS2_SB(inode);
 
-       if (gfs2_is_writeback(ip))
+       if (gfs2_is_jdata(ip))
+               inode->i_mapping->a_ops = &gfs2_jdata_aops;
+       else if (gfs2_is_writeback(sdp))
                inode->i_mapping->a_ops = &gfs2_writeback_aops;
-       else if (gfs2_is_ordered(ip))
+       else if (gfs2_is_ordered(sdp))
                inode->i_mapping->a_ops = &gfs2_ordered_aops;
-       else if (gfs2_is_jdata(ip))
-               inode->i_mapping->a_ops = &gfs2_jdata_aops;
        else
                BUG();
 }
-