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>
This commit is contained in:
parent
fd4c5748b8
commit
44f52122a2
1 changed files with 2 additions and 3 deletions
|
@ -658,6 +658,7 @@ void gfs2_rs_deltree(struct gfs2_blkreserv *rs)
|
|||
if (rgd) {
|
||||
spin_lock(&rgd->rd_rsspin);
|
||||
__rs_deltree(rs);
|
||||
BUG_ON(rs->rs_free);
|
||||
spin_unlock(&rgd->rd_rsspin);
|
||||
}
|
||||
}
|
||||
|
@ -671,10 +672,8 @@ void gfs2_rs_deltree(struct gfs2_blkreserv *rs)
|
|||
void gfs2_rsqa_delete(struct gfs2_inode *ip, atomic_t *wcount)
|
||||
{
|
||||
down_write(&ip->i_rw_mutex);
|
||||
if ((wcount == NULL) || (atomic_read(wcount) <= 1)) {
|
||||
if ((wcount == NULL) || (atomic_read(wcount) <= 1))
|
||||
gfs2_rs_deltree(&ip->i_res);
|
||||
BUG_ON(ip->i_res.rs_free);
|
||||
}
|
||||
up_write(&ip->i_rw_mutex);
|
||||
gfs2_qa_delete(ip, wcount);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue