diff options
author | Bob Peterson <rpeterso@redhat.com> | 2016-07-06 11:36:43 -0400 |
---|---|---|
committer | Bob Peterson <rpeterso@redhat.com> | 2016-07-12 12:48:22 -0400 |
commit | 44f52122a22004de9c3bae288bbc6dff3624fe9c (patch) | |
tree | df0c36e3d387d2cd46b74c0f1228bc3da6fcad4e | |
parent | fd4c5748b8d3f7420e8932ed0bde3d53cc8acc9d (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.c | 5 |
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) | |||
671 | void gfs2_rsqa_delete(struct gfs2_inode *ip, atomic_t *wcount) | 672 | void 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 | } |