diff options
| -rw-r--r-- | fs/nilfs2/inode.c | 27 | ||||
| -rw-r--r-- | fs/nilfs2/namei.c | 5 | ||||
| -rw-r--r-- | fs/nilfs2/nilfs.h | 7 | ||||
| -rw-r--r-- | fs/nilfs2/recovery.c | 12 | ||||
| -rw-r--r-- | fs/nilfs2/super.c | 37 |
5 files changed, 68 insertions, 20 deletions
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 82cfdbc43e1c..7306fc7c4962 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
| @@ -37,6 +37,7 @@ | |||
| 37 | struct nilfs_iget_args { | 37 | struct nilfs_iget_args { |
| 38 | u64 ino; | 38 | u64 ino; |
| 39 | __u64 cno; | 39 | __u64 cno; |
| 40 | struct nilfs_root *root; | ||
| 40 | int for_gc; | 41 | int for_gc; |
| 41 | }; | 42 | }; |
| 42 | 43 | ||
| @@ -284,6 +285,7 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) | |||
| 284 | struct nilfs_sb_info *sbi = NILFS_SB(sb); | 285 | struct nilfs_sb_info *sbi = NILFS_SB(sb); |
| 285 | struct inode *inode; | 286 | struct inode *inode; |
| 286 | struct nilfs_inode_info *ii; | 287 | struct nilfs_inode_info *ii; |
| 288 | struct nilfs_root *root; | ||
| 287 | int err = -ENOMEM; | 289 | int err = -ENOMEM; |
| 288 | ino_t ino; | 290 | ino_t ino; |
| 289 | 291 | ||
| @@ -294,8 +296,10 @@ struct inode *nilfs_new_inode(struct inode *dir, int mode) | |||
| 294 | mapping_set_gfp_mask(inode->i_mapping, | 296 | mapping_set_gfp_mask(inode->i_mapping, |
| 295 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); | 297 | mapping_gfp_mask(inode->i_mapping) & ~__GFP_FS); |
| 296 | 298 | ||
| 299 | root = NILFS_I(dir)->i_root; | ||
| 297 | ii = NILFS_I(inode); | 300 | ii = NILFS_I(inode); |
| 298 | ii->i_state = 1 << NILFS_I_NEW; | 301 | ii->i_state = 1 << NILFS_I_NEW; |
| 302 | ii->i_root = root; | ||
| 299 | 303 | ||
| 300 | err = nilfs_ifile_create_inode(sbi->s_ifile, &ino, &ii->i_bh); | 304 | err = nilfs_ifile_create_inode(sbi->s_ifile, &ino, &ii->i_bh); |
| 301 | if (unlikely(err)) | 305 | if (unlikely(err)) |
| @@ -484,7 +488,7 @@ static int nilfs_iget_test(struct inode *inode, void *opaque) | |||
| 484 | struct nilfs_iget_args *args = opaque; | 488 | struct nilfs_iget_args *args = opaque; |
| 485 | struct nilfs_inode_info *ii; | 489 | struct nilfs_inode_info *ii; |
| 486 | 490 | ||
| 487 | if (args->ino != inode->i_ino) | 491 | if (args->ino != inode->i_ino || args->root != NILFS_I(inode)->i_root) |
| 488 | return 0; | 492 | return 0; |
| 489 | 493 | ||
| 490 | ii = NILFS_I(inode); | 494 | ii = NILFS_I(inode); |
| @@ -502,13 +506,21 @@ static int nilfs_iget_set(struct inode *inode, void *opaque) | |||
| 502 | if (args->for_gc) { | 506 | if (args->for_gc) { |
| 503 | NILFS_I(inode)->i_state = 1 << NILFS_I_GCINODE; | 507 | NILFS_I(inode)->i_state = 1 << NILFS_I_GCINODE; |
| 504 | NILFS_I(inode)->i_cno = args->cno; | 508 | NILFS_I(inode)->i_cno = args->cno; |
| 509 | NILFS_I(inode)->i_root = NULL; | ||
| 510 | } else { | ||
| 511 | if (args->root && args->ino == NILFS_ROOT_INO) | ||
| 512 | nilfs_get_root(args->root); | ||
| 513 | NILFS_I(inode)->i_root = args->root; | ||
| 505 | } | 514 | } |
| 506 | return 0; | 515 | return 0; |
| 507 | } | 516 | } |
| 508 | 517 | ||
| 509 | struct inode *nilfs_iget(struct super_block *sb, unsigned long ino) | 518 | struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, |
| 519 | unsigned long ino) | ||
| 510 | { | 520 | { |
| 511 | struct nilfs_iget_args args = { .ino = ino, .cno = 0, .for_gc = 0 }; | 521 | struct nilfs_iget_args args = { |
| 522 | .ino = ino, .root = root, .cno = 0, .for_gc = 0 | ||
| 523 | }; | ||
| 512 | struct inode *inode; | 524 | struct inode *inode; |
| 513 | int err; | 525 | int err; |
| 514 | 526 | ||
| @@ -530,7 +542,9 @@ struct inode *nilfs_iget(struct super_block *sb, unsigned long ino) | |||
| 530 | struct inode *nilfs_iget_for_gc(struct super_block *sb, unsigned long ino, | 542 | struct inode *nilfs_iget_for_gc(struct super_block *sb, unsigned long ino, |
| 531 | __u64 cno) | 543 | __u64 cno) |
| 532 | { | 544 | { |
| 533 | struct nilfs_iget_args args = { .ino = ino, .cno = cno, .for_gc = 1 }; | 545 | struct nilfs_iget_args args = { |
| 546 | .ino = ino, .root = NULL, .cno = cno, .for_gc = 1 | ||
| 547 | }; | ||
| 534 | struct inode *inode; | 548 | struct inode *inode; |
| 535 | int err; | 549 | int err; |
| 536 | 550 | ||
| @@ -682,6 +696,9 @@ static void nilfs_clear_inode(struct inode *inode) | |||
| 682 | nilfs_bmap_clear(ii->i_bmap); | 696 | nilfs_bmap_clear(ii->i_bmap); |
| 683 | 697 | ||
| 684 | nilfs_btnode_cache_clear(&ii->i_btnode_cache); | 698 | nilfs_btnode_cache_clear(&ii->i_btnode_cache); |
| 699 | |||
| 700 | if (ii->i_root && inode->i_ino == NILFS_ROOT_INO) | ||
| 701 | nilfs_put_root(ii->i_root); | ||
| 685 | } | 702 | } |
| 686 | 703 | ||
| 687 | void nilfs_evict_inode(struct inode *inode) | 704 | void nilfs_evict_inode(struct inode *inode) |
| @@ -690,7 +707,7 @@ void nilfs_evict_inode(struct inode *inode) | |||
| 690 | struct super_block *sb = inode->i_sb; | 707 | struct super_block *sb = inode->i_sb; |
| 691 | struct nilfs_inode_info *ii = NILFS_I(inode); | 708 | struct nilfs_inode_info *ii = NILFS_I(inode); |
| 692 | 709 | ||
| 693 | if (inode->i_nlink || unlikely(is_bad_inode(inode))) { | 710 | if (inode->i_nlink || !ii->i_root || unlikely(is_bad_inode(inode))) { |
| 694 | if (inode->i_data.nrpages) | 711 | if (inode->i_data.nrpages) |
| 695 | truncate_inode_pages(&inode->i_data, 0); | 712 | truncate_inode_pages(&inode->i_data, 0); |
| 696 | end_writeback(inode); | 713 | end_writeback(inode); |
diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index ad6ed2cf19b4..1110d56a23f5 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c | |||
| @@ -70,7 +70,7 @@ nilfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd) | |||
| 70 | ino = nilfs_inode_by_name(dir, &dentry->d_name); | 70 | ino = nilfs_inode_by_name(dir, &dentry->d_name); |
| 71 | inode = NULL; | 71 | inode = NULL; |
| 72 | if (ino) { | 72 | if (ino) { |
| 73 | inode = nilfs_iget(dir->i_sb, ino); | 73 | inode = nilfs_iget(dir->i_sb, NILFS_I(dir)->i_root, ino); |
| 74 | if (IS_ERR(inode)) | 74 | if (IS_ERR(inode)) |
| 75 | return ERR_CAST(inode); | 75 | return ERR_CAST(inode); |
| 76 | } | 76 | } |
| @@ -87,7 +87,8 @@ struct dentry *nilfs_get_parent(struct dentry *child) | |||
| 87 | if (!ino) | 87 | if (!ino) |
| 88 | return ERR_PTR(-ENOENT); | 88 | return ERR_PTR(-ENOENT); |
| 89 | 89 | ||
| 90 | inode = nilfs_iget(child->d_inode->i_sb, ino); | 90 | inode = nilfs_iget(child->d_inode->i_sb, |
| 91 | NILFS_I(child->d_inode)->i_root, ino); | ||
| 91 | if (IS_ERR(inode)) | 92 | if (IS_ERR(inode)) |
| 92 | return ERR_CAST(inode); | 93 | return ERR_CAST(inode); |
| 93 | return d_obtain_alias(inode); | 94 | return d_obtain_alias(inode); |
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index 797cd437970e..21d90c4b4e2d 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h | |||
| @@ -59,6 +59,7 @@ struct nilfs_inode_info { | |||
| 59 | #endif | 59 | #endif |
| 60 | struct buffer_head *i_bh; /* i_bh contains a new or dirty | 60 | struct buffer_head *i_bh; /* i_bh contains a new or dirty |
| 61 | disk inode */ | 61 | disk inode */ |
| 62 | struct nilfs_root *i_root; | ||
| 62 | struct inode vfs_inode; | 63 | struct inode vfs_inode; |
| 63 | }; | 64 | }; |
| 64 | 65 | ||
| @@ -247,7 +248,8 @@ extern int nilfs_get_block(struct inode *, sector_t, struct buffer_head *, int); | |||
| 247 | extern void nilfs_set_inode_flags(struct inode *); | 248 | extern void nilfs_set_inode_flags(struct inode *); |
| 248 | extern int nilfs_read_inode_common(struct inode *, struct nilfs_inode *); | 249 | extern int nilfs_read_inode_common(struct inode *, struct nilfs_inode *); |
| 249 | extern void nilfs_write_inode_common(struct inode *, struct nilfs_inode *, int); | 250 | extern void nilfs_write_inode_common(struct inode *, struct nilfs_inode *, int); |
| 250 | extern struct inode *nilfs_iget(struct super_block *, unsigned long); | 251 | struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, |
| 252 | unsigned long ino); | ||
| 251 | extern struct inode *nilfs_iget_for_gc(struct super_block *sb, | 253 | extern struct inode *nilfs_iget_for_gc(struct super_block *sb, |
| 252 | unsigned long ino, __u64 cno); | 254 | unsigned long ino, __u64 cno); |
| 253 | extern void nilfs_update_inode(struct inode *, struct buffer_head *); | 255 | extern void nilfs_update_inode(struct inode *, struct buffer_head *); |
| @@ -285,7 +287,8 @@ extern struct nilfs_super_block **nilfs_prepare_super(struct nilfs_sb_info *, | |||
| 285 | int flip); | 287 | int flip); |
| 286 | extern int nilfs_commit_super(struct nilfs_sb_info *, int); | 288 | extern int nilfs_commit_super(struct nilfs_sb_info *, int); |
| 287 | extern int nilfs_cleanup_super(struct nilfs_sb_info *); | 289 | extern int nilfs_cleanup_super(struct nilfs_sb_info *); |
| 288 | extern int nilfs_attach_checkpoint(struct nilfs_sb_info *, __u64); | 290 | int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt, |
| 291 | struct nilfs_root **root); | ||
| 289 | extern void nilfs_detach_checkpoint(struct nilfs_sb_info *); | 292 | extern void nilfs_detach_checkpoint(struct nilfs_sb_info *); |
| 290 | 293 | ||
| 291 | /* gcinode.c */ | 294 | /* gcinode.c */ |
diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c index d0c35ef39f6a..a9a5ba8f57d5 100644 --- a/fs/nilfs2/recovery.c +++ b/fs/nilfs2/recovery.c | |||
| @@ -504,6 +504,7 @@ static int nilfs_recovery_copy_block(struct the_nilfs *nilfs, | |||
| 504 | 504 | ||
| 505 | static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs, | 505 | static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs, |
| 506 | struct nilfs_sb_info *sbi, | 506 | struct nilfs_sb_info *sbi, |
| 507 | struct nilfs_root *root, | ||
| 507 | struct list_head *head, | 508 | struct list_head *head, |
| 508 | unsigned long *nr_salvaged_blocks) | 509 | unsigned long *nr_salvaged_blocks) |
| 509 | { | 510 | { |
| @@ -515,7 +516,7 @@ static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs, | |||
| 515 | int err = 0, err2 = 0; | 516 | int err = 0, err2 = 0; |
| 516 | 517 | ||
| 517 | list_for_each_entry_safe(rb, n, head, list) { | 518 | list_for_each_entry_safe(rb, n, head, list) { |
| 518 | inode = nilfs_iget(sbi->s_super, rb->ino); | 519 | inode = nilfs_iget(sbi->s_super, root, rb->ino); |
| 519 | if (IS_ERR(inode)) { | 520 | if (IS_ERR(inode)) { |
| 520 | |||
