aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nilfs2/super.c')
-rw-r--r--fs/nilfs2/super.c333
1 files changed, 234 insertions, 99 deletions
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 414ef68931cf..26078b3407c9 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -55,6 +55,8 @@
55#include "nilfs.h" 55#include "nilfs.h"
56#include "mdt.h" 56#include "mdt.h"
57#include "alloc.h" 57#include "alloc.h"
58#include "btree.h"
59#include "btnode.h"
58#include "page.h" 60#include "page.h"
59#include "cpfile.h" 61#include "cpfile.h"
60#include "ifile.h" 62#include "ifile.h"
@@ -74,6 +76,25 @@ struct kmem_cache *nilfs_btree_path_cache;
74 76
75static int nilfs_remount(struct super_block *sb, int *flags, char *data); 77static int nilfs_remount(struct super_block *sb, int *flags, char *data);
76 78
79static void nilfs_set_error(struct nilfs_sb_info *sbi)
80{
81 struct the_nilfs *nilfs = sbi->s_nilfs;
82 struct nilfs_super_block **sbp;
83
84 down_write(&nilfs->ns_sem);
85 if (!(nilfs->ns_mount_state & NILFS_ERROR_FS)) {
86 nilfs->ns_mount_state |= NILFS_ERROR_FS;
87 sbp = nilfs_prepare_super(sbi, 0);
88 if (likely(sbp)) {
89 sbp[0]->s_state |= cpu_to_le16(NILFS_ERROR_FS);
90 if (sbp[1])
91 sbp[1]->s_state |= cpu_to_le16(NILFS_ERROR_FS);
92 nilfs_commit_super(sbi, NILFS_SB_COMMIT_ALL);
93 }
94 }
95 up_write(&nilfs->ns_sem);
96}
97
77/** 98/**
78 * nilfs_error() - report failure condition on a filesystem 99 * nilfs_error() - report failure condition on a filesystem
79 * 100 *
@@ -99,16 +120,7 @@ void nilfs_error(struct super_block *sb, const char *function,
99 va_end(args); 120 va_end(args);
100 121
101 if (!(sb->s_flags & MS_RDONLY)) { 122 if (!(sb->s_flags & MS_RDONLY)) {
102 struct the_nilfs *nilfs = sbi->s_nilfs; 123 nilfs_set_error(sbi);
103
104 down_write(&nilfs->ns_sem);
105 if (!(nilfs->ns_mount_state & NILFS_ERROR_FS)) {
106 nilfs->ns_mount_state |= NILFS_ERROR_FS;
107 nilfs->ns_sbp[0]->s_state |=
108 cpu_to_le16(NILFS_ERROR_FS);
109 nilfs_commit_super(sbi, 1);
110 }
111 up_write(&nilfs->ns_sem);
112 124
113 if (nilfs_test_opt(sbi, ERRORS_RO)) { 125 if (nilfs_test_opt(sbi, ERRORS_RO)) {
114 printk(KERN_CRIT "Remounting filesystem read-only\n"); 126 printk(KERN_CRIT "Remounting filesystem read-only\n");
@@ -176,7 +188,7 @@ static void nilfs_clear_inode(struct inode *inode)
176 nilfs_btnode_cache_clear(&ii->i_btnode_cache); 188 nilfs_btnode_cache_clear(&ii->i_btnode_cache);
177} 189}
178 190
179static int nilfs_sync_super(struct nilfs_sb_info *sbi, int dupsb) 191static int nilfs_sync_super(struct nilfs_sb_info *sbi, int flag)
180{ 192{
181 struct the_nilfs *nilfs = sbi->s_nilfs; 193 struct the_nilfs *nilfs = sbi->s_nilfs;
182 int err; 194 int err;
@@ -202,12 +214,20 @@ static int nilfs_sync_super(struct nilfs_sb_info *sbi, int dupsb)
202 printk(KERN_ERR 214 printk(KERN_ERR
203 "NILFS: unable to write superblock (err=%d)\n", err); 215 "NILFS: unable to write superblock (err=%d)\n", err);
204 if (err == -EIO && nilfs->ns_sbh[1]) { 216 if (err == -EIO && nilfs->ns_sbh[1]) {
217 /*
218 * sbp[0] points to newer log than sbp[1],
219 * so copy sbp[0] to sbp[1] to take over sbp[0].
220 */
221 memcpy(nilfs->ns_sbp[1], nilfs->ns_sbp[0],
222 nilfs->ns_sbsize);
205 nilfs_fall_back_super_block(nilfs); 223 nilfs_fall_back_super_block(nilfs);
206 goto retry; 224 goto retry;
207 } 225 }
208 } else { 226 } else {
209 struct nilfs_super_block *sbp = nilfs->ns_sbp[0]; 227 struct nilfs_super_block *sbp = nilfs->ns_sbp[0];
210 228
229 nilfs->ns_sbwcount++;
230
211 /* 231 /*
212 * The latest segment becomes trailable from the position 232 * The latest segment becomes trailable from the position
213 * written in superblock. 233 * written in superblock.
@@ -216,66 +236,122 @@ static int nilfs_sync_super(struct nilfs_sb_info *sbi, int dupsb)
216 236
217 /* update GC protection for recent segments */ 237 /* update GC protection for recent segments */
218 if (nilfs->ns_sbh[1]) { 238 if (nilfs->ns_sbh[1]) {
219 sbp = NULL; 239 if (flag == NILFS_SB_COMMIT_ALL) {
220 if (dupsb) {
221 set_buffer_dirty(nilfs->ns_sbh[1]); 240 set_buffer_dirty(nilfs->ns_sbh[1]);
222 if (!sync_dirty_buffer(nilfs->ns_sbh[1])) 241 if (sync_dirty_buffer(nilfs->ns_sbh[1]) < 0)
223 sbp = nilfs->ns_sbp[1]; 242 goto out;
224 } 243 }
244 if (le64_to_cpu(nilfs->ns_sbp[1]->s_last_cno) <
245 le64_to_cpu(nilfs->ns_sbp[0]->s_last_cno))
246 sbp = nilfs->ns_sbp[1];
225 } 247 }
226 if (sbp) {
227 spin_lock(&nilfs->ns_last_segment_lock);
228 nilfs->ns_prot_seq = le64_to_cpu(sbp->s_last_seq);
229 spin_unlock(&nilfs->ns_last_segment_lock);
230 }
231 }
232 248
249 spin_lock(&nilfs->ns_last_segment_lock);
250 nilfs->ns_prot_seq = le64_to_cpu(sbp->s_last_seq);
251 spin_unlock(&nilfs->ns_last_segment_lock);
252 }
253 out:
233 return err; 254 return err;
234} 255}
235 256
236int nilfs_commit_super(struct nilfs_sb_info *sbi, int dupsb) 257void nilfs_set_log_cursor(struct nilfs_super_block *sbp,
258 struct the_nilfs *nilfs)
259{
260 sector_t nfreeblocks;
261
262 /* nilfs->ns_sem must be locked by the caller. */
263 nilfs_count_free_blocks(nilfs, &nfreeblocks);
264 sbp->s_free_blocks_count = cpu_to_le64(nfreeblocks);
265
266 spin_lock(&nilfs->ns_last_segment_lock);
267 sbp->s_last_seq = cpu_to_le64(nilfs->ns_last_seq);
268 sbp->s_last_pseg = cpu_to_le64(nilfs->ns_last_pseg);
269 sbp->s_last_cno = cpu_to_le64(nilfs->ns_last_cno);
270 spin_unlock(&nilfs->ns_last_segment_lock);
271}
272
273struct nilfs_super_block **nilfs_prepare_super(struct nilfs_sb_info *sbi,
274 int flip)
237{ 275{
238 struct the_nilfs *nilfs = sbi->s_nilfs; 276 struct the_nilfs *nilfs = sbi->s_nilfs;
239 struct nilfs_super_block **sbp = nilfs->ns_sbp; 277 struct nilfs_super_block **sbp = nilfs->ns_sbp;
240 sector_t nfreeblocks;
241 time_t t;
242 int err;
243 278
244 /* nilfs->sem must be locked by the caller. */ 279 /* nilfs->ns_sem must be locked by the caller. */
245 if (sbp[0]->s_magic != cpu_to_le16(NILFS_SUPER_MAGIC)) { 280 if (sbp[0]->s_magic != cpu_to_le16(NILFS_SUPER_MAGIC)) {
246 if (sbp[1] && sbp[1]->s_magic == cpu_to_le16(NILFS_SUPER_MAGIC)) 281 if (sbp[1] &&
247 nilfs_swap_super_block(nilfs); 282 sbp[1]->s_magic == cpu_to_le16(NILFS_SUPER_MAGIC)) {
248 else { 283 memcpy(sbp[0], sbp[1], nilfs->ns_sbsize);
284 } else {
249 printk(KERN_CRIT "NILFS: superblock broke on dev %s\n", 285 printk(KERN_CRIT "NILFS: superblock broke on dev %s\n",
250 sbi->s_super->s_id); 286 sbi->s_super->s_id);
251 return -EIO; 287 return NULL;
252 } 288 }
289 } else if (sbp[1] &&
290 sbp[1]->s_magic != cpu_to_le16(NILFS_SUPER_MAGIC)) {
291 memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);
253 } 292 }
254 err = nilfs_count_free_blocks(nilfs, &nfreeblocks);
255 if (unlikely(err)) {
256 printk(KERN_ERR "NILFS: failed to count free blocks\n");
257 return err;
258 }
259 spin_lock(&nilfs->ns_last_segment_lock);
260 sbp[0]->s_last_seq = cpu_to_le64(nilfs->ns_last_seq);
261 sbp[0]->s_last_pseg = cpu_to_le64(nilfs->ns_last_pseg);
262 sbp[0]->s_last_cno = cpu_to_le64(nilfs->ns_last_cno);
263 spin_unlock(&nilfs->ns_last_segment_lock);
264 293
294 if (flip && sbp[1])
295 nilfs_swap_super_block(nilfs);
296
297 return sbp;
298}
299
300int nilfs_commit_super(struct nilfs_sb_info *sbi, int flag)
301{
302 struct the_nilfs *nilfs = sbi->s_nilfs;
303 struct nilfs_super_block **sbp = nilfs->ns_sbp;
304 time_t t;
305
306 /* nilfs->ns_sem must be locked by the caller. */
265 t = get_seconds(); 307 t = get_seconds();
266 nilfs->ns_sbwtime[0] = t; 308 nilfs->ns_sbwtime = t;
267 sbp[0]->s_free_blocks_count = cpu_to_le64(nfreeblocks);
268 sbp[0]->s_wtime = cpu_to_le64(t); 309 sbp[0]->s_wtime = cpu_to_le64(t);
269 sbp[0]->s_sum = 0; 310 sbp[0]->s_sum = 0;
270 sbp[0]->s_sum = cpu_to_le32(crc32_le(nilfs->ns_crc_seed, 311 sbp[0]->s_sum = cpu_to_le32(crc32_le(nilfs->ns_crc_seed,
271 (unsigned char *)sbp[0], 312 (unsigned char *)sbp[0],
272 nilfs->ns_sbsize)); 313 nilfs->ns_sbsize));
273 if (dupsb && sbp[1]) { 314 if (flag == NILFS_SB_COMMIT_ALL && sbp[1]) {
274 memcpy(sbp[1], sbp[0], nilfs->ns_sbsize); 315 sbp[1]->s_wtime = sbp[0]->s_wtime;
275 nilfs->ns_sbwtime[1] = t; 316 sbp[1]->s_sum = 0;
317 sbp[1]->s_sum = cpu_to_le32(crc32_le(nilfs->ns_crc_seed,
318 (unsigned char *)sbp[1],
319 nilfs->ns_sbsize));
276 } 320 }
277 clear_nilfs_sb_dirty(nilfs); 321 clear_nilfs_sb_dirty(nilfs);
278 return nilfs_sync_super(sbi, dupsb); 322 return nilfs_sync_super(sbi, flag);
323}
324
325/**
326 * nilfs_cleanup_super() - write filesystem state for cleanup
327 * @sbi: nilfs_sb_info to be unmounted or degraded to read-only
328 *
329 * This function restores state flags in the on-disk super block.
330 * This will set "clean" flag (i.e. NILFS_VALID_FS) unless the
331 * filesystem was not clean previously.
332 */
333int nilfs_cleanup_super(struct nilfs_sb_info *sbi)
334{
335 struct nilfs_super_block **sbp;
336 int flag = NILFS_SB_COMMIT;
337 int ret = -EIO;
338
339 sbp = nilfs_prepare_super(sbi, 0);
340 if (sbp) {
341 sbp[0]->s_state = cpu_to_le16(sbi->s_nilfs->ns_mount_state);
342 nilfs_set_log_cursor(sbp[0], sbi->s_nilfs);
343 if (sbp[1] && sbp[0]->s_last_cno == sbp[1]->s_last_cno) {
344 /*
345 * make the "clean" flag also to the opposite
346 * super block if both super blocks point to
347 * the same checkpoint.
348 */
349 sbp[1]->s_state = sbp[0]->s_state;
350 flag = NILFS_SB_COMMIT_ALL;
351 }
352 ret = nilfs_commit_super(sbi, flag);
353 }
354 return ret;
279} 355}
280 356
281static void nilfs_put_super(struct super_block *sb) 357static void nilfs_put_super(struct super_block *sb)
@@ -289,8 +365,7 @@ static void nilfs_put_super(struct super_block *sb)
289 365
290 if (!(sb->s_flags & MS_RDONLY)) { 366 if (!(sb->s_flags & MS_RDONLY)) {
291 down_write(&nilfs->ns_sem); 367 down_write(&nilfs->ns_sem);
292 nilfs->ns_sbp[0]->s_state = cpu_to_le16(nilfs->ns_mount_state); 368 nilfs_cleanup_super(sbi);
293 nilfs_commit_super(sbi, 1);
294 up_write(&nilfs->ns_sem); 369 up_write(&nilfs->ns_sem);
295 } 370 }
296 down_write(&nilfs->ns_super_sem); 371 down_write(&nilfs->ns_super_sem);
@@ -311,6 +386,7 @@ static int nilfs_sync_fs(struct super_block *sb, int wait)
311{ 386{
312 struct nilfs_sb_info *sbi = NILFS_SB(sb); 387 struct nilfs_sb_info *sbi = NILFS_SB(sb);
313 struct the_nilfs *nilfs = sbi->s_nilfs; 388 struct the_nilfs *nilfs = sbi->s_nilfs;
389 struct nilfs_super_block **sbp;
314 int err = 0; 390 int err = 0;
315 391
316 /* This function is called when super block should be written back */ 392 /* This function is called when super block should be written back */
@@ -318,8 +394,13 @@ static int nilfs_sync_fs(struct super_block *sb, int wait)
318 err = nilfs_construct_segment(sb); 394 err = nilfs_construct_segment(sb);
319 395
320 down_write(&nilfs->ns_sem); 396 down_write(&nilfs->ns_sem);
321 if (nilfs_sb_dirty(nilfs)) 397 if (nilfs_sb_dirty(nilfs)) {
322 nilfs_commit_super(sbi, 1); 398 sbp = nilfs_prepare_super(sbi, nilfs_sb_will_flip(nilfs));
399 if (likely(sbp)) {
400 nilfs_set_log_cursor(sbp[0], nilfs);
401 nilfs_commit_super(sbi, NILFS_SB_COMMIT);
402 }
403 }
323 up_write(&nilfs->ns_sem); 404 up_write(&nilfs->ns_sem);
324 405
325 return err; 406 return err;
@@ -442,20 +523,20 @@ static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
442 struct nilfs_sb_info *sbi = NILFS_SB(sb); 523 struct nilfs_sb_info *sbi = NILFS_SB(sb);
443 524
444 if (!nilfs_test_opt(sbi, BARRIER)) 525 if (!nilfs_test_opt(sbi, BARRIER))
445 seq_printf(seq, ",nobarrier"); 526 seq_puts(seq, ",nobarrier");
446 if (nilfs_test_opt(sbi, SNAPSHOT)) 527 if (nilfs_test_opt(sbi, SNAPSHOT))
447 seq_printf(seq, ",cp=%llu", 528 seq_printf(seq, ",cp=%llu",
448 (unsigned long long int)sbi->s_snapshot_cno); 529 (unsigned long long int)sbi->s_snapshot_cno);
449 if (nilfs_test_opt(sbi, ERRORS_PANIC)) 530 if (nilfs_test_opt(sbi, ERRORS_PANIC))
450 seq_printf(seq, ",errors=panic"); 531 seq_puts(seq, ",errors=panic");
451 if (nilfs_test_opt(sbi, ERRORS_CONT)) 532 if (nilfs_test_opt(sbi, ERRORS_CONT))
452 seq_printf(seq, ",errors=continue"); 533 seq_puts(seq, ",errors=continue");
453 if (nilfs_test_opt(sbi, STRICT_ORDER)) 534 if (nilfs_test_opt(sbi, STRICT_ORDER))
454 seq_printf(seq, ",order=strict"); 535 seq_puts(seq, ",order=strict");
455 if (nilfs_test_opt(sbi, NORECOVERY)) 536 if (nilfs_test_opt(sbi, NORECOVERY))
456 seq_printf(seq, ",norecovery"); 537 seq_puts(seq, ",norecovery");
457 if (nilfs_test_opt(sbi, DISCARD)) 538 if (nilfs_test_opt(sbi, DISCARD))
458 seq_printf(seq, ",discard"); 539 seq_puts(seq, ",discard");
459 540
460 return 0; 541 return 0;
461} 542}
@@ -524,23 +605,25 @@ static const struct export_operations nilfs_export_ops = {
524 605
525enum { 606enum {
526 Opt_err_cont, Opt_err_panic, Opt_err_ro, 607 Opt_err_cont, Opt_err_panic, Opt_err_ro,
527 Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery, 608 Opt_barrier, Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery,
528 Opt_discard, Opt_err, 609 Opt_discard, Opt_nodiscard, Opt_err,
529}; 610};
530 611
531static match_table_t tokens = { 612static match_table_t tokens = {
532 {Opt_err_cont, "errors=continue"}, 613 {Opt_err_cont, "errors=continue"},
533 {Opt_err_panic, "errors=panic"}, 614 {Opt_err_panic, "errors=panic"},
534 {Opt_err_ro, "errors=remount-ro"}, 615 {Opt_err_ro, "errors=remount-ro"},
616 {Opt_barrier, "barrier"},
535 {Opt_nobarrier, "nobarrier"}, 617 {Opt_nobarrier, "nobarrier"},
536 {Opt_snapshot, "cp=%u"}, 618 {Opt_snapshot, "cp=%u"},
537 {Opt_order, "order=%s"}, 619 {Opt_order, "order=%s"},
538 {Opt_norecovery, "norecovery"}, 620 {Opt_norecovery, "norecovery"},
539 {Opt_discard, "discard"}, 621 {Opt_discard, "discard"},
622 {Opt_nodiscard, "nodiscard"},
540 {Opt_err, NULL} 623 {Opt_err, NULL}
541}; 624};
542 625
543static int parse_options(char *options, struct super_block *sb) 626static int parse_options(char *options, struct super_block *sb, int is_remount)
544{ 627{
545 struct nilfs_sb_info *sbi = NILFS_SB(sb); 628 struct nilfs_sb_info *sbi = NILFS_SB(sb);
546 char *p; 629 char *p;
@@ -557,6 +640,9 @@ static int parse_options(char *options, struct super_block *sb)
557 640
558 token = match_token(p, tokens, args); 641 token = match_token(p, tokens, args);
559 switch (token) { 642 switch (token) {
643 case Opt_barrier:
644 nilfs_set_opt(sbi, BARRIER);
645 break;
560 case Opt_nobarrier: 646 case Opt_nobarrier:
561 nilfs_clear_opt(sbi, BARRIER); 647 nilfs_clear_opt(sbi, BARRIER);
562 break; 648 break;
@@ -582,8 +668,26 @@ static int parse_options(char *options, struct super_block *sb)
582 case Opt_snapshot: 668 case Opt_snapshot:
583 if (match_int(&args[0], &option) || option <= 0) 669 if (match_int(&args[0], &option) || option <= 0)
584 return 0; 670 return 0;
585 if (!(sb->s_flags & MS_RDONLY)) 671 if (is_remount) {
672 if (!nilfs_test_opt(sbi, SNAPSHOT)) {
673 printk(KERN_ERR
674 "NILFS: cannot change regular "
675 "mount to snapshot.\n");
676 return 0;
677 } else if (option != sbi->s_snapshot_cno) {
678 printk(KERN_ERR
679 "NILFS: cannot remount to a "
680 "different snapshot.\n");
681 return 0;
682 }
683 break;
684 }
685 if (!(sb->s_flags & MS_RDONLY)) {
686 printk(KERN_ERR "NILFS: cannot mount snapshot "
687 "read/write. A read-only option is "
688 "required.\n");
586 return 0; 689 return 0;
690 }
587 sbi->s_snapshot_cno = option; 691 sbi->s_snapshot_cno = option;
588 nilfs_set_opt(sbi, SNAPSHOT); 692 nilfs_set_opt(sbi, SNAPSHOT);
589 break; 693 break;
@@ -593,6 +697,9 @@ static int parse_options(char *options, struct super_block *sb)
593 case Opt_discard: 697 case Opt_discard:
594 nilfs_set_opt(sbi, DISCARD); 698 nilfs_set_opt(sbi, DISCARD);
595 break; 699 break;
700 case Opt_nodiscard:
701 nilfs_clear_opt(sbi, DISCARD);
702 break;
596 default: 703 default:
597 printk(KERN_ERR 704 printk(KERN_ERR
598 "NILFS: Unrecognized mount option \"%s\"\n", p); 705 "NILFS: Unrecognized mount option \"%s\"\n", p);
@@ -613,11 +720,18 @@ nilfs_set_default_options(struct nilfs_sb_info *sbi,
613static int nilfs_setup_super(struct nilfs_sb_info *sbi) 720static int nilfs_setup_super(struct nilfs_sb_info *sbi)
614{ 721{
615 struct the_nilfs *nilfs = sbi->s_nilfs; 722 struct the_nilfs *nilfs = sbi->s_nilfs;
616 struct nilfs_super_block *sbp = nilfs->ns_sbp[0]; 723 struct nilfs_super_block **sbp;
617 int max_mnt_count = le16_to_cpu(sbp->s_max_mnt_count); 724 int max_mnt_count;
618 int mnt_count = le16_to_cpu(sbp->s_mnt_count); 725 int mnt_count;
726
727 /* nilfs->ns_sem must be locked by the caller. */
728 sbp = nilfs_prepare_super(sbi, 0);
729 if (!sbp)
730 return -EIO;
731
732 max_mnt_count = le16_to_cpu(sbp[0]->s_max_mnt_count);
733 mnt_count = le16_to_cpu(sbp[0]->s_mnt_count);
619 734
620 /* nilfs->sem must be locked by the caller. */
621 if (nilfs->ns_mount_state & NILFS_ERROR_FS) { 735 if (nilfs->ns_mount_state & NILFS_ERROR_FS) {
622 printk(KERN_WARNING 736 printk(KERN_WARNING
623 "NILFS warning: mounting fs with errors\n"); 737 "NILFS warning: mounting fs with errors\n");
@@ -628,12 +742,15 @@ static int nilfs_setup_super(struct nilfs_sb_info *sbi)
628#endif 742#endif
629 } 743 }
630 if (!max_mnt_count) 744 if (!max_mnt_count)
631 sbp->s_max_mnt_count = cpu_to_le16(NILFS_DFL_MAX_MNT_COUNT); 745 sbp[0]->s_max_mnt_count = cpu_to_le16(NILFS_DFL_MAX_MNT_COUNT);
632 746
633 sbp->s_mnt_count = cpu_to_le16(mnt_count + 1); 747 sbp[0]->s_mnt_count = cpu_to_le16(mnt_count + 1);
634 sbp->s_state = cpu_to_le16(le16_to_cpu(sbp->s_state) & ~NILFS_VALID_FS); 748 sbp[0]->s_state =
635 sbp->s_mtime = cpu_to_le64(get_seconds()); 749 cpu_to_le16(le16_to_cpu(sbp[0]->s_state) & ~NILFS_VALID_FS);
636 return nilfs_commit_super(sbi, 1); 750 sbp[0]->s_mtime = cpu_to_le64(get_seconds());
751 /* synchronize sbp[1] with sbp[0] */
752 memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);
753 return nilfs_commit_super(sbi, NILFS_SB_COMMIT_ALL);
637} 754}
638 755
639struct nilfs_super_block *nilfs_read_super_block(struct super_block *sb, 756struct nilfs_super_block *nilfs_read_super_block(struct super_block *sb,
@@ -670,7 +787,31 @@ int nilfs_store_magic_and_option(struct super_block *sb,
670 sbi->s_interval = le32_to_cpu(sbp->s_c_interval); 787 sbi->s_interval = le32_to_cpu(sbp->s_c_interval);
671 sbi->s_watermark = le32_to_cpu(sbp->s_c_block_max); 788 sbi->s_watermark = le32_to_cpu(sbp->s_c_block_max);
672 789
673 return !parse_options(data, sb) ? -EINVAL : 0 ; 790 return !parse_options(data, sb, 0) ? -EINVAL : 0 ;
791}
792
793int nilfs_check_feature_compatibility(struct super_block *sb,
794 struct nilfs_super_block *sbp)
795{
796 __u64 features;
797
798 features = le64_to_cpu(sbp->s_feature_incompat) &
799 ~NILFS_FEATURE_INCOMPAT_SUPP;
800 if (features) {
801 printk(KERN_ERR "NILFS: couldn't mount because of unsupported "
802 "optional features (%llx)\n",
803 (unsigned long long)features);
804 return -EINVAL;
805 }
806 features = le64_to_cpu(sbp->s_feature_compat_ro) &
807 ~NILFS_FEATURE_COMPAT_RO_SUPP;
808 if (!(sb->s_flags & MS_RDONLY) && features) {
809 printk(KERN_ERR "NILFS: couldn't mount RDWR because of "
810 "unsupported optional features (%llx)\n",
811 (unsigned long long)features);
812 return -EINVAL;
813 }
814 return 0;
674} 815}
675 816
676/** 817/**
@@ -819,7 +960,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
819static int nilfs_remount(struct super_block *sb, int *flags, char *data) 960static int nilfs_remount(struct super_block *sb, int *flags, char *data)
820{ 961{
821 struct nilfs_sb_info *sbi = NILFS_SB(sb); 962 struct nilfs_sb_info *sbi = NILFS_SB(sb);
822 struct nilfs_super_block *sbp;
823 struct the_nilfs *nilfs = sbi->s_nilfs; 963 struct the_nilfs *nilfs = sbi->s_nilfs;
824 unsigned long old_sb_flags; 964 unsigned long old_sb_flags;
825 struct nilfs_mount_options old_opts; 965 struct nilfs_mount_options old_opts;
@@ -833,32 +973,17 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
833 old_opts.snapshot_cno = sbi->s_snapshot_cno; 973 old_opts.snapshot_cno = sbi->s_snapshot_cno;
834 was_snapshot = nilfs_test_opt(sbi, SNAPSHOT); 974 was_snapshot = nilfs_test_opt(sbi, SNAPSHOT);
835 975
836 if (!parse_options(data, sb)) { 976 if (!parse_options(data, sb, 1)) {
837 err = -EINVAL; 977 err = -EINVAL;
838 goto restore_opts; 978 goto restore_opts;
839 } 979 }
840 sb->s_flags = (sb->s_flags & ~MS_POSIXACL); 980 sb->s_flags = (sb->s_flags & ~MS_POSIXACL);
841 981
842 err = -EINVAL; 982 err = -EINVAL;
843 if (was_snapshot) { 983 if (was_snapshot && !(*flags & MS_RDONLY)) {
844 if (!(*flags & MS_RDONLY)) { 984 printk(KERN_ERR "NILFS (device %s): cannot remount snapshot "
845 printk(KERN_ERR "NILFS (device %s): cannot remount " 985 "read/write.\n", sb->s_id);
846 "snapshot read/write.\n", 986 goto restore_opts;
847 sb->s_id);
848 goto restore_opts;
849 } else if (sbi->s_snapshot_cno != old_opts.snapshot_cno) {
850 printk(KERN_ERR "NILFS (device %s): cannot "
851 "remount to a different snapshot.\n",
852 sb->s_id);
853 goto restore_opts;
854 }
855 } else {
856 if (nilfs_test_opt(sbi, SNAPSHOT)) {
857 printk(KERN_ERR "NILFS (device %s): cannot change "
858 "a regular mount to a snapshot.\n",
859 sb->s_id);
860 goto restore_opts;
861 }
862 } 987 }
863 988
864 if (!nilfs_valid_fs(nilfs)) { 989 if (!nilfs_valid_fs(nilfs)) {
@@ -880,19 +1005,29 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
880 * the RDONLY flag and then mark the partition as valid again. 1005 * the RDONLY flag and then mark the partition as valid again.
881 */ 1006 */
882 down_write(&nilfs->ns_sem); 1007 down_write(&nilfs->ns_sem);
883 sbp = nilfs->ns_sbp[0]; 1008 nilfs_cleanup_super(sbi);
884 if (!(sbp->s_state & le16_to_cpu(NILFS_VALID_FS)) &&
885 (nilfs->ns_mount_state & NILFS_VALID_FS))
886 sbp->s_state = cpu_to_le16(nilfs->ns_mount_state);
887 sbp->s_mtime = cpu_to_le64(get_seconds());
888 nilfs_commit_super(sbi, 1);
889 up_write(&nilfs->ns_sem); 1009 up_write(&nilfs->ns_sem);
890 } else { 1010 } else {
1011 __u64 features;
1012
891 /* 1013 /*
892 * Mounting a RDONLY partition read-write, so reread and 1014 * Mounting a RDONLY partition read-write, so reread and
893 * store the current valid flag. (It may have been changed 1015 * store the current valid flag. (It may have been changed
894 * by fsck since we originally mounted the partition.) 1016 * by fsck since we originally mounted the partition.)
895 */ 1017 */
1018 down_read(&nilfs->ns_sem);
1019 features = le64_to_cpu(nilfs->ns_sbp[0]->s_feature_compat_ro) &
1020 ~NILFS_FEATURE_COMPAT_RO_SUPP;
1021 up_read(&nilfs->ns_sem);
1022 if (features) {
1023 printk(KERN_WARNING "NILFS (device %s): couldn't "
1024 "remount RDWR because of unsupported optional "
1025 "features (%llx)\n",
1026 sb->s_id, (unsigned long long)features);
1027 err = -EROFS;
1028 goto restore_opts;
1029 }
1030
896 sb->s_flags &= ~MS_RDONLY; 1031 sb->s_flags &= ~MS_RDONLY;
897 1032
898 err = nilfs_attach_segment_constructor(sbi); 1033 err = nilfs_attach_segment_constructor(sbi);
@@ -1119,7 +1254,7 @@ static void nilfs_inode_init_once(void *obj)
1119 init_rwsem(&ii->xattr_sem); 1254 init_rwsem(&ii->xattr_sem);
1120#endif 1255#endif
1121 nilfs_btnode_cache_init_once(&ii->i_btnode_cache); 1256 nilfs_btnode_cache_init_once(&ii->i_btnode_cache);
1122 ii->i_bmap = (struct nilfs_bmap *)&ii->i_bmap_union; 1257 ii->i_bmap = &ii->i_bmap_data;
1123 inode_init_once(&ii->vfs_inode); 1258 inode_init_once(&ii->vfs_inode);
1124} 1259}
1125 1260