diff options
| -rw-r--r-- | fs/nilfs2/cpfile.c | 23 | ||||
| -rw-r--r-- | fs/nilfs2/inode.c | 10 | ||||
| -rw-r--r-- | fs/nilfs2/nilfs.h | 3 | ||||
| -rw-r--r-- | fs/nilfs2/super.c | 32 | ||||
| -rw-r--r-- | fs/nilfs2/the_nilfs.c | 21 | ||||
| -rw-r--r-- | fs/nilfs2/the_nilfs.h | 1 |
6 files changed, 53 insertions, 37 deletions
diff --git a/fs/nilfs2/cpfile.c b/fs/nilfs2/cpfile.c index 03de1da8795b..5ff15a8a1024 100644 --- a/fs/nilfs2/cpfile.c +++ b/fs/nilfs2/cpfile.c | |||
| @@ -863,26 +863,19 @@ int nilfs_cpfile_is_snapshot(struct inode *cpfile, __u64 cno) | |||
| 863 | */ | 863 | */ |
| 864 | int nilfs_cpfile_change_cpmode(struct inode *cpfile, __u64 cno, int mode) | 864 | int nilfs_cpfile_change_cpmode(struct inode *cpfile, __u64 cno, int mode) |
| 865 | { | 865 | { |
| 866 | struct the_nilfs *nilfs; | ||
| 867 | int ret; | 866 | int ret; |
| 868 | 867 | ||
| 869 | nilfs = NILFS_MDT(cpfile)->mi_nilfs; | ||
| 870 | |||
| 871 | switch (mode) { | 868 | switch (mode) { |
| 872 | case NILFS_CHECKPOINT: | 869 | case NILFS_CHECKPOINT: |
| 873 | /* | 870 | if (nilfs_checkpoint_is_mounted(cpfile->i_sb, cno)) |
| 874 | * Check for protecting existing snapshot mounts: | 871 | /* |
| 875 | * ns_mount_mutex is used to make this operation atomic and | 872 | * Current implementation does not have to protect |
| 876 | * exclusive with a new mount job. Though it doesn't cover | 873 | * plain read-only mounts since they are exclusive |
| 877 | * umount, it's enough for the purpose. | 874 | * with a read/write mount and are protected from the |
| 878 | */ | 875 | * cleaner. |
| 879 | if (nilfs_checkpoint_is_mounted(nilfs, cno, 1)) { | 876 | */ |
| 880 | /* Current implementation does not have to protect | ||
| 881 | plain read-only mounts since they are exclusive | ||
| 882 | with a read/write mount and are protected from the | ||
| 883 | cleaner. */ | ||
| 884 | ret = -EBUSY; | 877 | ret = -EBUSY; |
| 885 | } else | 878 | else |
| 886 | ret = nilfs_cpfile_clear_snapshot(cpfile, cno); | 879 | ret = nilfs_cpfile_clear_snapshot(cpfile, cno); |
| 887 | return ret; | 880 | return ret; |
| 888 | case NILFS_SNAPSHOT: | 881 | case NILFS_SNAPSHOT: |
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index 5b3d43fb4e12..71d4bc8464e0 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c | |||
| @@ -506,6 +506,16 @@ static int nilfs_iget_set(struct inode *inode, void *opaque) | |||
| 506 | return 0; | 506 | return 0; |
| 507 | } | 507 | } |
| 508 | 508 | ||
| 509 | struct inode *nilfs_ilookup(struct super_block *sb, struct nilfs_root *root, | ||
| 510 | unsigned long ino) | ||
| 511 | { | ||
| 512 | struct nilfs_iget_args args = { | ||
| 513 | .ino = ino, .root = root, .cno = 0, .for_gc = 0 | ||
| 514 | }; | ||
| 515 | |||
| 516 | return ilookup5(sb, ino, nilfs_iget_test, &args); | ||
| 517 | } | ||
| 518 | |||
| 509 | struct inode *nilfs_iget_locked(struct super_block *sb, struct nilfs_root *root, | 519 | struct inode *nilfs_iget_locked(struct super_block *sb, struct nilfs_root *root, |
| 510 | unsigned long ino) | 520 | unsigned long ino) |
| 511 | { | 521 | { |
diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index 2ca2ca5ca848..f6e276eaaf6f 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_ilookup(struct super_block *sb, struct nilfs_root *root, | ||
| 248 | unsigned long ino); | ||
| 247 | struct inode *nilfs_iget_locked(struct super_block *sb, struct nilfs_root *root, | 249 | struct inode *nilfs_iget_locked(struct super_block *sb, struct nilfs_root *root, |
| 248 | unsigned long ino); | 250 | unsigned long ino); |
| 249 | struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, | 251 | struct inode *nilfs_iget(struct super_block *sb, struct nilfs_root *root, |
| @@ -285,6 +287,7 @@ extern int nilfs_commit_super(struct nilfs_sb_info *, int); | |||
| 285 | extern int nilfs_cleanup_super(struct nilfs_sb_info *); | 287 | extern int nilfs_cleanup_super(struct nilfs_sb_info *); |
| 286 | int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt, | 288 | int nilfs_attach_checkpoint(struct nilfs_sb_info *sbi, __u64 cno, int curr_mnt, |
| 287 | struct nilfs_root **root); | 289 | struct nilfs_root **root); |
| 290 | int nilfs_checkpoint_is_mounted(struct super_block *sb, __u64 cno); | ||
| 288 | 291 | ||
| 289 | /* gcinode.c */ | 292 | /* gcinode.c */ |
| 290 | int nilfs_gccache_submit_read_data(struct inode *, sector_t, sector_t, __u64, | 293 | int nilfs_gccache_submit_read_data(struct inode *, sector_t, sector_t, __u64, |
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 39e7d7f8eda0..ab96d26bf7e9 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
| @@ -833,6 +833,38 @@ static int nilfs_try_to_shrink_tree(struct dentry *root_dentry) | |||
| 833 | return nilfs_tree_was_touched(root_dentry); | 833 | return nilfs_tree_was_touched(root_dentry); |
| 834 | } | 834 | } |
| 835 | 835 | ||
| 836 | int nilfs_checkpoint_is_mounted(struct super_block *sb, __u64 cno) | ||
| 837 | { | ||
| 838 | struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs; | ||
| 839 | struct nilfs_root *root; | ||
| 840 | struct inode *inode; | ||
| 841 | struct dentry *dentry; | ||
| 842 | int ret; | ||
| 843 | |||
| 844 | if (cno < 0 || cno > nilfs->ns_cno) | ||
| 845 | return false; | ||
| 846 | |||
| 847 | if (cno >= nilfs_last_cno(nilfs)) | ||
| 848 | return true; /* protect recent checkpoints */ | ||
| 849 | |||
| 850 | ret = false; | ||
| 851 | root = nilfs_lookup_root(NILFS_SB(sb)->s_nilfs, cno); | ||
| 852 | if (root) { | ||
| 853 | inode = nilfs_ilookup(sb, root, NILFS_ROOT_INO); | ||
| 854 | if (inode) { | ||
| 855 | dentry = d_find_alias(inode); | ||
| 856 | if (dentry) { | ||
| 857 | if (nilfs_tree_was_touched(dentry)) | ||
| 858 | ret = nilfs_try_to_shrink_tree(dentry); | ||
| 859 | dput(dentry); | ||
| 860 | } | ||
| 861 | iput(inode); | ||
| 862 | } | ||
| 863 | nilfs_put_root(root); | ||
| 864 | } | ||
| 865 | return ret; | ||
| 866 | } | ||
| 867 | |||
| 836 | /** | 868 | /** |
| 837 | * nilfs_fill_super() - initialize a super block instance | 869 | * nilfs_fill_super() - initialize a super block instance |
| 838 | * @sb: super_block | 870 | * @sb: super_block |
diff --git a/fs/nilfs2/the_nilfs.c b/fs/nilfs2/the_nilfs.c index 4d6763e28eb5..4cc705a1d135 100644 --- a/fs/nilfs2/the_nilfs.c +++ b/fs/nilfs2/the_nilfs.c | |||
| @@ -769,24 +769,3 @@ void nilfs_put_root(struct nilfs_root *root) | |||
| 769 | kfree(root); | 769 | kfree(root); |
| 770 | } | 770 | } |
| 771 | } | 771 | } |
| 772 | |||
| 773 | int nilfs_checkpoint_is_mounted(struct the_nilfs *nilfs, __u64 cno, | ||
| 774 | int snapshot_mount) | ||
| 775 | { | ||
| 776 | struct nilfs_root *root; | ||
| 777 | int ret; | ||
| 778 | |||
| 779 | if (cno < 0 || cno > nilfs->ns_cno) | ||
| 780 | return false; | ||
| 781 | |||
| 782 | if (cno >= nilfs_last_cno(nilfs)) | ||
| 783 | return true; /* protect recent checkpoints */ | ||
| 784 | |||
| 785 | ret = false; | ||
| 786 | root = nilfs_lookup_root(nilfs, cno); | ||
| 787 | if (root) { | ||
| 788 | ret = true; | ||
| 789 | nilfs_put_root(root); | ||
| 790 | } | ||
| 791 | return ret; | ||
| 792 | } | ||
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h index a5178dc43dfd..cae56f338b64 100644 --- a/fs/nilfs2/the_nilfs.h +++ b/fs/nilfs2/the_nilfs.h | |||
| @@ -242,7 +242,6 @@ struct nilfs_root *nilfs_find_or_create_root(struct the_nilfs *nilfs, | |||
| 242 | __u64 cno); | 242 | __u64 cno); |
| 243 | void nilfs_put_root(struct nilfs_root *root); | 243 | void nilfs_put_root(struct nilfs_root *root); |
| 244 | struct nilfs_sb_info *nilfs_find_sbinfo(struct the_nilfs *, int, __u64); | 244 | struct nilfs_sb_info *nilfs_find_sbinfo(struct the_nilfs *, int, __u64); |
| 245 | int nilfs_checkpoint_is_mounted(struct the_nilfs *, __u64, int); | ||
| 246 | int nilfs_near_disk_full(struct the_nilfs *); | 245 | int nilfs_near_disk_full(struct the_nilfs *); |
| 247 | void nilfs_fall_back_super_block(struct the_nilfs *); | 246 | void nilfs_fall_back_super_block(struct the_nilfs *); |
| 248 | void nilfs_swap_super_block(struct the_nilfs *); | 247 | void nilfs_swap_super_block(struct the_nilfs *); |
