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.c353
1 files changed, 235 insertions, 118 deletions
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 414ef68931cf..1fa86b9df73b 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");
@@ -159,24 +171,7 @@ void nilfs_destroy_inode(struct inode *inode)
159 kmem_cache_free(nilfs_inode_cachep, NILFS_I(inode)); 171 kmem_cache_free(nilfs_inode_cachep, NILFS_I(inode));
160} 172}
161 173
162static void nilfs_clear_inode(struct inode *inode) 174static int nilfs_sync_super(struct nilfs_sb_info *sbi, int flag)
163{
164 struct nilfs_inode_info *ii = NILFS_I(inode);
165
166 /*
167 * Free resources allocated in nilfs_read_inode(), here.
168 */
169 BUG_ON(!list_empty(&ii->i_dirty));
170 brelse(ii->i_bh);
171 ii->i_bh = NULL;
172
173 if (test_bit(NILFS_I_BMAP, &ii->i_state))
174 nilfs_bmap_clear(ii->i_bmap);
175
176 nilfs_btnode_cache_clear(&ii->i_btnode_cache);
177}
178
179static int nilfs_sync_super(struct nilfs_sb_info *sbi, int dupsb)
180{ 175{
181 struct the_nilfs *nilfs = sbi->s_nilfs; 176 struct the_nilfs *nilfs = sbi->s_nilfs;
182 int err; 177 int err;
@@ -202,12 +197,20 @@ static int nilfs_sync_super(struct nilfs_sb_info *sbi, int dupsb)
202 printk(KERN_ERR 197 printk(KERN_ERR
203 "NILFS: unable to write superblock (err=%d)\n", err); 198 "NILFS: unable to write superblock (err=%d)\n", err);
204 if (err == -EIO && nilfs->ns_sbh[1]) { 199 if (err == -EIO && nilfs->ns_sbh[1]) {
200 /*
201 * sbp[0] points to newer log than sbp[1],
202 * so copy sbp[0] to sbp[1] to take over sbp[0].
203 */
204 memcpy(nilfs->ns_sbp[1], nilfs->ns_sbp[0],
205 nilfs->ns_sbsize);
205 nilfs_fall_back_super_block(nilfs); 206 nilfs_fall_back_super_block(nilfs);
206 goto retry; 207 goto retry;
207 } 208 }
208 } else { 209 } else {
209 struct nilfs_super_block *sbp = nilfs->ns_sbp[0]; 210 struct nilfs_super_block *sbp = nilfs->ns_sbp[0];
210 211
212 nilfs->ns_sbwcount++;
213
211 /* 214 /*
212 * The latest segment becomes trailable from the position 215 * The latest segment becomes trailable from the position
213 * written in superblock. 216 * written in superblock.
@@ -216,66 +219,122 @@ static int nilfs_sync_super(struct nilfs_sb_info *sbi, int dupsb)
216 219
217 /* update GC protection for recent segments */ 220 /* update GC protection for recent segments */
218 if (nilfs->ns_sbh[1]) { 221 if (nilfs->ns_sbh[1]) {
219 sbp = NULL; 222 if (flag == NILFS_SB_COMMIT_ALL) {
220 if (dupsb) {
221 set_buffer_dirty(nilfs->ns_sbh[1]); 223 set_buffer_dirty(nilfs->ns_sbh[1]);
222 if (!sync_dirty_buffer(nilfs->ns_sbh[1])) 224 if (sync_dirty_buffer(nilfs->ns_sbh[1]) < 0)
223 sbp = nilfs->ns_sbp[1]; 225 goto out;
224 } 226 }
227 if (le64_to_cpu(nilfs->ns_sbp[1]->s_last_cno) <
228 le64_to_cpu(nilfs->ns_sbp[0]->s_last_cno))
229 sbp = nilfs->ns_sbp[1];
225 } 230 }
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 231
232 spin_lock(&nilfs->ns_last_segment_lock);
233 nilfs->ns_prot_seq = le64_to_cpu(sbp->s_last_seq);
234 spin_unlock(&nilfs->ns_last_segment_lock);
235 }
236 out:
233 return err; 237 return err;
234} 238}
235 239
236int nilfs_commit_super(struct nilfs_sb_info *sbi, int dupsb) 240void nilfs_set_log_cursor(struct nilfs_super_block *sbp,
241 struct the_nilfs *nilfs)
242{
243 sector_t nfreeblocks;
244
245 /* nilfs->ns_sem must be locked by the caller. */
246 nilfs_count_free_blocks(nilfs, &nfreeblocks);
247 sbp->s_free_blocks_count = cpu_to_le64(nfreeblocks);
248
249 spin_lock(&nilfs->ns_last_segment_lock);
250 sbp->s_last_seq = cpu_to_le64(nilfs->ns_last_seq);
251 sbp->s_last_pseg = cpu_to_le64(nilfs->ns_last_pseg);
252 sbp->s_last_cno = cpu_to_le64(nilfs->ns_last_cno);
253 spin_unlock(&nilfs->ns_last_segment_lock);
254}
255
256struct nilfs_super_block **nilfs_prepare_super(struct nilfs_sb_info *sbi,
257 int flip)
237{ 258{
238 struct the_nilfs *nilfs = sbi->s_nilfs; 259 struct the_nilfs *nilfs = sbi->s_nilfs;
239 struct nilfs_super_block **sbp = nilfs->ns_sbp; 260 struct nilfs_super_block **sbp = nilfs->ns_sbp;
240 sector_t nfreeblocks;
241 time_t t;
242 int err;
243 261
244 /* nilfs->sem must be locked by the caller. */ 262 /* nilfs->ns_sem must be locked by the caller. */
245 if (sbp[0]->s_magic != cpu_to_le16(NILFS_SUPER_MAGIC)) { 263 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)) 264 if (sbp[1] &&
247 nilfs_swap_super_block(nilfs); 265 sbp[1]->s_magic == cpu_to_le16(NILFS_SUPER_MAGIC)) {
248 else { 266 memcpy(sbp[0], sbp[1], nilfs->ns_sbsize);
267 } else {
249 printk(KERN_CRIT "NILFS: superblock broke on dev %s\n", 268 printk(KERN_CRIT "NILFS: superblock broke on dev %s\n",
250 sbi->s_super->s_id); 269 sbi->s_super->s_id);
251 return -EIO; 270 return NULL;
252 } 271 }
272 } else if (sbp[1] &&
273 sbp[1]->s_magic != cpu_to_le16(NILFS_SUPER_MAGIC)) {
274 memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);
253 } 275 }
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 276
277 if (flip && sbp[1])
278 nilfs_swap_super_block(nilfs);
279
280 return sbp;
281}
282
283int nilfs_commit_super(struct nilfs_sb_info *sbi, int flag)
284{
285 struct the_nilfs *nilfs = sbi->s_nilfs;
286 struct nilfs_super_block **sbp = nilfs->ns_sbp;
287 time_t t;
288
289 /* nilfs->ns_sem must be locked by the caller. */
265 t = get_seconds(); 290 t = get_seconds();
266 nilfs->ns_sbwtime[0] = t; 291 nilfs->ns_sbwtime = t;
267 sbp[0]->s_free_blocks_count = cpu_to_le64(nfreeblocks);
268 sbp[0]->s_wtime = cpu_to_le64(t); 292 sbp[0]->s_wtime = cpu_to_le64(t);
269 sbp[0]->s_sum = 0; 293 sbp[0]->s_sum = 0;
270 sbp[0]->s_sum = cpu_to_le32(crc32_le(nilfs->ns_crc_seed, 294 sbp[0]->s_sum = cpu_to_le32(crc32_le(nilfs->ns_crc_seed,
271 (unsigned char *)sbp[0], 295 (unsigned char *)sbp[0],
272 nilfs->ns_sbsize)); 296 nilfs->ns_sbsize));
273 if (dupsb && sbp[1]) { 297 if (flag == NILFS_SB_COMMIT_ALL && sbp[1]) {
274 memcpy(sbp[1], sbp[0], nilfs->ns_sbsize); 298 sbp[1]->s_wtime = sbp[0]->s_wtime;
275 nilfs->ns_sbwtime[1] = t; 299 sbp[1]->s_sum = 0;
300 sbp[1]->s_sum = cpu_to_le32(crc32_le(nilfs->ns_crc_seed,
301 (unsigned char *)sbp[1],
302 nilfs->ns_sbsize));
276 } 303 }
277 clear_nilfs_sb_dirty(nilfs); 304 clear_nilfs_sb_dirty(nilfs);
278 return nilfs_sync_super(sbi, dupsb); 305 return nilfs_sync_super(sbi, flag);
306}
307
308/**
309 * nilfs_cleanup_super() - write filesystem state for cleanup
310 * @sbi: nilfs_sb_info to be unmounted or degraded to read-only
311 *
312 * This function restores state flags in the on-disk super block.
313 * This will set "clean" flag (i.e. NILFS_VALID_FS) unless the
314 * filesystem was not clean previously.
315 */
316int nilfs_cleanup_super(struct nilfs_sb_info *sbi)
317{
318 struct nilfs_super_block **sbp;
319 int flag = NILFS_SB_COMMIT;
320 int ret = -EIO;
321
322 sbp = nilfs_prepare_super(sbi, 0);
323 if (sbp) {
324 sbp[0]->s_state = cpu_to_le16(sbi->s_nilfs->ns_mount_state);
325 nilfs_set_log_cursor(sbp[0], sbi->s_nilfs);
326 if (sbp[1] && sbp[0]->s_last_cno == sbp[1]->s_last_cno) {
327 /*
328 * make the "clean" flag also to the opposite
329 * super block if both super blocks point to
330 * the same checkpoint.
331 */
332 sbp[1]->s_state = sbp[0]->s_state;
333 flag = NILFS_SB_COMMIT_ALL;
334 }
335 ret = nilfs_commit_super(sbi, flag);
336 }
337 return ret;
279} 338}
280 339
281static void nilfs_put_super(struct super_block *sb) 340static void nilfs_put_super(struct super_block *sb)
@@ -289,8 +348,7 @@ static void nilfs_put_super(struct super_block *sb)
289 348
290 if (!(sb->s_flags & MS_RDONLY)) { 349 if (!(sb->s_flags & MS_RDONLY)) {
291 down_write(&nilfs->ns_sem); 350 down_write(&nilfs->ns_sem);
292 nilfs->ns_sbp[0]->s_state = cpu_to_le16(nilfs->ns_mount_state); 351 nilfs_cleanup_super(sbi);
293 nilfs_commit_super(sbi, 1);
294 up_write(&nilfs->ns_sem); 352 up_write(&nilfs->ns_sem);
295 } 353 }
296 down_write(&nilfs->ns_super_sem); 354 down_write(&nilfs->ns_super_sem);
@@ -311,6 +369,7 @@ static int nilfs_sync_fs(struct super_block *sb, int wait)
311{ 369{
312 struct nilfs_sb_info *sbi = NILFS_SB(sb); 370 struct nilfs_sb_info *sbi = NILFS_SB(sb);
313 struct the_nilfs *nilfs = sbi->s_nilfs; 371 struct the_nilfs *nilfs = sbi->s_nilfs;
372 struct nilfs_super_block **sbp;
314 int err = 0; 373 int err = 0;
315 374
316 /* This function is called when super block should be written back */ 375 /* This function is called when super block should be written back */
@@ -318,8 +377,13 @@ static int nilfs_sync_fs(struct super_block *sb, int wait)
318 err = nilfs_construct_segment(sb); 377 err = nilfs_construct_segment(sb);
319 378
320 down_write(&nilfs->ns_sem); 379 down_write(&nilfs->ns_sem);
321 if (nilfs_sb_dirty(nilfs)) 380 if (nilfs_sb_dirty(nilfs)) {
322 nilfs_commit_super(sbi, 1); 381 sbp = nilfs_prepare_super(sbi, nilfs_sb_will_flip(nilfs));
382 if (likely(sbp)) {
383 nilfs_set_log_cursor(sbp[0], nilfs);
384 nilfs_commit_super(sbi, NILFS_SB_COMMIT);
385 }
386 }
323 up_write(&nilfs->ns_sem); 387 up_write(&nilfs->ns_sem);
324 388
325 return err; 389 return err;
@@ -442,20 +506,20 @@ static int nilfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
442 struct nilfs_sb_info *sbi = NILFS_SB(sb); 506 struct nilfs_sb_info *sbi = NILFS_SB(sb);
443 507
444 if (!nilfs_test_opt(sbi, BARRIER)) 508 if (!nilfs_test_opt(sbi, BARRIER))
445 seq_printf(seq, ",nobarrier"); 509 seq_puts(seq, ",nobarrier");
446 if (nilfs_test_opt(sbi, SNAPSHOT)) 510 if (nilfs_test_opt(sbi, SNAPSHOT))
447 seq_printf(seq, ",cp=%llu", 511 seq_printf(seq, ",cp=%llu",
448 (unsigned long long int)sbi->s_snapshot_cno); 512 (unsigned long long int)sbi->s_snapshot_cno);
449 if (nilfs_test_opt(sbi, ERRORS_PANIC)) 513 if (nilfs_test_opt(sbi, ERRORS_PANIC))
450 seq_printf(seq, ",errors=panic"); 514 seq_puts(seq, ",errors=panic");
451 if (nilfs_test_opt(sbi, ERRORS_CONT)) 515 if (nilfs_test_opt(sbi, ERRORS_CONT))
452 seq_printf(seq, ",errors=continue"); 516 seq_puts(seq, ",errors=continue");
453 if (nilfs_test_opt(sbi, STRICT_ORDER)) 517 if (nilfs_test_opt(sbi, STRICT_ORDER))
454 seq_printf(seq, ",order=strict"); 518 seq_puts(seq, ",order=strict");
455 if (nilfs_test_opt(sbi, NORECOVERY)) 519 if (nilfs_test_opt(sbi, NORECOVERY))
456 seq_printf(seq, ",norecovery"); 520 seq_puts(seq, ",norecovery");
457 if (nilfs_test_opt(sbi, DISCARD)) 521 if (nilfs_test_opt(sbi, DISCARD))
458 seq_printf(seq, ",discard"); 522 seq_puts(seq, ",discard");
459 523
460 return 0; 524 return 0;
461} 525}
@@ -467,7 +531,7 @@ static const struct super_operations nilfs_sops = {
467 /* .write_inode = nilfs_write_inode, */ 531 /* .write_inode = nilfs_write_inode, */
468 /* .put_inode = nilfs_put_inode, */ 532 /* .put_inode = nilfs_put_inode, */
469 /* .drop_inode = nilfs_drop_inode, */ 533 /* .drop_inode = nilfs_drop_inode, */
470 .delete_inode = nilfs_delete_inode, 534 .evict_inode = nilfs_evict_inode,
471 .put_super = nilfs_put_super, 535 .put_super = nilfs_put_super,
472 /* .write_super = nilfs_write_super, */ 536 /* .write_super = nilfs_write_super, */
473 .sync_fs = nilfs_sync_fs, 537 .sync_fs = nilfs_sync_fs,
@@ -475,7 +539,6 @@ static const struct super_operations nilfs_sops = {
475 /* .unlockfs */ 539 /* .unlockfs */
476 .statfs = nilfs_statfs, 540 .statfs = nilfs_statfs,
477 .remount_fs = nilfs_remount, 541 .remount_fs = nilfs_remount,
478 .clear_inode = nilfs_clear_inode,
479 /* .umount_begin */ 542 /* .umount_begin */
480 .show_options = nilfs_show_options 543 .show_options = nilfs_show_options
481}; 544};
@@ -524,23 +587,25 @@ static const struct export_operations nilfs_export_ops = {
524 587
525enum { 588enum {
526 Opt_err_cont, Opt_err_panic, Opt_err_ro, 589 Opt_err_cont, Opt_err_panic, Opt_err_ro,
527 Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery, 590 Opt_barrier, Opt_nobarrier, Opt_snapshot, Opt_order, Opt_norecovery,
528 Opt_discard, Opt_err, 591 Opt_discard, Opt_nodiscard, Opt_err,
529}; 592};
530 593
531static match_table_t tokens = { 594static match_table_t tokens = {
532 {Opt_err_cont, "errors=continue"}, 595 {Opt_err_cont, "errors=continue"},
533 {Opt_err_panic, "errors=panic"}, 596 {Opt_err_panic, "errors=panic"},
534 {Opt_err_ro, "errors=remount-ro"}, 597 {Opt_err_ro, "errors=remount-ro"},
598 {Opt_barrier, "barrier"},
535 {Opt_nobarrier, "nobarrier"}, 599 {Opt_nobarrier, "nobarrier"},
536 {Opt_snapshot, "cp=%u"}, 600 {Opt_snapshot, "cp=%u"},
537 {Opt_order, "order=%s"}, 601 {Opt_order, "order=%s"},
538 {Opt_norecovery, "norecovery"}, 602 {Opt_norecovery, "norecovery"},
539 {Opt_discard, "discard"}, 603 {Opt_discard, "discard"},
604 {Opt_nodiscard, "nodiscard"},
540 {Opt_err, NULL} 605 {Opt_err, NULL}
541}; 606};
542 607
543static int parse_options(char *options, struct super_block *sb) 608static int parse_options(char *options, struct super_block *sb, int is_remount)
544{ 609{
545 struct nilfs_sb_info *sbi = NILFS_SB(sb); 610 struct nilfs_sb_info *sbi = NILFS_SB(sb);
546 char *p; 611 char *p;
@@ -557,6 +622,9 @@ static int parse_options(char *options, struct super_block *sb)
557 622
558 token = match_token(p, tokens, args); 623 token = match_token(p, tokens, args);
559 switch (token) { 624 switch (token) {
625 case Opt_barrier:
626 nilfs_set_opt(sbi, BARRIER);
627 break;
560 case Opt_nobarrier: 628 case Opt_nobarrier:
561 nilfs_clear_opt(sbi, BARRIER); 629 nilfs_clear_opt(sbi, BARRIER);
562 break; 630 break;
@@ -582,8 +650,26 @@ static int parse_options(char *options, struct super_block *sb)
582 case Opt_snapshot: 650 case Opt_snapshot:
583 if (match_int(&args[0], &option) || option <= 0) 651 if (match_int(&args[0], &option) || option <= 0)
584 return 0; 652 return 0;
585 if (!(sb->s_flags & MS_RDONLY)) 653 if (is_remount) {
654 if (!nilfs_test_opt(sbi, SNAPSHOT)) {
655 printk(KERN_ERR
656 "NILFS: cannot change regular "
657 "mount to snapshot.\n");
658 return 0;
659 } else if (option != sbi->s_snapshot_cno) {
660 printk(KERN_ERR
661 "NILFS: cannot remount to a "
662 "different snapshot.\n");
663 return 0;
664 }
665 break;
666 }
667 if (!(sb->s_flags & MS_RDONLY)) {
668 printk(KERN_ERR "NILFS: cannot mount snapshot "
669 "read/write. A read-only option is "
670 "required.\n");
586 return 0; 671 return 0;
672 }
587 sbi->s_snapshot_cno = option; 673 sbi->s_snapshot_cno = option;
588 nilfs_set_opt(sbi, SNAPSHOT); 674 nilfs_set_opt(sbi, SNAPSHOT);
589 break; 675 break;
@@ -593,6 +679,9 @@ static int parse_options(char *options, struct super_block *sb)
593 case Opt_discard: 679 case Opt_discard:
594 nilfs_set_opt(sbi, DISCARD); 680 nilfs_set_opt(sbi, DISCARD);
595 break; 681 break;
682 case Opt_nodiscard:
683 nilfs_clear_opt(sbi, DISCARD);
684 break;
596 default: 685 default:
597 printk(KERN_ERR 686 printk(KERN_ERR
598 "NILFS: Unrecognized mount option \"%s\"\n", p); 687 "NILFS: Unrecognized mount option \"%s\"\n", p);
@@ -613,11 +702,18 @@ nilfs_set_default_options(struct nilfs_sb_info *sbi,
613static int nilfs_setup_super(struct nilfs_sb_info *sbi) 702static int nilfs_setup_super(struct nilfs_sb_info *sbi)
614{ 703{
615 struct the_nilfs *nilfs = sbi->s_nilfs; 704 struct the_nilfs *nilfs = sbi->s_nilfs;
616 struct nilfs_super_block *sbp = nilfs->ns_sbp[0]; 705 struct nilfs_super_block **sbp;
617 int max_mnt_count = le16_to_cpu(sbp->s_max_mnt_count); 706 int max_mnt_count;
618 int mnt_count = le16_to_cpu(sbp->s_mnt_count); 707 int mnt_count;
708
709 /* nilfs->ns_sem must be locked by the caller. */
710 sbp = nilfs_prepare_super(sbi, 0);
711 if (!sbp)
712 return -EIO;
713
714 max_mnt_count = le16_to_cpu(sbp[0]->s_max_mnt_count);
715 mnt_count = le16_to_cpu(sbp[0]->s_mnt_count);
619 716
620 /* nilfs->sem must be locked by the caller. */
621 if (nilfs->ns_mount_state & NILFS_ERROR_FS) { 717 if (nilfs->ns_mount_state & NILFS_ERROR_FS) {
622 printk(KERN_WARNING 718 printk(KERN_WARNING
623 "NILFS warning: mounting fs with errors\n"); 719 "NILFS warning: mounting fs with errors\n");
@@ -628,12 +724,15 @@ static int nilfs_setup_super(struct nilfs_sb_info *sbi)
628#endif 724#endif
629 } 725 }
630 if (!max_mnt_count) 726 if (!max_mnt_count)
631 sbp->s_max_mnt_count = cpu_to_le16(NILFS_DFL_MAX_MNT_COUNT); 727 sbp[0]->s_max_mnt_count = cpu_to_le16(NILFS_DFL_MAX_MNT_COUNT);
632 728
633 sbp->s_mnt_count = cpu_to_le16(mnt_count + 1); 729 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); 730 sbp[0]->s_state =
635 sbp->s_mtime = cpu_to_le64(get_seconds()); 731 cpu_to_le16(le16_to_cpu(sbp[0]->s_state) & ~NILFS_VALID_FS);
636 return nilfs_commit_super(sbi, 1); 732 sbp[0]->s_mtime = cpu_to_le64(get_seconds());
733 /* synchronize sbp[1] with sbp[0] */
734 memcpy(sbp[1], sbp[0], nilfs->ns_sbsize);
735 return nilfs_commit_super(sbi, NILFS_SB_COMMIT_ALL);
637} 736}
638 737
639struct nilfs_super_block *nilfs_read_super_block(struct super_block *sb, 738struct nilfs_super_block *nilfs_read_super_block(struct super_block *sb,
@@ -670,7 +769,31 @@ int nilfs_store_magic_and_option(struct super_block *sb,
670 sbi->s_interval = le32_to_cpu(sbp->s_c_interval); 769 sbi->s_interval = le32_to_cpu(sbp->s_c_interval);
671 sbi->s_watermark = le32_to_cpu(sbp->s_c_block_max); 770 sbi->s_watermark = le32_to_cpu(sbp->s_c_block_max);
672 771
673 return !parse_options(data, sb) ? -EINVAL : 0 ; 772 return !parse_options(data, sb, 0) ? -EINVAL : 0 ;
773}
774
775int nilfs_check_feature_compatibility(struct super_block *sb,
776 struct nilfs_super_block *sbp)
777{
778 __u64 features;
779
780 features = le64_to_cpu(sbp->s_feature_incompat) &
781 ~NILFS_FEATURE_INCOMPAT_SUPP;
782 if (features) {
783 printk(KERN_ERR "NILFS: couldn't mount because of unsupported "
784 "optional features (%llx)\n",
785 (unsigned long long)features);
786 return -EINVAL;
787 }
788 features = le64_to_cpu(sbp->s_feature_compat_ro) &
789 ~NILFS_FEATURE_COMPAT_RO_SUPP;
790 if (!(sb->s_flags & MS_RDONLY) && features) {
791 printk(KERN_ERR "NILFS: couldn't mount RDWR because of "
792 "unsupported optional features (%llx)\n",
793 (unsigned long long)features);
794 return -EINVAL;
795 }
796 return 0;
674} 797}
675 798
676/** 799/**
@@ -819,7 +942,6 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent,
819static int nilfs_remount(struct super_block *sb, int *flags, char *data) 942static int nilfs_remount(struct super_block *sb, int *flags, char *data)
820{ 943{
821 struct nilfs_sb_info *sbi = NILFS_SB(sb); 944 struct nilfs_sb_info *sbi = NILFS_SB(sb);
822 struct nilfs_super_block *sbp;
823 struct the_nilfs *nilfs = sbi->s_nilfs; 945 struct the_nilfs *nilfs = sbi->s_nilfs;
824 unsigned long old_sb_flags; 946 unsigned long old_sb_flags;
825 struct nilfs_mount_options old_opts; 947 struct nilfs_mount_options old_opts;
@@ -833,32 +955,17 @@ static int nilfs_remount(struct super_block *sb, int *flags, char *data)
833 old_opts.snapshot_cno = sbi->s_snapshot_cno; 955 old_opts.snapshot_cno = sbi->s_snapshot_cno;
834 was_snapshot = nilfs_test_opt(sbi, SNAPSHOT); 956 was_snapshot = nilfs_test_opt(sbi, SNAPSHOT);
835 957
836 if (!parse_options(data, sb)) { 958 if (!parse_options(data, sb, 1)) {
837 err = -EINVAL; 959 err = -EINVAL;
838 goto restore_opts; 960 goto restore_opts;
839 } 961 }
840 sb->s_flags = (sb->s_flags & ~MS_POSIXACL); 962 sb->s_flags = (sb->s_flags & ~MS_POSIXACL);
841 963
842 err = -EINVAL; 964 err = -EINVAL;
843 if (was_snapshot) { 965 if (was_snapshot && !(*flags & MS_RDONLY)) {
844 if (!(*flags & MS_RDONLY)) { 966 printk(KERN_ERR "NILFS (device %s): cannot remount snapshot "
845 printk(KERN_ERR "NILFS (device %s): cannot remount " 967 "read/write.\n", sb->s_id);
846 "snapshot read/write.\n", 968 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 } 969 }
863 970
864 if (!nilfs_valid_fs(nilfs)) { 971 if (!nilfs_valid_fs(nilfs)) {
@@ -880,19 +987,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. 987 * the RDONLY flag and then mark the partition as valid again.
881 */ 988 */
882 down_write(&nilfs->ns_sem); 989 down_write(&nilfs->ns_sem);
883 sbp = nilfs->ns_sbp[0]; 990 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); 991 up_write(&nilfs->ns_sem);
890 } else { 992 } else {
993 __u64 features;
994
891 /* 995 /*
892 * Mounting a RDONLY partition read-write, so reread and 996 * Mounting a RDONLY partition read-write, so reread and
893 * store the current valid flag. (It may have been changed 997 * store the current valid flag. (It may have been changed
894 * by fsck since we originally mounted the partition.) 998 * by fsck since we originally mounted the partition.)
895 */ 999 */
1000 down_read(&nilfs->ns_sem);
1001 features = le64_to_cpu(nilfs->ns_sbp[0]->s_feature_compat_ro) &
1002 ~NILFS_FEATURE_COMPAT_RO_SUPP;
1003 up_read(&nilfs->ns_sem);
1004 if (features) {
1005 printk(KERN_WARNING "NILFS (device %s): couldn't "
1006 "remount RDWR because of unsupported optional "
1007 "features (%llx)\n",
1008 sb->s_id, (unsigned long long)features);
1009 err = -EROFS;
1010 goto restore_opts;
1011 }
1012
896 sb->s_flags &= ~MS_RDONLY; 1013 sb->s_flags &= ~MS_RDONLY;
897 1014
898 err = nilfs_attach_segment_constructor(sbi); 1015 err = nilfs_attach_segment_constructor(sbi);
@@ -1119,7 +1236,7 @@ static void nilfs_inode_init_once(void *obj)
1119 init_rwsem(&ii->xattr_sem); 1236 init_rwsem(&ii->xattr_sem);
1120#endif 1237#endif
1121 nilfs_btnode_cache_init_once(&ii->i_btnode_cache); 1238 nilfs_btnode_cache_init_once(&ii->i_btnode_cache);
1122 ii->i_bmap = (struct nilfs_bmap *)&ii->i_bmap_union; 1239 ii->i_bmap = &ii->i_bmap_data;
1123 inode_init_once(&ii->vfs_inode); 1240 inode_init_once(&ii->vfs_inode);
1124} 1241}
1125 1242