]> Git Repo - J-u-boot.git/blob - fs/ext4/ext4_journal.c
Merge tag 'xilinx-for-v2020.07-rc2' of https://gitlab.denx.de/u-boot/custodians/u...
[J-u-boot.git] / fs / ext4 / ext4_journal.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * (C) Copyright 2011 - 2012 Samsung Electronics
4  * EXT4 filesystem implementation in Uboot by
5  * Uma Shankar <[email protected]>
6  * Manjunatha C Achar <[email protected]>
7  *
8  * Journal data structures and headers for Journaling feature of ext4
9  * have been referred from JBD2 (Journaling Block device 2)
10  * implementation in Linux Kernel.
11  * Written by Stephen C. Tweedie <[email protected]>
12  *
13  * Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved
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         if (dirty_block_ptr[gd_index]->buf)
194                 assert(dirty_block_ptr[gd_index]->blknr == blknr);
195         else
196                 dirty_block_ptr[gd_index]->buf = zalloc(fs->blksz);
197
198         if (!dirty_block_ptr[gd_index]->buf)
199                 return -ENOMEM;
200         memcpy(dirty_block_ptr[gd_index]->buf, metadata_buffer, fs->blksz);
201         dirty_block_ptr[gd_index++]->blknr = blknr;
202
203         return 0;
204 }
205
206 void print_revoke_blks(char *revk_blk)
207 {
208         int offset;
209         int max;
210         long int blocknr;
211         struct journal_revoke_header_t *header;
212
213         if (revk_blk == NULL)
214                 return;
215
216         header = (struct journal_revoke_header_t *) revk_blk;
217         offset = sizeof(struct journal_revoke_header_t);
218         max = be32_to_cpu(header->r_count);
219         printf("total bytes %d\n", max);
220
221         while (offset < max) {
222                 blocknr = be32_to_cpu(*((__be32 *)(revk_blk + offset)));
223                 printf("revoke blknr is %ld\n", blocknr);
224                 offset += 4;
225         }
226 }
227
228 static struct revoke_blk_list *_get_node(void)
229 {
230         struct revoke_blk_list *tmp_node;
231         tmp_node = zalloc(sizeof(struct revoke_blk_list));
232         if (tmp_node == NULL)
233                 return NULL;
234         tmp_node->content = NULL;
235         tmp_node->next = NULL;
236
237         return tmp_node;
238 }
239
240 void ext4fs_push_revoke_blk(char *buffer)
241 {
242         struct revoke_blk_list *node = NULL;
243         struct ext_filesystem *fs = get_fs();
244         if (buffer == NULL) {
245                 printf("buffer ptr is NULL\n");
246                 return;
247         }
248         node = _get_node();
249         if (!node) {
250                 printf("_get_node: malloc failed\n");
251                 return;
252         }
253
254         node->content = zalloc(fs->blksz);
255         if (node->content == NULL)
256                 return;
257         memcpy(node->content, buffer, fs->blksz);
258
259         if (first_node == true) {
260                 revk_blk_list = node;
261                 prev_node = node;
262                  first_node = false;
263         } else {
264                 prev_node->next = node;
265                 prev_node = node;
266         }
267 }
268
269 void ext4fs_free_revoke_blks(void)
270 {
271         struct revoke_blk_list *tmp_node = revk_blk_list;
272         struct revoke_blk_list *next_node = NULL;
273
274         while (tmp_node != NULL) {
275                 if (tmp_node->content)
276                         free(tmp_node->content);
277                 tmp_node = tmp_node->next;
278         }
279
280         tmp_node = revk_blk_list;
281         while (tmp_node != NULL) {
282                 next_node = tmp_node->next;
283                 free(tmp_node);
284                 tmp_node = next_node;
285         }
286
287         revk_blk_list = NULL;
288         prev_node = NULL;
289         first_node = true;
290 }
291
292 int check_blknr_for_revoke(long int blknr, int sequence_no)
293 {
294         struct journal_revoke_header_t *header;
295         int offset;
296         int max;
297         long int blocknr;
298         char *revk_blk;
299         struct revoke_blk_list *tmp_revk_node = revk_blk_list;
300         while (tmp_revk_node != NULL) {
301                 revk_blk = tmp_revk_node->content;
302
303                 header = (struct journal_revoke_header_t *) revk_blk;
304                 if (sequence_no < be32_to_cpu(header->r_header.h_sequence)) {
305                         offset = sizeof(struct journal_revoke_header_t);
306                         max = be32_to_cpu(header->r_count);
307
308                         while (offset < max) {
309                                 blocknr = be32_to_cpu(*((__be32 *)
310                                                   (revk_blk + offset)));
311                                 if (blocknr == blknr)
312                                         goto found;
313                                 offset += 4;
314                         }
315                 }
316                 tmp_revk_node = tmp_revk_node->next;
317         }
318
319         return -1;
320
321 found:
322         return 0;
323 }
324
325 /*
326  * This function parses the journal blocks and replays the
327  * suceessful transactions. A transaction is successfull
328  * if commit block is found for a descriptor block
329  * The tags in descriptor block contain the disk block
330  * numbers of the metadata  to be replayed
331  */
332 void recover_transaction(int prev_desc_logical_no)
333 {
334         struct ext2_inode inode_journal;
335         struct ext_filesystem *fs = get_fs();
336         struct journal_header_t *jdb;
337         long int blknr;
338         char *p_jdb;
339         int ofs, flags;
340         int i;
341         struct ext3_journal_block_tag *tag;
342         char *temp_buff = zalloc(fs->blksz);
343         char *metadata_buff = zalloc(fs->blksz);
344         if (!temp_buff || !metadata_buff)
345                 goto fail;
346         i = prev_desc_logical_no;
347         ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO,
348                           (struct ext2_inode *)&inode_journal);
349         blknr = read_allocated_block((struct ext2_inode *)
350                                      &inode_journal, i, NULL);
351         ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
352                        temp_buff);
353         p_jdb = (char *)temp_buff;
354         jdb = (struct journal_header_t *) temp_buff;
355         ofs = sizeof(struct journal_header_t);
356
357         do {
358                 tag = (struct ext3_journal_block_tag *)(p_jdb + ofs);
359                 ofs += sizeof(struct ext3_journal_block_tag);
360
361                 if (ofs > fs->blksz)
362                         break;
363
364                 flags = be32_to_cpu(tag->flags);
365                 if (!(flags & EXT3_JOURNAL_FLAG_SAME_UUID))
366                         ofs += 16;
367
368                 i++;
369                 debug("\t\ttag %u\n", be32_to_cpu(tag->block));
370                 if (revk_blk_list != NULL) {
371                         if (check_blknr_for_revoke(be32_to_cpu(tag->block),
372                                 be32_to_cpu(jdb->h_sequence)) == 0)
373                                 continue;
374                 }
375                 blknr = read_allocated_block(&inode_journal, i, NULL);
376                 ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0,
377                                fs->blksz, metadata_buff);
378                 put_ext4((uint64_t)((uint64_t)be32_to_cpu(tag->block) * (uint64_t)fs->blksz),
379                          metadata_buff, (uint32_t) fs->blksz);
380         } while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG));
381 fail:
382         free(temp_buff);
383         free(metadata_buff);
384 }
385
386 void print_jrnl_status(int recovery_flag)
387 {
388         if (recovery_flag == RECOVER)
389                 printf("Journal Recovery Completed\n");
390         else
391                 printf("Journal Scan Completed\n");
392 }
393
394 int ext4fs_check_journal_state(int recovery_flag)
395 {
396         int i;
397         int DB_FOUND = NO;
398         long int blknr;
399         int transaction_state = TRANSACTION_COMPLETE;
400         int prev_desc_logical_no = 0;
401         int curr_desc_logical_no = 0;
402         int ofs, flags;
403         struct ext2_inode inode_journal;
404         struct journal_superblock_t *jsb = NULL;
405         struct journal_header_t *jdb = NULL;
406         char *p_jdb = NULL;
407         struct ext3_journal_block_tag *tag = NULL;
408         char *temp_buff = NULL;
409         char *temp_buff1 = NULL;
410         struct ext_filesystem *fs = get_fs();
411
412         if (le32_to_cpu(fs->sb->feature_ro_compat) & EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)
413                 return 0;
414
415         temp_buff = zalloc(fs->blksz);
416         if (!temp_buff)
417                 return -ENOMEM;
418         temp_buff1 = zalloc(fs->blksz);
419         if (!temp_buff1) {
420                 free(temp_buff);
421                 return -ENOMEM;
422         }
423
424         ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
425         blknr = read_allocated_block(&inode_journal, EXT2_JOURNAL_SUPERBLOCK,
426                                      NULL);
427         ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
428                        temp_buff);
429         jsb = (struct journal_superblock_t *) temp_buff;
430
431         if (le32_to_cpu(fs->sb->feature_incompat) & EXT3_FEATURE_INCOMPAT_RECOVER) {
432                 if (recovery_flag == RECOVER)
433                         printf("Recovery required\n");
434         } else {
435                 if (recovery_flag == RECOVER)
436                         printf("File System is consistent\n");
437                 goto end;
438         }
439
440         if (be32_to_cpu(jsb->s_start) == 0)
441                 goto end;
442
443         if (!(jsb->s_feature_compat &
444                                 cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM)))
445                 jsb->s_feature_compat |=
446                                 cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM);
447
448         i = be32_to_cpu(jsb->s_first);
449         while (1) {
450                 blknr = read_allocated_block(&inode_journal, i, NULL);
451                 memset(temp_buff1, '\0', fs->blksz);
452                 ext4fs_devread((lbaint_t)blknr * fs->sect_perblk,
453                                0, fs->blksz, temp_buff1);
454                 jdb = (struct journal_header_t *) temp_buff1;
455
456                 if (be32_to_cpu(jdb->h_blocktype) ==
457                     EXT3_JOURNAL_DESCRIPTOR_BLOCK) {
458                         if (be32_to_cpu(jdb->h_sequence) !=
459                             be32_to_cpu(jsb->s_sequence)) {
460                                 print_jrnl_status(recovery_flag);
461                                 break;
462                         }
463
464                         curr_desc_logical_no = i;
465                         if (transaction_state == TRANSACTION_COMPLETE)
466                                 transaction_state = TRANSACTION_RUNNING;
467                         else
468                                 return -1;
469                         p_jdb = (char *)temp_buff1;
470                         ofs = sizeof(struct journal_header_t);
471                         do {
472                                 tag = (struct ext3_journal_block_tag *)
473                                     (p_jdb + ofs);
474                                 ofs += sizeof(struct ext3_journal_block_tag);
475                                 if (ofs > fs->blksz)
476                                         break;
477                                 flags = be32_to_cpu(tag->flags);
478                                 if (!(flags & EXT3_JOURNAL_FLAG_SAME_UUID))
479                                         ofs += 16;
480                                 i++;
481                                 debug("\t\ttag %u\n", be32_to_cpu(tag->block));
482                         } while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG));
483                         i++;
484                         DB_FOUND = YES;
485                 } else if (be32_to_cpu(jdb->h_blocktype) ==
486                                 EXT3_JOURNAL_COMMIT_BLOCK) {
487                         if (be32_to_cpu(jdb->h_sequence) !=
488                              be32_to_cpu(jsb->s_sequence)) {
489                                 print_jrnl_status(recovery_flag);
490                                 break;
491                         }
492
493                         if (transaction_state == TRANSACTION_RUNNING ||
494                                         (DB_FOUND == NO)) {
495                                 transaction_state = TRANSACTION_COMPLETE;
496                                 i++;
497                                 jsb->s_sequence =
498                                         cpu_to_be32(be32_to_cpu(
499                                                 jsb->s_sequence) + 1);
500                         }
501                         prev_desc_logical_no = curr_desc_logical_no;
502                         if ((recovery_flag == RECOVER) && (DB_FOUND == YES))
503                                 recover_transaction(prev_desc_logical_no);
504
505                         DB_FOUND = NO;
506                 } else if (be32_to_cpu(jdb->h_blocktype) ==
507                                 EXT3_JOURNAL_REVOKE_BLOCK) {
508                         if (be32_to_cpu(jdb->h_sequence) !=
509                             be32_to_cpu(jsb->s_sequence)) {
510                                 print_jrnl_status(recovery_flag);
511                                 break;
512                         }
513                         if (recovery_flag == SCAN)
514                                 ext4fs_push_revoke_blk((char *)jdb);
515                         i++;
516                 } else {
517                         debug("Else Case\n");
518                         if (be32_to_cpu(jdb->h_sequence) !=
519                             be32_to_cpu(jsb->s_sequence)) {
520                                 print_jrnl_status(recovery_flag);
521                                 break;
522                         }
523                 }
524         }
525
526 end:
527         if (recovery_flag == RECOVER) {
528                 uint32_t new_feature_incompat;
529                 jsb->s_start = cpu_to_be32(1);
530                 jsb->s_sequence = cpu_to_be32(be32_to_cpu(jsb->s_sequence) + 1);
531                 /* get the superblock */
532                 ext4_read_superblock((char *)fs->sb);
533                 new_feature_incompat = le32_to_cpu(fs->sb->feature_incompat);
534                 new_feature_incompat |= EXT3_FEATURE_INCOMPAT_RECOVER;
535                 fs->sb->feature_incompat = cpu_to_le32(new_feature_incompat);
536
537                 /* Update the super block */
538                 put_ext4((uint64_t) (SUPERBLOCK_SIZE),
539                          (struct ext2_sblock *)fs->sb,
540                          (uint32_t) SUPERBLOCK_SIZE);
541                 ext4_read_superblock((char *)fs->sb);
542
543                 blknr = read_allocated_block(&inode_journal,
544                                          EXT2_JOURNAL_SUPERBLOCK, NULL);
545                 put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz),
546                          (struct journal_superblock_t *)temp_buff,
547                          (uint32_t) fs->blksz);
548                 ext4fs_free_revoke_blks();
549         }
550         free(temp_buff);
551         free(temp_buff1);
552
553         return 0;
554 }
555
556 static void update_descriptor_block(long int blknr)
557 {
558         int i;
559         long int jsb_blknr;
560         struct journal_header_t jdb;
561         struct ext3_journal_block_tag tag;
562         struct ext2_inode inode_journal;
563         struct journal_superblock_t *jsb = NULL;
564         char *buf = NULL;
565         char *temp = NULL;
566         struct ext_filesystem *fs = get_fs();
567         char *temp_buff = zalloc(fs->blksz);
568         if (!temp_buff)
569                 return;
570
571         ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
572         jsb_blknr = read_allocated_block(&inode_journal,
573                                          EXT2_JOURNAL_SUPERBLOCK, NULL);
574         ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz,
575                        temp_buff);
576         jsb = (struct journal_superblock_t *) temp_buff;
577
578         jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_DESCRIPTOR_BLOCK);
579         jdb.h_magic = cpu_to_be32(EXT3_JOURNAL_MAGIC_NUMBER);
580         jdb.h_sequence = jsb->s_sequence;
581         buf = zalloc(fs->blksz);
582         if (!buf) {
583                 free(temp_buff);
584                 return;
585         }
586         temp = buf;
587         memcpy(buf, &jdb, sizeof(struct journal_header_t));
588         temp += sizeof(struct journal_header_t);
589
590         for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
591                 if (journal_ptr[i]->blknr == -1)
592                         break;
593
594                 tag.block = cpu_to_be32(journal_ptr[i]->blknr);
595                 tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_SAME_UUID);
596                 memcpy(temp, &tag, sizeof(struct ext3_journal_block_tag));
597                 temp = temp + sizeof(struct ext3_journal_block_tag);
598         }
599
600         tag.block = cpu_to_be32(journal_ptr[--i]->blknr);
601         tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_LAST_TAG);
602         memcpy(temp - sizeof(struct ext3_journal_block_tag), &tag,
603                sizeof(struct ext3_journal_block_tag));
604         put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), buf, (uint32_t) fs->blksz);
605
606         free(temp_buff);
607         free(buf);
608 }
609
610 static void update_commit_block(long int blknr)
611 {
612         struct journal_header_t jdb;
613         struct ext_filesystem *fs = get_fs();
614         char *buf = NULL;
615         struct ext2_inode inode_journal;
616         struct journal_superblock_t *jsb;
617         long int jsb_blknr;
618         char *temp_buff = zalloc(fs->blksz);
619         if (!temp_buff)
620                 return;
621
622         ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO,
623                           &inode_journal);
624         jsb_blknr = read_allocated_block(&inode_journal,
625                                          EXT2_JOURNAL_SUPERBLOCK, NULL);
626         ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz,
627                        temp_buff);
628         jsb = (struct journal_superblock_t *) temp_buff;
629
630         jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_COMMIT_BLOCK);
631         jdb.h_magic = cpu_to_be32(EXT3_JOURNAL_MAGIC_NUMBER);
632         jdb.h_sequence = jsb->s_sequence;
633         buf = zalloc(fs->blksz);
634         if (!buf) {
635                 free(temp_buff);
636                 return;
637         }
638         memcpy(buf, &jdb, sizeof(struct journal_header_t));
639         put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), buf, (uint32_t) fs->blksz);
640
641         free(temp_buff);
642         free(buf);
643 }
644
645 void ext4fs_update_journal(void)
646 {
647         struct ext2_inode inode_journal;
648         struct ext_filesystem *fs = get_fs();
649         long int blknr;
650         int i;
651
652         if (!(fs->sb->feature_compatibility & EXT4_FEATURE_COMPAT_HAS_JOURNAL))
653                 return;
654
655         ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
656         blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++, NULL);
657         update_descriptor_block(blknr);
658         for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
659                 if (journal_ptr[i]->blknr == -1)
660                         break;
661                 blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++,
662                                              NULL);
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++, NULL);
667         update_commit_block(blknr);
668         printf("update journal finished\n");
669 }
This page took 0.067145 seconds and 4 git commands to generate.