diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/gfs2/incore.h | 4 | ||||
-rw-r--r-- | fs/gfs2/log.c | 100 | ||||
-rw-r--r-- | fs/gfs2/lops.c | 53 | ||||
-rw-r--r-- | fs/gfs2/lops.h | 23 | ||||
-rw-r--r-- | fs/gfs2/meta_io.c | 8 |
5 files changed, 132 insertions, 56 deletions
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index c7c6ec0f17c7..170ba93829c0 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
@@ -354,7 +354,9 @@ struct gfs2_trans { | |||
354 | 354 | ||
355 | unsigned int tr_num_buf; | 355 | unsigned int tr_num_buf; |
356 | unsigned int tr_num_buf_new; | 356 | unsigned int tr_num_buf_new; |
357 | unsigned int tr_num_databuf_new; | ||
357 | unsigned int tr_num_buf_rm; | 358 | unsigned int tr_num_buf_rm; |
359 | unsigned int tr_num_databuf_rm; | ||
358 | struct list_head tr_list_buf; | 360 | struct list_head tr_list_buf; |
359 | 361 | ||
360 | unsigned int tr_num_revoke; | 362 | unsigned int tr_num_revoke; |
@@ -599,6 +601,7 @@ struct gfs2_sbd { | |||
599 | 601 | ||
600 | unsigned int sd_log_blks_reserved; | 602 | unsigned int sd_log_blks_reserved; |
601 | unsigned int sd_log_commited_buf; | 603 | unsigned int sd_log_commited_buf; |
604 | unsigned int sd_log_commited_databuf; | ||
602 | unsigned int sd_log_commited_revoke; | 605 | unsigned int sd_log_commited_revoke; |
603 | 606 | ||
604 | unsigned int sd_log_num_gl; | 607 | unsigned int sd_log_num_gl; |
@@ -607,7 +610,6 @@ struct gfs2_sbd { | |||
607 | unsigned int sd_log_num_rg; | 610 | unsigned int sd_log_num_rg; |
608 | unsigned int sd_log_num_databuf; | 611 | unsigned int sd_log_num_databuf; |
609 | unsigned int sd_log_num_jdata; | 612 | unsigned int sd_log_num_jdata; |
610 | unsigned int sd_log_num_hdrs; | ||
611 | 613 | ||
612 | struct list_head sd_log_le_gl; | 614 | struct list_head sd_log_le_gl; |
613 | struct list_head sd_log_le_buf; | 615 | struct list_head sd_log_le_buf; |
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index fbdc0dc9923e..8fcfb784f906 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -276,7 +276,7 @@ static void ail2_empty(struct gfs2_sbd *sdp, unsigned int new_tail) | |||
276 | * @blks: The number of blocks to reserve | 276 | * @blks: The number of blocks to reserve |
277 | * | 277 | * |
278 | * Note that we never give out the last few blocks of the journal. Thats | 278 | * Note that we never give out the last few blocks of the journal. Thats |
279 | * due to the fact that there is are a small number of header blocks | 279 | * due to the fact that there is a small number of header blocks |
280 | * associated with each log flush. The exact number can't be known until | 280 | * associated with each log flush. The exact number can't be known until |
281 | * flush time, so we ensure that we have just enough free blocks at all | 281 | * flush time, so we ensure that we have just enough free blocks at all |
282 | * times to avoid running out during a log flush. | 282 | * times to avoid running out during a log flush. |
@@ -371,6 +371,58 @@ static inline unsigned int log_distance(struct gfs2_sbd *sdp, unsigned int newer | |||
371 | return dist; | 371 | return dist; |
372 | } | 372 | } |
373 | 373 | ||
374 | /** | ||
375 | * calc_reserved - Calculate the number of blocks to reserve when | ||
376 | * refunding a transaction's unused buffers. | ||
377 | * @sdp: The GFS2 superblock | ||
378 | * | ||
379 | * This is complex. We need to reserve room for all our currently used | ||
380 | * metadata buffers (e.g. normal file I/O rewriting file time stamps) and | ||
381 | * all our journaled data buffers for journaled files (e.g. files in the | ||
382 | * meta_fs like rindex, or files for which chattr +j was done.) | ||
383 | * If we don't reserve enough space, gfs2_log_refund and gfs2_log_flush | ||
384 | * will count it as free space (sd_log_blks_free) and corruption will follow. | ||
385 | * | ||
386 | * We can have metadata bufs and jdata bufs in the same journal. So each | ||
387 | * type gets its own log header, for which we need to reserve a block. | ||
388 | * In fact, each type has the potential for needing more than one header | ||
389 | * in cases where we have more buffers than will fit on a journal page. | ||
390 | * Metadata journal entries take up half the space of journaled buffer entries. | ||
391 | * Thus, metadata entries have buf_limit (502) and journaled buffers have | ||
392 | * databuf_limit (251) before they cause a wrap around. | ||
393 | * | ||
394 | * Also, we need to reserve blocks for revoke journal entries and one for an | ||
395 | * overall header for the lot. | ||
396 | * | ||
397 | * Returns: the number of blocks reserved | ||
398 | */ | ||
399 | static unsigned int calc_reserved(struct gfs2_sbd *sdp) | ||
400 | { | ||
401 | unsigned int reserved = 0; | ||
402 | unsigned int mbuf_limit, metabufhdrs_needed; | ||
403 | unsigned int dbuf_limit, databufhdrs_needed; | ||
404 | unsigned int revokes = 0; | ||
405 | |||
406 | mbuf_limit = buf_limit(sdp); | ||
407 | metabufhdrs_needed = (sdp->sd_log_commited_buf + | ||
408 | (mbuf_limit - 1)) / mbuf_limit; | ||
409 | dbuf_limit = databuf_limit(sdp); | ||
410 | databufhdrs_needed = (sdp->sd_log_commited_databuf + | ||
411 | (dbuf_limit - 1)) / dbuf_limit; | ||
412 | |||
413 | if (sdp->sd_log_commited_revoke) | ||
414 | revokes = gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke, | ||
415 | sizeof(u64)); | ||
416 | |||
417 | reserved = sdp->sd_log_commited_buf + metabufhdrs_needed + | ||
418 | sdp->sd_log_commited_databuf + databufhdrs_needed + | ||
419 | revokes; | ||
420 | /* One for the overall header */ | ||
421 | if (reserved) | ||
422 | reserved++; | ||
423 | return reserved; | ||
424 | } | ||
425 | |||
374 | static unsigned int current_tail(struct gfs2_sbd *sdp) | 426 | static unsigned int current_tail(struct gfs2_sbd *sdp) |
375 | { | 427 | { |
376 | struct gfs2_ail *ai; | 428 | struct gfs2_ail *ai; |
@@ -461,14 +513,14 @@ struct buffer_head *gfs2_log_fake_buf(struct gfs2_sbd *sdp, | |||
461 | return bh; | 513 | return bh; |
462 | } | 514 | } |
463 | 515 | ||
464 | static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail, int pull) | 516 | static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail) |
465 | { | 517 | { |
466 | unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail); | 518 | unsigned int dist = log_distance(sdp, new_tail, sdp->sd_log_tail); |
467 | 519 | ||
468 | ail2_empty(sdp, new_tail); | 520 | ail2_empty(sdp, new_tail); |
469 | 521 | ||
470 | gfs2_log_lock(sdp); | 522 | gfs2_log_lock(sdp); |
471 | sdp->sd_log_blks_free += dist - (pull ? 1 : 0); | 523 | sdp->sd_log_blks_free += dist; |
472 | gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks); | 524 | gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks); |
473 | gfs2_log_unlock(sdp); | 525 | gfs2_log_unlock(sdp); |
474 | 526 | ||
@@ -518,7 +570,7 @@ static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull) | |||
518 | brelse(bh); | 570 | brelse(bh); |
519 | 571 | ||
520 | if (sdp->sd_log_tail != tail) | 572 | if (sdp->sd_log_tail != tail) |
521 | log_pull_tail(sdp, tail, pull); | 573 | log_pull_tail(sdp, tail); |
522 | else | 574 | else |
523 | gfs2_assert_withdraw(sdp, !pull); | 575 | gfs2_assert_withdraw(sdp, !pull); |
524 | 576 | ||
@@ -579,7 +631,10 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
579 | INIT_LIST_HEAD(&ai->ai_ail1_list); | 631 | INIT_LIST_HEAD(&ai->ai_ail1_list); |
580 | INIT_LIST_HEAD(&ai->ai_ail2_list); | 632 | INIT_LIST_HEAD(&ai->ai_ail2_list); |
581 | 633 | ||
582 | gfs2_assert_withdraw(sdp, sdp->sd_log_num_buf + sdp->sd_log_num_jdata == sdp->sd_log_commited_buf); | 634 | gfs2_assert_withdraw(sdp, |
635 | sdp->sd_log_num_buf + sdp->sd_log_num_jdata == | ||
636 | sdp->sd_log_commited_buf + | ||
637 | sdp->sd_log_commited_databuf); | ||
583 | gfs2_assert_withdraw(sdp, | 638 | gfs2_assert_withdraw(sdp, |
584 | sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); | 639 | sdp->sd_log_num_revoke == sdp->sd_log_commited_revoke); |
585 | 640 | ||
@@ -590,16 +645,19 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
590 | lops_before_commit(sdp); | 645 | lops_before_commit(sdp); |
591 | if (!list_empty(&sdp->sd_log_flush_list)) | 646 | if (!list_empty(&sdp->sd_log_flush_list)) |
592 | log_flush_commit(sdp); | 647 | log_flush_commit(sdp); |
593 | else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle) | 648 | else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ |
649 | gfs2_log_lock(sdp); | ||
650 | sdp->sd_log_blks_free--; /* Adjust for unreserved buffer */ | ||
651 | gfs2_log_unlock(sdp); | ||
594 | log_write_header(sdp, 0, PULL); | 652 | log_write_header(sdp, 0, PULL); |
653 | } | ||
595 | lops_after_commit(sdp, ai); | 654 | lops_after_commit(sdp, ai); |
596 | 655 | ||
597 | gfs2_log_lock(sdp); | 656 | gfs2_log_lock(sdp); |
598 | sdp->sd_log_head = sdp->sd_log_flush_head; | 657 | sdp->sd_log_head = sdp->sd_log_flush_head; |
599 | sdp->sd_log_blks_free -= sdp->sd_log_num_hdrs; | ||
600 | sdp->sd_log_blks_reserved = 0; | 658 | sdp->sd_log_blks_reserved = 0; |
601 | sdp->sd_log_commited_buf = 0; | 659 | sdp->sd_log_commited_buf = 0; |
602 | sdp->sd_log_num_hdrs = 0; | 660 | sdp->sd_log_commited_databuf = 0; |
603 | sdp->sd_log_commited_revoke = 0; | 661 | sdp->sd_log_commited_revoke = 0; |
604 | 662 | ||
605 | if (!list_empty(&ai->ai_ail1_list)) { | 663 | if (!list_empty(&ai->ai_ail1_list)) { |
@@ -616,32 +674,26 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
616 | 674 | ||
617 | static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) | 675 | static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr) |
618 | { | 676 | { |
619 | unsigned int reserved = 0; | 677 | unsigned int reserved; |
620 | unsigned int old; | 678 | unsigned int old; |
621 | 679 | ||
622 | gfs2_log_lock(sdp); | 680 | gfs2_log_lock(sdp); |
623 | 681 | ||
624 | sdp->sd_log_commited_buf += tr->tr_num_buf_new - tr->tr_num_buf_rm; | 682 | sdp->sd_log_commited_buf += tr->tr_num_buf_new - tr->tr_num_buf_rm; |
625 | gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_buf) >= 0); | 683 | sdp->sd_log_commited_databuf += tr->tr_num_databuf_new - |
684 | tr->tr_num_databuf_rm; | ||
685 | gfs2_assert_withdraw(sdp, (((int)sdp->sd_log_commited_buf) >= 0) || | ||
686 | (((int)sdp->sd_log_commited_databuf) >= 0)); | ||
626 | sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; | 687 | sdp->sd_log_commited_revoke += tr->tr_num_revoke - tr->tr_num_revoke_rm; |
627 | gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0); | 688 | gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0); |
628 | 689 | reserved = calc_reserved(sdp); | |
629 | if (sdp->sd_log_commited_buf) | ||
630 | reserved += sdp->sd_log_commited_buf; | ||
631 | if (sdp->sd_log_commited_revoke) | ||
632 | reserved += gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke, | ||
633 | sizeof(u64)); | ||
634 | if (reserved) | ||
635 | reserved++; | ||
636 | |||
637 | old = sdp->sd_log_blks_free; | 690 | old = sdp->sd_log_blks_free; |
638 | sdp->sd_log_blks_free += tr->tr_reserved - | 691 | sdp->sd_log_blks_free += tr->tr_reserved - |
639 | (reserved - sdp->sd_log_blks_reserved); | 692 | (reserved - sdp->sd_log_blks_reserved); |
640 | 693 | ||
641 | gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old); | 694 | gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old); |
642 | gfs2_assert_withdraw(sdp, | 695 | gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free <= |
643 | sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks + | 696 | sdp->sd_jdesc->jd_blocks); |
644 | sdp->sd_log_num_hdrs); | ||
645 | 697 | ||
646 | sdp->sd_log_blks_reserved = reserved; | 698 | sdp->sd_log_blks_reserved = reserved; |
647 | 699 | ||
@@ -687,13 +739,13 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp) | |||
687 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); | 739 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); |
688 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg); | 740 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg); |
689 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf); | 741 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf); |
690 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_hdrs); | ||
691 | gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list)); | 742 | gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list)); |
692 | 743 | ||
693 | sdp->sd_log_flush_head = sdp->sd_log_head; | 744 | sdp->sd_log_flush_head = sdp->sd_log_head; |
694 | sdp->sd_log_flush_wrapped = 0; | 745 | sdp->sd_log_flush_wrapped = 0; |
695 | 746 | ||
696 | log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, 0); | 747 | log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, |
748 | (sdp->sd_log_tail == current_tail(sdp)) ? 0 : PULL); | ||
697 | 749 | ||
698 | gfs2_assert_warn(sdp, sdp->sd_log_blks_free == sdp->sd_jdesc->jd_blocks); | 750 | gfs2_assert_warn(sdp, sdp->sd_log_blks_free == sdp->sd_jdesc->jd_blocks); |
699 | gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); | 751 | gfs2_assert_warn(sdp, sdp->sd_log_head == sdp->sd_log_tail); |
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c index df6bceea379a..dd810ad68cf0 100644 --- a/fs/gfs2/lops.c +++ b/fs/gfs2/lops.c | |||
@@ -17,6 +17,7 @@ | |||
17 | 17 | ||
18 | #include "gfs2.h" | 18 | #include "gfs2.h" |
19 | #include "incore.h" | 19 | #include "incore.h" |
20 | #include "inode.h" | ||
20 | #include "glock.h" | 21 | #include "glock.h" |
21 | #include "log.h" | 22 | #include "log.h" |
22 | #include "lops.h" | 23 | #include "lops.h" |
@@ -117,15 +118,13 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp) | |||
117 | struct gfs2_log_descriptor *ld; | 118 | struct gfs2_log_descriptor *ld; |
118 | struct gfs2_bufdata *bd1 = NULL, *bd2; | 119 | struct gfs2_bufdata *bd1 = NULL, *bd2; |
119 | unsigned int total = sdp->sd_log_num_buf; | 120 | unsigned int total = sdp->sd_log_num_buf; |
120 | unsigned int offset = sizeof(struct gfs2_log_descriptor); | 121 | unsigned int offset = BUF_OFFSET; |
121 | unsigned int limit; | 122 | unsigned int limit; |
122 | unsigned int num; | 123 | unsigned int num; |
123 | unsigned n; | 124 | unsigned n; |
124 | __be64 *ptr; | 125 | __be64 *ptr; |
125 | 126 | ||
126 | offset += sizeof(__be64) - 1; | 127 | limit = buf_limit(sdp); |
127 | offset &= ~(sizeof(__be64) - 1); | ||
128 | limit = (sdp->sd_sb.sb_bsize - offset)/sizeof(__be64); | ||
129 | /* for 4k blocks, limit = 503 */ | 128 | /* for 4k blocks, limit = 503 */ |
130 | 129 | ||
131 | bd1 = bd2 = list_prepare_entry(bd1, &sdp->sd_log_le_buf, bd_le.le_list); | 130 | bd1 = bd2 = list_prepare_entry(bd1, &sdp->sd_log_le_buf, bd_le.le_list); |
@@ -134,7 +133,6 @@ static void buf_lo_before_commit(struct gfs2_sbd *sdp) | |||
134 | if (total > limit) | 133 | if (total > limit) |
135 | num = limit; | 134 | num = limit; |
136 | bh = gfs2_log_get_buf(sdp); | 135 | bh = gfs2_log_get_buf(sdp); |
137 | sdp->sd_log_num_hdrs++; | ||
138 | ld = (struct gfs2_log_descriptor *)bh->b_data; | 136 | ld = (struct gfs2_log_descriptor *)bh->b_data; |
139 | ptr = (__be64 *)(bh->b_data + offset); | 137 | ptr = (__be64 *)(bh->b_data + offset); |
140 | ld->ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC); | 138 | ld->ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC); |
@@ -469,27 +467,26 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le) | |||
469 | struct gfs2_inode *ip = GFS2_I(mapping->host); | 467 | struct gfs2_inode *ip = GFS2_I(mapping->host); |
470 | 468 | ||
471 | gfs2_log_lock(sdp); | 469 | gfs2_log_lock(sdp); |
472 | tr->tr_touched = 1; | 470 | if (!list_empty(&bd->bd_list_tr)) { |
473 | if (list_empty(&bd->bd_list_tr) && | ||
474 | (ip->i_di.di_flags & GFS2_DIF_JDATA)) { | ||
475 | tr->tr_num_buf++; | ||
476 | list_add(&bd->bd_list_tr, &tr->tr_list_buf); | ||
477 | gfs2_log_unlock(sdp); | ||
478 | if (!list_empty(&le->le_list)) | ||
479 | return; | ||
480 | gfs2_pin(sdp, bd->bd_bh); | ||
481 | tr->tr_num_buf_new++; | ||
482 | } else { | ||
483 | gfs2_log_unlock(sdp); | 471 | gfs2_log_unlock(sdp); |
472 | return; | ||
484 | } | 473 | } |
474 | tr->tr_touched = 1; | ||
475 | tr->tr_num_buf++; | ||
476 | list_add(&bd->bd_list_tr, &tr->tr_list_buf); | ||
477 | gfs2_log_unlock(sdp); | ||
478 | if (!list_empty(&le->le_list)) | ||
479 | return; | ||
480 | |||
485 | gfs2_trans_add_gl(bd->bd_gl); | 481 | gfs2_trans_add_gl(bd->bd_gl); |
486 | gfs2_log_lock(sdp); | 482 | if (gfs2_is_jdata(ip)) { |
487 | if (list_empty(&le->le_list)) { | 483 | sdp->sd_log_num_jdata++; |
488 | if (ip->i_di.di_flags & GFS2_DIF_JDATA) | 484 | gfs2_pin(sdp, bd->bd_bh); |
489 | sdp->sd_log_num_jdata++; | 485 | tr->tr_num_databuf_new++; |
490 | sdp->sd_log_num_databuf++; | ||
491 | list_add(&le->le_list, &sdp->sd_log_le_databuf); | ||
492 | } | 486 | } |
487 | sdp->sd_log_num_databuf++; | ||
488 | gfs2_log_lock(sdp); | ||
489 | list_add(&le->le_list, &sdp->sd_log_le_databuf); | ||
493 | gfs2_log_unlock(sdp); | 490 | gfs2_log_unlock(sdp); |
494 | } | 491 | } |
495 | 492 | ||
@@ -522,7 +519,6 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
522 | LIST_HEAD(started); | 519 | LIST_HEAD(started); |
523 | struct gfs2_bufdata *bd1 = NULL, *bd2, *bdt; | 520 | struct gfs2_bufdata *bd1 = NULL, *bd2, *bdt; |
524 | struct buffer_head *bh = NULL,*bh1 = NULL; | 521 | struct buffer_head *bh = NULL,*bh1 = NULL; |
525 | unsigned int offset = sizeof(struct gfs2_log_descriptor); | ||
526 | struct gfs2_log_descriptor *ld; | 522 | struct gfs2_log_descriptor *ld; |
527 | unsigned int limit; | 523 | unsigned int limit; |
528 | unsigned int total_dbuf = sdp->sd_log_num_databuf; | 524 | unsigned int total_dbuf = sdp->sd_log_num_databuf; |
@@ -530,9 +526,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
530 | unsigned int num, n; | 526 | unsigned int num, n; |
531 | __be64 *ptr = NULL; | 527 | __be64 *ptr = NULL; |
532 | 528 | ||
533 | offset += 2*sizeof(__be64) - 1; | 529 | limit = databuf_limit(sdp); |
534 | offset &= ~(2*sizeof(__be64) - 1); | ||
535 | limit = (sdp->sd_sb.sb_bsize - offset)/sizeof(__be64); | ||
536 | 530 | ||
537 | /* | 531 | /* |
538 | * Start writing ordered buffers, write journaled buffers | 532 | * Start writing ordered buffers, write journaled buffers |
@@ -583,10 +577,10 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
583 | gfs2_log_unlock(sdp); | 577 | gfs2_log_unlock(sdp); |
584 | if (!bh) { | 578 | if (!bh) { |
585 | bh = gfs2_log_get_buf(sdp); | 579 | bh = gfs2_log_get_buf(sdp); |
586 | sdp->sd_log_num_hdrs++; | ||
587 | ld = (struct gfs2_log_descriptor *) | 580 | ld = (struct gfs2_log_descriptor *) |
588 | bh->b_data; | 581 | bh->b_data; |
589 | ptr = (__be64 *)(bh->b_data + offset); | 582 | ptr = (__be64 *)(bh->b_data + |
583 | DATABUF_OFFSET); | ||
590 | ld->ld_header.mh_magic = | 584 | ld->ld_header.mh_magic = |
591 | cpu_to_be32(GFS2_MAGIC); | 585 | cpu_to_be32(GFS2_MAGIC); |
592 | ld->ld_header.mh_type = | 586 | ld->ld_header.mh_type = |
@@ -607,8 +601,7 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp) | |||
607 | if (unlikely(magic != 0)) | 601 | if (unlikely(magic != 0)) |
608 | set_buffer_escaped(bh1); | 602 | set_buffer_escaped(bh1); |
609 | gfs2_log_lock(sdp); | 603 | gfs2_log_lock(sdp); |
610 | n += 2; | 604 | if (++n >= num) |
611 | if (n >= num) | ||
612 | break; | 605 | break; |
613 | } else if (!bh1) { | 606 | } else if (!bh1) { |
614 | total_dbuf--; | 607 | total_dbuf--; |
diff --git a/fs/gfs2/lops.h b/fs/gfs2/lops.h index 965bc65c7c64..41a00df75587 100644 --- a/fs/gfs2/lops.h +++ b/fs/gfs2/lops.h | |||
@@ -13,6 +13,13 @@ | |||
13 | #include <linux/list.h> | 13 | #include <linux/list.h> |
14 | #include "incore.h" | 14 | #include "incore.h" |
15 | 15 | ||
16 | #define BUF_OFFSET \ | ||
17 | ((sizeof(struct gfs2_log_descriptor) + sizeof(__be64) - 1) & \ | ||
18 | ~(sizeof(__be64) - 1)) | ||
19 | #define DATABUF_OFFSET \ | ||
20 | ((sizeof(struct gfs2_log_descriptor) + (2 * sizeof(__be64) - 1)) & \ | ||
21 | ~(2 * sizeof(__be64) - 1)) | ||
22 | |||
16 | extern const struct gfs2_log_operations gfs2_glock_lops; | 23 | extern const struct gfs2_log_operations gfs2_glock_lops; |
17 | extern const struct gfs2_log_operations gfs2_buf_lops; | 24 | extern const struct gfs2_log_operations gfs2_buf_lops; |
18 | extern const struct gfs2_log_operations gfs2_revoke_lops; | 25 | extern const struct gfs2_log_operations gfs2_revoke_lops; |
@@ -21,6 +28,22 @@ extern const struct gfs2_log_operations gfs2_databuf_lops; | |||
21 | 28 | ||
22 | extern const struct gfs2_log_operations *gfs2_log_ops[]; | 29 | extern const struct gfs2_log_operations *gfs2_log_ops[]; |
23 | 30 | ||
31 | static inline unsigned int buf_limit(struct gfs2_sbd *sdp) | ||
32 | { | ||
33 | unsigned int limit; | ||
34 | |||
35 | limit = (sdp->sd_sb.sb_bsize - BUF_OFFSET) / sizeof(__be64); | ||
36 | return limit; | ||
37 | } | ||
38 | |||
39 | static inline unsigned int databuf_limit(struct gfs2_sbd *sdp) | ||
40 | { | ||
41 | unsigned int limit; | ||
42 | |||
43 | limit = (sdp->sd_sb.sb_bsize - DATABUF_OFFSET) / (2 * sizeof(__be64)); | ||
44 | return limit; | ||
45 | } | ||
46 | |||
24 | static inline void lops_init_le(struct gfs2_log_element *le, | 47 | static inline void lops_init_le(struct gfs2_log_element *le, |
25 | const struct gfs2_log_operations *lops) | 48 | const struct gfs2_log_operations *lops) |
26 | { | 49 | { |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index e62d4f620c58..8da343b34ae7 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -387,12 +387,18 @@ void gfs2_meta_wipe(struct gfs2_inode *ip, u64 bstart, u32 blen) | |||
387 | 387 | ||
388 | if (test_clear_buffer_pinned(bh)) { | 388 | if (test_clear_buffer_pinned(bh)) { |
389 | struct gfs2_trans *tr = current->journal_info; | 389 | struct gfs2_trans *tr = current->journal_info; |
390 | struct gfs2_inode *bh_ip = | ||
391 | GFS2_I(bh->b_page->mapping->host); | ||
392 | |||
390 | gfs2_log_lock(sdp); | 393 | gfs2_log_lock(sdp); |
391 | list_del_init(&bd->bd_le.le_list); | 394 | list_del_init(&bd->bd_le.le_list); |
392 | gfs2_assert_warn(sdp, sdp->sd_log_num_buf); | 395 | gfs2_assert_warn(sdp, sdp->sd_log_num_buf); |
393 | sdp->sd_log_num_buf--; | 396 | sdp->sd_log_num_buf--; |
394 | gfs2_log_unlock(sdp); | 397 | gfs2_log_unlock(sdp); |
395 | tr->tr_num_buf_rm++; | 398 | if (bh_ip->i_inode.i_private != NULL) |
399 | tr->tr_num_databuf_rm++; | ||
400 | else | ||
401 | tr->tr_num_buf_rm++; | ||
396 | brelse(bh); | 402 | brelse(bh); |
397 | } | 403 | } |
398 | if (bd) { | 404 | if (bd) { |