has_journal compatible feature cannot be enabled
tammyleino opened this issue · comments
The LWEXT4 github page lists has_journal as a supported compatible feature:
compatible:
• has_journal, ext_attr, dir_index: yes
• dir_prealloc, imagic_inodes, resize_inode: no
ext4_mkfs() configures the feature sets for a mount point. The feature set for F_SET_EXT4 is:
info->feat_compat = EXT4_SUPPORTED_FCOM;
info->feat_ro_compat = EXT4_SUPPORTED_FRO_COM;
info->feat_incompat = EXT4_SUPPORTED_FINCOM;
The compatible features set up by default for the EXT4 build are EXT4_SUPPORTED_FCOM
#define EXT4_SUPPORTED_FCOM (EXT4_FCOM_DIR_INDEX)
#define EXT4_FCOM_DIR_INDEX 0x0020
Note that EXT4_FCOM_HAS_JOURNAL is not included in the compatible feature set macro and is never added to the feature list anywhere in the source code.
There are three references to EXT4_FCOM_HAS_JOURNAL that would cause journaling operations to occur, but all three references are within functions that are not called by default within the LWEXT4 codebase.
__unused
static int __ext4_journal_start(const char *mount_point)
__unused
static int __ext4_journal_stop(const char *mount_point)
__unused
static int __ext4_recover(const char *mount_point)
According to ext4.h, ext4_journal_start() and ext4_journal_stop() should be called when a mount point is mounted and/or unmounted:
/**@brief Start journaling. Journaling start/stop functions are transparent
* and might be used on filesystems without journaling support.
* @warning Usage:
* ext4_mount("sda1", "/");
* ext4_journal_start("/");
*
* //File operations here...
*
* ext4_journal_stop("/");
* ext4_umount("/");
* @param mount_point mount name
* @return standard error code */
int ext4_journal_start(const char *mount_point);
/**@brief Stop journaling. Journaling start/stop functions are transparent
* and might be used on filesystems without journaling support.
* @param mount_point mount name
* @return standard error code */
int ext4_journal_stop(const char *mount_point);
The example that comes with LWEXT4 shows the following order of operations:
r = ext4_device_register(bd, bc ? bc : 0, "ext4_fs");
r = ext4_mount("ext4_fs", "/mp/", false);
r = ext4_recover("/mp/");
r = ext4_journal_start("/mp/");
However, ext4_recover() and ext4_journal_start() do nothing since both functions require the EXT4_FCOM_HAS_JOURNAL flag, and this flag is never set by the application or the LWEXT4 codebase.
I made two modifications to the code to try to get this to work. First, I updated ext4_mkfs() to include EXT4_FCOM_HAS_JOURNAL in the list of compatible features:
if (info->journal == 1)
info->feat_compat |= EXT4_FCOM_HAS_JOURNAL;
Second, I added calls to ext4_recover() and ext4_journal_start() after a successful mount operation. This leads ext4_recover() and ext4_journal_start() to crash due to a dereference of NULL memory:
if (!jbd_verify_sb(&jbd_fs->sb)) {
memset(jbd_fs, 0, sizeof(struct jbd_fs));
ext4_fs_put_inode_ref(&jbd_fs->inode_ref);
rc = EIO;
}
ext4_fs_put_inode_ref goes on to dereference a pointer in jbd->inode_ref, which is pointing to NULL.
I verified that journaling appears to work when LWEXT4 is built and run on Linux, but I am unable to get it to work when building the library for a custom RTOS.
I will paste here a part of our email discussion:
At this point lwext4 mkfs doesn't support journal inode creation. That's why your code crashes when you call journal related functions (EXT4_FCOM_HAS_JOURNAL flag set is not enough). There is a TODO left in code:
https://github.com/gkostka/lwext4/blob/master/src/ext4_mkfs.c#L684
I will implement this soon. Stay tuned.
ext4_mkfs + journal node creation and initialization should be functional now:
12af982
Let me know if you find any issue.
Thank you very much, @gkostka . I downloaded the code, but I still see a crash when calling ext4_recover or ext4_journal_start. Please verify the sequence of events from the demo:
ext4_mount
ext4_recover
ext4_journal_start
Thank you.
Please try again download 12af982 (git push --force has been done recently). Please verify whether info->journal is set to true value in your code:
https://github.com/gkostka/lwext4/blob/master/src/ext4_mkfs.c#L766
@gkostka - Thank you for the response. info->journal is set, and I see the code set EXT4_FCOM_HAS_JOURNAL and initialize all the journaling code within ext4_mkfs. The problem is that __ext4_journal_start causes an unhandled exception at the call to jbd_get_fs(). If I omit this call, fs.jbd_journal doesn't get initialized.
Strange. lwext4-mkfs + lwext4-generic seems to work correctly on my setup. You have to provide some test code here. Could you reproduce it on PC?
@gkostka - It is working now. I had mistakenly truncated one line of code when merging my changes. Thank you so much.
Nice to hear that it is working. I'm looking forward to get more feedback.