diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index f4b4030cf406e2320b329120e86594b72d0611cc..c28085cb82a52874780ce5f021291a4fb87089d0 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h @@ -206,11 +206,8 @@ extern const struct inode_operations autofs4_symlink_inode_operations; extern const struct inode_operations autofs4_dir_inode_operations; extern const struct file_operations autofs4_dir_operations; extern const struct file_operations autofs4_root_operations; - -/* Operations methods */ - -struct vfsmount *autofs4_d_automount(struct path *); -int autofs4_d_manage(struct dentry *, bool); +extern const struct dentry_operations autofs4_dentry_operations; +extern const struct dentry_operations autofs4_mount_dentry_operations; /* VFS automount flags management functions */ diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index dac3dc79ccb49bec62a8db423ef51456c2c14237..427c35746340c886b66934d056a66f1722007b2e 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c @@ -251,12 +251,6 @@ static struct autofs_info *autofs4_mkroot(struct autofs_sb_info *sbi) return ino; } -static const struct dentry_operations autofs4_sb_dentry_operations = { - .d_automount = autofs4_d_automount, - .d_manage = autofs4_d_manage, - .d_release = autofs4_dentry_release, -}; - int autofs4_fill_super(struct super_block *s, void *data, int silent) { struct inode * root_inode; @@ -311,7 +305,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) goto fail_iput; pipe = NULL; - d_set_d_op(root, &autofs4_sb_dentry_operations); + d_set_d_op(root, &autofs4_dentry_operations); root->d_fsdata = ino; /* Can this call block? */ @@ -322,8 +316,10 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) goto fail_dput; } - if (autofs_type_trigger(sbi->type)) + if (autofs_type_trigger(sbi->type)) { + d_set_d_op(root, &autofs4_mount_dentry_operations); __managed_dentry_set_managed(root); + } root_inode->i_fop = &autofs4_root_operations; root_inode->i_op = &autofs4_dir_inode_operations; diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 52af410a831dc09ec95adccb9db2005754053e5c..62c1229a4d3174369f14f60cb6c28e53b923feb7 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c @@ -35,6 +35,8 @@ static long autofs4_root_compat_ioctl(struct file *,unsigned int,unsigned long); #endif static int autofs4_dir_open(struct inode *inode, struct file *file); static struct dentry *autofs4_lookup(struct inode *,struct dentry *, struct nameidata *); +static struct vfsmount *autofs4_d_automount(struct path *); +static int autofs4_d_manage(struct dentry *, bool); const struct file_operations autofs4_root_operations = { .open = dcache_dir_open, @@ -64,6 +66,18 @@ const struct inode_operations autofs4_dir_inode_operations = { .rmdir = autofs4_dir_rmdir, }; +/* For dentries that don't initiate mounting */ +const struct dentry_operations autofs4_dentry_operations = { + .d_release = autofs4_dentry_release, +}; + +/* For dentries that do initiate mounting */ +const struct dentry_operations autofs4_mount_dentry_operations = { + .d_automount = autofs4_d_automount, + .d_manage = autofs4_d_manage, + .d_release = autofs4_dentry_release, +}; + static void autofs4_add_active(struct dentry *dentry) { struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); @@ -158,18 +172,6 @@ void autofs4_dentry_release(struct dentry *de) } } -/* For dentries of directories in the root dir */ -static const struct dentry_operations autofs4_root_dentry_operations = { - .d_release = autofs4_dentry_release, -}; - -/* For other dentries */ -static const struct dentry_operations autofs4_dentry_operations = { - .d_automount = autofs4_d_automount, - .d_manage = autofs4_d_manage, - .d_release = autofs4_dentry_release, -}; - static struct dentry *autofs4_lookup_active(struct dentry *dentry) { struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); @@ -337,7 +339,7 @@ static struct dentry *autofs4_mountpoint_changed(struct path *path) return path->dentry; } -struct vfsmount *autofs4_d_automount(struct path *path) +static struct vfsmount *autofs4_d_automount(struct path *path) { struct dentry *dentry = path->dentry; struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb); @@ -501,7 +503,7 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s if (active) { return active; } else { - d_set_d_op(dentry, &autofs4_root_dentry_operations); + d_set_d_op(dentry, &autofs4_dentry_operations); /* * A dentry that is not within the root can never trigger a @@ -514,7 +516,7 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s /* Mark entries in the root as mount triggers */ if (autofs_type_indirect(sbi->type) && IS_ROOT(dentry->d_parent)) { - d_set_d_op(dentry, &autofs4_dentry_operations); + d_set_d_op(dentry, &autofs4_mount_dentry_operations); __managed_dentry_set_managed(dentry); } @@ -573,6 +575,8 @@ static int autofs4_dir_symlink(struct inode *dir, } d_add(dentry, inode); + d_set_d_op(dentry, &autofs4_dentry_operations); + dentry->d_fsdata = ino; ino->dentry = dget(dentry); atomic_inc(&ino->count); @@ -791,7 +795,7 @@ static inline int autofs4_ask_umount(struct vfsmount *mnt, int __user *p) int is_autofs4_dentry(struct dentry *dentry) { return dentry && dentry->d_inode && - (dentry->d_op == &autofs4_root_dentry_operations || + (dentry->d_op == &autofs4_mount_dentry_operations || dentry->d_op == &autofs4_dentry_operations) && dentry->d_fsdata != NULL; }