GFS2: Check rs_free with rd_rsspin protection
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/1 GFS2: Check rs_free with rd_rsspin protection
Hi,
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.
Regards,
Bob Peterson
Red Hat File Systems
---
fs/gfs2/rgrp.c +2 -3
@@ -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); }
PATCH 1/1 GFS2: Check rs_free with rd_rsspin protection
Hi,
Steve.
Quoted 43 lines · Bob Peterson
Hi,
For the last process to close a file opened for write, function
gfs2_rsqa_deletewas deleting the file's inode's block reservation out of the rgrp reservations tree. Then it was checking to make surers_freewas 0, but it was performing the check outside the protection ofrd_rsspinspin_lock. Therd_rsspinspin_lockprotection 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 <[email protected]>Regards,
Bob Peterson
Red Hat File Systems
---fs/gfs2/rgrp.c +2
-3@@ -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); }