]> git.ipfire.org Git - people/ms/u-boot.git/blob - fs/ext4/ext4_journal.c
cf14049c32931465630ab4e3832f3816226c7a15
[people/ms/u-boot.git] / fs / ext4 / ext4_journal.c
1 /*
2 * (C) Copyright 2011 - 2012 Samsung Electronics
3 * EXT4 filesystem implementation in Uboot by
4 * Uma Shankar <uma.shankar@samsung.com>
5 * Manjunatha C Achar <a.manjunatha@samsung.com>
6 *
7 * Journal data structures and headers for Journaling feature of ext4
8 * have been referred from JBD2 (Journaling Block device 2)
9 * implementation in Linux Kernel.
10 * Written by Stephen C. Tweedie <sct@redhat.com>
11 *
12 * Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved
13 * SPDX-License-Identifier: GPL-2.0+
14 */
15
16 #include <common.h>
17 #include <ext4fs.h>
18 #include <malloc.h>
19 #include <ext_common.h>
20 #include "ext4_common.h"
21
22 static struct revoke_blk_list *revk_blk_list;
23 static struct revoke_blk_list *prev_node;
24 static int first_node = true;
25
26 int gindex;
27 int gd_index;
28 int jrnl_blk_idx;
29 struct journal_log *journal_ptr[MAX_JOURNAL_ENTRIES];
30 struct dirty_blocks *dirty_block_ptr[MAX_JOURNAL_ENTRIES];
31
32 int ext4fs_init_journal(void)
33 {
34 int i;
35 char *temp = NULL;
36 struct ext_filesystem *fs = get_fs();
37
38 /* init globals */
39 revk_blk_list = NULL;
40 prev_node = NULL;
41 gindex = 0;
42 gd_index = 0;
43 jrnl_blk_idx = 1;
44
45 for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
46 journal_ptr[i] = zalloc(sizeof(struct journal_log));
47 if (!journal_ptr[i])
48 goto fail;
49 dirty_block_ptr[i] = zalloc(sizeof(struct dirty_blocks));
50 if (!dirty_block_ptr[i])
51 goto fail;
52 journal_ptr[i]->buf = NULL;
53 journal_ptr[i]->blknr = -1;
54
55 dirty_block_ptr[i]->buf = NULL;
56 dirty_block_ptr[i]->blknr = -1;
57 }
58
59 if (fs->blksz == 4096) {
60 temp = zalloc(fs->blksz);
61 if (!temp)
62 goto fail;
63 journal_ptr[gindex]->buf = zalloc(fs->blksz);
64 if (!journal_ptr[gindex]->buf)
65 goto fail;
66 ext4fs_devread(0, 0, fs->blksz, temp);
67 memcpy(temp + SUPERBLOCK_SIZE, fs->sb, SUPERBLOCK_SIZE);
68 memcpy(journal_ptr[gindex]->buf, temp, fs->blksz);
69 journal_ptr[gindex++]->blknr = 0;
70 free(temp);
71 } else {
72 journal_ptr[gindex]->buf = zalloc(fs->blksz);
73 if (!journal_ptr[gindex]->buf)
74 goto fail;
75 memcpy(journal_ptr[gindex]->buf, fs->sb, SUPERBLOCK_SIZE);
76 journal_ptr[gindex++]->blknr = 1;
77 }
78
79 /* Check the file system state using journal super block */
80 if (ext4fs_check_journal_state(SCAN))
81 goto fail;
82 /* Check the file system state using journal super block */
83 if (ext4fs_check_journal_state(RECOVER))
84 goto fail;
85
86 return 0;
87 fail:
88 return -1;
89 }
90
91 void ext4fs_dump_metadata(void)
92 {
93 struct ext_filesystem *fs = get_fs();
94 int i;
95 for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
96 if (dirty_block_ptr[i]->blknr == -1)
97 break;
98 put_ext4((uint64_t) ((uint64_t)dirty_block_ptr[i]->blknr *
99 (uint64_t)fs->blksz), dirty_block_ptr[i]->buf,
100 fs->blksz);
101 }
102 }
103
104 void ext4fs_free_journal(void)
105 {
106 int i;
107 for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
108 if (dirty_block_ptr[i]->blknr == -1)
109 break;
110 if (dirty_block_ptr[i]->buf)
111 free(dirty_block_ptr[i]->buf);
112 }
113
114 for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
115 if (journal_ptr[i]->blknr == -1)
116 break;
117 if (journal_ptr[i]->buf)
118 free(journal_ptr[i]->buf);
119 }
120
121 for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
122 if (journal_ptr[i])
123 free(journal_ptr[i]);
124 if (dirty_block_ptr[i])
125 free(dirty_block_ptr[i]);
126 }
127 gindex = 0;
128 gd_index = 0;
129 jrnl_blk_idx = 1;
130 }
131
132 int ext4fs_log_gdt(char *gd_table)
133 {
134 struct ext_filesystem *fs = get_fs();
135 short i;
136 long int var = fs->gdtable_blkno;
137 for (i = 0; i < fs->no_blk_pergdt; i++) {
138 journal_ptr[gindex]->buf = zalloc(fs->blksz);
139 if (!journal_ptr[gindex]->buf)
140 return -ENOMEM;
141 memcpy(journal_ptr[gindex]->buf, gd_table, fs->blksz);
142 gd_table += fs->blksz;
143 journal_ptr[gindex++]->blknr = var++;
144 }
145
146 return 0;
147 }
148
149 /*
150 * This function stores the backup copy of meta data in RAM
151 * journal_buffer -- Buffer containing meta data
152 * blknr -- Block number on disk of the meta data buffer
153 */
154 int ext4fs_log_journal(char *journal_buffer, uint32_t blknr)
155 {
156 struct ext_filesystem *fs = get_fs();
157 short i;
158
159 if (!journal_buffer) {
160 printf("Invalid input arguments %s\n", __func__);
161 return -EINVAL;
162 }
163
164 for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
165 if (journal_ptr[i]->blknr == -1)
166 break;
167 if (journal_ptr[i]->blknr == blknr)
168 return 0;
169 }
170
171 journal_ptr[gindex]->buf = zalloc(fs->blksz);
172 if (!journal_ptr[gindex]->buf)
173 return -ENOMEM;
174
175 memcpy(journal_ptr[gindex]->buf, journal_buffer, fs->blksz);
176 journal_ptr[gindex++]->blknr = blknr;
177
178 return 0;
179 }
180
181 /*
182 * This function stores the modified meta data in RAM
183 * metadata_buffer -- Buffer containing meta data
184 * blknr -- Block number on disk of the meta data buffer
185 */
186 int ext4fs_put_metadata(char *metadata_buffer, uint32_t blknr)
187 {
188 struct ext_filesystem *fs = get_fs();
189 if (!metadata_buffer) {
190 printf("Invalid input arguments %s\n", __func__);
191 return -EINVAL;
192 }
193 dirty_block_ptr[gd_index]->buf = zalloc(fs->blksz);
194 if (!dirty_block_ptr[gd_index]->buf)
195 return -ENOMEM;
196 memcpy(dirty_block_ptr[gd_index]->buf, metadata_buffer, fs->blksz);
197 dirty_block_ptr[gd_index++]->blknr = blknr;
198
199 return 0;
200 }
201
202 void print_revoke_blks(char *revk_blk)
203 {
204 int offset;
205 int max;
206 long int blocknr;
207 struct journal_revoke_header_t *header;
208
209 if (revk_blk == NULL)
210 return;
211
212 header = (struct journal_revoke_header_t *) revk_blk;
213 offset = sizeof(struct journal_revoke_header_t);
214 max = be32_to_cpu(header->r_count);
215 printf("total bytes %d\n", max);
216
217 while (offset < max) {
218 blocknr = be32_to_cpu(*((__be32 *)(revk_blk + offset)));
219 printf("revoke blknr is %ld\n", blocknr);
220 offset += 4;
221 }
222 }
223
224 static struct revoke_blk_list *_get_node(void)
225 {
226 struct revoke_blk_list *tmp_node;
227 tmp_node = zalloc(sizeof(struct revoke_blk_list));
228 if (tmp_node == NULL)
229 return NULL;
230 tmp_node->content = NULL;
231 tmp_node->next = NULL;
232
233 return tmp_node;
234 }
235
236 void ext4fs_push_revoke_blk(char *buffer)
237 {
238 struct revoke_blk_list *node = NULL;
239 struct ext_filesystem *fs = get_fs();
240 if (buffer == NULL) {
241 printf("buffer ptr is NULL\n");
242 return;
243 }
244 node = _get_node();
245 if (!node) {
246 printf("_get_node: malloc failed\n");
247 return;
248 }
249
250 node->content = zalloc(fs->blksz);
251 if (node->content == NULL)
252 return;
253 memcpy(node->content, buffer, fs->blksz);
254
255 if (first_node == true) {
256 revk_blk_list = node;
257 prev_node = node;
258 first_node = false;
259 } else {
260 prev_node->next = node;
261 prev_node = node;
262 }
263 }
264
265 void ext4fs_free_revoke_blks(void)
266 {
267 struct revoke_blk_list *tmp_node = revk_blk_list;
268 struct revoke_blk_list *next_node = NULL;
269
270 while (tmp_node != NULL) {
271 if (tmp_node->content)
272 free(tmp_node->content);
273 tmp_node = tmp_node->next;
274 }
275
276 tmp_node = revk_blk_list;
277 while (tmp_node != NULL) {
278 next_node = tmp_node->next;
279 free(tmp_node);
280 tmp_node = next_node;
281 }
282
283 revk_blk_list = NULL;
284 prev_node = NULL;
285 first_node = true;
286 }
287
288 int check_blknr_for_revoke(long int blknr, int sequence_no)
289 {
290 struct journal_revoke_header_t *header;
291 int offset;
292 int max;
293 long int blocknr;
294 char *revk_blk;
295 struct revoke_blk_list *tmp_revk_node = revk_blk_list;
296 while (tmp_revk_node != NULL) {
297 revk_blk = tmp_revk_node->content;
298
299 header = (struct journal_revoke_header_t *) revk_blk;
300 if (sequence_no < be32_to_cpu(header->r_header.h_sequence)) {
301 offset = sizeof(struct journal_revoke_header_t);
302 max = be32_to_cpu(header->r_count);
303
304 while (offset < max) {
305 blocknr = be32_to_cpu(*((__be32 *)
306 (revk_blk + offset)));
307 if (blocknr == blknr)
308 goto found;
309 offset += 4;
310 }
311 }
312 tmp_revk_node = tmp_revk_node->next;
313 }
314
315 return -1;
316
317 found:
318 return 0;
319 }
320
321 /*
322 * This function parses the journal blocks and replays the
323 * suceessful transactions. A transaction is successfull
324 * if commit block is found for a descriptor block
325 * The tags in descriptor block contain the disk block
326 * numbers of the metadata to be replayed
327 */
328 void recover_transaction(int prev_desc_logical_no)
329 {
330 struct ext2_inode inode_journal;
331 struct ext_filesystem *fs = get_fs();
332 struct journal_header_t *jdb;
333 long int blknr;
334 char *p_jdb;
335 int ofs, flags;
336 int i;
337 struct ext3_journal_block_tag *tag;
338 char *temp_buff = zalloc(fs->blksz);
339 char *metadata_buff = zalloc(fs->blksz);
340 if (!temp_buff || !metadata_buff)
341 goto fail;
342 i = prev_desc_logical_no;
343 ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO,
344 (struct ext2_inode *)&inode_journal);
345 blknr = read_allocated_block((struct ext2_inode *)
346 &inode_journal, i);
347 ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
348 temp_buff);
349 p_jdb = (char *)temp_buff;
350 jdb = (struct journal_header_t *) temp_buff;
351 ofs = sizeof(struct journal_header_t);
352
353 do {
354 tag = (struct ext3_journal_block_tag *)&p_jdb[ofs];
355 ofs += sizeof(struct ext3_journal_block_tag);
356
357 if (ofs > fs->blksz)
358 break;
359
360 flags = be32_to_cpu(tag->flags);
361 if (!(flags & EXT3_JOURNAL_FLAG_SAME_UUID))
362 ofs += 16;
363
364 i++;
365 debug("\t\ttag %u\n", be32_to_cpu(tag->block));
366 if (revk_blk_list != NULL) {
367 if (check_blknr_for_revoke(be32_to_cpu(tag->block),
368 be32_to_cpu(jdb->h_sequence)) == 0)
369 continue;
370 }
371 blknr = read_allocated_block(&inode_journal, i);
372 ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0,
373 fs->blksz, metadata_buff);
374 put_ext4((uint64_t)((uint64_t)be32_to_cpu(tag->block) * (uint64_t)fs->blksz),
375 metadata_buff, (uint32_t) fs->blksz);
376 } while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG));
377 fail:
378 free(temp_buff);
379 free(metadata_buff);
380 }
381
382 void print_jrnl_status(int recovery_flag)
383 {
384 if (recovery_flag == RECOVER)
385 printf("Journal Recovery Completed\n");
386 else
387 printf("Journal Scan Completed\n");
388 }
389
390 int ext4fs_check_journal_state(int recovery_flag)
391 {
392 int i;
393 int DB_FOUND = NO;
394 long int blknr;
395 int transaction_state = TRANSACTION_COMPLETE;
396 int prev_desc_logical_no = 0;
397 int curr_desc_logical_no = 0;
398 int ofs, flags;
399 struct ext2_inode inode_journal;
400 struct journal_superblock_t *jsb = NULL;
401 struct journal_header_t *jdb = NULL;
402 char *p_jdb = NULL;
403 struct ext3_journal_block_tag *tag = NULL;
404 char *temp_buff = NULL;
405 char *temp_buff1 = NULL;
406 struct ext_filesystem *fs = get_fs();
407
408 temp_buff = zalloc(fs->blksz);
409 if (!temp_buff)
410 return -ENOMEM;
411 temp_buff1 = zalloc(fs->blksz);
412 if (!temp_buff1) {
413 free(temp_buff);
414 return -ENOMEM;
415 }
416
417 ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
418 blknr = read_allocated_block(&inode_journal, EXT2_JOURNAL_SUPERBLOCK);
419 ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
420 temp_buff);
421 jsb = (struct journal_superblock_t *) temp_buff;
422
423 if (le32_to_cpu(fs->sb->feature_incompat) & EXT3_FEATURE_INCOMPAT_RECOVER) {
424 if (recovery_flag == RECOVER)
425 printf("Recovery required\n");
426 } else {
427 if (recovery_flag == RECOVER)
428 printf("File System is consistent\n");
429 goto end;
430 }
431
432 if (be32_to_cpu(jsb->s_start) == 0)
433 goto end;
434
435 if (!(jsb->s_feature_compat &
436 cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM)))
437 jsb->s_feature_compat |=
438 cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM);
439
440 i = be32_to_cpu(jsb->s_first);
441 while (1) {
442 blknr = read_allocated_block(&inode_journal, i);
443 memset(temp_buff1, '\0', fs->blksz);
444 ext4fs_devread((lbaint_t)blknr * fs->sect_perblk,
445 0, fs->blksz, temp_buff1);
446 jdb = (struct journal_header_t *) temp_buff1;
447
448 if (be32_to_cpu(jdb->h_blocktype) ==
449 EXT3_JOURNAL_DESCRIPTOR_BLOCK) {
450 if (be32_to_cpu(jdb->h_sequence) !=
451 be32_to_cpu(jsb->s_sequence)) {
452 print_jrnl_status(recovery_flag);
453 break;
454 }
455
456 curr_desc_logical_no = i;
457 if (transaction_state == TRANSACTION_COMPLETE)
458 transaction_state = TRANSACTION_RUNNING;
459 else
460 return -1;
461 p_jdb = (char *)temp_buff1;
462 ofs = sizeof(struct journal_header_t);
463 do {
464 tag = (struct ext3_journal_block_tag *)
465 &p_jdb[ofs];
466 ofs += sizeof(struct ext3_journal_block_tag);
467 if (ofs > fs->blksz)
468 break;
469 flags = be32_to_cpu(tag->flags);
470 if (!(flags & EXT3_JOURNAL_FLAG_SAME_UUID))
471 ofs += 16;
472 i++;
473 debug("\t\ttag %u\n", be32_to_cpu(tag->block));
474 } while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG));
475 i++;
476 DB_FOUND = YES;
477 } else if (be32_to_cpu(jdb->h_blocktype) ==
478 EXT3_JOURNAL_COMMIT_BLOCK) {
479 if (be32_to_cpu(jdb->h_sequence) !=
480 be32_to_cpu(jsb->s_sequence)) {
481 print_jrnl_status(recovery_flag);
482 break;
483 }
484
485 if (transaction_state == TRANSACTION_RUNNING ||
486 (DB_FOUND == NO)) {
487 transaction_state = TRANSACTION_COMPLETE;
488 i++;
489 jsb->s_sequence =
490 cpu_to_be32(be32_to_cpu(
491 jsb->s_sequence) + 1);
492 }
493 prev_desc_logical_no = curr_desc_logical_no;
494 if ((recovery_flag == RECOVER) && (DB_FOUND == YES))
495 recover_transaction(prev_desc_logical_no);
496
497 DB_FOUND = NO;
498 } else if (be32_to_cpu(jdb->h_blocktype) ==
499 EXT3_JOURNAL_REVOKE_BLOCK) {
500 if (be32_to_cpu(jdb->h_sequence) !=
501 be32_to_cpu(jsb->s_sequence)) {
502 print_jrnl_status(recovery_flag);
503 break;
504 }
505 if (recovery_flag == SCAN)
506 ext4fs_push_revoke_blk((char *)jdb);
507 i++;
508 } else {
509 debug("Else Case\n");
510 if (be32_to_cpu(jdb->h_sequence) !=
511 be32_to_cpu(jsb->s_sequence)) {
512 print_jrnl_status(recovery_flag);
513 break;
514 }
515 }
516 }
517
518 end:
519 if (recovery_flag == RECOVER) {
520 uint32_t new_feature_incompat;
521 jsb->s_start = cpu_to_be32(1);
522 jsb->s_sequence = cpu_to_be32(be32_to_cpu(jsb->s_sequence) + 1);
523 /* get the superblock */
524 ext4_read_superblock((char *)fs->sb);
525 new_feature_incompat = le32_to_cpu(fs->sb->feature_incompat);
526 new_feature_incompat |= EXT3_FEATURE_INCOMPAT_RECOVER;
527 fs->sb->feature_incompat = cpu_to_le32(new_feature_incompat);
528
529 /* Update the super block */
530 put_ext4((uint64_t) (SUPERBLOCK_SIZE),
531 (struct ext2_sblock *)fs->sb,
532 (uint32_t) SUPERBLOCK_SIZE);
533 ext4_read_superblock((char *)fs->sb);
534
535 blknr = read_allocated_block(&inode_journal,
536 EXT2_JOURNAL_SUPERBLOCK);
537 put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz),
538 (struct journal_superblock_t *)temp_buff,
539 (uint32_t) fs->blksz);
540 ext4fs_free_revoke_blks();
541 }
542 free(temp_buff);
543 free(temp_buff1);
544
545 return 0;
546 }
547
548 static void update_descriptor_block(long int blknr)
549 {
550 int i;
551 long int jsb_blknr;
552 struct journal_header_t jdb;
553 struct ext3_journal_block_tag tag;
554 struct ext2_inode inode_journal;
555 struct journal_superblock_t *jsb = NULL;
556 char *buf = NULL;
557 char *temp = NULL;
558 struct ext_filesystem *fs = get_fs();
559 char *temp_buff = zalloc(fs->blksz);
560 if (!temp_buff)
561 return;
562
563 ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
564 jsb_blknr = read_allocated_block(&inode_journal,
565 EXT2_JOURNAL_SUPERBLOCK);
566 ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz,
567 temp_buff);
568 jsb = (struct journal_superblock_t *) temp_buff;
569
570 jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_DESCRIPTOR_BLOCK);
571 jdb.h_magic = cpu_to_be32(EXT3_JOURNAL_MAGIC_NUMBER);
572 jdb.h_sequence = jsb->s_sequence;
573 buf = zalloc(fs->blksz);
574 if (!buf) {
575 free(temp_buff);
576 return;
577 }
578 temp = buf;
579 memcpy(buf, &jdb, sizeof(struct journal_header_t));
580 temp += sizeof(struct journal_header_t);
581
582 for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
583 if (journal_ptr[i]->blknr == -1)
584 break;
585
586 tag.block = cpu_to_be32(journal_ptr[i]->blknr);
587 tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_SAME_UUID);
588 memcpy(temp, &tag, sizeof(struct ext3_journal_block_tag));
589 temp = temp + sizeof(struct ext3_journal_block_tag);
590 }
591
592 tag.block = cpu_to_be32(journal_ptr[--i]->blknr);
593 tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_LAST_TAG);
594 memcpy(temp - sizeof(struct ext3_journal_block_tag), &tag,
595 sizeof(struct ext3_journal_block_tag));
596 put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), buf, (uint32_t) fs->blksz);
597
598 free(temp_buff);
599 free(buf);
600 }
601
602 static void update_commit_block(long int blknr)
603 {
604 struct journal_header_t jdb;
605 struct ext_filesystem *fs = get_fs();
606 char *buf = NULL;
607 struct ext2_inode inode_journal;
608 struct journal_superblock_t *jsb;
609 long int jsb_blknr;
610 char *temp_buff = zalloc(fs->blksz);
611 if (!temp_buff)
612 return;
613
614 ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO,
615 &inode_journal);
616 jsb_blknr = read_allocated_block(&inode_journal,
617 EXT2_JOURNAL_SUPERBLOCK);
618 ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz,
619 temp_buff);
620 jsb = (struct journal_superblock_t *) temp_buff;
621
622 jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_COMMIT_BLOCK);
623 jdb.h_magic = cpu_to_be32(EXT3_JOURNAL_MAGIC_NUMBER);
624 jdb.h_sequence = jsb->s_sequence;
625 buf = zalloc(fs->blksz);
626 if (!buf) {
627 free(temp_buff);
628 return;
629 }
630 memcpy(buf, &jdb, sizeof(struct journal_header_t));
631 put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), buf, (uint32_t) fs->blksz);
632
633 free(temp_buff);
634 free(buf);
635 }
636
637 void ext4fs_update_journal(void)
638 {
639 struct ext2_inode inode_journal;
640 struct ext_filesystem *fs = get_fs();
641 long int blknr;
642 int i;
643 ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
644 blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++);
645 update_descriptor_block(blknr);
646 for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
647 if (journal_ptr[i]->blknr == -1)
648 break;
649 blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++);
650 put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz),
651 journal_ptr[i]->buf, fs->blksz);
652 }
653 blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++);
654 update_commit_block(blknr);
655 printf("update journal finished\n");
656 }