Skip to content

Commit

Permalink
Add journal to write function
Browse files Browse the repository at this point in the history
In the current design of simplefs, we can only access the extent
metadata and perform the 'journal' action on it. To write inode and
other metadata, we might need to emulate `ext4_dirty_inode`.
This method primarily uses the content of struct ext4_iloc to find the
correct location of the inode on disk and records it in the journal.
However, in our current situation, simply using `mark_inode_dirty` to
handle dirty inodes does not allow us to obtain the inode's location,
thus preventing us from recording it in the journal.

But currently, the idea is that we might create a new buffer head, use
`jbd2_journal_get_create_access` to put the dirty inode in it, and then
use `jbd2_journal_dirty_metadata` to write it to the journal.
  • Loading branch information
jason50123 committed Jun 20, 2024
1 parent 71898cd commit e2af929
Showing 1 changed file with 55 additions and 0 deletions.
55 changes: 55 additions & 0 deletions file.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include <linux/buffer_head.h>
#include <linux/fs.h>
#include <linux/jbd2.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/mpage.h>
Expand Down Expand Up @@ -34,6 +35,20 @@ static int simplefs_file_get_block(struct inode *inode,
bh_index = sb_bread(sb, ci->ei_block);
if (!bh_index)
return -EIO;

handle_t *handle = journal_current_handle();
if (!handle) {
brelse(bh_index);
return -EIO;
}

ret = jbd2_journal_get_write_access(handle, bh_index);
if (ret) {
brelse(bh_index);
pr_info("Can't get write access for bh\n");
return ret;
}

index = (struct simplefs_file_ei_block *) bh_index->b_data;

extent = simplefs_ext_search(index, iblock);
Expand Down Expand Up @@ -63,6 +78,13 @@ static int simplefs_file_get_block(struct inode *inode,
extent ? index->extents[extent - 1].ee_block +
index->extents[extent - 1].ee_len
: 0;
ret = jbd2_journal_dirty_metadata(handle, bh_index);
if (ret) {
brelse(bh_index);
return ret;
}
mark_buffer_dirty_inode(bh_index, inode);

} else {
bno = index->extents[extent].ee_start + iblock -
index->extents[extent].ee_block;
Expand Down Expand Up @@ -133,6 +155,7 @@ static int simplefs_write_begin(struct file *file,
struct simplefs_sb_info *sbi = SIMPLEFS_SB(file->f_inode->i_sb);
int err;
uint32_t nr_allocs = 0;
handle_t *handle;

/* Check if the write can be completed (enough space?) */
if (pos + len > SIMPLEFS_MAX_FILESIZE)
Expand All @@ -146,6 +169,16 @@ static int simplefs_write_begin(struct file *file,
if (nr_allocs > sbi->nr_free_blocks)
return -ENOSPC;

// handle journal start here
/*
* Fix me: the metadata type we should store into journal
* In the current situation, we only record the location of the extent
* and write that metadata to the journal.
*/
handle = jbd2_journal_start(sbi->journal, 1);
if (IS_ERR(handle))
return PTR_ERR(handle);

/* prepare the write */
#if SIMPLEFS_AT_LEAST(5, 19, 0)
err = block_write_begin(mapping, pos, len, pagep, simplefs_file_get_block);
Expand Down Expand Up @@ -174,6 +207,16 @@ static int simplefs_write_end(struct file *file,
struct inode *inode = file->f_inode;
struct simplefs_inode_info *ci = SIMPLEFS_INODE(inode);
struct super_block *sb = inode->i_sb;

handle_t *handle;

// handle journal start here
handle = journal_current_handle();
if (!handle) {
pr_err("can't get journal handle\n");
return -EIO;
}

#if SIMPLEFS_AT_LEAST(6, 6, 0)
struct timespec64 cur_time;
#endif
Expand Down Expand Up @@ -223,6 +266,14 @@ static int simplefs_write_end(struct file *file,
nr_blocks_old - inode->i_blocks);
goto end;
}

int retval = jbd2_journal_get_write_access(handle, bh_index);
if (WARN_ON(retval)) {
brelse(bh_index);
pr_info("cant get journal write access\n");
return retval;
}

index = (struct simplefs_file_ei_block *) bh_index->b_data;

first_ext = simplefs_ext_search(index, inode->i_blocks - 1);
Expand All @@ -238,9 +289,13 @@ static int simplefs_write_end(struct file *file,
index->extents[i].ee_len);
memset(&index->extents[i], 0, sizeof(struct simplefs_extent));
}
jbd2_journal_dirty_metadata(handle, bh_index);
mark_buffer_dirty(bh_index);
brelse(bh_index);
}

jbd2_journal_stop(handle);

end:
return ret;
}
Expand Down

0 comments on commit e2af929

Please sign in to comment.