aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2016-07-06 11:36:43 -0400
committerBob Peterson <rpeterso@redhat.com>2016-07-12 12:48:22 -0400
commit44f52122a22004de9c3bae288bbc6dff3624fe9c (patch)
treedf0c36e3d387d2cd46b74c0f1228bc3da6fcad4e
parentfd4c5748b8d3f7420e8932ed0bde3d53cc8acc9d (diff)
GFS2: Check rs_free with rd_rsspin protection
For the last process to close a file opened for write, function gfs2_rsqa_delete was deleting the file's inode's block reservation out of the rgrp reservations tree. Then it was checking to make sure rs_free was 0, but it was performing the check outside the protection of rd_rsspin spin_lock. The rd_rsspin spin_lock protection is needed to prevent a race between the process freeing the reservation and another who is allocating a new set of blocks inside the same rgrp for the same inode, thus changing its value. Signed-off-by: Bob Peterson <rpeterso@redhat.com>
-rw-r--r--fs/gfs2/rgrp.c5
1 files changed, 2 insertions, 3 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index fba38ca94135..86ccc0159393 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -658,6 +658,7 @@ void gfs2_rs_deltree(struct gfs2_blkreserv *rs)
658 if (rgd) { 658 if (rgd) {
659 spin_lock(&rgd->rd_rsspin); 659 spin_lock(&rgd->rd_rsspin);
660 __rs_deltree(rs); 660 __rs_deltree(rs);
661 BUG_ON(rs->rs_free);
661 spin_unlock(&rgd->rd_rsspin); 662 spin_unlock(&rgd->rd_rsspin);
662 } 663 }
663} 664}
@@ -671,10 +672,8 @@ void gfs2_rs_deltree(struct gfs2_blkreserv *rs)
671void gfs2_rsqa_delete(struct gfs2_inode *ip, atomic_t *wcount) 672void gfs2_rsqa_delete(struct gfs2_inode *ip, atomic_t *wcount)
672{ 673{
673 down_write(&ip->i_rw_mutex); 674 down_write(&ip->i_rw_mutex);
674 if ((wcount == NULL) || (atomic_read(wcount) <= 1)) { 675 if ((wcount == NULL) || (atomic_read(wcount) <= 1))
675 gfs2_rs_deltree(&ip->i_res); 676 gfs2_rs_deltree(&ip->i_res);
676 BUG_ON(ip->i_res.rs_free);
677 }
678 up_write(&ip->i_rw_mutex); 677 up_write(&ip->i_rw_mutex);
679 gfs2_qa_delete(ip, wcount); 678 gfs2_qa_delete(ip, wcount);
680} 679}