ext4_journal: add journal helpers to ext4_journal.h
[lwext4.git] / lwext4 / ext4_journal.c
1 /**
2  * @file  ext4_journal.c
3  * @brief Journalling
4  */
5
6 #include "ext4_config.h"
7 #include "ext4_types.h"
8 #include "ext4_fs.h"
9 #include "ext4_super.h"
10 #include "ext4_errno.h"
11 #include "ext4_blockdev.h"
12 #include "ext4_crc32c.h"
13 #include "ext4_debug.h"
14
15 #include <string.h>
16
17 int jbd_inode_bmap(struct jbd_fs *jbd_fs,
18                    ext4_lblk_t iblock,
19                    ext4_fsblk_t *fblock);
20
21 int jbd_sb_write(struct jbd_fs *jbd_fs, struct jbd_sb *s)
22 {
23         int rc;
24         struct ext4_fs *fs = jbd_fs->inode_ref.fs;
25         uint64_t offset;
26         ext4_fsblk_t fblock;
27         rc = jbd_inode_bmap(jbd_fs, 0, &fblock);
28         if (rc != EOK)
29                 return rc;
30
31         offset = fblock * ext4_sb_get_block_size(&fs->sb);
32         return ext4_block_writebytes(fs->bdev, offset, s,
33                                      EXT4_SUPERBLOCK_SIZE);
34 }
35
36 int jbd_sb_read(struct jbd_fs *jbd_fs, struct jbd_sb *s)
37 {
38         int rc;
39         struct ext4_fs *fs = jbd_fs->inode_ref.fs;
40         uint64_t offset;
41         ext4_fsblk_t fblock;
42         rc = jbd_inode_bmap(jbd_fs, 0, &fblock);
43         if (rc != EOK)
44                 return rc;
45
46         offset = fblock * ext4_sb_get_block_size(&fs->sb);
47         return ext4_block_readbytes(fs->bdev, offset, s,
48                                     EXT4_SUPERBLOCK_SIZE);
49 }
50
51 int jbd_get_fs(struct ext4_fs *fs,
52                struct jbd_fs *jbd_fs)
53 {
54         int rc;
55         uint32_t journal_ino;
56
57         memset(jbd_fs, 0, sizeof(struct jbd_fs));
58         journal_ino = ext4_get32(&fs->sb, journal_inode_number);
59
60         rc = ext4_fs_get_inode_ref(fs,
61                                    journal_ino,
62                                    &jbd_fs->inode_ref);
63         if (rc != EOK) {
64                 memset(jbd_fs, 0, sizeof(struct jbd_fs));
65                 return rc;
66         }
67         rc = jbd_sb_read(jbd_fs, &jbd_fs->sb);
68         if (rc != EOK) {
69                 memset(jbd_fs, 0, sizeof(struct jbd_fs));
70                 ext4_fs_put_inode_ref(&jbd_fs->inode_ref);
71         }
72         return rc;
73 }
74
75 int jbd_put_fs(struct jbd_fs *jbd_fs)
76 {
77         int rc;
78         rc = ext4_fs_put_inode_ref(&jbd_fs->inode_ref);
79         return rc;
80 }
81
82 int jbd_inode_bmap(struct jbd_fs *jbd_fs,
83                    ext4_lblk_t iblock,
84                    ext4_fsblk_t *fblock)
85 {
86         int rc = ext4_fs_get_inode_data_block_index(
87                         &jbd_fs->inode_ref,
88                         iblock,
89                         fblock,
90                         false);
91         return rc;
92 }
93
94 int jbd_block_get(struct jbd_fs *jbd_fs,
95                   struct ext4_block *block,
96                   ext4_fsblk_t fblock)
97 {
98         /* TODO: journal device. */
99         int rc;
100         ext4_lblk_t iblock = (ext4_lblk_t)fblock;
101         rc = jbd_inode_bmap(jbd_fs, iblock,
102                             &fblock);
103         if (rc != EOK)
104                 return rc;
105
106         struct ext4_blockdev *bdev = jbd_fs->inode_ref.fs->bdev;
107         rc = ext4_block_get(bdev, block, fblock);
108         return rc;
109 }
110
111 int jbd_block_get_noread(struct jbd_fs *jbd_fs,
112                          struct ext4_block *block,
113                          ext4_fsblk_t fblock)
114 {
115         /* TODO: journal device. */
116         int rc;
117         ext4_lblk_t iblock = (ext4_lblk_t)fblock;
118         rc = jbd_inode_bmap(jbd_fs, iblock,
119                             &fblock);
120         if (rc != EOK)
121                 return rc;
122
123         struct ext4_blockdev *bdev = jbd_fs->inode_ref.fs->bdev;
124         rc = ext4_block_get_noread(bdev, block, fblock);
125         return rc;
126 }
127
128 int jbd_block_set(struct jbd_fs *jbd_fs,
129                   struct ext4_block *block)
130 {
131         return ext4_block_set(jbd_fs->inode_ref.fs->bdev,
132                               block);
133 }
134
135 int jbd_recovery(struct jbd_fs *jbd_fs)
136 {
137         struct jbd_sb *sb = &jbd_fs->sb;
138         if (!sb->start)
139                 return EOK;
140
141 }