]> Git Repo - J-u-boot.git/blob - fs/ext4/ext4_journal.c
Merge commit '0344c602eadc0802776b65ff90f0a02c856cf53c' as 'lib/mbedtls/external...
[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 <blk.h>
17 #include <ext4fs.h>
18 #include <log.h>
19 #include <malloc.h>
20 #include <ext_common.h>
21 #include "ext4_common.h"
22
23 static struct revoke_blk_list *revk_blk_list;
24 static struct revoke_blk_list *prev_node;
25 static int first_node = true;
26
27 int gindex;
28 int gd_index;
29 int jrnl_blk_idx;
30 struct journal_log *journal_ptr[MAX_JOURNAL_ENTRIES];
31 struct dirty_blocks *dirty_block_ptr[MAX_JOURNAL_ENTRIES];
32
33 int ext4fs_init_journal(void)
34 {
35         int i;
36         char *temp = NULL;
37         struct ext_filesystem *fs = get_fs();
38
39         /* init globals */
40         revk_blk_list = NULL;
41         prev_node = NULL;
42         gindex = 0;
43         gd_index = 0;
44         jrnl_blk_idx = 1;
45
46         for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
47                 journal_ptr[i] = zalloc(sizeof(struct journal_log));
48                 if (!journal_ptr[i])
49                         goto fail;
50                 dirty_block_ptr[i] = zalloc(sizeof(struct dirty_blocks));
51                 if (!dirty_block_ptr[i])
52                         goto fail;
53                 journal_ptr[i]->buf = NULL;
54                 journal_ptr[i]->blknr = -1;
55
56                 dirty_block_ptr[i]->buf = NULL;
57                 dirty_block_ptr[i]->blknr = -1;
58         }
59
60         if (fs->blksz == 4096) {
61                 temp = zalloc(fs->blksz);
62                 if (!temp)
63                         goto fail;
64                 journal_ptr[gindex]->buf = zalloc(fs->blksz);
65                 if (!journal_ptr[gindex]->buf)
66                         goto fail;
67                 ext4fs_devread(0, 0, fs->blksz, temp);
68                 memcpy(temp + SUPERBLOCK_SIZE, fs->sb, SUPERBLOCK_SIZE);
69                 memcpy(journal_ptr[gindex]->buf, temp, fs->blksz);
70                 journal_ptr[gindex++]->blknr = 0;
71                 free(temp);
72         } else {
73                 journal_ptr[gindex]->buf = zalloc(fs->blksz);
74                 if (!journal_ptr[gindex]->buf)
75                         goto fail;
76                 memcpy(journal_ptr[gindex]->buf, fs->sb, SUPERBLOCK_SIZE);
77                 journal_ptr[gindex++]->blknr = 1;
78         }
79
80         /* Check the file system state using journal super block */
81         if (ext4fs_check_journal_state(SCAN))
82                 goto fail;
83         /* Check the file system state using journal super block */
84         if (ext4fs_check_journal_state(RECOVER))
85                 goto fail;
86
87         return 0;
88 fail:
89         return -1;
90 }
91
92 void ext4fs_dump_metadata(void)
93 {
94         struct ext_filesystem *fs = get_fs();
95         int i;
96         for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
97                 if (dirty_block_ptr[i]->blknr == -1)
98                         break;
99                 put_ext4((uint64_t) ((uint64_t)dirty_block_ptr[i]->blknr *
100                                 (uint64_t)fs->blksz), dirty_block_ptr[i]->buf,
101                                                                 fs->blksz);
102         }
103 }
104
105 void ext4fs_free_journal(void)
106 {
107         int i;
108         for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
109                 if (dirty_block_ptr[i]->blknr == -1)
110                         break;
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                 free(journal_ptr[i]->buf);
118         }
119
120         for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
121                 free(journal_ptr[i]);
122                 free(dirty_block_ptr[i]);
123         }
124         gindex = 0;
125         gd_index = 0;
126         jrnl_blk_idx = 1;
127 }
128
129 int ext4fs_log_gdt(char *gd_table)
130 {
131         struct ext_filesystem *fs = get_fs();
132         short i;
133         long int var = fs->gdtable_blkno;
134         for (i = 0; i < fs->no_blk_pergdt; i++) {
135                 journal_ptr[gindex]->buf = zalloc(fs->blksz);
136                 if (!journal_ptr[gindex]->buf)
137                         return -ENOMEM;
138                 memcpy(journal_ptr[gindex]->buf, gd_table, fs->blksz);
139                 gd_table += fs->blksz;
140                 journal_ptr[gindex++]->blknr = var++;
141         }
142
143         return 0;
144 }
145
146 /*
147  * This function stores the backup copy of meta data in RAM
148  * journal_buffer -- Buffer containing meta data
149  * blknr -- Block number on disk of the meta data buffer
150  */
151 int ext4fs_log_journal(char *journal_buffer, uint32_t blknr)
152 {
153         struct ext_filesystem *fs = get_fs();
154         short i;
155
156         if (!journal_buffer) {
157                 printf("Invalid input arguments %s\n", __func__);
158                 return -EINVAL;
159         }
160
161         for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
162                 if (journal_ptr[i]->blknr == -1)
163                         break;
164                 if (journal_ptr[i]->blknr == blknr)
165                         return 0;
166         }
167
168         journal_ptr[gindex]->buf = zalloc(fs->blksz);
169         if (!journal_ptr[gindex]->buf)
170                 return -ENOMEM;
171
172         memcpy(journal_ptr[gindex]->buf, journal_buffer, fs->blksz);
173         journal_ptr[gindex++]->blknr = blknr;
174
175         return 0;
176 }
177
178 /*
179  * This function stores the modified meta data in RAM
180  * metadata_buffer -- Buffer containing meta data
181  * blknr -- Block number on disk of the meta data buffer
182  */
183 int ext4fs_put_metadata(char *metadata_buffer, uint32_t blknr)
184 {
185         struct ext_filesystem *fs = get_fs();
186         if (!metadata_buffer) {
187                 printf("Invalid input arguments %s\n", __func__);
188                 return -EINVAL;
189         }
190         if (dirty_block_ptr[gd_index]->buf)
191                 assert(dirty_block_ptr[gd_index]->blknr == blknr);
192         else
193                 dirty_block_ptr[gd_index]->buf = zalloc(fs->blksz);
194
195         if (!dirty_block_ptr[gd_index]->buf)
196                 return -ENOMEM;
197         memcpy(dirty_block_ptr[gd_index]->buf, metadata_buffer, fs->blksz);
198         dirty_block_ptr[gd_index++]->blknr = blknr;
199
200         return 0;
201 }
202
203 void print_revoke_blks(char *revk_blk)
204 {
205         int offset;
206         int max;
207         long int blocknr;
208         struct journal_revoke_header_t *header;
209
210         if (revk_blk == NULL)
211                 return;
212
213         header = (struct journal_revoke_header_t *) revk_blk;
214         offset = sizeof(struct journal_revoke_header_t);
215         max = be32_to_cpu(header->r_count);
216         printf("total bytes %d\n", max);
217
218         while (offset < max) {
219                 blocknr = be32_to_cpu(*((__be32 *)(revk_blk + offset)));
220                 printf("revoke blknr is %ld\n", blocknr);
221                 offset += 4;
222         }
223 }
224
225 static struct revoke_blk_list *_get_node(void)
226 {
227         struct revoke_blk_list *tmp_node;
228         tmp_node = zalloc(sizeof(struct revoke_blk_list));
229         if (tmp_node == NULL)
230                 return NULL;
231         tmp_node->content = NULL;
232         tmp_node->next = NULL;
233
234         return tmp_node;
235 }
236
237 void ext4fs_push_revoke_blk(char *buffer)
238 {
239         struct revoke_blk_list *node = NULL;
240         struct ext_filesystem *fs = get_fs();
241         if (buffer == NULL) {
242                 printf("buffer ptr is NULL\n");
243                 return;
244         }
245         node = _get_node();
246         if (!node) {
247                 printf("_get_node: malloc failed\n");
248                 return;
249         }
250
251         node->content = zalloc(fs->blksz);
252         if (node->content == NULL)
253                 return;
254         memcpy(node->content, buffer, fs->blksz);
255
256         if (first_node == true) {
257                 revk_blk_list = node;
258                 prev_node = node;
259                  first_node = false;
260         } else {
261                 prev_node->next = node;
262                 prev_node = node;
263         }
264 }
265
266 void ext4fs_free_revoke_blks(void)
267 {
268         struct revoke_blk_list *tmp_node = revk_blk_list;
269         struct revoke_blk_list *next_node = NULL;
270
271         while (tmp_node != NULL) {
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, NULL);
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, NULL);
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         if (le32_to_cpu(fs->sb->feature_ro_compat) & EXT4_FEATURE_RO_COMPAT_METADATA_CSUM)
409                 return 0;
410
411         temp_buff = zalloc(fs->blksz);
412         if (!temp_buff)
413                 return -ENOMEM;
414         temp_buff1 = zalloc(fs->blksz);
415         if (!temp_buff1) {
416                 free(temp_buff);
417                 return -ENOMEM;
418         }
419
420         ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
421         blknr = read_allocated_block(&inode_journal, EXT2_JOURNAL_SUPERBLOCK,
422                                      NULL);
423         ext4fs_devread((lbaint_t)blknr * fs->sect_perblk, 0, fs->blksz,
424                        temp_buff);
425         jsb = (struct journal_superblock_t *) temp_buff;
426
427         if (le32_to_cpu(fs->sb->feature_incompat) & EXT3_FEATURE_INCOMPAT_RECOVER) {
428                 if (recovery_flag == RECOVER)
429                         printf("Recovery required\n");
430         } else {
431                 if (recovery_flag == RECOVER)
432                         log_debug("File System is consistent\n");
433                 goto end;
434         }
435
436         if (be32_to_cpu(jsb->s_start) == 0)
437                 goto end;
438
439         if (!(jsb->s_feature_compat &
440                                 cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM)))
441                 jsb->s_feature_compat |=
442                                 cpu_to_be32(JBD2_FEATURE_COMPAT_CHECKSUM);
443
444         i = be32_to_cpu(jsb->s_first);
445         while (1) {
446                 blknr = read_allocated_block(&inode_journal, i, NULL);
447                 memset(temp_buff1, '\0', fs->blksz);
448                 ext4fs_devread((lbaint_t)blknr * fs->sect_perblk,
449                                0, fs->blksz, temp_buff1);
450                 jdb = (struct journal_header_t *) temp_buff1;
451
452                 if (be32_to_cpu(jdb->h_blocktype) ==
453                     EXT3_JOURNAL_DESCRIPTOR_BLOCK) {
454                         if (be32_to_cpu(jdb->h_sequence) !=
455                             be32_to_cpu(jsb->s_sequence)) {
456                                 print_jrnl_status(recovery_flag);
457                                 break;
458                         }
459
460                         curr_desc_logical_no = i;
461                         if (transaction_state == TRANSACTION_COMPLETE)
462                                 transaction_state = TRANSACTION_RUNNING;
463                         else
464                                 return -1;
465                         p_jdb = (char *)temp_buff1;
466                         ofs = sizeof(struct journal_header_t);
467                         do {
468                                 tag = (struct ext3_journal_block_tag *)
469                                     (p_jdb + ofs);
470                                 ofs += sizeof(struct ext3_journal_block_tag);
471                                 if (ofs > fs->blksz)
472                                         break;
473                                 flags = be32_to_cpu(tag->flags);
474                                 if (!(flags & EXT3_JOURNAL_FLAG_SAME_UUID))
475                                         ofs += 16;
476                                 i++;
477                                 debug("\t\ttag %u\n", be32_to_cpu(tag->block));
478                         } while (!(flags & EXT3_JOURNAL_FLAG_LAST_TAG));
479                         i++;
480                         DB_FOUND = YES;
481                 } else if (be32_to_cpu(jdb->h_blocktype) ==
482                                 EXT3_JOURNAL_COMMIT_BLOCK) {
483                         if (be32_to_cpu(jdb->h_sequence) !=
484                              be32_to_cpu(jsb->s_sequence)) {
485                                 print_jrnl_status(recovery_flag);
486                                 break;
487                         }
488
489                         if (transaction_state == TRANSACTION_RUNNING ||
490                                         (DB_FOUND == NO)) {
491                                 transaction_state = TRANSACTION_COMPLETE;
492                                 i++;
493                                 jsb->s_sequence =
494                                         cpu_to_be32(be32_to_cpu(
495                                                 jsb->s_sequence) + 1);
496                         }
497                         prev_desc_logical_no = curr_desc_logical_no;
498                         if ((recovery_flag == RECOVER) && (DB_FOUND == YES))
499                                 recover_transaction(prev_desc_logical_no);
500
501                         DB_FOUND = NO;
502                 } else if (be32_to_cpu(jdb->h_blocktype) ==
503                                 EXT3_JOURNAL_REVOKE_BLOCK) {
504                         if (be32_to_cpu(jdb->h_sequence) !=
505                             be32_to_cpu(jsb->s_sequence)) {
506                                 print_jrnl_status(recovery_flag);
507                                 break;
508                         }
509                         if (recovery_flag == SCAN)
510                                 ext4fs_push_revoke_blk((char *)jdb);
511                         i++;
512                 } else {
513                         debug("Else Case\n");
514                         if (be32_to_cpu(jdb->h_sequence) !=
515                             be32_to_cpu(jsb->s_sequence)) {
516                                 print_jrnl_status(recovery_flag);
517                                 break;
518                         }
519                 }
520         }
521
522 end:
523         if (recovery_flag == RECOVER) {
524                 uint32_t new_feature_incompat;
525                 jsb->s_start = cpu_to_be32(1);
526                 jsb->s_sequence = cpu_to_be32(be32_to_cpu(jsb->s_sequence) + 1);
527                 /* get the superblock */
528                 ext4_read_superblock((char *)fs->sb);
529                 new_feature_incompat = le32_to_cpu(fs->sb->feature_incompat);
530                 new_feature_incompat |= EXT3_FEATURE_INCOMPAT_RECOVER;
531                 fs->sb->feature_incompat = cpu_to_le32(new_feature_incompat);
532
533                 /* Update the super block */
534                 put_ext4((uint64_t) (SUPERBLOCK_SIZE),
535                          (struct ext2_sblock *)fs->sb,
536                          (uint32_t) SUPERBLOCK_SIZE);
537                 ext4_read_superblock((char *)fs->sb);
538
539                 blknr = read_allocated_block(&inode_journal,
540                                          EXT2_JOURNAL_SUPERBLOCK, NULL);
541                 put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz),
542                          (struct journal_superblock_t *)temp_buff,
543                          (uint32_t) fs->blksz);
544                 ext4fs_free_revoke_blks();
545         }
546         free(temp_buff);
547         free(temp_buff1);
548
549         return 0;
550 }
551
552 static void update_descriptor_block(long int blknr)
553 {
554         int i;
555         long int jsb_blknr;
556         struct journal_header_t jdb;
557         struct ext3_journal_block_tag tag;
558         struct ext2_inode inode_journal;
559         struct journal_superblock_t *jsb = NULL;
560         char *buf = NULL;
561         char *temp = NULL;
562         struct ext_filesystem *fs = get_fs();
563         char *temp_buff = zalloc(fs->blksz);
564         if (!temp_buff)
565                 return;
566
567         ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
568         jsb_blknr = read_allocated_block(&inode_journal,
569                                          EXT2_JOURNAL_SUPERBLOCK, NULL);
570         ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz,
571                        temp_buff);
572         jsb = (struct journal_superblock_t *) temp_buff;
573
574         jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_DESCRIPTOR_BLOCK);
575         jdb.h_magic = cpu_to_be32(EXT3_JOURNAL_MAGIC_NUMBER);
576         jdb.h_sequence = jsb->s_sequence;
577         buf = zalloc(fs->blksz);
578         if (!buf) {
579                 free(temp_buff);
580                 return;
581         }
582         temp = buf;
583         memcpy(buf, &jdb, sizeof(struct journal_header_t));
584         temp += sizeof(struct journal_header_t);
585
586         for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
587                 if (journal_ptr[i]->blknr == -1)
588                         break;
589
590                 tag.block = cpu_to_be32(journal_ptr[i]->blknr);
591                 tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_SAME_UUID);
592                 memcpy(temp, &tag, sizeof(struct ext3_journal_block_tag));
593                 temp = temp + sizeof(struct ext3_journal_block_tag);
594         }
595
596         tag.block = cpu_to_be32(journal_ptr[--i]->blknr);
597         tag.flags = cpu_to_be32(EXT3_JOURNAL_FLAG_LAST_TAG);
598         memcpy(temp - sizeof(struct ext3_journal_block_tag), &tag,
599                sizeof(struct ext3_journal_block_tag));
600         put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), buf, (uint32_t) fs->blksz);
601
602         free(temp_buff);
603         free(buf);
604 }
605
606 static void update_commit_block(long int blknr)
607 {
608         struct journal_header_t jdb;
609         struct ext_filesystem *fs = get_fs();
610         char *buf = NULL;
611         struct ext2_inode inode_journal;
612         struct journal_superblock_t *jsb;
613         long int jsb_blknr;
614         char *temp_buff = zalloc(fs->blksz);
615         if (!temp_buff)
616                 return;
617
618         ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO,
619                           &inode_journal);
620         jsb_blknr = read_allocated_block(&inode_journal,
621                                          EXT2_JOURNAL_SUPERBLOCK, NULL);
622         ext4fs_devread((lbaint_t)jsb_blknr * fs->sect_perblk, 0, fs->blksz,
623                        temp_buff);
624         jsb = (struct journal_superblock_t *) temp_buff;
625
626         jdb.h_blocktype = cpu_to_be32(EXT3_JOURNAL_COMMIT_BLOCK);
627         jdb.h_magic = cpu_to_be32(EXT3_JOURNAL_MAGIC_NUMBER);
628         jdb.h_sequence = jsb->s_sequence;
629         buf = zalloc(fs->blksz);
630         if (!buf) {
631                 free(temp_buff);
632                 return;
633         }
634         memcpy(buf, &jdb, sizeof(struct journal_header_t));
635         put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz), buf, (uint32_t) fs->blksz);
636
637         free(temp_buff);
638         free(buf);
639 }
640
641 void ext4fs_update_journal(void)
642 {
643         struct ext2_inode inode_journal;
644         struct ext_filesystem *fs = get_fs();
645         long int blknr;
646         int i;
647
648         if (!(fs->sb->feature_compatibility & EXT4_FEATURE_COMPAT_HAS_JOURNAL))
649                 return;
650
651         ext4fs_read_inode(ext4fs_root, EXT2_JOURNAL_INO, &inode_journal);
652         blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++, NULL);
653         update_descriptor_block(blknr);
654         for (i = 0; i < MAX_JOURNAL_ENTRIES; i++) {
655                 if (journal_ptr[i]->blknr == -1)
656                         break;
657                 blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++,
658                                              NULL);
659                 put_ext4((uint64_t) ((uint64_t)blknr * (uint64_t)fs->blksz),
660                          journal_ptr[i]->buf, fs->blksz);
661         }
662         blknr = read_allocated_block(&inode_journal, jrnl_blk_idx++, NULL);
663         update_commit_block(blknr);
664         printf("update journal finished\n");
665 }
This page took 0.063993 seconds and 4 git commands to generate.