diff options
Diffstat (limited to 'fs/nilfs2')
-rw-r--r-- | fs/nilfs2/nilfs.h | 1 | ||||
-rw-r--r-- | fs/nilfs2/segment.c | 8 | ||||
-rw-r--r-- | fs/nilfs2/super.c | 73 |
3 files changed, 58 insertions, 24 deletions
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index 6718616183b7..462651061b03 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h | |||
@@ -272,6 +272,7 @@ extern int nilfs_store_magic_and_option(struct super_block *, | |||
272 | struct nilfs_super_block *, char *); | 272 | struct nilfs_super_block *, char *); |
273 | extern void nilfs_set_log_cursor(struct nilfs_super_block *, | 273 | extern void nilfs_set_log_cursor(struct nilfs_super_block *, |
274 | struct the_nilfs *); | 274 | struct the_nilfs *); |
275 | extern struct nilfs_super_block **nilfs_prepare_super(struct nilfs_sb_info *); | ||
275 | extern int nilfs_commit_super(struct nilfs_sb_info *, int); | 276 | extern int nilfs_commit_super(struct nilfs_sb_info *, int); |
276 | extern int nilfs_cleanup_super(struct nilfs_sb_info *); | 277 | extern int nilfs_cleanup_super(struct nilfs_sb_info *); |
277 | extern int nilfs_attach_checkpoint(struct nilfs_sb_info *, __u64); | 278 | extern int nilfs_attach_checkpoint(struct nilfs_sb_info *, __u64); |
diff --git a/fs/nilfs2/segment.c b/fs/nilfs2/segment.c index 1f7881ca01c4..9e680a93b13a 100644 --- a/fs/nilfs2/segment.c +++ b/fs/nilfs2/segment.c | |||
@@ -2408,6 +2408,7 @@ static int nilfs_segctor_construct(struct nilfs_sc_info *sci, int mode) | |||
2408 | { | 2408 | { |
2409 | struct nilfs_sb_info *sbi = sci->sc_sbi; | 2409 | struct nilfs_sb_info *sbi = sci->sc_sbi; |
2410 | struct the_nilfs *nilfs = sbi->s_nilfs; | 2410 | struct the_nilfs *nilfs = sbi->s_nilfs; |
2411 | struct nilfs_super_block **sbp; | ||
2411 | int err = 0; | 2412 | int err = 0; |
2412 | 2413 | ||
2413 | nilfs_segctor_accept(sci); | 2414 | nilfs_segctor_accept(sci); |
@@ -2423,8 +2424,11 @@ static int nilfs_segctor_construct(struct nilfs_sc_info *sci, int mode) | |||
2423 | if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) && | 2424 | if (test_bit(NILFS_SC_SUPER_ROOT, &sci->sc_flags) && |
2424 | nilfs_discontinued(nilfs)) { | 2425 | nilfs_discontinued(nilfs)) { |
2425 | down_write(&nilfs->ns_sem); | 2426 | down_write(&nilfs->ns_sem); |
2426 | err = nilfs_commit_super( | 2427 | err = -EIO; |
2427 | sbi, nilfs_altsb_need_update(nilfs)); | 2428 | sbp = nilfs_prepare_super(sbi); |
2429 | if (likely(sbp)) | ||
2430 | err = nilfs_commit_super( | ||
2431 | sbi, nilfs_altsb_need_update(nilfs)); | ||
2428 | up_write(&nilfs->ns_sem); | 2432 | up_write(&nilfs->ns_sem); |
2429 | } | 2433 | } |
2430 | } | 2434 | } |
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index c5328c8ba1d2..eb7de40828c7 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -77,12 +77,16 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data); | |||
77 | static void nilfs_set_error(struct nilfs_sb_info *sbi) | 77 | static void nilfs_set_error(struct nilfs_sb_info *sbi) |
78 | { | 78 | { |
79 | struct the_nilfs *nilfs = sbi->s_nilfs; | 79 | struct the_nilfs *nilfs = sbi->s_nilfs; |
80 | struct nilfs_super_block **sbp; | ||
80 | 81 | ||
81 | down_write(&nilfs->ns_sem); | 82 | down_write(&nilfs->ns_sem); |
82 | if (!(nilfs->ns_mount_state & NILFS_ERROR_FS)) { | 83 | if (!(nilfs->ns_mount_state & NILFS_ERROR_FS)) { |
83 | nilfs->ns_mount_state |= NILFS_ERROR_FS; | 84 | nilfs->ns_mount_state |= NILFS_ERROR_FS; |
84 | nilfs->ns_sbp[0]->s_state |= cpu_to_le16(NILFS_ERROR_FS); | 85 | sbp = nilfs_prepare_super(sbi); |
85 | nilfs_commit_super(sbi, 1); | 86 | if (likely(sbp)) { |
87 | sbp[0]->s_state |= cpu_to_le16(NILFS_ERROR_FS); | ||
88 | nilfs_commit_super(sbi, 1); | ||
89 | } | ||
86 | } | 90 | } |
87 | up_write(&nilfs->ns_sem); | 91 | up_write(&nilfs->ns_sem); |
88 | } | 92 | } |
@@ -253,22 +257,32 @@ void nilfs_set_log_cursor(struct nilfs_super_block *sbp, | |||
253 | spin_unlock(&nilfs->ns_last_segment_lock); | 257 | spin_unlock(&nilfs->ns_last_segment_lock); |
254 | } | 258 | } |
255 | 259 | ||
256 | int nilfs_commit_super(struct nilfs_sb_info *sbi, int dupsb) | 260 | struct nilfs_super_block **nilfs_prepare_super(struct nilfs_sb_info *sbi) |
257 | { | 261 | { |
258 | struct the_nilfs *nilfs = sbi->s_nilfs; | 262 | struct the_nilfs *nilfs = sbi->s_nilfs; |
259 | struct nilfs_super_block **sbp = nilfs->ns_sbp; | 263 | struct nilfs_super_block **sbp = nilfs->ns_sbp; |
260 | time_t t; | ||
261 | 264 | ||
262 | /* nilfs->sem must be locked by the caller. */ | 265 | /* nilfs->ns_sem must be locked by the caller. */ |
263 | if (sbp[0]->s_magic != cpu_to_le16(NILFS_SUPER_MAGIC)) { | 266 | if (sbp[0]->s_magic != cpu_to_le16(NILFS_SUPER_MAGIC)) { |
264 | if (sbp[1] && sbp[1]->s_magic == cpu_to_le16(NILFS_SUPER_MAGIC)) | 267 | if (sbp[1] && |
268 | sbp[1]->s_magic == cpu_to_le16(NILFS_SUPER_MAGIC)) { | ||
265 | nilfs_swap_super_block(nilfs); | 269 | nilfs_swap_super_block(nilfs); |
266 | else { | 270 | } else { |
267 | printk(KERN_CRIT "NILFS: superblock broke on dev %s\n", | 271 | printk(KERN_CRIT "NILFS: superblock broke on dev %s\n", |
268 | sbi->s_super->s_id); | 272 | sbi->s_super->s_id); |
269 | return -EIO; | 273 | return NULL; |
270 | } | 274 | } |
271 | } | 275 | } |
276 | return sbp; | ||
277 | } | ||
278 | |||
279 | int nilfs_commit_super(struct nilfs_sb_info *sbi, int dupsb) | ||
280 | { | ||
281 | struct the_nilfs *nilfs = sbi->s_nilfs; | ||
282 | struct nilfs_super_block **sbp = nilfs->ns_sbp; | ||
283 | time_t t; | ||
284 | |||
285 | /* nilfs->ns_sem must be locked by the caller. */ | ||
272 | nilfs_set_log_cursor(sbp[0], nilfs); | 286 | nilfs_set_log_cursor(sbp[0], nilfs); |
273 | 287 | ||
274 | t = get_seconds(); | 288 | t = get_seconds(); |
@@ -296,11 +310,14 @@ int nilfs_commit_super(struct nilfs_sb_info *sbi, int dupsb) | |||
296 | */ | 310 | */ |
297 | int nilfs_cleanup_super(struct nilfs_sb_info *sbi) | 311 | int nilfs_cleanup_super(struct nilfs_sb_info *sbi) |
298 | { | 312 | { |
299 | struct nilfs_super_block **sbp = sbi->s_nilfs->ns_sbp; | 313 | struct nilfs_super_block **sbp; |
300 | int ret; | 314 | int ret = -EIO; |
301 | 315 | ||
302 | sbp[0]->s_state = cpu_to_le16(sbi->s_nilfs->ns_mount_state); | 316 | sbp = nilfs_prepare_super(sbi); |
303 | ret = nilfs_commit_super(sbi, 1); | 317 | if (sbp) { |
318 | sbp[0]->s_state = cpu_to_le16(sbi->s_nilfs->ns_mount_state); | ||
319 | ret = nilfs_commit_super(sbi, 1); | ||
320 | } | ||
304 | return ret; | 321 | return ret; |
305 | } | 322 | } |
306 | 323 | ||
@@ -336,6 +353,7 @@ static int nilfs_sync_fs(struct super_block *sb, int wait) | |||
336 | { | 353 | { |
337 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 354 | struct nilfs_sb_info *sbi = NILFS_SB(sb); |
338 | struct the_nilfs *nilfs = sbi->s_nilfs; | 355 | struct the_nilfs *nilfs = sbi->s_nilfs; |
356 | struct nilfs_super_block **sbp; | ||
339 | int err = 0; | 357 | int err = 0; |
340 | 358 | ||
341 | /* This function is called when super block should be written back */ | 359 | /* This function is called when super block should be written back */ |
@@ -343,8 +361,11 @@ static int nilfs_sync_fs(struct super_block *sb, int wait) | |||
343 | err = nilfs_construct_segment(sb); | 361 | err = nilfs_construct_segment(sb); |
344 | 362 | ||
345 | down_write(&nilfs->ns_sem); | 363 | down_write(&nilfs->ns_sem); |
346 | if (nilfs_sb_dirty(nilfs)) | 364 | if (nilfs_sb_dirty(nilfs)) { |
347 | nilfs_commit_super(sbi, 1); | 365 | sbp = nilfs_prepare_super(sbi); |
366 | if (likely(sbp)) | ||
367 | nilfs_commit_super(sbi, 1); | ||
368 | } | ||
348 | up_write(&nilfs->ns_sem); | 369 | up_write(&nilfs->ns_sem); |
349 | 370 | ||
350 | return err; | 371 | return err; |
@@ -638,11 +659,18 @@ nilfs_set_default_options(struct nilfs_sb_info *sbi, | |||
638 | static int nilfs_setup_super(struct nilfs_sb_info *sbi) | 659 | static int nilfs_setup_super(struct nilfs_sb_info *sbi) |
639 | { | 660 | { |
640 | struct the_nilfs *nilfs = sbi->s_nilfs; | 661 | struct the_nilfs *nilfs = sbi->s_nilfs; |
641 | struct nilfs_super_block *sbp = nilfs->ns_sbp[0]; | 662 | struct nilfs_super_block **sbp; |
642 | int max_mnt_count = le16_to_cpu(sbp->s_max_mnt_count); | 663 | int max_mnt_count; |
643 | int mnt_count = le16_to_cpu(sbp->s_mnt_count); | 664 | int mnt_count; |
665 | |||
666 | /* nilfs->ns_sem must be locked by the caller. */ | ||
667 | sbp = nilfs_prepare_super(sbi); | ||
668 | if (!sbp) | ||
669 | return -EIO; | ||
670 | |||
671 | max_mnt_count = le16_to_cpu(sbp[0]->s_max_mnt_count); | ||
672 | mnt_count = le16_to_cpu(sbp[0]->s_mnt_count); | ||
644 | 673 | ||
645 | /* nilfs->sem must be locked by the caller. */ | ||
646 | if (nilfs->ns_mount_state & NILFS_ERROR_FS) { | 674 | if (nilfs->ns_mount_state & NILFS_ERROR_FS) { |
647 | printk(KERN_WARNING | 675 | printk(KERN_WARNING |
648 | "NILFS warning: mounting fs with errors\n"); | 676 | "NILFS warning: mounting fs with errors\n"); |
@@ -653,11 +681,12 @@ static int nilfs_setup_super(struct nilfs_sb_info *sbi) | |||
653 | #endif | 681 | #endif |
654 | } | 682 | } |
655 | if (!max_mnt_count) | 683 | if (!max_mnt_count) |
656 | sbp->s_max_mnt_count = cpu_to_le16(NILFS_DFL_MAX_MNT_COUNT); | 684 | sbp[0]->s_max_mnt_count = cpu_to_le16(NILFS_DFL_MAX_MNT_COUNT); |
657 | 685 | ||
658 | sbp->s_mnt_count = cpu_to_le16(mnt_count + 1); | 686 | sbp[0]->s_mnt_count = cpu_to_le16(mnt_count + 1); |
659 | sbp->s_state = cpu_to_le16(le16_to_cpu(sbp->s_state) & ~NILFS_VALID_FS); | 687 | sbp[0]->s_state = |
660 | sbp->s_mtime = cpu_to_le64(get_seconds()); | 688 | cpu_to_le16(le16_to_cpu(sbp[0]->s_state) & ~NILFS_VALID_FS); |
689 | sbp[0]->s_mtime = cpu_to_le64(get_seconds()); | ||
661 | return nilfs_commit_super(sbi, 1); | 690 | return nilfs_commit_super(sbi, 1); |
662 | } | 691 | } |
663 | 692 | ||