aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2010-09-04 23:20:59 -0400
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2010-10-22 20:24:38 -0400
commitf1e89c86fdd0f5e59f6768146c86437934202033 (patch)
treec5ba8766a3a029f0c10d6d0d09a57a7e28b7a51b /fs/nilfs2
parentc1c1d7092072093ad960db2f6c08f06705c57fa4 (diff)
nilfs2: use iget for all metadata files
This makes use of iget5_locked to allocate or get inode for metadata files to stop using own inode allocator. Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Diffstat (limited to 'fs/nilfs2')
-rw-r--r--fs/nilfs2/cpfile.c49
-rw-r--r--fs/nilfs2/cpfile.h4
-rw-r--r--fs/nilfs2/dat.c61
-rw-r--r--fs/nilfs2/dat.h4
-rw-r--r--fs/nilfs2/ifile.c51
-rw-r--r--fs/nilfs2/ifile.h4
-rw-r--r--fs/nilfs2/inode.c13
-rw-r--r--fs/nilfs2/mdt.c16
-rw-r--r--fs/nilfs2/mdt.h3
-rw-r--r--fs/nilfs2/nilfs.h2
-rw-r--r--fs/nilfs2/sufile.c73
-rw-r--r--fs/nilfs2/sufile.h4
-rw-r--r--fs/nilfs2/super.c21
-rw-r--r--fs/nilfs2/the_nilfs.c58
14 files changed, 207 insertions, 156 deletions
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c
index 18737818db6..03de1da8795 100644
--- a/fs/nilfs2/cpfile.c
+++ b/fs/nilfs2/cpfile.c
@@ -933,27 +933,40 @@ int nilfs_cpfile_get_stat(struct inode *cpfile, struct nilfs_cpstat *cpstat)
933} 933}
934 934
935/** 935/**
936 * nilfs_cpfile_read - read cpfile inode 936 * nilfs_cpfile_read - read or get cpfile inode
937 * @cpfile: cpfile inode 937 * @sb: super block instance
938 * @raw_inode: on-disk cpfile inode
939 */
940int nilfs_cpfile_read(struct inode *cpfile, struct nilfs_inode *raw_inode)
941{
942 return nilfs_read_inode_common(cpfile, raw_inode);
943}
944
945/**
946 * nilfs_cpfile_new - create cpfile
947 * @nilfs: nilfs object
948 * @cpsize: size of a checkpoint entry 938 * @cpsize: size of a checkpoint entry
939 * @raw_inode: on-disk cpfile inode
940 * @inodep: buffer to store the inode
949 */ 941 */
950struct inode *nilfs_cpfile_new(struct the_nilfs *nilfs, size_t cpsize) 942int nilfs_cpfile_read(struct super_block *sb, size_t cpsize,
943 struct nilfs_inode *raw_inode, struct inode **inodep)
951{ 944{
952 struct inode *cpfile; 945 struct inode *cpfile;
946 int err;
953 947
954 cpfile = nilfs_mdt_new(nilfs, NULL, NILFS_CPFILE_INO, 0); 948 cpfile = nilfs_iget_locked(sb, NULL, NILFS_CPFILE_INO);
955 if (cpfile) 949 if (unlikely(!cpfile))
956 nilfs_mdt_set_entry_size(cpfile, cpsize, 950 return -ENOMEM;
957 sizeof(struct nilfs_cpfile_header)); 951 if (!(cpfile->i_state & I_NEW))
958 return cpfile; 952 goto out;
953
954 err = nilfs_mdt_init(cpfile, NILFS_MDT_GFP, 0);
955 if (err)
956 goto failed;
957
958 nilfs_mdt_set_entry_size(cpfile, cpsize,
959 sizeof(struct nilfs_cpfile_header));
960
961 err = nilfs_read_inode_common(cpfile, raw_inode);
962 if (err)
963 goto failed;
964
965 unlock_new_inode(cpfile);
966 out:
967 *inodep = cpfile;
968 return 0;
969 failed:
970 iget_failed(cpfile);
971 return err;
959} 972}
diff --git a/fs/nilfs2/cpfile.h b/fs/nilfs2/cpfile.h
index bc0809e0ab4..a242b9a314f 100644
--- a/fs/nilfs2/cpfile.h
+++ b/fs/nilfs2/cpfile.h
@@ -40,7 +40,7 @@ int nilfs_cpfile_get_stat(struct inode *, struct nilfs_cpstat *);
40ssize_t nilfs_cpfile_get_cpinfo(struct inode *, __u64 *, int, void *, unsigned, 40ssize_t nilfs_cpfile_get_cpinfo(struct inode *, __u64 *, int, void *, unsigned,
41 size_t); 41 size_t);
42 42
43int nilfs_cpfile_read(struct inode *cpfile, struct nilfs_inode *raw_inode); 43int nilfs_cpfile_read(struct super_block *sb, size_t cpsize,
44struct inode *nilfs_cpfile_new(struct the_nilfs *nilfs, size_t cpsize); 44 struct nilfs_inode *raw_inode, struct inode **inodep);
45 45
46#endif /* _NILFS_CPFILE_H */ 46#endif /* _NILFS_CPFILE_H */
diff --git a/fs/nilfs2/dat.c b/fs/nilfs2/dat.c
index 7091c4e0f04..ab04a68f425 100644
--- a/fs/nilfs2/dat.c
+++ b/fs/nilfs2/dat.c
@@ -463,39 +463,48 @@ ssize_t nilfs_dat_get_vinfo(struct inode *dat, void *buf, unsigned visz,
463} 463}
464 464
465/** 465/**
466 * nilfs_dat_read - read dat inode 466 * nilfs_dat_read - read or get dat inode
467 * @dat: dat inode 467 * @sb: super block instance
468 * @raw_inode: on-disk dat inode
469 */
470int nilfs_dat_read(struct inode *dat, struct nilfs_inode *raw_inode)
471{
472 return nilfs_read_inode_common(dat, raw_inode);
473}
474
475/**
476 * nilfs_dat_new - create dat file
477 * @nilfs: nilfs object
478 * @entry_size: size of a dat entry 468 * @entry_size: size of a dat entry
469 * @raw_inode: on-disk dat inode
470 * @inodep: buffer to store the inode
479 */ 471 */
480struct inode *nilfs_dat_new(struct the_nilfs *nilfs, size_t entry_size) 472int nilfs_dat_read(struct super_block *sb, size_t entry_size,
473 struct nilfs_inode *raw_inode, struct inode **inodep)
481{ 474{
482 static struct lock_class_key dat_lock_key; 475 static struct lock_class_key dat_lock_key;
483 struct inode *dat; 476 struct inode *dat;
484 struct nilfs_dat_info *di; 477 struct nilfs_dat_info *di;
485 int err; 478 int err;
486 479
487 dat = nilfs_mdt_new(nilfs, NULL, NILFS_DAT_INO, sizeof(*di)); 480 dat = nilfs_iget_locked(sb, NULL, NILFS_DAT_INO);
488 if (dat) { 481 if (unlikely(!dat))
489 err = nilfs_palloc_init_blockgroup(dat, entry_size); 482 return -ENOMEM;
490 if (unlikely(err)) { 483 if (!(dat->i_state & I_NEW))
491 nilfs_mdt_destroy(dat); 484 goto out;
492 return NULL;
493 }
494 485
495 di = NILFS_DAT_I(dat); 486 err = nilfs_mdt_init(dat, NILFS_MDT_GFP, sizeof(*di));
496 lockdep_set_class(&di->mi.mi_sem, &dat_lock_key); 487 if (err)
497 nilfs_palloc_setup_cache(dat, &di->palloc_cache); 488 goto failed;
498 nilfs_mdt_setup_shadow_map(dat, &di->shadow); 489
499 } 490 err = nilfs_palloc_init_blockgroup(dat, entry_size);
500 return dat; 491 if (err)
492 goto failed;
493
494 di = NILFS_DAT_I(dat);
495 lockdep_set_class(&di->mi.mi_sem, &dat_lock_key);
496 nilfs_palloc_setup_cache(dat, &di->palloc_cache);
497 nilfs_mdt_setup_shadow_map(dat, &di->shadow);
498
499 err = nilfs_read_inode_common(dat, raw_inode);
500 if (err)
501 goto failed;
502
503 unlock_new_inode(dat);
504 out:
505 *inodep = dat;
506 return 0;
507 failed:
508 iget_failed(dat);
509 return err;
501} 510}
diff --git a/fs/nilfs2/dat.h b/fs/nilfs2/dat.h
index d31c3aab0ef..cbd8e973250 100644
--- a/fs/nilfs2/dat.h
+++ b/fs/nilfs2/dat.h
@@ -53,7 +53,7 @@ int nilfs_dat_freev(struct inode *, __u64 *, size_t);
53int nilfs_dat_move(struct inode *, __u64, sector_t); 53int nilfs_dat_move(struct inode *, __u64, sector_t);
54ssize_t nilfs_dat_get_vinfo(struct inode *, void *, unsigned, size_t); 54ssize_t nilfs_dat_get_vinfo(struct inode *, void *, unsigned, size_t);
55 55
56int nilfs_dat_read(struct inode *dat, struct nilfs_inode *raw_inode); 56int nilfs_dat_read(struct super_block *sb, size_t entry_size,
57struct inode *nilfs_dat_new(struct the_nilfs *nilfs, size_t entry_size); 57 struct nilfs_inode *raw_inode, struct inode **inodep);
58 58
59#endif /* _NILFS_DAT_H */ 59#endif /* _NILFS_DAT_H */
diff --git a/fs/nilfs2/ifile.c b/fs/nilfs2/ifile.c
index 922d9dd42c8..9f8a2da67f9 100644
--- a/fs/nilfs2/ifile.c
+++ b/fs/nilfs2/ifile.c
@@ -161,25 +161,46 @@ int nilfs_ifile_get_inode_block(struct inode *ifile, ino_t ino,
161} 161}
162 162
163/** 163/**
164 * nilfs_ifile_new - create inode file 164 * nilfs_ifile_read - read or get ifile inode
165 * @sbi: nilfs_sb_info struct 165 * @sb: super block instance
166 * @root: root object
166 * @inode_size: size of an inode 167 * @inode_size: size of an inode
168 * @raw_inode: on-disk ifile inode
169 * @inodep: buffer to store the inode
167 */ 170 */
168struct inode *nilfs_ifile_new(struct nilfs_sb_info *sbi, size_t inode_size) 171int nilfs_ifile_read(struct super_block *sb, struct nilfs_root *root,
172 size_t inode_size, struct nilfs_inode *raw_inode,
173 struct inode **inodep)
169{ 174{
170 struct inode *ifile; 175 struct inode *ifile;
171 int err; 176 int err;
172 177
173 ifile = nilfs_mdt_new(sbi->s_nilfs, sbi->s_super, NILFS_IFILE_INO, 178 ifile = nilfs_iget_locked(sb, root, NILFS_IFILE_INO);
174 sizeof(struct nilfs_ifile_info)); 179 if (unlikely(!ifile))
175 if (ifile) { 180 return -ENOMEM;
176 err = nilfs_palloc_init_blockgroup(ifile, inode_size); 181 if (!(ifile->i_state & I_NEW))
177 if (unlikely(err)) { 182 goto out;
178 nilfs_mdt_destroy(ifile); 183
179 return NULL; 184 err = nilfs_mdt_init(ifile, NILFS_MDT_GFP,
180 } 185 sizeof(struct nilfs_ifile_info));
181 nilfs_palloc_setup_cache(ifile, 186 if (err)
182 &NILFS_IFILE_I(ifile)->palloc_cache); 187 goto failed;
183 } 188
184 return ifile; 189 err = nilfs_palloc_init_blockgroup(ifile, inode_size);
190 if (err)
191 goto failed;
192
193 nilfs_palloc_setup_cache(ifile, &NILFS_IFILE_I(ifile)->palloc_cache);
194
195 err = nilfs_read_inode_common(ifile, raw_inode);
196 if (err)
197 goto failed;
198
199 unlock_new_inode(ifile);
200 out:
201 *inodep = ifile;
202 return 0;
203 failed:
204 iget_failed(ifile);
205 return err;
185} 206}
diff --git a/fs/nilfs2/ifile.h b/fs/nilfs2/ifile.h
index cbca32e498f..59b6f2b51df 100644
--- a/fs/nilfs2/ifile.h
+++ b/fs/nilfs2/ifile.h
@@ -49,6 +49,8 @@ int nilfs_ifile_create_inode(struct inode *, ino_t *, struct buffer_head **);
49int nilfs_ifile_delete_inode(struct inode *, ino_t); 49int nilfs_ifile_delete_inode(struct inode *, ino_t);
50int nilfs_ifile_get_inode_block(struct inode *, ino_t, struct buffer_head **); 50int nilfs_ifile_get_inode_block(struct inode *, ino_t, struct buffer_head **);
51 51
52struct inode *nilfs_ifile_new(struct nilfs_sb_info *sbi, size_t inode_size); 52int nilfs_ifile_read(struct super_block *sb, struct nilfs_root *root,
53 size_t inode_size, struct nilfs_inode *raw_inode,
54 struct inode **inodep);
53 55
54#endif /* _NILFS_IFILE_H */ 56#endif /* _NILFS_IFILE_H */
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c
index 5485dd12da6..5b3d43fb4e1 100644
--- a/fs/nilfs2/inode.c
+++ b/fs/nilfs2/inode.c
@@ -506,16 +506,23 @@ static int nilfs_iget_set(struct inode *inode, void *opaque)
506 return 0; 506 return 0;
507} 507}
508 508
509struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, 509struct inode *nilfs_iget_locked(struct super_block *sb, struct nilfs_root *root,
510 unsigned long ino) 510 unsigned long ino)
511{ 511{
512 struct nilfs_iget_args args = { 512 struct nilfs_iget_args args = {
513 .ino = ino, .root = root, .cno = 0, .for_gc = 0 513 .ino = ino, .root = root, .cno = 0, .for_gc = 0
514 }; 514 };
515
516 return iget5_locked(sb, ino, nilfs_iget_test, nilfs_iget_set, &args);
517}
518
519struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root,
520 unsigned long ino)
521{
515 struct inode *inode; 522 struct inode *inode;
516 int err; 523 int err;
517 524
518 inode = iget5_locked(sb, ino, nilfs_iget_test, nilfs_iget_set, &args); 525 inode = nilfs_iget_locked(sb, root, ino);
519 if (unlikely(!inode)) 526 if (unlikely(!inode))
520 return ERR_PTR(-ENOMEM); 527 return ERR_PTR(-ENOMEM);
521 if (!(inode->i_state & I_NEW)) 528 if (!(inode->i_state & I_NEW))
diff --git a/fs/nilfs2/mdt.c b/fs/nilfs2/mdt.c
index 3bbd340a513..44326cfe1fa 100644
--- a/fs/nilfs2/mdt.c
+++ b/fs/nilfs2/mdt.c
@@ -444,8 +444,7 @@ static const struct inode_operations def_mdt_iops;
444static const struct file_operations def_mdt_fops; 444static const struct file_operations def_mdt_fops;
445 445
446 446
447int nilfs_mdt_init(struct inode *inode, struct the_nilfs *nilfs, 447int nilfs_mdt_init(struct inode *inode, gfp_t gfp_mask, size_t objsz)
448 gfp_t gfp_mask, size_t objsz)
449{ 448{
450 struct nilfs_mdt_info *mi; 449 struct nilfs_mdt_info *mi;
451 450
@@ -453,13 +452,17 @@ int nilfs_mdt_init(struct inode *inode, struct the_nilfs *nilfs,
453 if (!mi) 452 if (!mi)
454 return -ENOMEM; 453 return -ENOMEM;
455 454
456 mi->mi_nilfs = nilfs; 455 mi->mi_nilfs = NILFS_I_NILFS(inode);
457 init_rwsem(&mi->mi_sem); 456 init_rwsem(&mi->mi_sem);
458 inode->i_private = mi; 457 inode->i_private = mi;
459 458
460 inode->i_mode = S_IFREG; 459 inode->i_mode = S_IFREG;
461 mapping_set_gfp_mask(inode->i_mapping, gfp_mask); 460 mapping_set_gfp_mask(inode->i_mapping, gfp_mask);
462 inode->i_mapping->backing_dev_info = nilfs->ns_bdi; 461 inode->i_mapping->backing_dev_info = inode->i_sb->s_bdi;
462
463 inode->i_op = &def_mdt_iops;
464 inode->i_fop = &def_mdt_fops;
465 inode->i_mapping->a_ops = &def_mdt_aops;
463 466
464 return 0; 467 return 0;
465} 468}
@@ -544,13 +547,10 @@ struct inode *nilfs_mdt_new(struct the_nilfs *nilfs, struct super_block *sb,
544 if (!inode) 547 if (!inode)
545 return NULL; 548 return NULL;
546 549
547 if (nilfs_mdt_init(inode, nilfs, NILFS_MDT_GFP, objsz) < 0) { 550 if (nilfs_mdt_init(inode, NILFS_MDT_GFP, objsz) < 0) {
548 nilfs_destroy_inode(inode); 551 nilfs_destroy_inode(inode);
549 return NULL; 552 return NULL;
550 } 553 }
551 inode->i_op = &def_mdt_iops;
552 inode->i_fop = &def_mdt_fops;
553 inode->i_mapping->a_ops = &def_mdt_aops;
554 return inode; 554 return inode;
555} 555}
556 556
diff --git a/fs/nilfs2/mdt.h b/fs/nilfs2/mdt.h
index 1e0901c3fd6..73ff7c05571 100644
--- a/fs/nilfs2/mdt.h
+++ b/fs/nilfs2/mdt.h
@@ -85,8 +85,7 @@ int nilfs_mdt_forget_block(struct inode *, unsigned long);
85int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long); 85int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long);
86int nilfs_mdt_fetch_dirty(struct inode *); 86int nilfs_mdt_fetch_dirty(struct inode *);
87 87
88int nilfs_mdt_init(struct inode *inode, struct the_nilfs *nilfs, 88int nilfs_mdt_init(struct inode *inode, gfp_t gfp_mask, size_t objsz);
89 gfp_t gfp_mask, size_t objsz);
90struct inode *nilfs_mdt_new(struct the_nilfs *, struct super_block *, ino_t, 89struct inode *nilfs_mdt_new(struct the_nilfs *, struct super_block *, ino_t,
91 size_t); 90 size_t);
92struct inode *nilfs_mdt_new_common(struct the_nilfs *, struct super_block *, 91struct inode *nilfs_mdt_new_common(struct the_nilfs *, struct super_block *,
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h
index e9f457951e3..2ca2ca5ca84 100644
--- a/fs/nilfs2/nilfs.h
+++ b/fs/nilfs2/nilfs.h
@@ -244,6 +244,8 @@ extern int nilfs_get_block(struct inode *, sector_t, struct buffer_head *, int);
244extern void nilfs_set_inode_flags(struct inode *); 244extern void nilfs_set_inode_flags(struct inode *);
245extern int nilfs_read_inode_common(struct inode *, struct nilfs_inode *); 245extern int nilfs_read_inode_common(struct inode *, struct nilfs_inode *);
246extern void nilfs_write_inode_common(struct inode *, struct nilfs_inode *, int); 246extern void nilfs_write_inode_common(struct inode *, struct nilfs_inode *, int);
247struct inode *nilfs_iget_locked(struct super_block *sb, struct nilfs_root *root,
248 unsigned long ino);
247struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, 249struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root,
248 unsigned long ino); 250 unsigned long ino);
249extern struct inode *nilfs_iget_for_gc(struct super_block *sb, 251extern struct inode *nilfs_iget_for_gc(struct super_block *sb,
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c
index 3c6cc6005c2..599d9c27761 100644
--- a/fs/nilfs2/sufile.c
+++ b/fs/nilfs2/sufile.c
@@ -635,46 +635,55 @@ ssize_t nilfs_sufile_get_suinfo(struct inode *sufile, __u64 segnum, void *buf,
635} 635}
636 636
637/** 637/**
638 * nilfs_sufile_read - read sufile inode 638 * nilfs_sufile_read - read or get sufile inode
639 * @sufile: sufile inode 639 * @sb: super block instance
640 * @susize: size of a segment usage entry
640 * @raw_inode: on-disk sufile inode 641 * @raw_inode: on-disk sufile inode
642 * @inodep: buffer to store the inode
641 */ 643 */
642int nilfs_sufile_read(struct inode *sufile, struct nilfs_inode *raw_inode) 644int nilfs_sufile_read(struct super_block *sb, size_t susize,
645 struct nilfs_inode *raw_inode, struct inode **inodep)
643{ 646{
644 struct nilfs_sufile_info *sui = NILFS_SUI(sufile); 647 struct inode *sufile;
648 struct nilfs_sufile_info *sui;
645 struct buffer_head *header_bh; 649 struct buffer_head *header_bh;
646 struct nilfs_sufile_header *header; 650 struct nilfs_sufile_header *header;
647 void *kaddr; 651 void *kaddr;
648 int ret; 652 int err;
649 653
650 ret = nilfs_read_inode_common(sufile, raw_inode); 654 sufile = nilfs_iget_locked(sb, NULL, NILFS_SUFILE_INO);
651 if (ret < 0) 655 if (unlikely(!sufile))
652 return ret; 656 return -ENOMEM;
657 if (!(sufile->i_state & I_NEW))
658 goto out;
653 659
654 ret = nilfs_sufile_get_header_block(sufile, &header_bh); 660 err = nilfs_mdt_init(sufile, NILFS_MDT_GFP, sizeof(*sui));
655 if (!ret) { 661 if (err)
656 kaddr = kmap_atomic(header_bh->b_page, KM_USER0); 662 goto failed;
657 header = kaddr + bh_offset(header_bh);
658 sui->ncleansegs = le64_to_cpu(header->sh_ncleansegs);
659 kunmap_atomic(kaddr, KM_USER0);
660 brelse(header_bh);
661 }
662 return ret;
663}
664 663
665/** 664 nilfs_mdt_set_entry_size(sufile, susize,
666 * nilfs_sufile_new - create sufile 665 sizeof(struct nilfs_sufile_header));
667 * @nilfs: nilfs object 666
668 * @susize: size of a segment usage entry 667 err = nilfs_read_inode_common(sufile, raw_inode);
669 */ 668 if (err)
670struct inode *nilfs_sufile_new(struct the_nilfs *nilfs, size_t susize) 669 goto failed;
671{ 670
672 struct inode *sufile; 671 err = nilfs_sufile_get_header_block(sufile, &header_bh);
672 if (err)
673 goto failed;
673 674
674 sufile = nilfs_mdt_new(nilfs, NULL, NILFS_SUFILE_INO, 675 sui = NILFS_SUI(sufile);
675 sizeof(struct nilfs_sufile_info)); 676 kaddr = kmap_atomic(header_bh->b_page, KM_USER0);
676 if (sufile) 677 header = kaddr + bh_offset(header_bh);
677 nilfs_mdt_set_entry_size(sufile, susize, 678 sui->ncleansegs = le64_to_cpu(header->sh_ncleansegs);
678 sizeof(struct nilfs_sufile_header)); 679 kunmap_atomic(kaddr, KM_USER0);
679 return sufile; 680 brelse(header_bh);
681
682 unlock_new_inode(sufile);
683 out:
684 *inodep = sufile;
685 return 0;
686 failed:
687 iget_failed(sufile);
688 return err;
680} 689}
diff --git a/fs/nilfs2/sufile.h b/fs/nilfs2/sufile.h
index 15163b8aff7..203f6102a62 100644
--- a/fs/nilfs2/sufile.h
+++ b/fs/nilfs2/sufile.h
@@ -61,8 +61,8 @@ void nilfs_sufile_do_cancel_free(struct inode *, __u64, struct buffer_head *,
61void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *, 61void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *,
62 struct buffer_head *); 62 struct buffer_head *);
63 63
64int nilfs_sufile_read(struct inode *sufile, struct nilfs_inode *raw_inode); 64int nilfs_sufile_read(struct super_block *sb, size_t susize,
65struct inode *nilfs_sufile_new(struct the_nilfs *nilfs, size_t susize); 65 struct nilfs_inode *raw_inode, struct inode **inodep);
66 66
67/** 67/**
68 * nilfs_sufile_scrap - make a segment garbage 68 * nilfs_sufile_scrap - make a segment garbage
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 5893cb27c90..39e7d7f8eda 100644
--- a/fs/nilfs2/super.c
+++ b/fs/nilfs2/super.c
@@ -356,6 +356,10 @@ static void nilfs_put_super(struct super_block *sb)
356 up_write(&nilfs->ns_sem); 356 up_write(&nilfs->ns_sem);
357 } 357 }
358 358
359 iput(nilfs->ns_sufile);
360 iput(nilfs->ns_cpfile);
361 iput(nilfs->ns_dat);
362
359 destroy_nilfs(nilfs); 363 destroy_nilfs(nilfs);
360 sbi->s_super = NULL; 364 sbi->s_super = NULL;
361 sb->s_fs_info = NULL; 365 sb->s_fs_info = NULL;
@@ -403,10 +407,6 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt,
403 if (root->ifile) 407 if (root->ifile)
404 goto reuse; /* already attached checkpoint */ 408 goto reuse; /* already attached checkpoint */
405 409
406 root->ifile = nilfs_ifile_new(sbi, nilfs->ns_inode_size);
407 if (!root->ifile)
408 goto failed;
409
410 down_read(&nilfs->ns_segctor_sem); 410 down_read(&nilfs->ns_segctor_sem);
411 err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp, 411 err = nilfs_cpfile_get_checkpoint(nilfs->ns_cpfile, cno, 0, &raw_cp,
412 &bh_cp); 412 &bh_cp);
@@ -421,8 +421,10 @@ int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt,
421 } 421 }
422 goto failed; 422 goto failed;
423 } 423 }
424 err = nilfs_read_inode_common(root->ifile, &raw_cp->cp_ifile_inode); 424
425 if (unlikely(err)) 425 err = nilfs_ifile_read(sbi->s_super, root, nilfs->ns_inode_size,
426 &raw_cp->cp_ifile_inode, &root->ifile);
427 if (err)
426 goto failed_bh; 428 goto failed_bh;
427 429
428 atomic_set(&root->inodes_count, le64_to_cpu(raw_cp->cp_inodes_count)); 430 atomic_set(&root->inodes_count, le64_to_cpu(raw_cp->cp_inodes_count));
@@ -895,7 +897,7 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent)
895 if (err) { 897 if (err) {
896 printk(KERN_ERR "NILFS: error loading last checkpoint " 898 printk(KERN_ERR "NILFS: error loading last checkpoint "
897 "(checkpoint number=%llu).\n", (unsigned long long)cno); 899 "(checkpoint number=%llu).\n", (unsigned long long)cno);
898 goto failed_nilfs; 900 goto failed_unload;
899 } 901 }
900 902
901 if (!(sb->s_flags & MS_RDONLY)) { 903 if (!(sb->s_flags & MS_RDONLY)) {
@@ -924,6 +926,11 @@ nilfs_fill_super(struct super_block *sb, void *data, int silent)
924 failed_checkpoint: 926 failed_checkpoint:
925 nilfs_put_root(fsroot); 927 nilfs_put_root(fsroot);
926 928
929 failed_unload:
930 iput(nilfs->ns_sufile);
931 iput(nilfs->ns_cpfile);
932 iput(nilfs->ns_dat);
933
927 failed_nilfs: 934 failed_nilfs:
928 destroy_nilfs(nilfs); 935 destroy_nilfs(nilfs);
929 936
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c
index b7666bc0425..4d6763e28eb 100644
--- a/fs/nilfs2/the_nilfs.c
+++ b/fs/nilfs2/the_nilfs.c
@@ -92,11 +92,6 @@ struct the_nilfs *alloc_nilfs(struct block_device *bdev)
92void destroy_nilfs(struct the_nilfs *nilfs) 92void destroy_nilfs(struct the_nilfs *nilfs)
93{ 93{
94 might_sleep(); 94 might_sleep();
95 if (nilfs_loaded(nilfs)) {
96 nilfs_mdt_destroy(nilfs->ns_sufile);
97 nilfs_mdt_destroy(nilfs->ns_cpfile);
98 nilfs_mdt_destroy(nilfs->ns_dat);
99 }
100 if (nilfs_init(nilfs)) { 95 if (nilfs_init(nilfs)) {
101 brelse(nilfs->ns_sbh[0]); 96 brelse(nilfs->ns_sbh[0]);
102 brelse(nilfs->ns_sbh[1]); 97 brelse(nilfs->ns_sbh[1]);
@@ -104,11 +99,13 @@ void destroy_nilfs(struct the_nilfs *nilfs)
104 kfree(nilfs); 99 kfree(nilfs);
105} 100}
106 101
107static int nilfs_load_super_root(struct the_nilfs *nilfs, sector_t sr_block) 102static int nilfs_load_super_root(struct the_nilfs *nilfs,
103 struct super_block *sb, sector_t sr_block)
108{ 104{
109 struct buffer_head *bh_sr; 105 struct buffer_head *bh_sr;
110 struct nilfs_super_root *raw_sr; 106 struct nilfs_super_root *raw_sr;
111 struct nilfs_super_block **sbp = nilfs->ns_sbp; 107 struct nilfs_super_block **sbp = nilfs->ns_sbp;
108 struct nilfs_inode *rawi;
112 unsigned dat_entry_size, segment_usage_size, checkpoint_size; 109 unsigned dat_entry_size, segment_usage_size, checkpoint_size;
113 unsigned inode_size; 110 unsigned inode_size;
114 int err; 111 int err;
@@ -125,34 +122,22 @@ static int nilfs_load_super_root(struct the_nilfs *nilfs, sector_t sr_block)
125 122
126 inode_size = nilfs->ns_inode_size; 123 inode_size = nilfs->ns_inode_size;
127 124
128 err = -ENOMEM; 125 rawi = (void *)bh_sr->b_data + NILFS_SR_DAT_OFFSET(inode_size);
129 nilfs->ns_dat = nilfs_dat_new(nilfs, dat_entry_size); 126 err = nilfs_dat_read(sb, dat_entry_size, rawi, &nilfs->ns_dat);
130 if (unlikely(!nilfs->ns_dat)) 127 if (err)
131 goto failed; 128 goto failed;
132 129
133 nilfs->ns_cpfile = nilfs_cpfile_new(nilfs, checkpoint_size); 130 rawi = (void *)bh_sr->b_data + NILFS_SR_CPFILE_OFFSET(inode_size);
134 if (unlikely(!nilfs->ns_cpfile)) 131 err = nilfs_cpfile_read(sb, checkpoint_size, rawi, &nilfs->ns_cpfile);
132 if (err)
135 goto failed_dat; 133 goto failed_dat;
136 134
137 nilfs->ns_sufile = nilfs_sufile_new(nilfs, segment_usage_size); 135 rawi = (void *)bh_sr->b_data + NILFS_SR_SUFILE_OFFSET(inode_size);
138 if (unlikely(!nilfs->ns_sufile)) 136 err = nilfs_sufile_read(sb, segment_usage_size, rawi,
137 &nilfs->ns_sufile);
138 if (err)
139 goto failed_cpfile; 139 goto failed_cpfile;
140 140
141 err = nilfs_dat_read(nilfs->ns_dat, (void *)bh_sr->b_data +
142 NILFS_SR_DAT_OFFSET(inode_size));
143 if (unlikely(err))
144 goto failed_sufile;
145
146 err = nilfs_cpfile_read(nilfs->ns_cpfile, (void *)bh_sr->b_data +
147 NILFS_SR_CPFILE_OFFSET(inode_size));
148 if (unlikely(err))
149 goto failed_sufile;
150
151 err = nilfs_sufile_read(nilfs->ns_sufile, (void *)bh_sr->b_data +
152 NILFS_SR_SUFILE_OFFSET(inode_size));
153 if (unlikely(err))
154 goto failed_sufile;
155
156 raw_sr = (struct nilfs_super_root *)bh_sr->b_data; 141 raw_sr = (struct nilfs_super_root *)bh_sr->b_data;
157 nilfs->ns_nongc_ctime = le64_to_cpu(raw_sr->sr_nongc_ctime); 142 nilfs->ns_nongc_ctime = le64_to_cpu(raw_sr->sr_nongc_ctime);
158 143
@@ -160,14 +145,11 @@ static int nilfs_load_super_root(struct the_nilfs *nilfs, sector_t sr_block)
160 brelse(bh_sr); 145 brelse(bh_sr);
161 return err; 146 return err;
162 147
163 failed_sufile:
164 nilfs_mdt_destroy(nilfs->ns_sufile);
165
166 failed_cpfile: 148 failed_cpfile:
167 nilfs_mdt_destroy(nilfs->ns_cpfile); 149 iput(nilfs->ns_cpfile);
168 150
169 failed_dat: 151 failed_dat:
170 nilfs_mdt_destroy(nilfs->ns_dat); 152 iput(nilfs->ns_dat);
171 goto failed; 153 goto failed;
172} 154}
173 155
@@ -290,7 +272,7 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
290 goto scan_error; 272 goto scan_error;
291 } 273 }
292 274
293 err = nilfs_load_super_root(nilfs, ri.ri_super_root); 275 err = nilfs_load_super_root(nilfs, sbi->s_super, ri.ri_super_root);
294 if (unlikely(err)) { 276 if (unlikely(err)) {
295 printk(KERN_ERR "NILFS: error loading super root.\n"); 277 printk(KERN_ERR "NILFS: error loading super root.\n");
296 goto failed; 278 goto failed;
@@ -358,9 +340,9 @@ int load_nilfs(struct the_nilfs *nilfs, struct nilfs_sb_info *sbi)
358 goto failed; 340 goto failed;
359 341
360 failed_unload: 342 failed_unload:
361 nilfs_mdt_destroy(nilfs->ns_cpfile); 343 iput(nilfs->ns_cpfile);
362 nilfs_mdt_destroy(nilfs->ns_sufile); 344 iput(nilfs->ns_sufile);
363 nilfs_mdt_destroy(nilfs->ns_dat); 345 iput(nilfs->ns_dat);
364 346
365 failed: 347 failed:
366 nilfs_clear_recovery_info(&ri); 348 nilfs_clear_recovery_info(&ri);
@@ -782,7 +764,7 @@ void nilfs_put_root(struct nilfs_root *root)
782 rb_erase(&root->rb_node, &nilfs->ns_cptree); 764 rb_erase(&root->rb_node, &nilfs->ns_cptree);
783 spin_unlock(&nilfs->ns_cptree_lock); 765 spin_unlock(&nilfs->ns_cptree_lock);
784 if (root->ifile) 766 if (root->ifile)
785 nilfs_mdt_destroy(root->ifile); 767 iput(root->ifile);
786 768
787 kfree(root); 769 kfree(root);
788 } 770 }