blob: a540367a70af35a494b018cb3df8944d371bd31c [file] [log] [blame]
Uma Shankared34f342012-05-25 21:22:49 +05301/*
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 * This file is part of the Linux kernel and is made available under
14 * the terms of the GNU General Public License, version 2, or at your
15 * option, any later version, incorporated herein by reference.
16 *
17 * This program is free software; you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation; either version 2 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program; if not, write to the Free Software
29 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
30 */
31
32#include <common.h>
33#include <ext4fs.h>
34#include <malloc.h>
35#include <ext_common.h>
36#include "ext4_common.h"
37
38static struct revoke_blk_list *revk_blk_list;
39static struct revoke_blk_list *prev_node;
York Sun472d5462013-04-01 11:29:11 -070040static int first_node = true;
Uma Shankared34f342012-05-25 21:22:49 +053041
42int gindex;
43int gd_index;
44int jrnl_blk_idx;
45struct journal_log *journal_ptr[MAX_JOURNAL_ENTRIES];
46struct dirty_blocks *dirty_block_ptr[MAX_JOURNAL_ENTRIES];
47
48int ext4fs_init_journal(void)
49{
50 int i;
51 char *temp = NULL;
52 struct ext_filesystem *fs = get_fs();
53
54 /* init globals */
55 revk_blk_list = NULL;
56 prev_node = NULL;
57 gindex = 0;
58 gd_index = 0;
59 jrnl_blk_idx = 1;
60
61 for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
62 journal_ptr[i] = zalloc(sizeof(struct journal_log));
63 if (!journal_ptr[i])
64 goto fail;
65 dirty_block_ptr[i] = zalloc(sizeof(struct dirty_blocks));
66 if (!dirty_block_ptr[i])
67 goto fail;
68 journal_ptr[i]->buf = NULL;
69 journal_ptr[i]->blknr = -1;
70
71 dirty_block_ptr[i]->buf = NULL;
72 dirty_block_ptr[i]->blknr = -1;
73 }
74
75 if (fs->blksz == 4096) {
76 temp = zalloc(fs->blksz);
77 if (!temp)
78 goto fail;
79 journal_ptr[gindex]->buf = zalloc(fs->blksz);
80 if (!journal_ptr[gindex]->buf)
81 goto fail;
82 ext4fs_devread(0, 0, fs->blksz, temp);
83 memcpy(temp + SUPERBLOCK_SIZE, fs->sb, SUPERBLOCK_SIZE);
84 memcpy(journal_ptr[gindex]->buf, temp, fs->blksz);
85 journal_ptr[gindex++]->blknr = 0;
86 free(temp);
87 } else {
88 journal_ptr[gindex]->buf = zalloc(fs->blksz);
89 if (!journal_ptr[gindex]->buf)
90 goto fail;
91 memcpy(journal_ptr[gindex]->buf, fs->sb, SUPERBLOCK_SIZE);
92 journal_ptr[gindex++]->blknr = 1;
93 }
94
95 /* Check the file system state using journal super block */
96 if (ext4fs_check_journal_state(SCAN))
97 goto fail;
98 /* Check the file system state using journal super block */
99 if (ext4fs_check_journal_state(RECOVER))
100 goto fail;
101
102 return 0;
103fail:
104 return -1;
105}
106
107void ext4fs_dump_metadata(void)
108{
109 struct ext_filesystem *fs = get_fs();
110 int i;
111 for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
112 if (dirty_block_ptr[i]->blknr == -1)
113 break;
114 put_ext4((uint64_t) ((uint64_t)dirty_block_ptr[i]->blknr *
115 (uint64_t)fs->blksz), dirty_block_ptr[i]->buf,
116 fs->blksz);
117 }
118}
119
120void ext4fs_free_journal(void)
121{
122 int i;
123 for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
124 if (dirty_block_ptr[i]->blknr == -1)
125 break;
126 if (dirty_block_ptr[i]->buf)
127 free(dirty_block_ptr[i]->buf);
128 }
129
130 for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
131 if (journal_ptr[i]->blknr == -1)
132 break;
133 if (journal_ptr[i]->buf)
134 free(journal_ptr[i]->buf);
135 }
136
137 for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
138 if (journal_ptr[i])
139 free(journal_ptr[i]);
140 if (dirty_block_ptr[i])
141 free(dirty_block_ptr[i]);
142 }
143 gindex = 0;
144 gd_index = 0;
145 jrnl_blk_idx = 1;
146}
147
148int ext4fs_log_gdt(char *gd_table)
149{
150 struct ext_filesystem *fs = get_fs();
151 short i;
152 long int var = fs->gdtable_blkno;
153 for (i = 0; i < fs->no_blk_pergdt; i++) {
154 journal_ptr[gindex]->buf = zalloc(fs->blksz);
155 if (!journal_ptr[gindex]->buf)
156 return -ENOMEM;
157 memcpy(journal_ptr[gindex]->buf, gd_table, fs->blksz);
158 gd_table += fs->blksz;
159 journal_ptr[gindex++]->blknr = var++;
160 }
161
162 return 0;
163}
164
165/*
166 * This function stores the backup copy of meta data in RAM
167 * journal_buffer -- Buffer containing meta data
168 * blknr -- Block number on disk of the meta data buffer
169 */
170int ext4fs_log_journal(char *journal_buffer, long int blknr)
171{
172 struct ext_filesystem *fs = get_fs();
173 short i;
174
175 if (!journal_buffer) {
176 printf("Invalid input arguments %s\n", __func__);
177 return -EINVAL;
178 }
179
180 for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
181 if (journal_ptr[i]->blknr == -1)
182 break;
183 if (journal_ptr[i]->blknr == blknr)
184 return 0;
185 }
186
187 journal_ptr[gindex]->buf = zalloc(fs->blksz);
188 if (!journal_ptr[gindex]->buf)
189 return -ENOMEM;
190
191 memcpy(journal_ptr[gindex]->buf, journal_buffer, fs->blksz);
192 journal_ptr[gindex++]->blknr = blknr;
193
194 return 0;
195}
196
197/*
198 * This function stores the modified meta data in RAM
199 * metadata_buffer -- Buffer containing meta data
200 * blknr -- Block number on disk of the meta data buffer
201 */
202int ext4fs_put_metadata(char *metadata_buffer, long int blknr)
203{
204 struct ext_filesystem *fs = get_fs();
205 if (!metadata_buffer) {
206 printf("Invalid input arguments %s\n", __func__);
207 return -EINVAL;
208 }
209 dirty_block_ptr[gd_index]->buf = zalloc(fs->blksz);
210 if (!dirty_block_ptr[gd_index]->buf)
211 return -ENOMEM;
212 memcpy(dirty_block_ptr[gd_index]->buf, metadata_buffer, fs->blksz);
213 dirty_block_ptr[gd_index++]->blknr = blknr;
214
215 return 0;
216}
217
218void print_revoke_blks(char *revk_blk)
219{
220 int offset;
221 int max;
222 long int blocknr;
223 struct journal_revoke_header_t *header;
224
225 if (revk_blk == NULL)
226 return;
227
228 header = (struct journal_revoke_header_t *) revk_blk;
229 offset = sizeof(struct journal_revoke_header_t);
230 max = be32_to_cpu(header->r_count);
231 printf("total bytes %d\n", max);
232
233 while (offset < max) {
234 blocknr = be32_to_cpu(*((long int *)(revk_blk + offset)));
235 printf("revoke blknr is %ld\n", blocknr);
236 offset += 4;
237 }
238}
239
240static struct revoke_blk_list *_get_node(void)
241{
242 struct revoke_blk_list *tmp_node;
243 tmp_node = zalloc(sizeof(struct revoke_blk_list));
244 if (tmp_node == NULL)
245 return NULL;
246 tmp_node->content = NULL;
247 tmp_node->next = NULL;
248
249 return tmp_node;
250}
251
252void ext4fs_push_revoke_blk(char *buffer)
253{
254 struct revoke_blk_list *node = NULL;
255 struct ext_filesystem *fs = get_fs();
256 if (buffer == NULL) {
257 printf("buffer ptr is NULL\n");
258 return;
259 }
260 node = _get_node();
261 if (!node) {
262 printf("_get_node: malloc failed\n");
263 return;
264 }
265
266 node->content = zalloc(fs->blksz);
267 if (node->content == NULL)
268 return;
269 memcpy(node->content, buffer, fs->blksz);
270
York Sun472d5462013-04-01 11:29:11 -0700271 if (first_node == true) {
Uma Shankared34f342012-05-25 21:22:49 +0530272 revk_blk_list = node;
273 prev_node = node;
York Sun472d5462013-04-01 11:29:11 -0700274 first_node = false;
Uma Shankared34f342012-05-25 21:22:49 +0530275 } else {
276 prev_node->next = node;
277 prev_node = node;
278 }
279}
280
281void ext4fs_free_revoke_blks(void)
282{
283 struct revoke_blk_list *tmp_node = revk_blk_list;
284 struct revoke_blk_list *next_node = NULL;
285
286 while (tmp_node != NULL) {
287 if (tmp_node->content)
288 free(tmp_node->content);
289 tmp_node = tmp_node->next;
290 }
291
292 tmp_node = revk_blk_list;
293 while (tmp_node != NULL) {
294 next_node = tmp_node->next;
295 free(tmp_node);
296 tmp_node = next_node;
297 }
298
299 revk_blk_list = NULL;
300 prev_node = NULL;
York Sun472d5462013-04-01 11:29:11 -0700301 first_node = true;
Uma Shankared34f342012-05-25 21:22:49 +0530302}
303
304int check_blknr_for_revoke(long int blknr, int sequence_no)
305{
306 struct journal_revoke_header_t *header;
307 int offset;
308 int max;
309 long int blocknr;
310 char *revk_blk;
311 struct revoke_blk_list *tmp_revk_node = revk_blk_list;
312 while (tmp_revk_node != NULL) {
313 revk_blk = tmp_revk_node->content;
314
315 header = (struct journal_revoke_header_t *) revk_blk;
316 if (sequence_no < be32_to_cpu(header->r_header.h_sequence)) {
317 offset = sizeof(struct journal_revoke_header_t);
318 max = be32_to_cpu(header->r_count);
319
320 while (offset < max) {
321 blocknr = be32_to_cpu(*((long int *)
322 (revk_blk + offset)));
323 if (blocknr == blknr)
324 goto found;
325 offset += 4;
326 }
327 }
328 tmp_revk_node = tmp_revk_node->next;
329 }
330
331 return -1;
332
333found:
334 return 0;
335}
336
337/*
338 * This function parses the journal blocks and replays the
339 * suceessful transactions. A transaction is successfull
340 * if commit block is found for a descriptor block
341 * The tags in descriptor block contain the disk block
342 * numbers of the metadata to be replayed
343 */
344void recover_transaction(int prev_desc_logical_no)
345{
346 struct ext2_inode inode_journal;
347 struct ext_filesystem *fs = get_fs();
348 struct journal_header_t *jdb;
349 long int blknr;
350 char *p_jdb;
351 int ofs, flags;
352 int i;
353 struct ext3_journal_block_tag *tag;
354 char *temp_buff = zalloc(fs->blksz);
355 char *metadata_buff = zalloc(fs->blksz);
356 if (!temp_buff || !metadata_buff)
357 goto fail;
358 i = prev_desc_logical_no;
359 ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO,
360 (struct ext2_inode *)&inode_journal);
361 blknr = read_allocated_block((struct ext2_inode *)
362 &inode_journal, i);
Frederic Leroy04735e92013-06-26 18:11:25 +0200363 ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
364 temp_buff);
Uma Shankared34f342012-05-25 21:22:49 +0530365 p_jdb = (char *)temp_buff;
366 jdb = (struct journal_header_t *) temp_buff;
367 ofs = sizeof(struct journal_header_t);
368
369 do {
370 tag = (struct ext3_journal_block_tag *)&p_jdb[ofs];
371 ofs += sizeof(struct ext3_journal_block_tag);
372
373 if (ofs > fs->blksz)
374 break;
375
376 flags = be32_to_cpu(tag->flags);
377 if (!(flags & EXT3_JOURNAL_FLAG_SAME_UUID))
378 ofs += 16;
379
380 i++;
381 debug("\t\ttag %u\n", be32_to_cpu(tag->block));
382 if (revk_blk_list != NULL) {
383 if (check_blknr_for_revoke(be32_to_cpu(tag->block),
384 be32_to_cpu(jdb->h_sequence)) == 0)
385 continue;
386 }
387 blknr = read_allocated_block(&inode_journal, i);
Frederic Leroy04735e92013-06-26 18:11:25 +0200388 ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0,
Uma Shankared34f342012-05-25 21:22:49 +0530389 fs->blksz, metadata_buff);
390 put_ext4((uint64_t)(be32_to_cpu(tag->block) * fs->blksz),
391 metadata_buff, (uint32_t) fs->blksz);
392 } while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG));
393fail:
394 free(temp_buff);
395 free(metadata_buff);
396}
397
398void print_jrnl_status(int recovery_flag)
399{
400 if (recovery_flag == RECOVER)
401 printf("Journal Recovery Completed\n");
402 else
403 printf("Journal Scan Completed\n");
404}
405
406int ext4fs_check_journal_state(int recovery_flag)
407{
408 int i;
409 int DB_FOUND = NO;
410 long int blknr;
411 int transaction_state = TRANSACTION_COMPLETE;
412 int prev_desc_logical_no = 0;
413 int curr_desc_logical_no = 0;
Łukasz Majewskid429ca02012-12-05 08:06:39 +0000414 int ofs, flags;
Uma Shankared34f342012-05-25 21:22:49 +0530415 struct ext2_inode inode_journal;
416 struct journal_superblock_t *jsb = NULL;
417 struct journal_header_t *jdb = NULL;
418 char *p_jdb = NULL;
419 struct ext3_journal_block_tag *tag = NULL;
420 char *temp_buff = NULL;
421 char *temp_buff1 = NULL;
422 struct ext_filesystem *fs = get_fs();
423
424 temp_buff = zalloc(fs->blksz);
425 if (!temp_buff)
426 return -ENOMEM;
427 temp_buff1 = zalloc(fs->blksz);
428 if (!temp_buff1) {
429 free(temp_buff);
430 return -ENOMEM;
431 }
432
433 ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
434 blknr = read_allocated_block(&inode_journal, EXT2_JOURNAL_SUPERBLOCK);
Frederic Leroy04735e92013-06-26 18:11:25 +0200435 ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
436 temp_buff);
Uma Shankared34f342012-05-25 21:22:49 +0530437 jsb = (struct journal_superblock_t *) temp_buff;
438
439 if (fs->sb->feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) {
440 if (recovery_flag == RECOVER)
441 printf("Recovery required\n");
442 } else {
443 if (recovery_flag == RECOVER)
444 printf("File System is consistent\n");
445 goto end;
446 }
447
448 if (be32_to_cpu(jsb->s_start) == 0)
449 goto end;
450
451 if (!(jsb->s_feature_compat &
452 cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM)))
453 jsb->s_feature_compat |=
454 cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM);
455
456 i = be32_to_cpu(jsb->s_first);
457 while (1) {
Uma Shankared34f342012-05-25 21:22:49 +0530458 blknr = read_allocated_block(&inode_journal, i);
459 memset(temp_buff1, '\0', fs->blksz);
Frederic Leroy04735e92013-06-26 18:11:25 +0200460 ext4fs_devread((lbaint_t)blknr * fs->sect_perblk,
Uma Shankared34f342012-05-25 21:22:49 +0530461 0, fs->blksz, temp_buff1);
462 jdb = (struct journal_header_t *) temp_buff1;
463
464 if (be32_to_cpu(jdb->h_blocktype) ==
465 EXT3_JOURNAL_DESCRIPTOR_BLOCK) {
466 if (be32_to_cpu(jdb->h_sequence) !=
467 be32_to_cpu(jsb->s_sequence)) {
468 print_jrnl_status(recovery_flag);
469 break;
470 }
471
472 curr_desc_logical_no = i;
473 if (transaction_state == TRANSACTION_COMPLETE)
474 transaction_state = TRANSACTION_RUNNING;
475 else
476 return -1;
477 p_jdb = (char *)temp_buff1;
478 ofs = sizeof(struct journal_header_t);
479 do {
480 tag = (struct ext3_journal_block_tag *)
481 &p_jdb[ofs];
482 ofs += sizeof(struct ext3_journal_block_tag);
483 if (ofs > fs->blksz)
484 break;
485 flags = be32_to_cpu(tag->flags);
486 if (!(flags & EXT3_JOURNAL_FLAG_SAME_UUID))
487 ofs += 16;
488 i++;
489 debug("\t\ttag %u\n", be32_to_cpu(tag->block));
490 } while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG));
491 i++;
492 DB_FOUND = YES;
493 } else if (be32_to_cpu(jdb->h_blocktype) ==
494 EXT3_JOURNAL_COMMIT_BLOCK) {
495 if (be32_to_cpu(jdb->h_sequence) !=
496 be32_to_cpu(jsb->s_sequence)) {
497 print_jrnl_status(recovery_flag);
498 break;
499 }
500
501 if (transaction_state == TRANSACTION_RUNNING ||
502 (DB_FOUND == NO)) {
503 transaction_state = TRANSACTION_COMPLETE;
504 i++;
505 jsb->s_sequence =
506 cpu_to_be32(be32_to_cpu(
507 jsb->s_sequence) + 1);
508 }
509 prev_desc_logical_no = curr_desc_logical_no;
510 if ((recovery_flag == RECOVER) && (DB_FOUND == YES))
511 recover_transaction(prev_desc_logical_no);
512
513 DB_FOUND = NO;
514 } else if (be32_to_cpu(jdb->h_blocktype) ==
515 EXT3_JOURNAL_REVOKE_BLOCK) {
516 if (be32_to_cpu(jdb->h_sequence) !=
517 be32_to_cpu(jsb->s_sequence)) {
518 print_jrnl_status(recovery_flag);
519 break;
520 }
521 if (recovery_flag == SCAN)
522 ext4fs_push_revoke_blk((char *)jdb);
523 i++;
524 } else {
525 debug("Else Case\n");
526 if (be32_to_cpu(jdb->h_sequence) !=
527 be32_to_cpu(jsb->s_sequence)) {
528 print_jrnl_status(recovery_flag);
529 break;
530 }
531 }
532 }
533
534end:
535 if (recovery_flag == RECOVER) {
536 jsb->s_start = cpu_to_be32(1);
537 jsb->s_sequence = cpu_to_be32(be32_to_cpu(jsb->s_sequence) + 1);
538 /* get the superblock */
Egbert Eich50ce4c02013-05-01 01:13:19 +0000539 ext4_read_superblock((char *)fs->sb);
Uma Shankared34f342012-05-25 21:22:49 +0530540 fs->sb->feature_incompat |= EXT3_FEATURE_INCOMPAT_RECOVER;
541
542 /* Update the super block */
543 put_ext4((uint64_t) (SUPERBLOCK_SIZE),
544 (struct ext2_sblock *)fs->sb,
545 (uint32_t) SUPERBLOCK_SIZE);
Egbert Eich50ce4c02013-05-01 01:13:19 +0000546 ext4_read_superblock((char *)fs->sb);
Uma Shankared34f342012-05-25 21:22:49 +0530547
548 blknr = read_allocated_block(&inode_journal,
549 EXT2_JOURNAL_SUPERBLOCK);
550 put_ext4((uint64_t) (blknr * fs->blksz),
551 (struct journal_superblock_t *)temp_buff,
552 (uint32_t) fs->blksz);
553 ext4fs_free_revoke_blks();
554 }
555 free(temp_buff);
556 free(temp_buff1);
557
558 return 0;
559}
560
561static void update_descriptor_block(long int blknr)
562{
563 int i;
564 long int jsb_blknr;
565 struct journal_header_t jdb;
566 struct ext3_journal_block_tag tag;
567 struct ext2_inode inode_journal;
568 struct journal_superblock_t *jsb = NULL;
569 char *buf = NULL;
570 char *temp = NULL;
571 struct ext_filesystem *fs = get_fs();
572 char *temp_buff = zalloc(fs->blksz);
573 if (!temp_buff)
574 return;
575
576 ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
577 jsb_blknr = read_allocated_block(&inode_journal,
578 EXT2_JOURNAL_SUPERBLOCK);
Frederic Leroy04735e92013-06-26 18:11:25 +0200579 ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz,
580 temp_buff);
Uma Shankared34f342012-05-25 21:22:49 +0530581 jsb = (struct journal_superblock_t *) temp_buff;
582
583 jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_DESCRIPTOR_BLOCK);
584 jdb.h_magic = cpu_to_be32(EXT3_JOURNAL_MAGIC_NUMBER);
585 jdb.h_sequence = jsb->s_sequence;
586 buf = zalloc(fs->blksz);
587 if (!buf) {
588 free(temp_buff);
589 return;
590 }
591 temp = buf;
592 memcpy(buf, &jdb, sizeof(struct journal_header_t));
593 temp += sizeof(struct journal_header_t);
594
595 for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
596 if (journal_ptr[i]->blknr == -1)
597 break;
598
599 tag.block = cpu_to_be32(journal_ptr[i]->blknr);
600 tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_SAME_UUID);
601 memcpy(temp, &tag, sizeof(struct ext3_journal_block_tag));
602 temp = temp + sizeof(struct ext3_journal_block_tag);
603 }
604
605 tag.block = cpu_to_be32(journal_ptr[--i]->blknr);
606 tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_LAST_TAG);
607 memcpy(temp - sizeof(struct ext3_journal_block_tag), &tag,
608 sizeof(struct ext3_journal_block_tag));
609 put_ext4((uint64_t) (blknr * fs->blksz), buf, (uint32_t) fs->blksz);
610
611 free(temp_buff);
612 free(buf);
613}
614
615static void update_commit_block(long int blknr)
616{
617 struct journal_header_t jdb;
618 struct ext_filesystem *fs = get_fs();
619 char *buf = NULL;
620 struct ext2_inode inode_journal;
621 struct journal_superblock_t *jsb;
622 long int jsb_blknr;
623 char *temp_buff = zalloc(fs->blksz);
624 if (!temp_buff)
625 return;
626
Frederic Leroy04735e92013-06-26 18:11:25 +0200627 ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO,
628 &inode_journal);
Uma Shankared34f342012-05-25 21:22:49 +0530629 jsb_blknr = read_allocated_block(&inode_journal,
630 EXT2_JOURNAL_SUPERBLOCK);
Frederic Leroy04735e92013-06-26 18:11:25 +0200631 ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz,
632 temp_buff);
Uma Shankared34f342012-05-25 21:22:49 +0530633 jsb = (struct journal_superblock_t *) temp_buff;
634
635 jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_COMMIT_BLOCK);
636 jdb.h_magic = cpu_to_be32(EXT3_JOURNAL_MAGIC_NUMBER);
637 jdb.h_sequence = jsb->s_sequence;
638 buf = zalloc(fs->blksz);
639 if (!buf) {
640 free(temp_buff);
641 return;
642 }
643 memcpy(buf, &jdb, sizeof(struct journal_header_t));
644 put_ext4((uint64_t) (blknr * fs->blksz), buf, (uint32_t) fs->blksz);
645
646 free(temp_buff);
647 free(buf);
648}
649
650void ext4fs_update_journal(void)
651{
652 struct ext2_inode inode_journal;
653 struct ext_filesystem *fs = get_fs();
654 long int blknr;
655 int i;
656 ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
657 blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++);
658 update_descriptor_block(blknr);
659 for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
660 if (journal_ptr[i]->blknr == -1)
661 break;
662 blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++);
663 put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz),
664 journal_ptr[i]->buf, fs->blksz);
665 }
666 blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++);
667 update_commit_block(blknr);
668 printf("update journal finished\n");
669}