aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2006-04-11 14:49:06 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2006-04-11 14:49:06 -0400
commitf4154ea039bbf45c52840b30c68143a2dc28d4b4 (patch)
treefa00645dd60a9140e885be96a4aa9797cf4cfeac /fs/gfs2
parented3865079b573ef55dc13ab0bfb242ed5ebab4c1 (diff)
[GFS2] Update journal accounting code.
A small update to the journaling code to change the way that the "extra" blocks are accounted for in the journal. These are used at a rate of one per 503 metadata blocks or one per 251 journaled data blocks (or just one if the total number of journaled blocks in the transaction is smaller). Since we are using them at two different rates the old method of accounting for them no longer works and we count them up as required. Since the "per transaction" accounting can't handle this (there is no fixed number of header blocks per transaction) we have to account for it in the general journal code. We now require that each transaction reserves more blocks than it actually needs to take account of the possible extra blocks. Also a final fix to dir.c to ensure that all ref counts are handled correctly. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2')
-rw-r--r--fs/gfs2/dir.c8
-rw-r--r--fs/gfs2/log.c10
-rw-r--r--fs/gfs2/trans.c13
3 files changed, 12 insertions, 19 deletions
diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c
index 100672d2c6c5..01f89c727cc8 100644
--- a/fs/gfs2/dir.c
+++ b/fs/gfs2/dir.c
@@ -776,9 +776,9 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
776 goto got_dent; 776 goto got_dent;
777 leaf = (struct gfs2_leaf *)bh->b_data; 777 leaf = (struct gfs2_leaf *)bh->b_data;
778 ln = be64_to_cpu(leaf->lf_next); 778 ln = be64_to_cpu(leaf->lf_next);
779 brelse(bh);
779 if (!ln) 780 if (!ln)
780 break; 781 break;
781 brelse(bh);
782 error = get_leaf(ip, ln, &bh); 782 error = get_leaf(ip, ln, &bh);
783 } while(!error); 783 } while(!error);
784 784
@@ -790,7 +790,7 @@ static struct gfs2_dirent *gfs2_dirent_search(struct inode *inode,
790 return ERR_PTR(error); 790 return ERR_PTR(error);
791 dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size, scan, name, NULL); 791 dent = gfs2_dirent_scan(inode, bh->b_data, bh->b_size, scan, name, NULL);
792got_dent: 792got_dent:
793 if (unlikely(IS_ERR(dent))) { 793 if (unlikely(dent == NULL || IS_ERR(dent))) {
794 brelse(bh); 794 brelse(bh);
795 bh = NULL; 795 bh = NULL;
796 } 796 }
@@ -1477,7 +1477,6 @@ int gfs2_dir_search(struct inode *dir, const struct qstr *name,
1477 brelse(bh); 1477 brelse(bh);
1478 return 0; 1478 return 0;
1479 } 1479 }
1480 brelse(bh);
1481 return -ENOENT; 1480 return -ENOENT;
1482} 1481}
1483 1482
@@ -1619,7 +1618,6 @@ int gfs2_dir_del(struct gfs2_inode *dip, const struct qstr *name)
1619 previous entry otherwise */ 1618 previous entry otherwise */
1620 dent = gfs2_dirent_search(dip->i_vnode, name, gfs2_dirent_prev, &bh); 1619 dent = gfs2_dirent_search(dip->i_vnode, name, gfs2_dirent_prev, &bh);
1621 if (!dent) { 1620 if (!dent) {
1622 brelse(bh);
1623 gfs2_consist_inode(dip); 1621 gfs2_consist_inode(dip);
1624 return -EIO; 1622 return -EIO;
1625 } 1623 }
@@ -1680,7 +1678,6 @@ int gfs2_dir_mvino(struct gfs2_inode *dip, const struct qstr *filename,
1680 1678
1681 dent = gfs2_dirent_search(dip->i_vnode, filename, gfs2_dirent_find, &bh); 1679 dent = gfs2_dirent_search(dip->i_vnode, filename, gfs2_dirent_find, &bh);
1682 if (!dent) { 1680 if (!dent) {
1683 brelse(bh);
1684 gfs2_consist_inode(dip); 1681 gfs2_consist_inode(dip);
1685 return -EIO; 1682 return -EIO;
1686 } 1683 }
@@ -1961,7 +1958,6 @@ int gfs2_diradd_alloc_required(struct inode *inode,
1961 1958
1962 dent = gfs2_dirent_search(inode, name, gfs2_dirent_find_space, &bh); 1959 dent = gfs2_dirent_search(inode, name, gfs2_dirent_find_space, &bh);
1963 if (!dent) { 1960 if (!dent) {
1964 brelse(bh);
1965 return 1; 1961 return 1;
1966 } 1962 }
1967 if (IS_ERR(dent)) 1963 if (IS_ERR(dent))
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 0b26d6a74118..b0dd0b9ad79b 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -412,11 +412,13 @@ static void log_flush_commit(struct gfs2_sbd *sdp)
412 struct list_head *head = &sdp->sd_log_flush_list; 412 struct list_head *head = &sdp->sd_log_flush_list;
413 struct gfs2_log_buf *lb; 413 struct gfs2_log_buf *lb;
414 struct buffer_head *bh; 414 struct buffer_head *bh;
415#if 0
415 unsigned int d; 416 unsigned int d;
416 417
417 d = log_distance(sdp, sdp->sd_log_flush_head, sdp->sd_log_head); 418 d = log_distance(sdp, sdp->sd_log_flush_head, sdp->sd_log_head);
418 419
419 gfs2_assert_withdraw(sdp, d + 1 == sdp->sd_log_blks_reserved); 420 gfs2_assert_withdraw(sdp, d + 1 == sdp->sd_log_blks_reserved);
421#endif
420 422
421 while (!list_empty(head)) { 423 while (!list_empty(head)) {
422 lb = list_entry(head->next, struct gfs2_log_buf, lb_list); 424 lb = list_entry(head->next, struct gfs2_log_buf, lb_list);
@@ -483,6 +485,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
483 sdp->sd_log_head = sdp->sd_log_flush_head; 485 sdp->sd_log_head = sdp->sd_log_flush_head;
484 486
485 /* printk(KERN_INFO "sd_log_num_hdrs %u\n", sdp->sd_log_num_hdrs); */ 487 /* printk(KERN_INFO "sd_log_num_hdrs %u\n", sdp->sd_log_num_hdrs); */
488 sdp->sd_log_blks_free -= sdp->sd_log_num_hdrs;
486 489
487 sdp->sd_log_blks_reserved = 490 sdp->sd_log_blks_reserved =
488 sdp->sd_log_commited_buf = 491 sdp->sd_log_commited_buf =
@@ -515,8 +518,7 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
515 gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0); 518 gfs2_assert_withdraw(sdp, ((int)sdp->sd_log_commited_revoke) >= 0);
516 519
517 if (sdp->sd_log_commited_buf) 520 if (sdp->sd_log_commited_buf)
518 reserved += 1 + sdp->sd_log_commited_buf + 521 reserved += sdp->sd_log_commited_buf;
519 sdp->sd_log_commited_buf/503;
520 if (sdp->sd_log_commited_revoke) 522 if (sdp->sd_log_commited_revoke)
521 reserved += gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke, 523 reserved += gfs2_struct2blk(sdp, sdp->sd_log_commited_revoke,
522 sizeof(uint64_t)); 524 sizeof(uint64_t));
@@ -527,7 +529,8 @@ static void log_refund(struct gfs2_sbd *sdp, struct gfs2_trans *tr)
527 529
528 gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old); 530 gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free >= old);
529 gfs2_assert_withdraw(sdp, 531 gfs2_assert_withdraw(sdp,
530 sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks); 532 sdp->sd_log_blks_free <= sdp->sd_jdesc->jd_blocks +
533 sdp->sd_log_num_hdrs);
531 534
532 sdp->sd_log_blks_reserved = reserved; 535 sdp->sd_log_blks_reserved = reserved;
533 536
@@ -582,6 +585,7 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp)
582 585
583 log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, 0); 586 log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT, 0);
584 587
588 /* printk(KERN_INFO "sd_log_blks_free %u, sd_jdesc->jd_blocks %u\n", sdp->sd_log_blks_free, sdp->sd_jdesc->jd_blocks); */
585 gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free == 589 gfs2_assert_withdraw(sdp, sdp->sd_log_blks_free ==
586 sdp->sd_jdesc->jd_blocks); 590 sdp->sd_jdesc->jd_blocks);
587 gfs2_assert_withdraw(sdp, sdp->sd_log_head == sdp->sd_log_tail); 591 gfs2_assert_withdraw(sdp, sdp->sd_log_head == sdp->sd_log_tail);
diff --git a/fs/gfs2/trans.c b/fs/gfs2/trans.c
index 061f4a9a1db4..6b02d8c38f0f 100644
--- a/fs/gfs2/trans.c
+++ b/fs/gfs2/trans.c
@@ -44,7 +44,7 @@ int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks,
44 tr->tr_revokes = revokes; 44 tr->tr_revokes = revokes;
45 tr->tr_reserved = 1; 45 tr->tr_reserved = 1;
46 if (blocks) 46 if (blocks)
47 tr->tr_reserved += 1 + blocks; 47 tr->tr_reserved += 6 + blocks;
48 if (revokes) 48 if (revokes)
49 tr->tr_reserved += gfs2_struct2blk(sdp, revokes, 49 tr->tr_reserved += gfs2_struct2blk(sdp, revokes,
50 sizeof(uint64_t)); 50 sizeof(uint64_t));
@@ -83,20 +83,15 @@ fail_holder_uninit:
83 83
84void gfs2_trans_end(struct gfs2_sbd *sdp) 84void gfs2_trans_end(struct gfs2_sbd *sdp)
85{ 85{
86 struct gfs2_trans *tr; 86 struct gfs2_trans *tr = current->journal_info;
87 87
88 tr = current->journal_info; 88 BUG_ON(!tr);
89 current->journal_info = NULL; 89 current->journal_info = NULL;
90 90
91 if (gfs2_assert_warn(sdp, tr))
92 return;
93
94 if (!tr->tr_touched) { 91 if (!tr->tr_touched) {
95 gfs2_log_release(sdp, tr->tr_reserved); 92 gfs2_log_release(sdp, tr->tr_reserved);
96
97 gfs2_glock_dq(&tr->tr_t_gh); 93 gfs2_glock_dq(&tr->tr_t_gh);
98 gfs2_holder_uninit(&tr->tr_t_gh); 94 gfs2_holder_uninit(&tr->tr_t_gh);
99
100 kfree(tr); 95 kfree(tr);
101 return; 96 return;
102 } 97 }
@@ -113,10 +108,8 @@ void gfs2_trans_end(struct gfs2_sbd *sdp)
113 } 108 }
114 109
115 gfs2_log_commit(sdp, tr); 110 gfs2_log_commit(sdp, tr);
116
117 gfs2_glock_dq(&tr->tr_t_gh); 111 gfs2_glock_dq(&tr->tr_t_gh);
118 gfs2_holder_uninit(&tr->tr_t_gh); 112 gfs2_holder_uninit(&tr->tr_t_gh);
119
120 kfree(tr); 113 kfree(tr);
121 114
122 if (sdp->sd_vfs->s_flags & MS_SYNCHRONOUS) 115 if (sdp->sd_vfs->s_flags & MS_SYNCHRONOUS)