aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2009-04-06 22:01:59 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-04-07 11:31:20 -0400
commite339ad31f59925b48a92ee3947692fdf9758b8c7 (patch)
tree6bb85c43bfd100b0a220c788c654f2f74ca553e4 /fs
parentcece552074c591970353ad48308d65f110aeaf28 (diff)
nilfs2: introduce secondary super block
The former versions didn't have extra super blocks. This improves the weak point by introducing another super block at unused region in tail of the partition. This doesn't break disk format compatibility; older versions just ingore the secondary super block, and new versions just recover it if it doesn't exist. The partition created by an old mkfs may not have unused region, but in that case, the secondary super block will not be added. This doesn't make more redundant copies of the super block; it is a future work. Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/nilfs2/nilfs.h7
-rw-r--r--fs/nilfs2/recovery.c1
-rw-r--r--fs/nilfs2/segment.c8
-rw-r--r--fs/nilfs2/segment.h2
-rw-r--r--fs/nilfs2/super.c229
-rw-r--r--fs/nilfs2/the_nilfs.c180
-rw-r--r--fs/nilfs2/the_nilfs.h18
7 files changed, 270 insertions, 175 deletions
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
index a7f5bc724e33..19af5ab86275 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -275,13 +275,10 @@ extern void nilfs_error(struct super_block *, const char *, const char *, ...)
275extern void nilfs_warning(struct super_block *, const char *, const char *, ...) 275extern void nilfs_warning(struct super_block *, const char *, const char *, ...)
276 __attribute__ ((format (printf, 3, 4))); 276 __attribute__ ((format (printf, 3, 4)));
277extern struct nilfs_super_block * 277extern struct nilfs_super_block *
278nilfs_load_super_block(struct super_block *, struct buffer_head **); 278nilfs_read_super_block(struct super_block *, u64, int, struct buffer_head **);
279extern struct nilfs_super_block *
280nilfs_reload_super_block(struct super_block *, struct buffer_head **, int);
281extern int nilfs_store_magic_and_option(struct super_block *, 279extern int nilfs_store_magic_and_option(struct super_block *,
282 struct nilfs_super_block *, char *); 280 struct nilfs_super_block *, char *);
283extern void nilfs_update_last_segment(struct nilfs_sb_info *, int); 281extern int nilfs_commit_super(struct nilfs_sb_info *, int);
284extern int nilfs_commit_super(struct nilfs_sb_info *);
285extern int nilfs_attach_checkpoint(struct nilfs_sb_info *, __u64); 282extern int nilfs_attach_checkpoint(struct nilfs_sb_info *, __u64);
286extern void nilfs_detach_checkpoint(struct nilfs_sb_info *); 283extern void nilfs_detach_checkpoint(struct nilfs_sb_info *);
287 284
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c
index 6ab4c8fc5e9f..6ade0963fc1d 100644
--- a/fs/nilfs2/recovery.c
+++ b/fs/nilfs2/recovery.c
@@ -870,7 +870,6 @@ int nilfs_search_super_root(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi,
870 if (scan_newer) 870 if (scan_newer)
871 ri->ri_need_recovery = NILFS_RECOVERY_SR_UPDATED; 871 ri->ri_need_recovery = NILFS_RECOVERY_SR_UPDATED;
872 else { 872 else {
873 nilfs->ns_prot_seq = ssi.seg_seq;
874 if (nilfs->ns_mount_state & NILFS_VALID_FS) 873 if (nilfs->ns_mount_state & NILFS_VALID_FS)
875 goto super_root_found; 874 goto super_root_found;
876 scan_newer = 1; 875 scan_newer = 1;
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c
index e43558d50e78..fb70ec3be20e 100644
--- a/fs/nilfs2/segment.c
+++ b/fs/nilfs2/segment.c
@@ -2068,7 +2068,8 @@ static void nilfs_segctor_complete_write(struct nilfs_sc_info *sci)
2068 2068
2069 if (update_sr) { 2069 if (update_sr) {
2070 nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start, 2070 nilfs_set_last_segment(nilfs, segbuf->sb_pseg_start,
2071 segbuf->sb_sum.seg_seq, nilfs->ns_cno); 2071 segbuf->sb_sum.seg_seq, nilfs->ns_cno++);
2072 sbi->s_super->s_dirt = 1;
2072 2073
2073 clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags); 2074 clear_bit(NILFS_SC_HAVE_DELTA, &sci->sc_flags);
2074 clear_bit(NILFS_SC_DIRTY, &sci->sc_flags); 2075 clear_bit(NILFS_SC_DIRTY, &sci->sc_flags);
@@ -2224,9 +2225,6 @@ static int nilfs_segctor_do_construct(struct nilfs_sc_info *sci, int mode)
2224 2225
2225 /* Commit segments */ 2226 /* Commit segments */
2226 if (has_sr) { 2227 if (has_sr) {
2227 down_write(&nilfs->ns_sem);
2228 nilfs_update_last_segment(sbi, 1);
2229 up_write(&nilfs->ns_sem);
2230 nilfs_segctor_commit_free_segments(sci); 2228 nilfs_segctor_commit_free_segments(sci);
2231 nilfs_segctor_clear_metadata_dirty(sci); 2229 nilfs_segctor_clear_metadata_dirty(sci);
2232 } 2230 }
@@ -2564,7 +2562,7 @@ static int nilfs_segctor_construct(struct nilfs_sc_info *sci,
2564 if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) && 2562 if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) &&
2565 nilfs_discontinued(nilfs)) { 2563 nilfs_discontinued(nilfs)) {
2566 down_write(&nilfs->ns_sem); 2564 down_write(&nilfs->ns_sem);
2567 req->sb_err = nilfs_commit_super(sbi); 2565 req->sb_err = nilfs_commit_super(sbi, 0);
2568 up_write(&nilfs->ns_sem); 2566 up_write(&nilfs->ns_sem);
2569 } 2567 }
2570 } 2568 }
diff --git a/fs/nilfs2/segment.h b/fs/nilfs2/segment.h
index 4a64eb82f1f5..a98fc1ed0bbb 100644
--- a/fs/nilfs2/segment.h
+++ b/fs/nilfs2/segment.h
@@ -206,8 +206,6 @@ enum {
206 logical segment with a super root */ 206 logical segment with a super root */
207#define NILFS_SC_DEFAULT_SR_FREQ 30 /* Maximum frequency of super root 207#define NILFS_SC_DEFAULT_SR_FREQ 30 /* Maximum frequency of super root
208 creation */ 208 creation */
209#define NILFS_SC_DEFAULT_SB_FREQ 30 /* Minimum interval of periodical
210 update of superblock (reserved) */
211 209
212/* 210/*
213 * The default threshold amount of data, in block counts. 211 * The default threshold amount of data, in block counts.
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index ef31e9a51c84..e2ced824c624 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -103,8 +103,9 @@ void nilfs_error(struct super_block *sb, const char *function,
103 down_write(&nilfs->ns_sem); 103 down_write(&nilfs->ns_sem);
104 if (!(nilfs->ns_mount_state & NILFS_ERROR_FS)) { 104 if (!(nilfs->ns_mount_state & NILFS_ERROR_FS)) {
105 nilfs->ns_mount_state |= NILFS_ERROR_FS; 105 nilfs->ns_mount_state |= NILFS_ERROR_FS;
106 nilfs->ns_sbp->s_state |= cpu_to_le16(NILFS_ERROR_FS); 106 nilfs->ns_sbp[0]->s_state |=
107 nilfs_commit_super(sbi); 107 cpu_to_le16(NILFS_ERROR_FS);
108 nilfs_commit_super(sbi, 1);
108 } 109 }
109 up_write(&nilfs->ns_sem); 110 up_write(&nilfs->ns_sem);
110 111
@@ -208,90 +209,106 @@ static void nilfs_clear_inode(struct inode *inode)
208 nilfs_btnode_cache_clear(&ii->i_btnode_cache); 209 nilfs_btnode_cache_clear(&ii->i_btnode_cache);
209} 210}
210 211
211/** 212static int nilfs_sync_super(struct nilfs_sb_info *sbi, int dupsb)
212 * nilfs_update_last_segment - change pointer to the latest segment
213 * @sbi: nilfs_sb_info
214 * @update_cno: flag whether to update checkpoint number.
215 *
216 * nilfs_update_last_segment() changes information in the super block
217 * after a partial segment is written out successfully. The super
218 * block is marked dirty. It will be written out at the next VFS sync
219 * operations such as sync_supers() and generic_shutdown_super().
220 */
221void nilfs_update_last_segment(struct nilfs_sb_info *sbi, int update_cno)
222{
223 struct the_nilfs *nilfs = sbi->s_nilfs;
224 struct nilfs_super_block *sbp = nilfs->ns_sbp;
225
226 /* nilfs->sem must be locked by the caller. */
227 spin_lock(&nilfs->ns_last_segment_lock);
228 if (update_cno)
229 nilfs->ns_last_cno = nilfs->ns_cno++;
230 sbp->s_last_seq = cpu_to_le64(nilfs->ns_last_seq);
231 sbp->s_last_pseg = cpu_to_le64(nilfs->ns_last_pseg);
232 sbp->s_last_cno = cpu_to_le64(nilfs->ns_last_cno);
233 spin_unlock(&nilfs->ns_last_segment_lock);
234
235 sbi->s_super->s_dirt = 1; /* must be set if delaying the call of
236 nilfs_commit_super() */
237}
238
239static int nilfs_sync_super(struct nilfs_sb_info *sbi)
240{ 213{
241 struct the_nilfs *nilfs = sbi->s_nilfs; 214 struct the_nilfs *nilfs = sbi->s_nilfs;
242 int err; 215 int err;
243 int barrier_done = 0; 216 int barrier_done = 0;
244 217
245 if (nilfs_test_opt(sbi, BARRIER)) { 218 if (nilfs_test_opt(sbi, BARRIER)) {
246 set_buffer_ordered(nilfs->ns_sbh); 219 set_buffer_ordered(nilfs->ns_sbh[0]);
247 barrier_done = 1; 220 barrier_done = 1;
248 } 221 }
249 retry: 222 retry:
250 set_buffer_dirty(nilfs->ns_sbh); 223 set_buffer_dirty(nilfs->ns_sbh[0]);
251 err = sync_dirty_buffer(nilfs->ns_sbh); 224 err = sync_dirty_buffer(nilfs->ns_sbh[0]);
252 if (err == -EOPNOTSUPP && barrier_done) { 225 if (err == -EOPNOTSUPP && barrier_done) {
253 nilfs_warning(sbi->s_super, __func__, 226 nilfs_warning(sbi->s_super, __func__,
254 "barrier-based sync failed. " 227 "barrier-based sync failed. "
255 "disabling barriers\n"); 228 "disabling barriers\n");
256 nilfs_clear_opt(sbi, BARRIER); 229 nilfs_clear_opt(sbi, BARRIER);
257 barrier_done = 0; 230 barrier_done = 0;
258 clear_buffer_ordered(nilfs->ns_sbh); 231 clear_buffer_ordered(nilfs->ns_sbh[0]);
259 goto retry; 232 goto retry;
260 } 233 }
261 if (unlikely(err)) 234 if (unlikely(err)) {
262 printk(KERN_ERR 235 printk(KERN_ERR
263 "NILFS: unable to write superblock (err=%d)\n", err); 236 "NILFS: unable to write superblock (err=%d)\n", err);
264 else { 237 if (err == -EIO && nilfs->ns_sbh[1]) {
238 nilfs_fall_back_super_block(nilfs);
239 goto retry;
240 }
241 } else {
242 struct nilfs_super_block *sbp = nilfs->ns_sbp[0];
243
244 /*
245 * The latest segment becomes trailable from the position
246 * written in superblock.
247 */
265 clear_nilfs_discontinued(nilfs); 248 clear_nilfs_discontinued(nilfs);
266 spin_lock(&nilfs->ns_last_segment_lock); 249
267 nilfs->ns_prot_seq = le64_to_cpu(nilfs->ns_sbp->s_last_seq); 250 /* update GC protection for recent segments */
268 spin_unlock(&nilfs->ns_last_segment_lock); 251 if (nilfs->ns_sbh[1]) {
252 sbp = NULL;
253 if (dupsb) {
254 set_buffer_dirty(nilfs->ns_sbh[1]);
255 if (!sync_dirty_buffer(nilfs->ns_sbh[1]))
256 sbp = nilfs->ns_sbp[1];
257 }
258 }
259 if (sbp) {
260 spin_lock(&nilfs->ns_last_segment_lock);
261 nilfs->ns_prot_seq = le64_to_cpu(sbp->s_last_seq);
262 spin_unlock(&nilfs->ns_last_segment_lock);
263 }
269 } 264 }
270 265
271 return err; 266 return err;
272} 267}
273 268
274int nilfs_commit_super(struct nilfs_sb_info *sbi) 269int nilfs_commit_super(struct nilfs_sb_info *sbi, int dupsb)
275{ 270{
276 struct the_nilfs *nilfs = sbi->s_nilfs; 271 struct the_nilfs *nilfs = sbi->s_nilfs;
277 struct nilfs_super_block *sbp = nilfs->ns_sbp; 272 struct nilfs_super_block **sbp = nilfs->ns_sbp;
278 sector_t nfreeblocks; 273 sector_t nfreeblocks;
274 time_t t;
279 int err; 275 int err;
280 276
281 /* nilfs->sem must be locked by the caller. */ 277 /* nilfs->sem must be locked by the caller. */
278 if (sbp[0]->s_magic != NILFS_SUPER_MAGIC) {
279 if (sbp[1] && sbp[1]->s_magic == NILFS_SUPER_MAGIC)
280 nilfs_swap_super_block(nilfs);
281 else {
282 printk(KERN_CRIT "NILFS: superblock broke on dev %s\n",
283 sbi->s_super->s_id);
284 return -EIO;
285 }
286 }
282 err = nilfs_count_free_blocks(nilfs, &nfreeblocks); 287 err = nilfs_count_free_blocks(nilfs, &nfreeblocks);
283 if (unlikely(err)) { 288 if (unlikely(err)) {
284 printk(KERN_ERR "NILFS: failed to count free blocks\n"); 289 printk(KERN_ERR "NILFS: failed to count free blocks\n");
285 return err; 290 return err;
286 } 291 }
287 sbp->s_free_blocks_count = cpu_to_le64(nfreeblocks); 292 spin_lock(&nilfs->ns_last_segment_lock);
288 sbp->s_wtime = cpu_to_le64(get_seconds()); 293 sbp[0]->s_last_seq = cpu_to_le64(nilfs->ns_last_seq);
289 sbp->s_sum = 0; 294 sbp[0]->s_last_pseg = cpu_to_le64(nilfs->ns_last_pseg);
290 sbp->s_sum = cpu_to_le32(crc32_le(nilfs->ns_crc_seed, 295 sbp[0]->s_last_cno = cpu_to_le64(nilfs->ns_last_cno);
291 (unsigned char *)sbp, 296 spin_unlock(&nilfs->ns_last_segment_lock);
292 le16_to_cpu(sbp->s_bytes))); 297
298 t = get_seconds();
299 nilfs->ns_sbwtime[0] = t;
300 sbp[0]->s_free_blocks_count = cpu_to_le64(nfreeblocks);
301 sbp[0]->s_wtime = cpu_to_le64(t);
302 sbp[0]->s_sum = 0;
303 sbp[0]->s_sum = cpu_to_le32(crc32_le(nilfs->ns_crc_seed,
304 (unsigned char *)sbp[0],
305 nilfs->ns_sbsize));
306 if (dupsb && sbp[1]) {
307 memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);
308 nilfs->ns_sbwtime[1] = t;
309 }
293 sbi->s_super->s_dirt = 0; 310 sbi->s_super->s_dirt = 0;
294 return nilfs_sync_super(sbi); 311 return nilfs_sync_super(sbi, dupsb);
295} 312}
296 313
297static void nilfs_put_super(struct super_block *sb) 314static void nilfs_put_super(struct super_block *sb)
@@ -303,8 +320,8 @@ static void nilfs_put_super(struct super_block *sb)
303 320
304 if (!(sb->s_flags & MS_RDONLY)) { 321 if (!(sb->s_flags & MS_RDONLY)) {
305 down_write(&nilfs->ns_sem); 322 down_write(&nilfs->ns_sem);
306 nilfs->ns_sbp->s_state = cpu_to_le16(nilfs->ns_mount_state); 323 nilfs->ns_sbp[0]->s_state = cpu_to_le16(nilfs->ns_mount_state);
307 nilfs_commit_super(sbi); 324 nilfs_commit_super(sbi, 1);
308 up_write(&nilfs->ns_sem); 325 up_write(&nilfs->ns_sem);
309 } 326 }
310 327
@@ -330,7 +347,7 @@ static void nilfs_put_super(struct super_block *sb)
330 * 2. down_write(&nilfs->ns_sem) 347 * 2. down_write(&nilfs->ns_sem)
331 * 348 *
332 * Inside NILFS, locking ns_sem is enough to protect s_dirt and the buffer 349 * Inside NILFS, locking ns_sem is enough to protect s_dirt and the buffer
333 * of the super block (nilfs->ns_sbp). 350 * of the super block (nilfs->ns_sbp[]).
334 * 351 *
335 * In most cases, VFS functions call lock_super() before calling these 352 * In most cases, VFS functions call lock_super() before calling these
336 * methods. So we must be careful not to bring on deadlocks when using 353 * methods. So we must be careful not to bring on deadlocks when using
@@ -346,8 +363,19 @@ static void nilfs_write_super(struct super_block *sb)
346 struct the_nilfs *nilfs = sbi->s_nilfs; 363 struct the_nilfs *nilfs = sbi->s_nilfs;
347 364
348 down_write(&nilfs->ns_sem); 365 down_write(&nilfs->ns_sem);
349 if (!(sb->s_flags & MS_RDONLY)) 366 if (!(sb->s_flags & MS_RDONLY)) {
350 nilfs_commit_super(sbi); 367 struct nilfs_super_block **sbp = nilfs->ns_sbp;
368 u64 t = get_seconds();
369 int dupsb;
370
371 if (!nilfs_discontinued(nilfs) && t >= nilfs->ns_sbwtime[0] &&
372 t < nilfs->ns_sbwtime[0] + NILFS_SB_FREQ) {
373 up_write(&nilfs->ns_sem);
374 return;
375 }
376 dupsb = sbp[1] && t > nilfs->ns_sbwtime[1] + NILFS_ALTSB_FREQ;
377 nilfs_commit_super(sbi, dupsb);
378 }
351 sb->s_dirt = 0; 379 sb->s_dirt = 0;
352 up_write(&nilfs->ns_sem); 380 up_write(&nilfs->ns_sem);
353} 381}
@@ -436,7 +464,7 @@ static int nilfs_mark_recovery_complete(struct nilfs_sb_info *sbi)
436 down_write(&nilfs->ns_sem); 464 down_write(&nilfs->ns_sem);
437 if (!(nilfs->ns_mount_state & NILFS_VALID_FS)) { 465 if (!(nilfs->ns_mount_state & NILFS_VALID_FS)) {
438 nilfs->ns_mount_state |= NILFS_VALID_FS; 466 nilfs->ns_mount_state |= NILFS_VALID_FS;
439 err = nilfs_commit_super(sbi); 467 err = nilfs_commit_super(sbi, 1);
440 if (likely(!err)) 468 if (likely(!err))
441 printk(KERN_INFO "NILFS: recovery complete.\n"); 469 printk(KERN_INFO "NILFS: recovery complete.\n");
442 } 470 }
@@ -652,7 +680,7 @@ nilfs_set_default_options(struct nilfs_sb_info *sbi,
652static int nilfs_setup_super(struct nilfs_sb_info *sbi) 680static int nilfs_setup_super(struct nilfs_sb_info *sbi)
653{ 681{
654 struct the_nilfs *nilfs = sbi->s_nilfs; 682 struct the_nilfs *nilfs = sbi->s_nilfs;
655 struct nilfs_super_block *sbp = nilfs->ns_sbp; 683 struct nilfs_super_block *sbp = nilfs->ns_sbp[0];
656 int max_mnt_count = le16_to_cpu(sbp->s_max_mnt_count); 684 int max_mnt_count = le16_to_cpu(sbp->s_max_mnt_count);
657 int mnt_count = le16_to_cpu(sbp->s_mnt_count); 685 int mnt_count = le16_to_cpu(sbp->s_mnt_count);
658 686
@@ -674,88 +702,29 @@ static int nilfs_setup_super(struct nilfs_sb_info *sbi)
674 sbp->s_mnt_count = cpu_to_le16(mnt_count + 1); 702 sbp->s_mnt_count = cpu_to_le16(mnt_count + 1);
675 sbp->s_state = cpu_to_le16(le16_to_cpu(sbp->s_state) & ~NILFS_VALID_FS); 703 sbp->s_state = cpu_to_le16(le16_to_cpu(sbp->s_state) & ~NILFS_VALID_FS);
676 sbp->s_mtime = cpu_to_le64(get_seconds()); 704 sbp->s_mtime = cpu_to_le64(get_seconds());
677 return nilfs_commit_super(sbi); 705 return nilfs_commit_super(sbi, 1);
678} 706}
679 707
680struct nilfs_super_block * 708struct nilfs_super_block *nilfs_read_super_block(struct super_block *sb,
681nilfs_load_super_block(struct super_block *sb, struct buffer_head **pbh) 709 u64 pos, int blocksize,
710 struct buffer_head **pbh)
682{ 711{
683 int blocksize; 712 unsigned long long sb_index = pos;
684 unsigned long offset, sb_index; 713 unsigned long offset;
685
686 /*
687 * Adjusting block size
688 * Blocksize will be enlarged when it is smaller than hardware
689 * sector size.
690 * Disk format of superblock does not change.
691 */
692 blocksize = sb_min_blocksize(sb, BLOCK_SIZE);
693 if (!blocksize) {
694 printk(KERN_ERR
695 "NILFS: unable to set blocksize of superblock\n");
696 return NULL;
697 }
698 sb_index = NILFS_SB_OFFSET_BYTES / blocksize;
699 offset = NILFS_SB_OFFSET_BYTES % blocksize;
700 714
715 offset = do_div(sb_index, blocksize);
701 *pbh = sb_bread(sb, sb_index); 716 *pbh = sb_bread(sb, sb_index);
702 if (!*pbh) { 717 if (!*pbh)
703 printk(KERN_ERR "NILFS: unable to read superblock\n");
704 return NULL; 718 return NULL;
705 }
706 return (struct nilfs_super_block *)((char *)(*pbh)->b_data + offset); 719 return (struct nilfs_super_block *)((char *)(*pbh)->b_data + offset);
707} 720}
708 721
709struct nilfs_super_block *
710nilfs_reload_super_block(struct super_block *sb, struct buffer_head **pbh,
711 int blocksize)
712{
713 struct nilfs_super_block *sbp;
714 unsigned long offset, sb_index;
715 int hw_blocksize = bdev_hardsect_size(sb->s_bdev);
716
717 if (blocksize < hw_blocksize) {
718 printk(KERN_ERR
719 "NILFS: blocksize %d too small for device "
720 "(sector-size = %d).\n",
721 blocksize, hw_blocksize);
722 goto failed_sbh;
723 }
724 brelse(*pbh);
725 sb_set_blocksize(sb, blocksize);
726
727 sb_index = NILFS_SB_OFFSET_BYTES / blocksize;
728 offset = NILFS_SB_OFFSET_BYTES % blocksize;
729
730 *pbh = sb_bread(sb, sb_index);
731 if (!*pbh) {
732 printk(KERN_ERR
733 "NILFS: cannot read superblock on 2nd try.\n");
734 goto failed;
735 }
736
737 sbp = (struct nilfs_super_block *)((char *)(*pbh)->b_data + offset);
738 if (sbp->s_magic != cpu_to_le16(NILFS_SUPER_MAGIC)) {
739 printk(KERN_ERR
740 "NILFS: !? Magic mismatch on 2nd try.\n");
741 goto failed_sbh;
742 }
743 return sbp;
744
745 failed_sbh:
746 brelse(*pbh);
747
748 failed:
749 return NULL;
750}
751
752int nilfs_store_magic_and_option(struct super_block *sb, 722int nilfs_store_magic_and_option(struct super_block *sb,
753 struct nilfs_super_block *sbp, 723 struct nilfs_super_block *sbp,
754 char *data) 724 char *data)
755{ 725{
756 struct nilfs_sb_info *sbi = NILFS_SB(sb); 726 struct nilfs_sb_info *sbi = NILFS_SB(sb);
757 727
758 /* trying to fill super (1st stage) */
759 sb->s_magic = le16_to_cpu(sbp->s_magic); 728 sb->s_magic = le16_to_cpu(sbp->s_magic);
760 729
761 /* FS independent flags */ 730 /* FS independent flags */
@@ -763,11 +732,6 @@ int nilfs_store_magic_and_option(struct super_block *sb,
763 sb->s_flags |= MS_NOATIME; 732 sb->s_flags |= MS_NOATIME;
764#endif 733#endif
765 734
766 if (sb->s_magic != NILFS_SUPER_MAGIC) {
767 printk("NILFS: Can't find nilfs on dev %s.\n", sb->s_id);
768 return -EINVAL;
769 }
770
771 nilfs_set_default_options(sbi, sbp); 735 nilfs_set_default_options(sbi, sbp);
772 736
773 sbi->s_resuid = le16_to_cpu(sbp->s_def_resuid); 737 sbi->s_resuid = le16_to_cpu(sbp->s_def_resuid);
@@ -775,10 +739,7 @@ int nilfs_store_magic_and_option(struct super_block *sb,
775 sbi->s_interval = le32_to_cpu(sbp->s_c_interval); 739 sbi->s_interval = le32_to_cpu(sbp->s_c_interval);
776 sbi->s_watermark = le32_to_cpu(sbp->s_c_block_max); 740 sbi->s_watermark = le32_to_cpu(sbp->s_c_block_max);
777 741
778 if (!parse_options(data, sb)) 742 return !parse_options(data, sb) ? -EINVAL : 0 ;
779 return -EINVAL;
780
781 return 0;
782} 743}
783 744
784/** 745/**
@@ -967,12 +928,12 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
967 * the RDONLY flag and then mark the partition as valid again. 928 * the RDONLY flag and then mark the partition as valid again.
968 */ 929 */
969 down_write(&nilfs->ns_sem); 930 down_write(&nilfs->ns_sem);
970 sbp = nilfs->ns_sbp; 931 sbp = nilfs->ns_sbp[0];
971 if (!(sbp->s_state & le16_to_cpu(NILFS_VALID_FS)) && 932 if (!(sbp->s_state & le16_to_cpu(NILFS_VALID_FS)) &&
972 (nilfs->ns_mount_state & NILFS_VALID_FS)) 933 (nilfs->ns_mount_state & NILFS_VALID_FS))
973 sbp->s_state = cpu_to_le16(nilfs->ns_mount_state); 934 sbp->s_state = cpu_to_le16(nilfs->ns_mount_state);
974 sbp->s_mtime = cpu_to_le64(get_seconds()); 935 sbp->s_mtime = cpu_to_le64(get_seconds());
975 nilfs_commit_super(sbi); 936 nilfs_commit_super(sbi, 1);
976 up_write(&nilfs->ns_sem); 937 up_write(&nilfs->ns_sem);
977 } else { 938 } else {
978 /* 939 /*
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index 661ab762d765..33400cf0bbe2 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -25,6 +25,7 @@
25#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/blkdev.h> 26#include <linux/blkdev.h>
27#include <linux/backing-dev.h> 27#include <linux/backing-dev.h>
28#include <linux/crc32.h>
28#include "nilfs.h" 29#include "nilfs.h"
29#include "segment.h" 30#include "segment.h"
30#include "alloc.h" 31#include "alloc.h"
@@ -105,7 +106,8 @@ void put_nilfs(struct the_nilfs *nilfs)
105 } 106 }
106 if (nilfs_init(nilfs)) { 107 if (nilfs_init(nilfs)) {
107 nilfs_destroy_gccache(nilfs); 108 nilfs_destroy_gccache(nilfs);
108 brelse(nilfs->ns_sbh); 109 brelse(nilfs->ns_sbh[0]);
110 brelse(nilfs->ns_sbh[1]);
109 } 111 }
110 kfree(nilfs); 112 kfree(nilfs);
111} 113}
@@ -115,6 +117,7 @@ static int nilfs_load_super_root(struct the_nilfs *nilfs,
115{ 117{
116 struct buffer_head *bh_sr; 118 struct buffer_head *bh_sr;
117 struct nilfs_super_root *raw_sr; 119 struct nilfs_super_root *raw_sr;
120 struct nilfs_super_block **sbp = nilfs->ns_sbp;
118 unsigned dat_entry_size, segment_usage_size, checkpoint_size; 121 unsigned dat_entry_size, segment_usage_size, checkpoint_size;
119 unsigned inode_size; 122 unsigned inode_size;
120 int err; 123 int err;
@@ -124,9 +127,9 @@ static int nilfs_load_super_root(struct the_nilfs *nilfs,
124 return err; 127 return err;
125 128
126 down_read(&nilfs->ns_sem); 129 down_read(&nilfs->ns_sem);
127 dat_entry_size = le16_to_cpu(nilfs->ns_sbp->s_dat_entry_size); 130 dat_entry_size = le16_to_cpu(sbp[0]->s_dat_entry_size);
128 checkpoint_size = le16_to_cpu(nilfs->ns_sbp->s_checkpoint_size); 131 checkpoint_size = le16_to_cpu(sbp[0]->s_checkpoint_size);
129 segment_usage_size = le16_to_cpu(nilfs->ns_sbp->s_segment_usage_size); 132 segment_usage_size = le16_to_cpu(sbp[0]->s_segment_usage_size);
130 up_read(&nilfs->ns_sem); 133 up_read(&nilfs->ns_sem);
131 134
132 inode_size = nilfs->ns_inode_size; 135 inode_size = nilfs->ns_inode_size;
@@ -270,11 +273,8 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
270 nilfs_mdt_destroy(nilfs->ns_dat); 273 nilfs_mdt_destroy(nilfs->ns_dat);
271 goto failed; 274 goto failed;
272 } 275 }
273 if (ri.ri_need_recovery == NILFS_RECOVERY_SR_UPDATED) { 276 if (ri.ri_need_recovery == NILFS_RECOVERY_SR_UPDATED)
274 down_write(&nilfs->ns_sem); 277 sbi->s_super->s_dirt = 1;
275 nilfs_update_last_segment(sbi, 0);
276 up_write(&nilfs->ns_sem);
277 }
278 } 278 }
279 279
280 set_nilfs_loaded(nilfs); 280 set_nilfs_loaded(nilfs);
@@ -296,9 +296,8 @@ static unsigned long long nilfs_max_size(unsigned int blkbits)
296 return res; 296 return res;
297} 297}
298 298
299static int 299static int nilfs_store_disk_layout(struct the_nilfs *nilfs,
300nilfs_store_disk_layout(struct the_nilfs *nilfs, struct super_block *sb, 300 struct nilfs_super_block *sbp)
301 struct nilfs_super_block *sbp)
302{ 301{
303 if (le32_to_cpu(sbp->s_rev_level) != NILFS_CURRENT_REV) { 302 if (le32_to_cpu(sbp->s_rev_level) != NILFS_CURRENT_REV) {
304 printk(KERN_ERR "NILFS: revision mismatch " 303 printk(KERN_ERR "NILFS: revision mismatch "
@@ -309,6 +308,10 @@ nilfs_store_disk_layout(struct the_nilfs *nilfs, struct super_block *sb,
309 NILFS_CURRENT_REV, NILFS_MINOR_REV); 308 NILFS_CURRENT_REV, NILFS_MINOR_REV);
310 return -EINVAL; 309 return -EINVAL;
311 } 310 }
311 nilfs->ns_sbsize = le16_to_cpu(sbp->s_bytes);
312 if (nilfs->ns_sbsize > BLOCK_SIZE)
313 return -EINVAL;
314
312 nilfs->ns_inode_size = le16_to_cpu(sbp->s_inode_size); 315 nilfs->ns_inode_size = le16_to_cpu(sbp->s_inode_size);
313 nilfs->ns_first_ino = le32_to_cpu(sbp->s_first_ino); 316 nilfs->ns_first_ino = le32_to_cpu(sbp->s_first_ino);
314 317
@@ -330,6 +333,122 @@ nilfs_store_disk_layout(struct the_nilfs *nilfs, struct super_block *sb,
330 return 0; 333 return 0;
331} 334}
332 335
336static int nilfs_valid_sb(struct nilfs_super_block *sbp)
337{
338 static unsigned char sum[4];
339 const int sumoff = offsetof(struct nilfs_super_block, s_sum);
340 size_t bytes;
341 u32 crc;
342
343 if (!sbp || le16_to_cpu(sbp->s_magic) != NILFS_SUPER_MAGIC)
344 return 0;
345 bytes = le16_to_cpu(sbp->s_bytes);
346 if (bytes > BLOCK_SIZE)
347 return 0;
348 crc = crc32_le(le32_to_cpu(sbp->s_crc_seed), (unsigned char *)sbp,
349 sumoff);
350 crc = crc32_le(crc, sum, 4);
351 crc = crc32_le(crc, (unsigned char *)sbp + sumoff + 4,
352 bytes - sumoff - 4);
353 return crc == le32_to_cpu(sbp->s_sum);
354}
355
356static int nilfs_sb2_bad_offset(struct nilfs_super_block *sbp, u64 offset)
357{
358 return offset < ((le64_to_cpu(sbp->s_nsegments) *
359 le32_to_cpu(sbp->s_blocks_per_segment)) <<
360 (le32_to_cpu(sbp->s_log_block_size) + 10));
361}
362
363static void nilfs_release_super_block(struct the_nilfs *nilfs)
364{
365 int i;
366
367 for (i = 0; i < 2; i++) {
368 if (nilfs->ns_sbp[i]) {
369 brelse(nilfs->ns_sbh[i]);
370 nilfs->ns_sbh[i] = NULL;
371 nilfs->ns_sbp[i] = NULL;
372 }
373 }
374}
375
376void nilfs_fall_back_super_block(struct the_nilfs *nilfs)
377{
378 brelse(nilfs->ns_sbh[0]);
379 nilfs->ns_sbh[0] = nilfs->ns_sbh[1];
380 nilfs->ns_sbp[0] = nilfs->ns_sbp[1];
381 nilfs->ns_sbh[1] = NULL;
382 nilfs->ns_sbp[1] = NULL;
383}
384
385void nilfs_swap_super_block(struct the_nilfs *nilfs)
386{
387 struct buffer_head *tsbh = nilfs->ns_sbh[0];
388 struct nilfs_super_block *tsbp = nilfs->ns_sbp[0];
389
390 nilfs->ns_sbh[0] = nilfs->ns_sbh[1];
391 nilfs->ns_sbp[0] = nilfs->ns_sbp[1];
392 nilfs->ns_sbh[1] = tsbh;
393 nilfs->ns_sbp[1] = tsbp;
394}
395
396static int nilfs_load_super_block(struct the_nilfs *nilfs,
397 struct super_block *sb, int blocksize,
398 struct nilfs_super_block **sbpp)
399{
400 struct nilfs_super_block **sbp = nilfs->ns_sbp;
401 struct buffer_head **sbh = nilfs->ns_sbh;
402 u64 sb2off = NILFS_SB2_OFFSET_BYTES(nilfs->ns_bdev->bd_inode->i_size);
403 int valid[2], swp = 0;
404
405 sbp[0] = nilfs_read_super_block(sb, NILFS_SB_OFFSET_BYTES, blocksize,
406 &sbh[0]);
407 sbp[1] = nilfs_read_super_block(sb, sb2off, blocksize, &sbh[1]);
408
409 if (!sbp[0]) {
410 if (!sbp[1]) {
411 printk(KERN_ERR "NILFS: unable to read superblock\n");
412 return -EIO;
413 }
414 printk(KERN_WARNING
415 "NILFS warning: unable to read primary superblock\n");
416 } else if (!sbp[1])
417 printk(KERN_WARNING
418 "NILFS warning: unable to read secondary superblock\n");
419
420 valid[0] = nilfs_valid_sb(sbp[0]);
421 valid[1] = nilfs_valid_sb(sbp[1]);
422 swp = valid[1] &&
423 (!valid[0] ||
424 le64_to_cpu(sbp[1]->s_wtime) > le64_to_cpu(sbp[0]->s_wtime));
425
426 if (valid[swp] && nilfs_sb2_bad_offset(sbp[swp], sb2off)) {
427 brelse(sbh[1]);
428 sbh[1] = NULL;
429 sbp[1] = NULL;
430 swp = 0;
431 }
432 if (!valid[swp]) {
433 nilfs_release_super_block(nilfs);
434 printk(KERN_ERR "NILFS: Can't find nilfs on dev %s.\n",
435 sb->s_id);
436 return -EINVAL;
437 }
438
439 if (swp) {
440 printk(KERN_WARNING "NILFS warning: broken superblock. "
441 "using spare superblock.\n");
442 nilfs_swap_super_block(nilfs);
443 }
444
445 nilfs->ns_sbwtime[0] = le64_to_cpu(sbp[0]->s_wtime);
446 nilfs->ns_sbwtime[1] = valid[!swp] ? le64_to_cpu(sbp[1]->s_wtime) : 0;
447 nilfs->ns_prot_seq = le64_to_cpu(sbp[valid[1] & !swp]->s_last_seq);
448 *sbpp = sbp[0];
449 return 0;
450}
451
333/** 452/**
334 * init_nilfs - initialize a NILFS instance. 453 * init_nilfs - initialize a NILFS instance.
335 * @nilfs: the_nilfs structure 454 * @nilfs: the_nilfs structure
@@ -352,16 +471,15 @@ nilfs_store_disk_layout(struct the_nilfs *nilfs, struct super_block *sb,
352int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data) 471int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data)
353{ 472{
354 struct super_block *sb = sbi->s_super; 473 struct super_block *sb = sbi->s_super;
355 struct buffer_head *sbh;
356 struct nilfs_super_block *sbp; 474 struct nilfs_super_block *sbp;
357 struct backing_dev_info *bdi; 475 struct backing_dev_info *bdi;
358 int blocksize; 476 int blocksize;
359 int err = 0; 477 int err;
360 478
361 down_write(&nilfs->ns_sem); 479 down_write(&nilfs->ns_sem);
362 if (nilfs_init(nilfs)) { 480 if (nilfs_init(nilfs)) {
363 /* Load values from existing the_nilfs */ 481 /* Load values from existing the_nilfs */
364 sbp = nilfs->ns_sbp; 482 sbp = nilfs->ns_sbp[0];
365 err = nilfs_store_magic_and_option(sb, sbp, data); 483 err = nilfs_store_magic_and_option(sb, sbp, data);
366 if (err) 484 if (err)
367 goto out; 485 goto out;
@@ -377,36 +495,50 @@ int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data)
377 goto out; 495 goto out;
378 } 496 }
379 497
380 sbp = nilfs_load_super_block(sb, &sbh); 498 blocksize = sb_min_blocksize(sb, BLOCK_SIZE);
381 if (!sbp) { 499 if (!blocksize) {
500 printk(KERN_ERR "NILFS: unable to set blocksize\n");
382 err = -EINVAL; 501 err = -EINVAL;
383 goto out; 502 goto out;
384 } 503 }
504 err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp);
505 if (err)
506 goto out;
507
385 err = nilfs_store_magic_and_option(sb, sbp, data); 508 err = nilfs_store_magic_and_option(sb, sbp, data);
386 if (err) 509 if (err)
387 goto failed_sbh; 510 goto failed_sbh;
388 511
389 blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size); 512 blocksize = BLOCK_SIZE << le32_to_cpu(sbp->s_log_block_size);
390 if (sb->s_blocksize != blocksize) { 513 if (sb->s_blocksize != blocksize) {
391 sbp = nilfs_reload_super_block(sb, &sbh, blocksize); 514 int hw_blocksize = bdev_hardsect_size(sb->s_bdev);
392 if (!sbp) { 515
516 if (blocksize < hw_blocksize) {
517 printk(KERN_ERR
518 "NILFS: blocksize %d too small for device "
519 "(sector-size = %d).\n",
520 blocksize, hw_blocksize);
393 err = -EINVAL; 521 err = -EINVAL;
522 goto failed_sbh;
523 }
524 nilfs_release_super_block(nilfs);
525 sb_set_blocksize(sb, blocksize);
526
527 err = nilfs_load_super_block(nilfs, sb, blocksize, &sbp);
528 if (err)
394 goto out; 529 goto out;
395 /* not failed_sbh; sbh is released automatically 530 /* not failed_sbh; sbh is released automatically
396 when reloading fails. */ 531 when reloading fails. */
397 }
398 } 532 }
399 nilfs->ns_blocksize_bits = sb->s_blocksize_bits; 533 nilfs->ns_blocksize_bits = sb->s_blocksize_bits;
400 534
401 err = nilfs_store_disk_layout(nilfs, sb, sbp); 535 err = nilfs_store_disk_layout(nilfs, sbp);
402 if (err) 536 if (err)
403 goto failed_sbh; 537 goto failed_sbh;
404 538
405 sb->s_maxbytes = nilfs_max_size(sb->s_blocksize_bits); 539 sb->s_maxbytes = nilfs_max_size(sb->s_blocksize_bits);
406 540
407 nilfs->ns_mount_state = le16_to_cpu(sbp->s_state); 541 nilfs->ns_mount_state = le16_to_cpu(sbp->s_state);
408 nilfs->ns_sbh = sbh;
409 nilfs->ns_sbp = sbp;
410 542
411 bdi = nilfs->ns_bdev->bd_inode_backing_dev_info; 543 bdi = nilfs->ns_bdev->bd_inode_backing_dev_info;
412 if (!bdi) 544 if (!bdi)
@@ -443,7 +575,7 @@ int init_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi, char *data)
443 return err; 575 return err;
444 576
445 failed_sbh: 577 failed_sbh:
446 brelse(sbh); 578 nilfs_release_super_block(nilfs);
447 goto out; 579 goto out;
448} 580}
449 581
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h
index d750e48257c9..30fe58778d05 100644
--- a/fs/nilfs2/the_nilfs.h
+++ b/fs/nilfs2/the_nilfs.h
@@ -49,8 +49,10 @@ enum {
49 * @ns_sem: semaphore for shared states 49 * @ns_sem: semaphore for shared states
50 * @ns_writer_mutex: mutex protecting ns_writer attach/detach 50 * @ns_writer_mutex: mutex protecting ns_writer attach/detach
51 * @ns_writer_refcount: number of referrers on ns_writer 51 * @ns_writer_refcount: number of referrers on ns_writer
52 * @ns_sbh: buffer head of the on-disk super block 52 * @ns_sbh: buffer heads of on-disk super blocks
53 * @ns_sbp: pointer to the super block data 53 * @ns_sbp: pointers to super block data
54 * @ns_sbwtime: previous write time of super blocks
55 * @ns_sbsize: size of valid data in super block
54 * @ns_supers: list of nilfs super block structs 56 * @ns_supers: list of nilfs super block structs
55 * @ns_seg_seq: segment sequence counter 57 * @ns_seg_seq: segment sequence counter
56 * @ns_segnum: index number of the latest full segment. 58 * @ns_segnum: index number of the latest full segment.
@@ -101,8 +103,10 @@ struct the_nilfs {
101 * - protecting s_dirt in the super_block struct 103 * - protecting s_dirt in the super_block struct
102 * (see nilfs_write_super) and the following fields. 104 * (see nilfs_write_super) and the following fields.
103 */ 105 */
104 struct buffer_head *ns_sbh; 106 struct buffer_head *ns_sbh[2];
105 struct nilfs_super_block *ns_sbp; 107 struct nilfs_super_block *ns_sbp[2];
108 time_t ns_sbwtime[2];
109 unsigned ns_sbsize;
106 unsigned ns_mount_state; 110 unsigned ns_mount_state;
107 struct list_head ns_supers; 111 struct list_head ns_supers;
108 112
@@ -182,6 +186,10 @@ THE_NILFS_FNS(INIT, init)
182THE_NILFS_FNS(LOADED, loaded) 186THE_NILFS_FNS(LOADED, loaded)
183THE_NILFS_FNS(DISCONTINUED, discontinued) 187THE_NILFS_FNS(DISCONTINUED, discontinued)
184 188
189/* Minimum interval of periodical update of superblocks (in seconds) */
190#define NILFS_SB_FREQ 10
191#define NILFS_ALTSB_FREQ 60 /* spare superblock */
192
185void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64); 193void nilfs_set_last_segment(struct the_nilfs *, sector_t, u64, __u64);
186struct the_nilfs *alloc_nilfs(struct block_device *); 194struct the_nilfs *alloc_nilfs(struct block_device *);
187void put_nilfs(struct the_nilfs *); 195void put_nilfs(struct the_nilfs *);
@@ -190,6 +198,8 @@ int load_nilfs(struct the_nilfs *, struct nilfs_sb_info *);
190int nilfs_count_free_blocks(struct the_nilfs *, sector_t *); 198int nilfs_count_free_blocks(struct the_nilfs *, sector_t *);
191int nilfs_checkpoint_is_mounted(struct the_nilfs *, __u64, int); 199int nilfs_checkpoint_is_mounted(struct the_nilfs *, __u64, int);
192int nilfs_near_disk_full(struct the_nilfs *); 200int nilfs_near_disk_full(struct the_nilfs *);
201void nilfs_fall_back_super_block(struct the_nilfs *);
202void nilfs_swap_super_block(struct the_nilfs *);
193 203
194 204
195static inline void get_nilfs(struct the_nilfs *nilfs) 205static inline void get_nilfs(struct the_nilfs *nilfs)