aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nilfs2/super.c
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2010-09-13 11:16:34 +0900
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2010-10-23 09:24:38 +0900
commit032dbb3b503a30fce732ec4c05525d0abed1f1d6 (patch)
tree462696abcf0783d50efe97a3ca2641beecc91a3e /fs/nilfs2/super.c
parentf1e89c86fdd0f5e59f6768146c86437934202033 (diff)
downloadkernel_samsung_smdk4412-032dbb3b503a30fce732ec4c05525d0abed1f1d6.zip
kernel_samsung_smdk4412-032dbb3b503a30fce732ec4c05525d0abed1f1d6.tar.gz
kernel_samsung_smdk4412-032dbb3b503a30fce732ec4c05525d0abed1f1d6.tar.bz2
nilfs2: see state of root dentry for mount check of snapshots
After applied the patch that unified sb instances, root dentry of snapshots can be left in dcache even after their trees are unmounted. The orphan root dentry/inode keeps a root object, and this causes false positive of nilfs_checkpoint_is_mounted function. This resolves the issue by having nilfs_checkpoint_is_mounted test whether the root dentry is busy or not. Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Diffstat (limited to 'fs/nilfs2/super.c')
-rw-r--r--fs/nilfs2/super.c32
1 files changed, 32 insertions, 0 deletions
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c
index 39e7d7f..ab96d26 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)
return nilfs_tree_was_touched(root_dentry);
}
+int nilfs_checkpoint_is_mounted(struct super_block *sb, __u64 cno)
+{
+ struct the_nilfs *nilfs = NILFS_SB(sb)->s_nilfs;
+ struct nilfs_root *root;
+ struct inode *inode;
+ struct dentry *dentry;
+ int ret;
+
+ if (cno < 0 || cno > nilfs->ns_cno)
+ return false;
+
+ if (cno >= nilfs_last_cno(nilfs))
+ return true; /* protect recent checkpoints */
+
+ ret = false;
+ root = nilfs_lookup_root(NILFS_SB(sb)->s_nilfs, cno);
+ if (root) {
+ inode = nilfs_ilookup(sb, root, NILFS_ROOT_INO);
+ if (inode) {
+ dentry = d_find_alias(inode);
+ if (dentry) {
+ if (nilfs_tree_was_touched(dentry))
+ ret = nilfs_try_to_shrink_tree(dentry);
+ dput(dentry);
+ }
+ iput(inode);
+ }
+ nilfs_put_root(root);
+ }
+ return ret;
+}
+
/**
* nilfs_fill_super() - initialize a super block instance
* @sb: super_block