diff options
Diffstat (limited to 'fs/nilfs2')
-rw-r--r-- | fs/nilfs2/cpfile.c | 49 | ||||
-rw-r--r-- | fs/nilfs2/cpfile.h | 4 | ||||
-rw-r--r-- | fs/nilfs2/dat.c | 61 | ||||
-rw-r--r-- | fs/nilfs2/dat.h | 4 | ||||
-rw-r--r-- | fs/nilfs2/ifile.c | 51 | ||||
-rw-r--r-- | fs/nilfs2/ifile.h | 4 | ||||
-rw-r--r-- | fs/nilfs2/inode.c | 13 | ||||
-rw-r--r-- | fs/nilfs2/mdt.c | 16 | ||||
-rw-r--r-- | fs/nilfs2/mdt.h | 3 | ||||
-rw-r--r-- | fs/nilfs2/nilfs.h | 2 | ||||
-rw-r--r-- | fs/nilfs2/sufile.c | 73 | ||||
-rw-r--r-- | fs/nilfs2/sufile.h | 4 | ||||
-rw-r--r-- | fs/nilfs2/super.c | 21 | ||||
-rw-r--r-- | fs/nilfs2/the_nilfs.c | 58 |
14 files changed, 207 insertions, 156 deletions
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c index 18737818db63..03de1da8795b 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 | */ | ||
940 | int 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 | */ |
950 | struct inode *nilfs_cpfile_new(struct the_nilfs *nilfs, size_t cpsize) | 942 | int 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 bc0809e0ab43..a242b9a314f9 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 *); | |||
40 | ssize_t nilfs_cpfile_get_cpinfo(struct inode *, __u64 *, int, void *, unsigned, | 40 | ssize_t nilfs_cpfile_get_cpinfo(struct inode *, __u64 *, int, void *, unsigned, |
41 | size_t); | 41 | size_t); |
42 | 42 | ||
43 | int nilfs_cpfile_read(struct inode *cpfile, struct nilfs_inode *raw_inode); | 43 | int nilfs_cpfile_read(struct super_block *sb, size_t cpsize, |
44 | struct 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 7091c4e0f042..ab04a68f425d 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 | */ | ||
470 | int 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 | */ |
480 | struct inode *nilfs_dat_new(struct the_nilfs *nilfs, size_t entry_size) | 472 | int 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 d31c3aab0efe..cbd8e9732503 100644 --- a/fs/nilfs2/dat.h +++ b/fs/nilfs2/dat.h | |||
@@ -53,7 +53,7 @@ int nilfs_dat_freev(struct inode *, __u64 *, size_t); | |||
53 | int nilfs_dat_move(struct inode *, __u64, sector_t); | 53 | int nilfs_dat_move(struct inode *, __u64, sector_t); |
54 | ssize_t nilfs_dat_get_vinfo(struct inode *, void *, unsigned, size_t); | 54 | ssize_t nilfs_dat_get_vinfo(struct inode *, void *, unsigned, size_t); |
55 | 55 | ||
56 | int nilfs_dat_read(struct inode *dat, struct nilfs_inode *raw_inode); | 56 | int nilfs_dat_read(struct super_block *sb, size_t entry_size, |
57 | struct 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 922d9dd42c8f..9f8a2da67f90 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 | */ |
168 | struct inode *nilfs_ifile_new(struct nilfs_sb_info *sbi, size_t inode_size) | 171 | int 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 cbca32e498f2..59b6f2b51df6 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 **); | |||
49 | int nilfs_ifile_delete_inode(struct inode *, ino_t); | 49 | int nilfs_ifile_delete_inode(struct inode *, ino_t); |
50 | int nilfs_ifile_get_inode_block(struct inode *, ino_t, struct buffer_head **); | 50 | int nilfs_ifile_get_inode_block(struct inode *, ino_t, struct buffer_head **); |
51 | 51 | ||
52 | struct inode *nilfs_ifile_new(struct nilfs_sb_info *sbi, size_t inode_size); | 52 | int 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 5485dd12da64..5b3d43fb4e12 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 | ||
509 | struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, | 509 | struct 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 | |||
519 | struct 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 3bbd340a5136..44326cfe1fa9 100644 --- a/fs/nilfs2/mdt.c +++ b/fs/nilfs2/mdt.c | |||
@@ -444,8 +444,7 @@ static const struct inode_operations def_mdt_iops; | |||
444 | static const struct file_operations def_mdt_fops; | 444 | static const struct file_operations def_mdt_fops; |
445 | 445 | ||
446 | 446 | ||
447 | int nilfs_mdt_init(struct inode *inode, struct the_nilfs *nilfs, | 447 | int 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 1e0901c3fd6b..73ff7c055715 100644 --- a/fs/nilfs2/mdt.h +++ b/fs/nilfs2/mdt.h | |||
@@ -85,8 +85,7 @@ int nilfs_mdt_forget_block(struct inode *, unsigned long); | |||
85 | int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long); | 85 | int nilfs_mdt_mark_block_dirty(struct inode *, unsigned long); |
86 | int nilfs_mdt_fetch_dirty(struct inode *); | 86 | int nilfs_mdt_fetch_dirty(struct inode *); |
87 | 87 | ||
88 | int nilfs_mdt_init(struct inode *inode, struct the_nilfs *nilfs, | 88 | int nilfs_mdt_init(struct inode *inode, gfp_t gfp_mask, size_t objsz); |
89 | gfp_t gfp_mask, size_t objsz); | ||
90 | struct inode *nilfs_mdt_new(struct the_nilfs *, struct super_block *, ino_t, | 89 | struct inode *nilfs_mdt_new(struct the_nilfs *, struct super_block *, ino_t, |
91 | size_t); | 90 | size_t); |
92 | struct inode *nilfs_mdt_new_common(struct the_nilfs *, struct super_block *, | 91 | struct inode *nilfs_mdt_new_common(struct the_nilfs *, struct super_block *, |
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index e9f457951e32..2ca2ca5ca848 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); | |||
244 | extern void nilfs_set_inode_flags(struct inode *); | 244 | extern void nilfs_set_inode_flags(struct inode *); |
245 | extern int nilfs_read_inode_common(struct inode *, struct nilfs_inode *); | 245 | extern int nilfs_read_inode_common(struct inode *, struct nilfs_inode *); |
246 | extern void nilfs_write_inode_common(struct inode *, struct nilfs_inode *, int); | 246 | extern void nilfs_write_inode_common(struct inode *, struct nilfs_inode *, int); |
247 | struct inode *nilfs_iget_locked(struct super_block *sb, struct nilfs_root *root, | ||
248 | unsigned long ino); | ||
247 | struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, | 249 | struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, |
248 | unsigned long ino); | 250 | unsigned long ino); |
249 | extern struct inode *nilfs_iget_for_gc(struct super_block *sb, | 251 | extern struct inode *nilfs_iget_for_gc(struct super_block *sb, |
diff --git a/fs/nilfs2/sufile.c b/fs/nilfs2/sufile.c index 3c6cc6005c2e..599d9c27761e 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 | */ |
642 | int nilfs_sufile_read(struct inode *sufile, struct nilfs_inode *raw_inode) | 644 | int 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) |
670 | struct 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 15163b8aff7d..203f6102a62f 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 *, | |||
61 | void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *, | 61 | void nilfs_sufile_do_set_error(struct inode *, __u64, struct buffer_head *, |
62 | struct buffer_head *); | 62 | struct buffer_head *); |
63 | 63 | ||
64 | int nilfs_sufile_read(struct inode *sufile, struct nilfs_inode *raw_inode); | 64 | int nilfs_sufile_read(struct super_block *sb, size_t susize, |
65 | struct 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 5893cb27c909..39e7d7f8eda0 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 b7666bc04256..4d6763e28eb5 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) | |||
92 | void destroy_nilfs(struct the_nilfs *nilfs) | 92 | void 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 | ||
107 | static int nilfs_load_super_root(struct the_nilfs *nilfs, sector_t sr_block) | 102 | static 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 | } |