mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
[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.
This commit is contained in:
parent
9421502b4f
commit
c6d3830140
@ -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
|
/* Sync in-memory state with on-medium state in case they
|
||||||
* diverged */
|
* diverged */
|
||||||
logfs_write_anchor(super->s_master_inode);
|
logfs_write_anchor(sb);
|
||||||
round += logfs_scan_some(sb);
|
round += logfs_scan_some(sb);
|
||||||
if (no_free_segments(sb) >= target)
|
if (no_free_segments(sb) >= target)
|
||||||
goto write_alias;
|
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
|
if (super->s_dirty_used_bytes + super->s_dirty_free_bytes
|
||||||
+ LOGFS_MAX_OBJECTSIZE >= super->s_free_bytes)
|
+ LOGFS_MAX_OBJECTSIZE >= super->s_free_bytes)
|
||||||
logfs_write_anchor(super->s_master_inode);
|
logfs_write_anchor(sb);
|
||||||
__logfs_gc_pass(sb, logfs_super(sb)->s_total_levels);
|
__logfs_gc_pass(sb, super->s_total_levels);
|
||||||
logfs_wl_pass(sb);
|
logfs_wl_pass(sb);
|
||||||
logfs_journal_wl_pass(sb);
|
logfs_journal_wl_pass(sb);
|
||||||
}
|
}
|
||||||
|
@ -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*
|
* bit wasteful, but robustness is more important. With this we can *always*
|
||||||
* erase all journal segments except the one containing the most recent commit.
|
* 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_super *super = logfs_super(sb);
|
||||||
struct logfs_area *area = super->s_journal_area;
|
struct logfs_area *area = super->s_journal_area;
|
||||||
int i, err;
|
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);
|
mutex_lock(&super->s_journal_mutex);
|
||||||
|
|
||||||
/* Do this first or suffer corruption */
|
/* 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_is_open = 0;
|
||||||
area->a_used_bytes = 0;
|
area->a_used_bytes = 0;
|
||||||
/* Write journal */
|
/* Write journal */
|
||||||
logfs_write_anchor(super->s_master_inode);
|
logfs_write_anchor(sb);
|
||||||
/* Write superblocks */
|
/* Write superblocks */
|
||||||
err = logfs_write_sb(sb);
|
err = logfs_write_sb(sb);
|
||||||
BUG_ON(err);
|
BUG_ON(err);
|
||||||
|
@ -82,7 +82,7 @@
|
|||||||
|
|
||||||
/* Read-only filesystem */
|
/* Read-only filesystem */
|
||||||
#define LOGFS_SB_FLAG_RO 0x0001
|
#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_OBJ_ALIAS 0x0004
|
||||||
#define LOGFS_SB_FLAG_SHUTDOWN 0x0008
|
#define LOGFS_SB_FLAG_SHUTDOWN 0x0008
|
||||||
|
|
||||||
@ -526,7 +526,7 @@ void logfs_delete_inode(struct inode *inode);
|
|||||||
void logfs_clear_inode(struct inode *inode);
|
void logfs_clear_inode(struct inode *inode);
|
||||||
|
|
||||||
/* journal.c */
|
/* 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);
|
int logfs_init_journal(struct super_block *sb);
|
||||||
void logfs_cleanup_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,
|
int write_alias_journal(struct super_block *sb, u64 ino, u64 bix,
|
||||||
|
@ -421,7 +421,7 @@ static void inode_write_block(struct logfs_block *block)
|
|||||||
|
|
||||||
inode = block->inode;
|
inode = block->inode;
|
||||||
if (inode->i_ino == LOGFS_INO_MASTER)
|
if (inode->i_ino == LOGFS_INO_MASTER)
|
||||||
logfs_write_anchor(inode);
|
logfs_write_anchor(inode->i_sb);
|
||||||
else {
|
else {
|
||||||
ret = __logfs_write_inode(inode, 0);
|
ret = __logfs_write_inode(inode, 0);
|
||||||
/* see indirect_write_block comment */
|
/* see indirect_write_block comment */
|
||||||
|
@ -352,7 +352,8 @@ int logfs_segment_write(struct inode *inode, struct page *page,
|
|||||||
int ret;
|
int ret;
|
||||||
void *buf;
|
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;
|
do_compress = logfs_inode(inode)->li_flags & LOGFS_IF_COMPRESSED;
|
||||||
if (shadow->gc_level != 0) {
|
if (shadow->gc_level != 0) {
|
||||||
/* temporarily disable compression for indirect blocks */
|
/* 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)
|
int logfs_segment_delete(struct inode *inode, struct logfs_shadow *shadow)
|
||||||
{
|
{
|
||||||
struct super_block *sb = inode->i_sb;
|
struct super_block *sb = inode->i_sb;
|
||||||
|
struct logfs_super *super = logfs_super(sb);
|
||||||
struct logfs_object_header h;
|
struct logfs_object_header h;
|
||||||
u16 len;
|
u16 len;
|
||||||
int err;
|
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);
|
BUG_ON(shadow->old_ofs & LOGFS_FULLY_POPULATED);
|
||||||
if (!shadow->old_ofs)
|
if (!shadow->old_ofs)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -490,7 +490,7 @@ static void logfs_kill_sb(struct super_block *sb)
|
|||||||
log_super("LogFS: Start unmounting\n");
|
log_super("LogFS: Start unmounting\n");
|
||||||
/* Alias entries slow down mount, so evict as many as possible */
|
/* Alias entries slow down mount, so evict as many as possible */
|
||||||
sync_filesystem(sb);
|
sync_filesystem(sb);
|
||||||
logfs_write_anchor(super->s_master_inode);
|
logfs_write_anchor(sb);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* From this point on alias entries are simply dropped - and any
|
* From this point on alias entries are simply dropped - and any
|
||||||
|
Loading…
Reference in New Issue
Block a user