Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c6d38301 authored by Joern Engel's avatar Joern Engel
Browse files

[LogFS] Only write journal if dirty

This prevents unnecessary journal writes.  More importantly it prevents
an oops due to a journal write on failed mount.
parent 9421502b
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -469,7 +469,7 @@ static void __logfs_gc_pass(struct super_block *sb, int target)

		/* Sync in-memory state with on-medium state in case they
		 * diverged */
		logfs_write_anchor(super->s_master_inode);
		logfs_write_anchor(sb);
		round += logfs_scan_some(sb);
		if (no_free_segments(sb) >= target)
			goto write_alias;
@@ -613,8 +613,8 @@ void logfs_gc_pass(struct super_block *sb)
	 */
	if (super->s_dirty_used_bytes + super->s_dirty_free_bytes
			+ LOGFS_MAX_OBJECTSIZE >= super->s_free_bytes)
		logfs_write_anchor(super->s_master_inode);
	__logfs_gc_pass(sb, logfs_super(sb)->s_total_levels);
		logfs_write_anchor(sb);
	__logfs_gc_pass(sb, super->s_total_levels);
	logfs_wl_pass(sb);
	logfs_journal_wl_pass(sb);
}
+7 −4
Original line number Diff line number Diff line
@@ -724,14 +724,17 @@ static int logfs_write_obj_aliases(struct super_block *sb)
 * bit wasteful, but robustness is more important.  With this we can *always*
 * erase all journal segments except the one containing the most recent commit.
 */
void logfs_write_anchor(struct inode *inode)
void logfs_write_anchor(struct super_block *sb)
{
	struct super_block *sb = inode->i_sb;
	struct logfs_super *super = logfs_super(sb);
	struct logfs_area *area = super->s_journal_area;
	int i, err;

	BUG_ON(logfs_super(sb)->s_flags & LOGFS_SB_FLAG_SHUTDOWN);
	if (!(super->s_flags & LOGFS_SB_FLAG_DIRTY))
		return;
	super->s_flags &= ~LOGFS_SB_FLAG_DIRTY;

	BUG_ON(super->s_flags & LOGFS_SB_FLAG_SHUTDOWN);
	mutex_lock(&super->s_journal_mutex);

	/* Do this first or suffer corruption */
@@ -821,7 +824,7 @@ void do_logfs_journal_wl_pass(struct super_block *sb)
	area->a_is_open = 0;
	area->a_used_bytes = 0;
	/* Write journal */
	logfs_write_anchor(super->s_master_inode);
	logfs_write_anchor(sb);
	/* Write superblocks */
	err = logfs_write_sb(sb);
	BUG_ON(err);
+2 −2
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@

/* Read-only filesystem */
#define LOGFS_SB_FLAG_RO	0x0001
#define LOGFS_SB_FLAG_SEG_ALIAS	0x0002
#define LOGFS_SB_FLAG_DIRTY	0x0002
#define LOGFS_SB_FLAG_OBJ_ALIAS	0x0004
#define LOGFS_SB_FLAG_SHUTDOWN	0x0008

@@ -526,7 +526,7 @@ void logfs_delete_inode(struct inode *inode);
void logfs_clear_inode(struct inode *inode);

/* journal.c */
void logfs_write_anchor(struct inode *inode);
void logfs_write_anchor(struct super_block *sb);
int logfs_init_journal(struct super_block *sb);
void logfs_cleanup_journal(struct super_block *sb);
int write_alias_journal(struct super_block *sb, u64 ino, u64 bix,
+1 −1
Original line number Diff line number Diff line
@@ -421,7 +421,7 @@ static void inode_write_block(struct logfs_block *block)

	inode = block->inode;
	if (inode->i_ino == LOGFS_INO_MASTER)
		logfs_write_anchor(inode);
		logfs_write_anchor(inode->i_sb);
	else {
		ret = __logfs_write_inode(inode, 0);
		/* see indirect_write_block comment */
+5 −2
Original line number Diff line number Diff line
@@ -352,7 +352,8 @@ int logfs_segment_write(struct inode *inode, struct page *page,
	int ret;
	void *buf;

	BUG_ON(logfs_super(sb)->s_flags & LOGFS_SB_FLAG_SHUTDOWN);
	super->s_flags |= LOGFS_SB_FLAG_DIRTY;
	BUG_ON(super->s_flags & LOGFS_SB_FLAG_SHUTDOWN);
	do_compress = logfs_inode(inode)->li_flags & LOGFS_IF_COMPRESSED;
	if (shadow->gc_level != 0) {
		/* temporarily disable compression for indirect blocks */
@@ -653,11 +654,13 @@ int logfs_segment_read(struct inode *inode, struct page *page,
int logfs_segment_delete(struct inode *inode, struct logfs_shadow *shadow)
{
	struct super_block *sb = inode->i_sb;
	struct logfs_super *super = logfs_super(sb);
	struct logfs_object_header h;
	u16 len;
	int err;

	BUG_ON(logfs_super(sb)->s_flags & LOGFS_SB_FLAG_SHUTDOWN);
	super->s_flags |= LOGFS_SB_FLAG_DIRTY;
	BUG_ON(super->s_flags & LOGFS_SB_FLAG_SHUTDOWN);
	BUG_ON(shadow->old_ofs & LOGFS_FULLY_POPULATED);
	if (!shadow->old_ofs)
		return 0;
Loading