@@ -920,6 +920,7 @@ static int read_rindex_entry(struct gfs2_inode *ip)
920920 rgd -> rd_data = be32_to_cpu (buf .ri_data );
921921 rgd -> rd_bitbytes = be32_to_cpu (buf .ri_bitbytes );
922922 spin_lock_init (& rgd -> rd_rsspin );
923+ mutex_init (& rgd -> rd_mutex );
923924
924925 error = compute_bitstructs (rgd );
925926 if (error )
@@ -1449,9 +1450,11 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
14491450 /* Trim each bitmap in the rgrp */
14501451 for (x = 0 ; x < rgd -> rd_length ; x ++ ) {
14511452 struct gfs2_bitmap * bi = rgd -> rd_bits + x ;
1453+ rgrp_lock_local (rgd );
14521454 ret = gfs2_rgrp_send_discards (sdp ,
14531455 rgd -> rd_data0 , NULL , bi , minlen ,
14541456 & amt );
1457+ rgrp_unlock_local (rgd );
14551458 if (ret ) {
14561459 gfs2_glock_dq_uninit (& gh );
14571460 goto out ;
@@ -1463,9 +1466,11 @@ int gfs2_fitrim(struct file *filp, void __user *argp)
14631466 ret = gfs2_trans_begin (sdp , RES_RG_HDR , 0 );
14641467 if (ret == 0 ) {
14651468 bh = rgd -> rd_bits [0 ].bi_bh ;
1469+ rgrp_lock_local (rgd );
14661470 rgd -> rd_flags |= GFS2_RGF_TRIMMED ;
14671471 gfs2_trans_add_meta (rgd -> rd_gl , bh );
14681472 gfs2_rgrp_out (rgd , bh -> b_data );
1473+ rgrp_unlock_local (rgd );
14691474 gfs2_trans_end (sdp );
14701475 }
14711476 }
@@ -2050,7 +2055,8 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, struct gfs2_alloc_parms *ap)
20502055 struct gfs2_sbd * sdp = GFS2_SB (& ip -> i_inode );
20512056 struct gfs2_rgrpd * begin = NULL ;
20522057 struct gfs2_blkreserv * rs = & ip -> i_res ;
2053- int error = 0 , rg_locked , flags = 0 ;
2058+ int error = 0 , flags = 0 ;
2059+ bool rg_locked ;
20542060 u64 last_unlinked = NO_BLOCK ;
20552061 u32 target = ap -> target ;
20562062 int loops = 0 ;
@@ -2079,10 +2085,10 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, struct gfs2_alloc_parms *ap)
20792085 while (loops < 3 ) {
20802086 struct gfs2_rgrpd * rgd ;
20812087
2082- rg_locked = 1 ;
2083-
2084- if (! gfs2_glock_is_locked_by_me ( rs -> rs_rgd -> rd_gl )) {
2085- rg_locked = 0 ;
2088+ rg_locked = gfs2_glock_is_locked_by_me ( rs -> rs_rgd -> rd_gl ) ;
2089+ if ( rg_locked ) {
2090+ rgrp_lock_local ( rs -> rs_rgd );
2091+ } else {
20862092 if (skip && skip -- )
20872093 goto next_rgrp ;
20882094 if (!gfs2_rs_active (rs )) {
@@ -2099,12 +2105,14 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, struct gfs2_alloc_parms *ap)
20992105 & ip -> i_rgd_gh );
21002106 if (unlikely (error ))
21012107 return error ;
2108+ rgrp_lock_local (rs -> rs_rgd );
21022109 if (!gfs2_rs_active (rs ) && (loops < 2 ) &&
21032110 gfs2_rgrp_congested (rs -> rs_rgd , loops ))
21042111 goto skip_rgrp ;
21052112 if (sdp -> sd_args .ar_rgrplvb ) {
21062113 error = update_rgrp_lvb (rs -> rs_rgd );
21072114 if (unlikely (error )) {
2115+ rgrp_unlock_local (rs -> rs_rgd );
21082116 gfs2_glock_dq_uninit (& ip -> i_rgd_gh );
21092117 return error ;
21102118 }
@@ -2142,13 +2150,16 @@ int gfs2_inplace_reserve(struct gfs2_inode *ip, struct gfs2_alloc_parms *ap)
21422150 rs -> rs_reserved = blocks_available ;
21432151 rgd -> rd_reserved += rs -> rs_reserved ;
21442152 spin_unlock (& rgd -> rd_rsspin );
2153+ rgrp_unlock_local (rs -> rs_rgd );
21452154 return 0 ;
21462155check_rgrp :
21472156 /* Check for unlinked inodes which can be reclaimed */
21482157 if (rs -> rs_rgd -> rd_flags & GFS2_RDF_CHECK )
21492158 try_rgrp_unlink (rs -> rs_rgd , & last_unlinked ,
21502159 ip -> i_no_addr );
21512160skip_rgrp :
2161+ rgrp_unlock_local (rs -> rs_rgd );
2162+
21522163 /* Drop reservation, if we couldn't use reserved rgrp */
21532164 if (gfs2_rs_active (rs ))
21542165 gfs2_rs_deltree (rs );
@@ -2293,6 +2304,7 @@ void gfs2_rgrp_dump(struct seq_file *seq, struct gfs2_rgrpd *rgd,
22932304 struct gfs2_blkreserv * trs ;
22942305 const struct rb_node * n ;
22952306
2307+ spin_lock (& rgd -> rd_rsspin );
22962308 gfs2_print_dbg (seq , "%s R: n:%llu f:%02x b:%u/%u i:%u q:%u r:%u e:%u\n" ,
22972309 fs_id_buf ,
22982310 (unsigned long long )rgd -> rd_addr , rgd -> rd_flags ,
@@ -2306,7 +2318,6 @@ void gfs2_rgrp_dump(struct seq_file *seq, struct gfs2_rgrpd *rgd,
23062318 be32_to_cpu (rgl -> rl_free ),
23072319 be32_to_cpu (rgl -> rl_dinodes ));
23082320 }
2309- spin_lock (& rgd -> rd_rsspin );
23102321 for (n = rb_first (& rgd -> rd_rstree ); n ; n = rb_next (& trs -> rs_node )) {
23112322 trs = rb_entry (n , struct gfs2_blkreserv , rs_node );
23122323 dump_rs (seq , trs , fs_id_buf );
@@ -2421,6 +2432,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
24212432
24222433 BUG_ON (ip -> i_res .rs_reserved < * nblocks );
24232434
2435+ rgrp_lock_local (rbm .rgd );
24242436 if (gfs2_rs_active (& ip -> i_res )) {
24252437 gfs2_set_alloc_start (& rbm , ip , dinode );
24262438 error = gfs2_rbm_find (& rbm , GFS2_BLKST_FREE , & minext , & ip -> i_res , false);
@@ -2477,6 +2489,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
24772489
24782490 gfs2_trans_add_meta (rbm .rgd -> rd_gl , rbm .rgd -> rd_bits [0 ].bi_bh );
24792491 gfs2_rgrp_out (rbm .rgd , rbm .rgd -> rd_bits [0 ].bi_bh -> b_data );
2492+ rgrp_unlock_local (rbm .rgd );
24802493
24812494 gfs2_statfs_change (sdp , 0 , - (s64 )* nblocks , dinode ? 1 : 0 );
24822495 if (dinode )
@@ -2490,6 +2503,7 @@ int gfs2_alloc_blocks(struct gfs2_inode *ip, u64 *bn, unsigned int *nblocks,
24902503 return 0 ;
24912504
24922505rgrp_error :
2506+ rgrp_unlock_local (rbm .rgd );
24932507 gfs2_rgrp_error (rbm .rgd );
24942508 return - EIO ;
24952509}
@@ -2509,12 +2523,14 @@ void __gfs2_free_blocks(struct gfs2_inode *ip, struct gfs2_rgrpd *rgd,
25092523{
25102524 struct gfs2_sbd * sdp = GFS2_SB (& ip -> i_inode );
25112525
2526+ rgrp_lock_local (rgd );
25122527 rgblk_free (sdp , rgd , bstart , blen , GFS2_BLKST_FREE );
25132528 trace_gfs2_block_alloc (ip , rgd , bstart , blen , GFS2_BLKST_FREE );
25142529 rgd -> rd_free += blen ;
25152530 rgd -> rd_flags &= ~GFS2_RGF_TRIMMED ;
25162531 gfs2_trans_add_meta (rgd -> rd_gl , rgd -> rd_bits [0 ].bi_bh );
25172532 gfs2_rgrp_out (rgd , rgd -> rd_bits [0 ].bi_bh -> b_data );
2533+ rgrp_unlock_local (rgd );
25182534
25192535 /* Directories keep their data in the metadata address space */
25202536 if (meta || ip -> i_depth || gfs2_is_jdata (ip ))
@@ -2550,17 +2566,20 @@ void gfs2_unlink_di(struct inode *inode)
25502566 rgd = gfs2_blk2rgrpd (sdp , blkno , true);
25512567 if (!rgd )
25522568 return ;
2569+ rgrp_lock_local (rgd );
25532570 rgblk_free (sdp , rgd , blkno , 1 , GFS2_BLKST_UNLINKED );
25542571 trace_gfs2_block_alloc (ip , rgd , blkno , 1 , GFS2_BLKST_UNLINKED );
25552572 gfs2_trans_add_meta (rgd -> rd_gl , rgd -> rd_bits [0 ].bi_bh );
25562573 gfs2_rgrp_out (rgd , rgd -> rd_bits [0 ].bi_bh -> b_data );
25572574 be32_add_cpu (& rgd -> rd_rgl -> rl_unlinked , 1 );
2575+ rgrp_unlock_local (rgd );
25582576}
25592577
25602578void gfs2_free_di (struct gfs2_rgrpd * rgd , struct gfs2_inode * ip )
25612579{
25622580 struct gfs2_sbd * sdp = rgd -> rd_sbd ;
25632581
2582+ rgrp_lock_local (rgd );
25642583 rgblk_free (sdp , rgd , ip -> i_no_addr , 1 , GFS2_BLKST_FREE );
25652584 if (!rgd -> rd_dinodes )
25662585 gfs2_consist_rgrpd (rgd );
@@ -2569,6 +2588,7 @@ void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip)
25692588
25702589 gfs2_trans_add_meta (rgd -> rd_gl , rgd -> rd_bits [0 ].bi_bh );
25712590 gfs2_rgrp_out (rgd , rgd -> rd_bits [0 ].bi_bh -> b_data );
2591+ rgrp_unlock_local (rgd );
25722592 be32_add_cpu (& rgd -> rd_rgl -> rl_unlinked , -1 );
25732593
25742594 gfs2_statfs_change (sdp , 0 , +1 , -1 );
@@ -2583,6 +2603,10 @@ void gfs2_free_di(struct gfs2_rgrpd *rgd, struct gfs2_inode *ip)
25832603 * @no_addr: The block number to check
25842604 * @type: The block type we are looking for
25852605 *
2606+ * The inode glock of @no_addr must be held. The @type to check for is either
2607+ * GFS2_BLKST_DINODE or GFS2_BLKST_UNLINKED; checking for type GFS2_BLKST_FREE
2608+ * or GFS2_BLKST_USED would make no sense.
2609+ *
25862610 * Returns: 0 if the block type matches the expected type
25872611 * -ESTALE if it doesn't match
25882612 * or -ve errno if something went wrong while checking
@@ -2606,6 +2630,13 @@ int gfs2_check_blk_type(struct gfs2_sbd *sdp, u64 no_addr, unsigned int type)
26062630 rbm .rgd = rgd ;
26072631 error = gfs2_rbm_from_block (& rbm , no_addr );
26082632 if (!WARN_ON_ONCE (error )) {
2633+ /*
2634+ * No need to take the local resource group lock here; the
2635+ * inode glock of @no_addr provides the necessary
2636+ * synchronization in case the block is an inode. (In case
2637+ * the block is not an inode, the block type will not match
2638+ * the @type we are looking for.)
2639+ */
26092640 if (gfs2_testbit (& rbm , false) != type )
26102641 error = - ESTALE ;
26112642 }
@@ -2730,3 +2761,14 @@ void gfs2_rlist_free(struct gfs2_rgrp_list *rlist)
27302761 }
27312762}
27322763
2764+ void rgrp_lock_local (struct gfs2_rgrpd * rgd )
2765+ {
2766+ BUG_ON (!gfs2_glock_is_held_excl (rgd -> rd_gl ) &&
2767+ !test_bit (SDF_NORECOVERY , & rgd -> rd_sbd -> sd_flags ));
2768+ mutex_lock (& rgd -> rd_mutex );
2769+ }
2770+
2771+ void rgrp_unlock_local (struct gfs2_rgrpd * rgd )
2772+ {
2773+ mutex_unlock (& rgd -> rd_mutex );
2774+ }
0 commit comments