Skip to content

Commit

Permalink
Implement external journal device initialization
Browse files Browse the repository at this point in the history
Added a function simplefs_parse_options in the fill super process to
obtain the external journal device and configure it using jbd2 related
functions. Additionally, journal-related functionality was added to the
write functions to record metadata "extent" information.

Also, added a "make journal" command in the Makefile, allowing users
to create an external journal device image and mount it to simplefs.
  • Loading branch information
jason50123 committed Jun 24, 2024
1 parent 92f3287 commit 1c9b940
Show file tree
Hide file tree
Showing 4 changed files with 404 additions and 3 deletions.
13 changes: 11 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ all: $(MKFS)

IMAGE ?= test.img
IMAGESIZE ?= 200
JOURNAL ?= journal.img
JOURNALSIZE ?= 8

# To test max files(40920) in directory, the image size should be at least 159.85 MiB
# 40920 * 4096(block size) ~= 159.85 MiB

Expand All @@ -20,12 +23,18 @@ $(IMAGE): $(MKFS)
dd if=/dev/zero of=${IMAGE} bs=1M count=${IMAGESIZE}
./$< $(IMAGE)

journal: $(JOURNAL)

$(JOURNAL):
dd if=/dev/zero of=$(JOURNAL) bs=1M count=$(JOURNALSIZE)
mke2fs -b 4096 -O journal_dev $(JOURNAL)

check: all
script/test.sh $(IMAGE) $(IMAGESIZE) $(MKFS)

clean:
make -C $(KDIR) M=$(PWD) clean
rm -f *~ $(PWD)/*.ur-safe
rm -f $(MKFS) $(IMAGE)
rm -f $(MKFS) $(IMAGE) $(JOURNAL)

.PHONY: all clean
.PHONY: all clean journal
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 starting here */
/*
* FIXME: 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
7 changes: 7 additions & 0 deletions simplefs.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
* | blocks | rest of the blocks
* +---------------+
*/
#ifdef __KERNEL__
#include <linux/jbd2.h>
#endif

struct simplefs_inode {
uint32_t i_mode; /* File mode */
Expand Down Expand Up @@ -69,6 +72,10 @@ struct simplefs_sb_info {
uint32_t nr_free_blocks; /* Number of free blocks */

#ifdef __KERNEL__
journal_t *journal;
struct block_device *s_journal_bdev; /* v6.5 external journal device */
struct bdev_handle
*s_journal_bdev_handle; /* v6.8 external journal device */
unsigned long *ifree_bitmap; /* In-memory free inodes bitmap */
unsigned long *bfree_bitmap; /* In-memory free blocks bitmap */
#endif
Expand Down
Loading

0 comments on commit 1c9b940

Please sign in to comment.