aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/the_nilfs.h
diff options
context:
space:
mode:
authorJiro SEKIBA <jir@unicus.jp>2010-06-28 04:49:33 -0400
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2010-07-22 21:02:11 -0400
commitb2ac86e1a8e3a3b0ab4449d062c582f07a078e7b (patch)
treeb681ea820685a278e06995ff23b58f7a85904b70 /fs/nilfs2/the_nilfs.h
parentd26493b6f017c0b0063a15bf893411ddae85eee4 (diff)
nilfs2: sync super blocks in turns
This will sync super blocks in turns instead of syncing duplicate super blocks at the time. This will help searching valid super root when super block is written into disk before log is written, which is happen when barrier-less block devices are unmounted uncleanly. In the situation, old super block likely points to valid log. This patch introduces ns_sbwcount member to the nilfs object and adds nilfs_sb_will_flip() function; ns_sbwcount counts how many times super blocks write back to the disk. And, nilfs_sb_will_flip() decides whether flipping required or not based on the count of ns_sbwcount to sync super blocks asymmetrically. The following functions are also changed: - nilfs_prepare_super(): flips super blocks according to the argument. The argument is calculated by nilfs_sb_will_flip() function. - nilfs_cleanup_super(): sets "clean" flag to both super blocks if they point to the same checkpoint. To update both of super block information, caller of nilfs_commit_super must set the information on both super blocks. Signed-off-by: Jiro SEKIBA <jir@unicus.jp> Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Diffstat (limited to 'fs/nilfs2/the_nilfs.h')
-rw-r--r--fs/nilfs2/the_nilfs.h17
1 files changed, 8 insertions, 9 deletions
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
index 191560ec2e7f..32b4983b7458 100644
--- a/fs/nilfs2/the_nilfs.h
+++ b/fs/nilfs2/the_nilfs.h
@@ -57,7 +57,8 @@ enum {
57 * @ns_current: back pointer to current mount 57 * @ns_current: back pointer to current mount
58 * @ns_sbh: buffer heads of on-disk super blocks 58 * @ns_sbh: buffer heads of on-disk super blocks
59 * @ns_sbp: pointers to super block data 59 * @ns_sbp: pointers to super block data
60 * @ns_sbwtime: previous write time of super blocks 60 * @ns_sbwtime: previous write time of super block
61 * @ns_sbwcount: write count of super block
61 * @ns_sbsize: size of valid data in super block 62 * @ns_sbsize: size of valid data in super block
62 * @ns_supers: list of nilfs super block structs 63 * @ns_supers: list of nilfs super block structs
63 * @ns_seg_seq: segment sequence counter 64 * @ns_seg_seq: segment sequence counter
@@ -119,7 +120,8 @@ struct the_nilfs {
119 */ 120 */
120 struct buffer_head *ns_sbh[2]; 121 struct buffer_head *ns_sbh[2];
121 struct nilfs_super_block *ns_sbp[2]; 122 struct nilfs_super_block *ns_sbp[2];
122 time_t ns_sbwtime[2]; 123 time_t ns_sbwtime;
124 unsigned ns_sbwcount;
123 unsigned ns_sbsize; 125 unsigned ns_sbsize;
124 unsigned ns_mount_state; 126 unsigned ns_mount_state;
125 127
@@ -203,20 +205,17 @@ THE_NILFS_FNS(SB_DIRTY, sb_dirty)
203 205
204/* Minimum interval of periodical update of superblocks (in seconds) */ 206/* Minimum interval of periodical update of superblocks (in seconds) */
205#define NILFS_SB_FREQ 10 207#define NILFS_SB_FREQ 10
206#define NILFS_ALTSB_FREQ 60 /* spare superblock */
207 208
208static inline int nilfs_sb_need_update(struct the_nilfs *nilfs) 209static inline int nilfs_sb_need_update(struct the_nilfs *nilfs)
209{ 210{
210 u64 t = get_seconds(); 211 u64 t = get_seconds();
211 return t < nilfs->ns_sbwtime[0] || 212 return t < nilfs->ns_sbwtime || t > nilfs->ns_sbwtime + NILFS_SB_FREQ;
212 t > nilfs->ns_sbwtime[0] + NILFS_SB_FREQ;
213} 213}
214 214
215static inline int nilfs_altsb_need_update(struct the_nilfs *nilfs) 215static inline int nilfs_sb_will_flip(struct the_nilfs *nilfs)
216{ 216{
217 u64 t = get_seconds(); 217 int flip_bits = nilfs->ns_sbwcount & 0x0FL;
218 struct nilfs_super_block **sbp = nilfs->ns_sbp; 218 return (flip_bits != 0x08 && flip_bits != 0x0F);
219 return sbp[1] && t > nilfs->ns_sbwtime[1] + NILFS_ALTSB_FREQ;
220} 219}
221 220
222void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64); 221void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64);