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 *); |