aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/log.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-04-07 11:17:32 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-04-07 11:17:32 -0400
commitb09e593d799560f1a0782c20ac5900058390a26f (patch)
tree20f04bd2c8ba9c09ac80a7bb1400d341c4fd7e21 /fs/gfs2/log.c
parent55eccc6d00cea224bf634d44e9871cfe83200ff2 (diff)
[GFS2] Fix a ref count bug and other clean ups
This fixes a ref count bug that sometimes showed up a umount time (causing it to hang) but it otherwise mostly harmless. At the same time there are some clean ups including making the log operations structures const, moving a memory allocation so that its not done in the fast path of checking to see if there is an outstanding transaction related to a particular glock. Removes the sd_log_wrap varaible which was updated, but never actually used anywhere. Updates the gfs2 ioctl() to run without the kernel lock (which it never needed anyway). Removes the "invalidate inodes" loop from GFS2's put_super routine. This is done in kill super anyway so we don't need to do it here. The loop was also bogus in that if there are any inodes "stuck" at this point its a bug and we need to know about it rather than hide it by hanging forever. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/log.c')
-rw-r--r--fs/gfs2/log.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index ea69376c00d8..cadfef193e55 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -171,13 +171,14 @@ int gfs2_log_reserve(struct gfs2_sbd *sdp, unsigned int blks)
171 while(sdp->sd_log_blks_free <= blks) { 171 while(sdp->sd_log_blks_free <= blks) {
172 gfs2_log_unlock(sdp); 172 gfs2_log_unlock(sdp);
173 gfs2_ail1_empty(sdp, 0); 173 gfs2_ail1_empty(sdp, 0);
174 gfs2_log_flush(sdp); 174 gfs2_log_flush(sdp, NULL);
175 175
176 if (try++) 176 if (try++)
177 gfs2_ail1_start(sdp, 0); 177 gfs2_ail1_start(sdp, 0);
178 gfs2_log_lock(sdp); 178 gfs2_log_lock(sdp);
179 } 179 }
180 sdp->sd_log_blks_free -= blks; 180 sdp->sd_log_blks_free -= blks;
181 /* printk(KERN_INFO "reserved %u blocks (%u left)\n", blks, sdp->sd_log_blks_free); */
181 gfs2_log_unlock(sdp); 182 gfs2_log_unlock(sdp);
182 mutex_unlock(&sdp->sd_log_reserve_mutex); 183 mutex_unlock(&sdp->sd_log_reserve_mutex);
183 184
@@ -199,6 +200,7 @@ void gfs2_log_release(struct gfs2_sbd *sdp, unsigned int blks)
199 200
200 gfs2_log_lock(sdp); 201 gfs2_log_lock(sdp);
201 sdp->sd_log_blks_free += blks; 202 sdp->sd_log_blks_free += blks;
203 /* printk(KERN_INFO "released %u blocks (%u left)\n", blks, sdp->sd_log_blks_free); */
202 gfs2_assert_withdraw(sdp, 204 gfs2_assert_withdraw(sdp,
203 sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks); 205 sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks);
204 gfs2_log_unlock(sdp); 206 gfs2_log_unlock(sdp);
@@ -342,6 +344,7 @@ static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail, int pull)
342 344
343 gfs2_log_lock(sdp); 345 gfs2_log_lock(sdp);
344 sdp->sd_log_blks_free += dist - ((pull) ? 1 : 0); 346 sdp->sd_log_blks_free += dist - ((pull) ? 1 : 0);
347 /* printk(KERN_INFO "pull tail refunding %u blocks (%u left) pull=%d\n", dist - ((pull) ? 1 : 0), sdp->sd_log_blks_free, pull); */
345 gfs2_assert_withdraw(sdp, 348 gfs2_assert_withdraw(sdp,
346 sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks); 349 sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks);
347 gfs2_log_unlock(sdp); 350 gfs2_log_unlock(sdp);
@@ -364,6 +367,8 @@ static void log_write_header(struct gfs2_sbd *sdp, uint32_t flags, int pull)
364 unsigned int tail; 367 unsigned int tail;
365 uint32_t hash; 368 uint32_t hash;
366 369
370 /* printk(KERN_INFO "log write header start (flags=%08x, pull=%d)\n", flags, pull); */
371
367 bh = sb_getblk(sdp->sd_vfs, blkno); 372 bh = sb_getblk(sdp->sd_vfs, blkno);
368 lock_buffer(bh); 373 lock_buffer(bh);
369 memset(bh->b_data, 0, bh->b_size); 374 memset(bh->b_data, 0, bh->b_size);
@@ -398,6 +403,8 @@ static void log_write_header(struct gfs2_sbd *sdp, uint32_t flags, int pull)
398 403
399 sdp->sd_log_idle = (tail == sdp->sd_log_flush_head); 404 sdp->sd_log_idle = (tail == sdp->sd_log_flush_head);
400 log_incr_head(sdp); 405 log_incr_head(sdp);
406
407 /* printk(KERN_INFO "log write header out\n"); */
401} 408}
402 409
403static void log_flush_commit(struct gfs2_sbd *sdp) 410static void log_flush_commit(struct gfs2_sbd *sdp)
@@ -432,20 +439,16 @@ static void log_flush_commit(struct gfs2_sbd *sdp)
432} 439}
433 440
434/** 441/**
435 * gfs2_log_flush_i - flush incore transaction(s) 442 * gfs2_log_flush - flush incore transaction(s)
436 * @sdp: the filesystem 443 * @sdp: the filesystem
437 * @gl: The glock structure to flush. If NULL, flush the whole incore log 444 * @gl: The glock structure to flush. If NULL, flush the whole incore log
438 * 445 *
439 */ 446 */
440 447
441void gfs2_log_flush_i(struct gfs2_sbd *sdp, struct gfs2_glock *gl) 448void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
442{ 449{
443 struct gfs2_ail *ai; 450 struct gfs2_ail *ai;
444 451
445 ai = kzalloc(sizeof(struct gfs2_ail), GFP_NOFS | __GFP_NOFAIL);
446 INIT_LIST_HEAD(&ai->ai_ail1_list);
447 INIT_LIST_HEAD(&ai->ai_ail2_list);
448
449 down_write(&sdp->sd_log_flush_lock); 452 down_write(&sdp->sd_log_flush_lock);
450 453
451 if (gl) { 454 if (gl) {
@@ -453,12 +456,14 @@ void gfs2_log_flush_i(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
453 if (list_empty(&gl->gl_le.le_list)) { 456 if (list_empty(&gl->gl_le.le_list)) {
454 gfs2_log_unlock(sdp); 457 gfs2_log_unlock(sdp);
455 up_write(&sdp->sd_log_flush_lock); 458 up_write(&sdp->sd_log_flush_lock);
456 kfree(ai);
457 return; 459 return;
458 } 460 }
459 gfs2_log_unlock(sdp); 461 gfs2_log_unlock(sdp);
460 } 462 }
461 463
464 ai = kzalloc(sizeof(struct gfs2_ail), GFP_NOFS | __GFP_NOFAIL);
465 INIT_LIST_HEAD(&ai->ai_ail1_list);
466 INIT_LIST_HEAD(&ai->ai_ail2_list);
462 467
463 gfs2_assert_withdraw(sdp, 468 gfs2_assert_withdraw(sdp,
464 sdp->sd_log_num_buf == sdp->sd_log_commited_buf); 469 sdp->sd_log_num_buf == sdp->sd_log_commited_buf);
@@ -476,11 +481,12 @@ void gfs2_log_flush_i(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
476 log_write_header(sdp, 0, PULL); 481 log_write_header(sdp, 0, PULL);
477 lops_after_commit(sdp, ai); 482 lops_after_commit(sdp, ai);
478 sdp->sd_log_head = sdp->sd_log_flush_head; 483 sdp->sd_log_head = sdp->sd_log_flush_head;
479 if (sdp->sd_log_flush_wrapped) 484
480 sdp->sd_log_wraps++; 485 /* printk(KERN_INFO "sd_log_num_hdrs %u\n", sdp->sd_log_num_hdrs); */
481 486
482 sdp->sd_log_blks_reserved = 487 sdp->sd_log_blks_reserved =
483 sdp->sd_log_commited_buf = 488 sdp->sd_log_commited_buf =
489 sdp->sd_log_num_hdrs =
484 sdp->sd_log_commited_revoke = 0; 490 sdp->sd_log_commited_revoke = 0;
485 491
486 gfs2_log_lock(sdp); 492 gfs2_log_lock(sdp);
@@ -519,8 +525,7 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
519 sdp->sd_log_blks_free += tr->tr_reserved - 525 sdp->sd_log_blks_free += tr->tr_reserved -
520 (reserved - sdp->sd_log_blks_reserved); 526 (reserved - sdp->sd_log_blks_reserved);
521 527
522 gfs2_assert_withdraw(sdp, 528 gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old);
523 sdp->sd_log_blks_free >= old);
524 gfs2_assert_withdraw(sdp, 529 gfs2_assert_withdraw(sdp,
525 sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks); 530 sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks);
526 531
@@ -548,7 +553,7 @@ void gfs2_log_commit(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
548 gfs2_log_lock(sdp); 553 gfs2_log_lock(sdp);
549 if (sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks)) { 554 if (sdp->sd_log_num_buf > gfs2_tune_get(sdp, gt_incore_log_blocks)) {
550 gfs2_log_unlock(sdp); 555 gfs2_log_unlock(sdp);
551 gfs2_log_flush(sdp); 556 gfs2_log_flush(sdp, NULL);
552 } else 557 } else
553 gfs2_log_unlock(sdp); 558 gfs2_log_unlock(sdp);
554} 559}
@@ -583,8 +588,6 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp)
583 gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail2_list)); 588 gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail2_list));
584 589
585 sdp->sd_log_head = sdp->sd_log_flush_head; 590 sdp->sd_log_head = sdp->sd_log_flush_head;
586 if (sdp->sd_log_flush_wrapped)
587 sdp->sd_log_wraps++;
588 sdp->sd_log_tail = sdp->sd_log_head; 591 sdp->sd_log_tail = sdp->sd_log_head;
589 592
590 up_write(&sdp->sd_log_flush_lock); 593 up_write(&sdp->sd_log_flush_lock);