@@ -429,6 +429,32 @@ bool gfs2_log_is_empty(struct gfs2_sbd *sdp) {
429429 return atomic_read (& sdp -> sd_log_blks_free ) == sdp -> sd_jdesc -> jd_blocks ;
430430}
431431
432+ static bool __gfs2_log_try_reserve_revokes (struct gfs2_sbd * sdp , unsigned int revokes )
433+ {
434+ unsigned int available ;
435+
436+ available = atomic_read (& sdp -> sd_log_revokes_available );
437+ while (available >= revokes ) {
438+ if (atomic_try_cmpxchg (& sdp -> sd_log_revokes_available ,
439+ & available , available - revokes ))
440+ return true;
441+ }
442+ return false;
443+ }
444+
445+ /**
446+ * gfs2_log_release_revokes - Release a given number of revokes
447+ * @sdp: The GFS2 superblock
448+ * @revokes: The number of revokes to release
449+ *
450+ * sdp->sd_log_flush_lock must be held.
451+ */
452+ void gfs2_log_release_revokes (struct gfs2_sbd * sdp , unsigned int revokes )
453+ {
454+ if (revokes )
455+ atomic_add (revokes , & sdp -> sd_log_revokes_available );
456+ }
457+
432458/**
433459 * gfs2_log_release - Release a given number of log blocks
434460 * @sdp: The GFS2 superblock
@@ -519,15 +545,59 @@ static void __gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks,
519545}
520546
521547/**
522- * gfs2_log_reserve - Make a log reservation
548+ * gfs2_log_try_reserve - Try to make a log reservation
523549 * @sdp: The GFS2 superblock
524- * @blks: The number of blocks to reserve
550+ * @tr: The transaction
551+ * @extra_revokes: The number of additional revokes reserved (output)
552+ *
553+ * This is similar to gfs2_log_reserve, but sdp->sd_log_flush_lock must be
554+ * held for correct revoke accounting.
525555 */
526556
527- void gfs2_log_reserve (struct gfs2_sbd * sdp , unsigned int blks )
557+ bool gfs2_log_try_reserve (struct gfs2_sbd * sdp , struct gfs2_trans * tr ,
558+ unsigned int * extra_revokes )
528559{
560+ unsigned int blks = tr -> tr_reserved ;
561+ unsigned int revokes = tr -> tr_revokes ;
562+ unsigned int revoke_blks = 0 ;
563+
564+ * extra_revokes = 0 ;
565+ if (revokes && !__gfs2_log_try_reserve_revokes (sdp , revokes )) {
566+ revoke_blks = DIV_ROUND_UP (revokes , sdp -> sd_inptrs );
567+ * extra_revokes = revoke_blks * sdp -> sd_inptrs - revokes ;
568+ blks += revoke_blks ;
569+ }
570+ if (!blks )
571+ return true;
529572 if (__gfs2_log_try_reserve (sdp , blks , GFS2_LOG_FLUSH_MIN_BLOCKS ))
530- return ;
573+ return true;
574+ if (!revoke_blks )
575+ gfs2_log_release_revokes (sdp , revokes );
576+ return false;
577+ }
578+
579+ /**
580+ * gfs2_log_reserve - Make a log reservation
581+ * @sdp: The GFS2 superblock
582+ * @tr: The transaction
583+ * @extra_revokes: The number of additional revokes reserved (output)
584+ *
585+ * sdp->sd_log_flush_lock must not be held.
586+ */
587+
588+ void gfs2_log_reserve (struct gfs2_sbd * sdp , struct gfs2_trans * tr ,
589+ unsigned int * extra_revokes )
590+ {
591+ unsigned int blks = tr -> tr_reserved ;
592+ unsigned int revokes = tr -> tr_revokes ;
593+ unsigned int revoke_blks = 0 ;
594+
595+ * extra_revokes = 0 ;
596+ if (revokes ) {
597+ revoke_blks = DIV_ROUND_UP (revokes , sdp -> sd_inptrs );
598+ * extra_revokes = revoke_blks * sdp -> sd_inptrs - revokes ;
599+ blks += revoke_blks ;
600+ }
531601 __gfs2_log_reserve (sdp , blks , GFS2_LOG_FLUSH_MIN_BLOCKS );
532602}
533603
@@ -588,9 +658,6 @@ static unsigned int calc_reserved(struct gfs2_sbd *sdp)
588658 blocks = tr -> tr_num_databuf_new - tr -> tr_num_databuf_rm ;
589659 reserved += blocks + DIV_ROUND_UP (blocks , databuf_limit (sdp ));
590660 }
591-
592- if (sdp -> sd_log_committed_revoke > 0 )
593- reserved += gfs2_struct2blk (sdp , sdp -> sd_log_committed_revoke ) - 1 ;
594661 return reserved ;
595662}
596663
@@ -730,14 +797,9 @@ void gfs2_glock_remove_revoke(struct gfs2_glock *gl)
730797void gfs2_flush_revokes (struct gfs2_sbd * sdp )
731798{
732799 /* number of revokes we still have room for */
733- unsigned int max_revokes ;
800+ unsigned int max_revokes = atomic_read ( & sdp -> sd_log_revokes_available ) ;
734801
735802 gfs2_log_lock (sdp );
736- max_revokes = sdp -> sd_ldptrs ;
737- if (sdp -> sd_log_num_revoke > sdp -> sd_ldptrs )
738- max_revokes += roundup (sdp -> sd_log_num_revoke - sdp -> sd_ldptrs ,
739- sdp -> sd_inptrs );
740- max_revokes -= sdp -> sd_log_num_revoke ;
741803 gfs2_ail1_empty (sdp , max_revokes );
742804 gfs2_log_unlock (sdp );
743805}
@@ -955,6 +1017,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
9551017 unsigned int reserved_blocks = 0 , used_blocks = 0 ;
9561018 enum gfs2_freeze_state state = atomic_read (& sdp -> sd_freeze_state );
9571019 unsigned int first_log_head ;
1020+ unsigned int reserved_revokes = 0 ;
9581021
9591022 down_write (& sdp -> sd_log_flush_lock );
9601023 trace_gfs2_log_flush (sdp , 1 , flags );
@@ -979,13 +1042,15 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
9791042 if (reserved_blocks )
9801043 gfs2_log_release (sdp , reserved_blocks );
9811044 reserved_blocks = sdp -> sd_log_blks_reserved ;
1045+ reserved_revokes = sdp -> sd_log_num_revoke ;
9821046 if (tr ) {
9831047 sdp -> sd_log_tr = NULL ;
9841048 tr -> tr_first = first_log_head ;
985- if (unlikely (state == SFS_FROZEN ))
1049+ if (unlikely (state == SFS_FROZEN )) {
9861050 if (gfs2_assert_withdraw_delayed (sdp ,
9871051 !tr -> tr_num_buf_new && !tr -> tr_num_databuf_new ))
9881052 goto out_withdraw ;
1053+ }
9891054 }
9901055 } else if (!reserved_blocks ) {
9911056 unsigned int taboo_blocks = GFS2_LOG_FLUSH_MIN_BLOCKS ;
@@ -1000,17 +1065,15 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
10001065 down_write (& sdp -> sd_log_flush_lock );
10011066 goto repeat ;
10021067 }
1068+ BUG_ON (sdp -> sd_log_num_revoke );
10031069 }
10041070
10051071 if (flags & GFS2_LOG_HEAD_FLUSH_SHUTDOWN )
10061072 clear_bit (SDF_JOURNAL_LIVE , & sdp -> sd_flags );
10071073
10081074 if (unlikely (state == SFS_FROZEN ))
1009- if (gfs2_assert_withdraw_delayed (sdp , !sdp -> sd_log_num_revoke ))
1075+ if (gfs2_assert_withdraw_delayed (sdp , !reserved_revokes ))
10101076 goto out_withdraw ;
1011- if (gfs2_assert_withdraw_delayed (sdp ,
1012- sdp -> sd_log_num_revoke == sdp -> sd_log_committed_revoke ))
1013- goto out_withdraw ;
10141077
10151078 gfs2_ordered_write (sdp );
10161079 if (gfs2_withdrawn (sdp ))
@@ -1034,7 +1097,6 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
10341097
10351098 gfs2_log_lock (sdp );
10361099 sdp -> sd_log_blks_reserved = 0 ;
1037- sdp -> sd_log_committed_revoke = 0 ;
10381100
10391101 spin_lock (& sdp -> sd_ail_lock );
10401102 if (tr && !list_empty (& tr -> tr_ail1_list )) {
@@ -1060,11 +1122,16 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
10601122
10611123out_end :
10621124 used_blocks = log_distance (sdp , sdp -> sd_log_flush_head , first_log_head );
1063- if (gfs2_assert_withdraw_delayed (sdp , used_blocks <= reserved_blocks ))
1064- goto out ;
1125+ reserved_revokes += atomic_read (& sdp -> sd_log_revokes_available );
1126+ atomic_set (& sdp -> sd_log_revokes_available , sdp -> sd_ldptrs );
1127+ gfs2_assert_withdraw (sdp , reserved_revokes % sdp -> sd_inptrs == sdp -> sd_ldptrs );
1128+ if (reserved_revokes > sdp -> sd_ldptrs )
1129+ reserved_blocks += (reserved_revokes - sdp -> sd_ldptrs ) / sdp -> sd_inptrs ;
10651130out :
1066- if (used_blocks != reserved_blocks )
1131+ if (used_blocks != reserved_blocks ) {
1132+ gfs2_assert_withdraw_delayed (sdp , used_blocks < reserved_blocks );
10671133 gfs2_log_release (sdp , reserved_blocks - used_blocks );
1134+ }
10681135 up_write (& sdp -> sd_log_flush_lock );
10691136 gfs2_trans_free (sdp , tr );
10701137 if (gfs2_withdrawing (sdp ))
@@ -1105,8 +1172,8 @@ static void gfs2_merge_trans(struct gfs2_sbd *sdp, struct gfs2_trans *new)
11051172 old -> tr_num_databuf_new += new -> tr_num_databuf_new ;
11061173 old -> tr_num_buf_rm += new -> tr_num_buf_rm ;
11071174 old -> tr_num_databuf_rm += new -> tr_num_databuf_rm ;
1175+ old -> tr_revokes += new -> tr_revokes ;
11081176 old -> tr_num_revoke += new -> tr_num_revoke ;
1109- old -> tr_num_revoke_rm += new -> tr_num_revoke_rm ;
11101177
11111178 list_splice_tail_init (& new -> tr_databuf , & old -> tr_databuf );
11121179 list_splice_tail_init (& new -> tr_buf , & old -> tr_buf );
@@ -1133,7 +1200,6 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
11331200 set_bit (TR_ATTACHED , & tr -> tr_flags );
11341201 }
11351202
1136- sdp -> sd_log_committed_revoke += tr -> tr_num_revoke - tr -> tr_num_revoke_rm ;
11371203 reserved = calc_reserved (sdp );
11381204 maxres = sdp -> sd_log_blks_reserved + tr -> tr_reserved ;
11391205 gfs2_assert_withdraw (sdp , maxres >= reserved );
0 commit comments