Skip to content

Commit

Permalink
nilfs2: do not update log cursor for small change
Browse files Browse the repository at this point in the history
Super blocks of nilfs are periodically overwritten in order to record
the recent log position.  This shortens recovery time after unclean
unmount, but the current implementation performs the update even for a
few blocks of change.  If the filesystem gets small changes slowly and
continually, super blocks may be updated excessively.

This moderates the issue by skipping update of log cursor if it does
not cross a segment boundary.

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
  • Loading branch information
Ryusuke Konishi committed Jul 23, 2010
1 parent 6c12516 commit 3250204
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 1 deletion.
1 change: 0 additions & 1 deletion fs/nilfs2/segment.c
Original file line number Diff line number Diff line change
Expand Up @@ -1951,7 +1951,6 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
if (update_sr) {
nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start,
segbuf->sb_sum.seg_seq, nilfs->ns_cno++);
set_nilfs_sb_dirty(nilfs);

clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags);
clear_bit(NILFS_SC_DIRTY, &sci->sc_flags);
Expand Down
11 changes: 11 additions & 0 deletions fs/nilfs2/the_nilfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ void nilfs_set_last_segment(struct the_nilfs *nilfs,
nilfs->ns_last_pseg = start_blocknr;
nilfs->ns_last_seq = seq;
nilfs->ns_last_cno = cno;

if (!nilfs_sb_dirty(nilfs)) {
if (nilfs->ns_prev_seq == nilfs->ns_last_seq)
goto stay_cursor;

set_nilfs_sb_dirty(nilfs);
}
nilfs->ns_prev_seq = nilfs->ns_last_seq;

stay_cursor:
spin_unlock(&nilfs->ns_last_segment_lock);
}

Expand Down Expand Up @@ -267,6 +277,7 @@ static int nilfs_store_log_cursor(struct the_nilfs *nilfs,
nilfs->ns_last_cno = le64_to_cpu(sbp->s_last_cno);
nilfs->ns_last_seq = le64_to_cpu(sbp->s_last_seq);

nilfs->ns_prev_seq = nilfs->ns_last_seq;
nilfs->ns_seg_seq = nilfs->ns_last_seq;
nilfs->ns_segnum =
nilfs_get_segnum_of_block(nilfs, nilfs->ns_last_pseg);
Expand Down
2 changes: 2 additions & 0 deletions fs/nilfs2/the_nilfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ enum {
* @ns_last_seq: sequence value of the latest segment
* @ns_last_cno: checkpoint number of the latest segment
* @ns_prot_seq: least sequence number of segments which must not be reclaimed
* @ns_prev_seq: base sequence number used to decide if advance log cursor
* @ns_segctor_sem: segment constructor semaphore
* @ns_dat: DAT file inode
* @ns_cpfile: checkpoint file inode
Expand Down Expand Up @@ -151,6 +152,7 @@ struct the_nilfs {
u64 ns_last_seq;
__u64 ns_last_cno;
u64 ns_prot_seq;
u64 ns_prev_seq;

struct rw_semaphore ns_segctor_sem;

Expand Down

0 comments on commit 3250204

Please sign in to comment.