Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mount the external journal device and write accessible extent metadata #59

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading