diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-08 20:14:59 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-01-08 20:14:59 -0500 |
commit | 2150edc6c5cf00f7adb54538b9ea2a3e9cedca3f (patch) | |
tree | f72a0d85e66f500b4cead348a231e3d3b9f357bc /fs/jbd2/journal.c | |
parent | cd764695b67386a81964f68e9c66efd9f13f4d29 (diff) | |
parent | 4b905671d2ea09fd48fed72c581df17e40823f39 (diff) |
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4: (57 commits)
jbd2: Fix oops in jbd2_journal_init_inode() on corrupted fs
ext4: Remove "extents" mount option
block: Add Kconfig help which notes that ext4 needs CONFIG_LBD
ext4: Make printk's consistently prefixed with "EXT4-fs: "
ext4: Add sanity checks for the superblock before mounting the filesystem
ext4: Add mount option to set kjournald's I/O priority
jbd2: Submit writes to the journal using WRITE_SYNC
jbd2: Add pid and journal device name to the "kjournald2 starting" message
ext4: Add markers for better debuggability
ext4: Remove code to create the journal inode
ext4: provide function to release metadata pages under memory pressure
ext3: provide function to release metadata pages under memory pressure
add releasepage hooks to block devices which can be used by file systems
ext4: Fix s_dirty_blocks_counter if block allocation failed with nodelalloc
ext4: Init the complete page while building buddy cache
ext4: Don't allow new groups to be added during block allocation
ext4: mark the blocks/inode bitmap beyond end of group as used
ext4: Use new buffer_head flag to check uninit group bitmaps initialization
ext4: Fix the race between read_inode_bitmap() and ext4_new_inode()
ext4: code cleanup
...
Diffstat (limited to 'fs/jbd2/journal.c')
-rw-r--r-- | fs/jbd2/journal.c | 124 |
1 files changed, 37 insertions, 87 deletions
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index f6bff9d6f8df..56675306ed81 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -40,6 +40,7 @@ | |||
40 | 40 | ||
41 | #include <asm/uaccess.h> | 41 | #include <asm/uaccess.h> |
42 | #include <asm/page.h> | 42 | #include <asm/page.h> |
43 | #include <asm/div64.h> | ||
43 | 44 | ||
44 | EXPORT_SYMBOL(jbd2_journal_start); | 45 | EXPORT_SYMBOL(jbd2_journal_start); |
45 | EXPORT_SYMBOL(jbd2_journal_restart); | 46 | EXPORT_SYMBOL(jbd2_journal_restart); |
@@ -66,7 +67,6 @@ EXPORT_SYMBOL(jbd2_journal_update_format); | |||
66 | EXPORT_SYMBOL(jbd2_journal_check_used_features); | 67 | EXPORT_SYMBOL(jbd2_journal_check_used_features); |
67 | EXPORT_SYMBOL(jbd2_journal_check_available_features); | 68 | EXPORT_SYMBOL(jbd2_journal_check_available_features); |
68 | EXPORT_SYMBOL(jbd2_journal_set_features); | 69 | EXPORT_SYMBOL(jbd2_journal_set_features); |
69 | EXPORT_SYMBOL(jbd2_journal_create); | ||
70 | EXPORT_SYMBOL(jbd2_journal_load); | 70 | EXPORT_SYMBOL(jbd2_journal_load); |
71 | EXPORT_SYMBOL(jbd2_journal_destroy); | 71 | EXPORT_SYMBOL(jbd2_journal_destroy); |
72 | EXPORT_SYMBOL(jbd2_journal_abort); | 72 | EXPORT_SYMBOL(jbd2_journal_abort); |
@@ -132,8 +132,9 @@ static int kjournald2(void *arg) | |||
132 | journal->j_task = current; | 132 | journal->j_task = current; |
133 | wake_up(&journal->j_wait_done_commit); | 133 | wake_up(&journal->j_wait_done_commit); |
134 | 134 | ||
135 | printk(KERN_INFO "kjournald2 starting. Commit interval %ld seconds\n", | 135 | printk(KERN_INFO "kjournald2 starting: pid %d, dev %s, " |
136 | journal->j_commit_interval / HZ); | 136 | "commit interval %ld seconds\n", current->pid, |
137 | journal->j_devname, journal->j_commit_interval / HZ); | ||
137 | 138 | ||
138 | /* | 139 | /* |
139 | * And now, wait forever for commit wakeup events. | 140 | * And now, wait forever for commit wakeup events. |
@@ -650,6 +651,8 @@ struct journal_head *jbd2_journal_get_descriptor_buffer(journal_t *journal) | |||
650 | return NULL; | 651 | return NULL; |
651 | 652 | ||
652 | bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); | 653 | bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); |
654 | if (!bh) | ||
655 | return NULL; | ||
653 | lock_buffer(bh); | 656 | lock_buffer(bh); |
654 | memset(bh->b_data, 0, journal->j_blocksize); | 657 | memset(bh->b_data, 0, journal->j_blocksize); |
655 | set_buffer_uptodate(bh); | 658 | set_buffer_uptodate(bh); |
@@ -843,6 +846,8 @@ static int jbd2_seq_info_show(struct seq_file *seq, void *v) | |||
843 | jiffies_to_msecs(s->stats->u.run.rs_flushing / s->stats->ts_tid)); | 846 | jiffies_to_msecs(s->stats->u.run.rs_flushing / s->stats->ts_tid)); |
844 | seq_printf(seq, " %ums logging transaction\n", | 847 | seq_printf(seq, " %ums logging transaction\n", |
845 | jiffies_to_msecs(s->stats->u.run.rs_logging / s->stats->ts_tid)); | 848 | jiffies_to_msecs(s->stats->u.run.rs_logging / s->stats->ts_tid)); |
849 | seq_printf(seq, " %luus average transaction commit time\n", | ||
850 | do_div(s->journal->j_average_commit_time, 1000)); | ||
846 | seq_printf(seq, " %lu handles per transaction\n", | 851 | seq_printf(seq, " %lu handles per transaction\n", |
847 | s->stats->u.run.rs_handle_count / s->stats->ts_tid); | 852 | s->stats->u.run.rs_handle_count / s->stats->ts_tid); |
848 | seq_printf(seq, " %lu blocks per transaction\n", | 853 | seq_printf(seq, " %lu blocks per transaction\n", |
@@ -980,6 +985,8 @@ static journal_t * journal_init_common (void) | |||
980 | spin_lock_init(&journal->j_state_lock); | 985 | spin_lock_init(&journal->j_state_lock); |
981 | 986 | ||
982 | journal->j_commit_interval = (HZ * JBD2_DEFAULT_MAX_COMMIT_AGE); | 987 | journal->j_commit_interval = (HZ * JBD2_DEFAULT_MAX_COMMIT_AGE); |
988 | journal->j_min_batch_time = 0; | ||
989 | journal->j_max_batch_time = 15000; /* 15ms */ | ||
983 | 990 | ||
984 | /* The journal is marked for error until we succeed with recovery! */ | 991 | /* The journal is marked for error until we succeed with recovery! */ |
985 | journal->j_flags = JBD2_ABORT; | 992 | journal->j_flags = JBD2_ABORT; |
@@ -1035,15 +1042,14 @@ journal_t * jbd2_journal_init_dev(struct block_device *bdev, | |||
1035 | 1042 | ||
1036 | /* journal descriptor can store up to n blocks -bzzz */ | 1043 | /* journal descriptor can store up to n blocks -bzzz */ |
1037 | journal->j_blocksize = blocksize; | 1044 | journal->j_blocksize = blocksize; |
1045 | jbd2_stats_proc_init(journal); | ||
1038 | n = journal->j_blocksize / sizeof(journal_block_tag_t); | 1046 | n = journal->j_blocksize / sizeof(journal_block_tag_t); |
1039 | journal->j_wbufsize = n; | 1047 | journal->j_wbufsize = n; |
1040 | journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL); | 1048 | journal->j_wbuf = kmalloc(n * sizeof(struct buffer_head*), GFP_KERNEL); |
1041 | if (!journal->j_wbuf) { | 1049 | if (!journal->j_wbuf) { |
1042 | printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n", | 1050 | printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n", |
1043 | __func__); | 1051 | __func__); |
1044 | kfree(journal); | 1052 | goto out_err; |
1045 | journal = NULL; | ||
1046 | goto out; | ||
1047 | } | 1053 | } |
1048 | journal->j_dev = bdev; | 1054 | journal->j_dev = bdev; |
1049 | journal->j_fs_dev = fs_dev; | 1055 | journal->j_fs_dev = fs_dev; |
@@ -1053,14 +1059,22 @@ journal_t * jbd2_journal_init_dev(struct block_device *bdev, | |||
1053 | p = journal->j_devname; | 1059 | p = journal->j_devname; |
1054 | while ((p = strchr(p, '/'))) | 1060 | while ((p = strchr(p, '/'))) |
1055 | *p = '!'; | 1061 | *p = '!'; |
1056 | jbd2_stats_proc_init(journal); | ||
1057 | 1062 | ||
1058 | bh = __getblk(journal->j_dev, start, journal->j_blocksize); | 1063 | bh = __getblk(journal->j_dev, start, journal->j_blocksize); |
1059 | J_ASSERT(bh != NULL); | 1064 | if (!bh) { |
1065 | printk(KERN_ERR | ||
1066 | "%s: Cannot get buffer for journal superblock\n", | ||
1067 | __func__); | ||
1068 | goto out_err; | ||
1069 | } | ||
1060 | journal->j_sb_buffer = bh; | 1070 | journal->j_sb_buffer = bh; |
1061 | journal->j_superblock = (journal_superblock_t *)bh->b_data; | 1071 | journal->j_superblock = (journal_superblock_t *)bh->b_data; |
1062 | out: | 1072 | |
1063 | return journal; | 1073 | return journal; |
1074 | out_err: | ||
1075 | jbd2_stats_proc_exit(journal); | ||
1076 | kfree(journal); | ||
1077 | return NULL; | ||
1064 | } | 1078 | } |
1065 | 1079 | ||
1066 | /** | 1080 | /** |
@@ -1108,9 +1122,7 @@ journal_t * jbd2_journal_init_inode (struct inode *inode) | |||
1108 | if (!journal->j_wbuf) { | 1122 | if (!journal->j_wbuf) { |
1109 | printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n", | 1123 | printk(KERN_ERR "%s: Cant allocate bhs for commit thread\n", |
1110 | __func__); | 1124 | __func__); |
1111 | jbd2_stats_proc_exit(journal); | 1125 | goto out_err; |
1112 | kfree(journal); | ||
1113 | return NULL; | ||
1114 | } | 1126 | } |
1115 | 1127 | ||
1116 | err = jbd2_journal_bmap(journal, 0, &blocknr); | 1128 | err = jbd2_journal_bmap(journal, 0, &blocknr); |
@@ -1118,17 +1130,24 @@ journal_t * jbd2_journal_init_inode (struct inode *inode) | |||
1118 | if (err) { | 1130 | if (err) { |
1119 | printk(KERN_ERR "%s: Cannnot locate journal superblock\n", | 1131 | printk(KERN_ERR "%s: Cannnot locate journal superblock\n", |
1120 | __func__); | 1132 | __func__); |
1121 | jbd2_stats_proc_exit(journal); | 1133 | goto out_err; |
1122 | kfree(journal); | ||
1123 | return NULL; | ||
1124 | } | 1134 | } |
1125 | 1135 | ||
1126 | bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); | 1136 | bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); |
1127 | J_ASSERT(bh != NULL); | 1137 | if (!bh) { |
1138 | printk(KERN_ERR | ||
1139 | "%s: Cannot get buffer for journal superblock\n", | ||
1140 | __func__); | ||
1141 | goto out_err; | ||
1142 | } | ||
1128 | journal->j_sb_buffer = bh; | 1143 | journal->j_sb_buffer = bh; |
1129 | journal->j_superblock = (journal_superblock_t *)bh->b_data; | 1144 | journal->j_superblock = (journal_superblock_t *)bh->b_data; |
1130 | 1145 | ||
1131 | return journal; | 1146 | return journal; |
1147 | out_err: | ||
1148 | jbd2_stats_proc_exit(journal); | ||
1149 | kfree(journal); | ||
1150 | return NULL; | ||
1132 | } | 1151 | } |
1133 | 1152 | ||
1134 | /* | 1153 | /* |
@@ -1177,77 +1196,6 @@ static int journal_reset(journal_t *journal) | |||
1177 | } | 1196 | } |
1178 | 1197 | ||
1179 | /** | 1198 | /** |
1180 | * int jbd2_journal_create() - Initialise the new journal file | ||
1181 | * @journal: Journal to create. This structure must have been initialised | ||
1182 | * | ||
1183 | * Given a journal_t structure which tells us which disk blocks we can | ||
1184 | * use, create a new journal superblock and initialise all of the | ||
1185 | * journal fields from scratch. | ||
1186 | **/ | ||
1187 | int jbd2_journal_create(journal_t *journal) | ||
1188 | { | ||
1189 | unsigned long long blocknr; | ||
1190 | struct buffer_head *bh; | ||
1191 | journal_superblock_t *sb; | ||
1192 | int i, err; | ||
1193 | |||
1194 | if (journal->j_maxlen < JBD2_MIN_JOURNAL_BLOCKS) { | ||
1195 | printk (KERN_ERR "Journal length (%d blocks) too short.\n", | ||
1196 | journal->j_maxlen); | ||
1197 | journal_fail_superblock(journal); | ||
1198 | return -EINVAL; | ||
1199 | } | ||
1200 | |||
1201 | if (journal->j_inode == NULL) { | ||
1202 | /* | ||
1203 | * We don't know what block to start at! | ||
1204 | */ | ||
1205 | printk(KERN_EMERG | ||
1206 | "%s: creation of journal on external device!\n", | ||
1207 | __func__); | ||
1208 | BUG(); | ||
1209 | } | ||
1210 | |||
1211 | /* Zero out the entire journal on disk. We cannot afford to | ||
1212 | have any blocks on disk beginning with JBD2_MAGIC_NUMBER. */ | ||
1213 | jbd_debug(1, "JBD: Zeroing out journal blocks...\n"); | ||
1214 | for (i = 0; i < journal->j_maxlen; i++) { | ||
1215 | err = jbd2_journal_bmap(journal, i, &blocknr); | ||
1216 | if (err) | ||
1217 | return err; | ||
1218 | bh = __getblk(journal->j_dev, blocknr, journal->j_blocksize); | ||
1219 | lock_buffer(bh); | ||
1220 | memset (bh->b_data, 0, journal->j_blocksize); | ||
1221 | BUFFER_TRACE(bh, "marking dirty"); | ||
1222 | mark_buffer_dirty(bh); | ||
1223 | BUFFER_TRACE(bh, "marking uptodate"); | ||
1224 | set_buffer_uptodate(bh); | ||
1225 | unlock_buffer(bh); | ||
1226 | __brelse(bh); | ||
1227 | } | ||
1228 | |||
1229 | sync_blockdev(journal->j_dev); | ||
1230 | jbd_debug(1, "JBD: journal cleared.\n"); | ||
1231 | |||
1232 | /* OK, fill in the initial static fields in the new superblock */ | ||
1233 | sb = journal->j_superblock; | ||
1234 | |||
1235 | sb->s_header.h_magic = cpu_to_be32(JBD2_MAGIC_NUMBER); | ||
1236 | sb->s_header.h_blocktype = cpu_to_be32(JBD2_SUPERBLOCK_V2); | ||
1237 | |||
1238 | sb->s_blocksize = cpu_to_be32(journal->j_blocksize); | ||
1239 | sb->s_maxlen = cpu_to_be32(journal->j_maxlen); | ||
1240 | sb->s_first = cpu_to_be32(1); | ||
1241 | |||
1242 | journal->j_transaction_sequence = 1; | ||
1243 | |||
1244 | journal->j_flags &= ~JBD2_ABORT; | ||
1245 | journal->j_format_version = 2; | ||
1246 | |||
1247 | return journal_reset(journal); | ||
1248 | } | ||
1249 | |||
1250 | /** | ||
1251 | * void jbd2_journal_update_superblock() - Update journal sb on disk. | 1199 | * void jbd2_journal_update_superblock() - Update journal sb on disk. |
1252 | * @journal: The journal to update. | 1200 | * @journal: The journal to update. |
1253 | * @wait: Set to '0' if you don't want to wait for IO completion. | 1201 | * @wait: Set to '0' if you don't want to wait for IO completion. |
@@ -1491,7 +1439,9 @@ int jbd2_journal_destroy(journal_t *journal) | |||
1491 | spin_lock(&journal->j_list_lock); | 1439 | spin_lock(&journal->j_list_lock); |
1492 | while (journal->j_checkpoint_transactions != NULL) { | 1440 | while (journal->j_checkpoint_transactions != NULL) { |
1493 | spin_unlock(&journal->j_list_lock); | 1441 | spin_unlock(&journal->j_list_lock); |
1442 | mutex_lock(&journal->j_checkpoint_mutex); | ||
1494 | jbd2_log_do_checkpoint(journal); | 1443 | jbd2_log_do_checkpoint(journal); |
1444 | mutex_unlock(&journal->j_checkpoint_mutex); | ||
1495 | spin_lock(&journal->j_list_lock); | 1445 | spin_lock(&journal->j_list_lock); |
1496 | } | 1446 | } |
1497 | 1447 | ||