Loading fs/nfs/inode.c +3 −0 Original line number Diff line number Diff line Loading @@ -167,6 +167,7 @@ static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags) struct nfs_server *server; struct rpc_clnt *rpc; shrink_submounts(vfsmnt, &nfs_automount_list); if (!(flags & MNT_FORCE)) return; /* -EIO all pending I/O */ Loading Loading @@ -1943,6 +1944,7 @@ static void nfs_kill_super(struct super_block *s) nfs_free_iostats(server->io_stats); kfree(server->hostname); kfree(server); nfs_release_automount_timer(); } static struct file_system_type nfs_fs_type = { Loading Loading @@ -2288,6 +2290,7 @@ static void nfs4_kill_super(struct super_block *sb) nfs_free_iostats(server->io_stats); kfree(server->hostname); kfree(server); nfs_release_automount_timer(); } static struct file_system_type nfs4_fs_type = { Loading fs/nfs/namespace.c +24 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,11 @@ #define NFSDBG_FACILITY NFSDBG_VFS LIST_HEAD(nfs_automount_list); static void nfs_expire_automounts(void *list); static DECLARE_WORK(nfs_automount_task, nfs_expire_automounts, &nfs_automount_list); int nfs_mountpoint_expiry_timeout = 500 * HZ; /* * nfs_follow_mountpoint - handle crossing a mountpoint on the server * @dentry - dentry of mountpoint Loading Loading @@ -59,7 +64,7 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) goto out_err; mntget(mnt); err = do_add_mount(mnt, nd, nd->mnt->mnt_flags, NULL); err = do_add_mount(mnt, nd, nd->mnt->mnt_flags|MNT_SHRINKABLE, &nfs_automount_list); if (err < 0) { mntput(mnt); if (err == -EBUSY) Loading @@ -70,6 +75,7 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) dput(nd->dentry); nd->mnt = mnt; nd->dentry = dget(mnt->mnt_root); schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); out: dprintk("%s: done, returned %d\n", __FUNCTION__, err); return ERR_PTR(err); Loading @@ -87,3 +93,20 @@ struct inode_operations nfs_mountpoint_inode_operations = { .follow_link = nfs_follow_mountpoint, .getattr = nfs_getattr, }; static void nfs_expire_automounts(void *data) { struct list_head *list = (struct list_head *)data; mark_mounts_for_expiry(list); if (!list_empty(list)) schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); } void nfs_release_automount_timer(void) { if (list_empty(&nfs_automount_list)) { cancel_delayed_work(&nfs_automount_task); flush_scheduled_work(); } } fs/nfs/sysctl.c +10 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/nfs4.h> #include <linux/nfs_idmap.h> #include <linux/nfs_fs.h> #include "callback.h" Loading Loading @@ -46,6 +47,15 @@ static ctl_table nfs_cb_sysctls[] = { .strategy = &sysctl_jiffies, }, #endif { .ctl_name = CTL_UNNUMBERED, .procname = "nfs_mountpoint_timeout", .data = &nfs_mountpoint_expiry_timeout, .maxlen = sizeof(nfs_mountpoint_expiry_timeout), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, .strategy = &sysctl_jiffies, }, { .ctl_name = 0 } }; Loading include/linux/nfs_fs.h +3 −0 Original line number Diff line number Diff line Loading @@ -405,7 +405,10 @@ extern void nfs_unregister_sysctl(void); /* * linux/fs/nfs/namespace.c */ extern struct list_head nfs_automount_list; extern struct inode_operations nfs_mountpoint_inode_operations; extern int nfs_mountpoint_expiry_timeout; extern void nfs_release_automount_timer(void); /* * linux/fs/nfs/unlink.c Loading Loading
fs/nfs/inode.c +3 −0 Original line number Diff line number Diff line Loading @@ -167,6 +167,7 @@ static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags) struct nfs_server *server; struct rpc_clnt *rpc; shrink_submounts(vfsmnt, &nfs_automount_list); if (!(flags & MNT_FORCE)) return; /* -EIO all pending I/O */ Loading Loading @@ -1943,6 +1944,7 @@ static void nfs_kill_super(struct super_block *s) nfs_free_iostats(server->io_stats); kfree(server->hostname); kfree(server); nfs_release_automount_timer(); } static struct file_system_type nfs_fs_type = { Loading Loading @@ -2288,6 +2290,7 @@ static void nfs4_kill_super(struct super_block *sb) nfs_free_iostats(server->io_stats); kfree(server->hostname); kfree(server); nfs_release_automount_timer(); } static struct file_system_type nfs4_fs_type = { Loading
fs/nfs/namespace.c +24 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,11 @@ #define NFSDBG_FACILITY NFSDBG_VFS LIST_HEAD(nfs_automount_list); static void nfs_expire_automounts(void *list); static DECLARE_WORK(nfs_automount_task, nfs_expire_automounts, &nfs_automount_list); int nfs_mountpoint_expiry_timeout = 500 * HZ; /* * nfs_follow_mountpoint - handle crossing a mountpoint on the server * @dentry - dentry of mountpoint Loading Loading @@ -59,7 +64,7 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) goto out_err; mntget(mnt); err = do_add_mount(mnt, nd, nd->mnt->mnt_flags, NULL); err = do_add_mount(mnt, nd, nd->mnt->mnt_flags|MNT_SHRINKABLE, &nfs_automount_list); if (err < 0) { mntput(mnt); if (err == -EBUSY) Loading @@ -70,6 +75,7 @@ static void * nfs_follow_mountpoint(struct dentry *dentry, struct nameidata *nd) dput(nd->dentry); nd->mnt = mnt; nd->dentry = dget(mnt->mnt_root); schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); out: dprintk("%s: done, returned %d\n", __FUNCTION__, err); return ERR_PTR(err); Loading @@ -87,3 +93,20 @@ struct inode_operations nfs_mountpoint_inode_operations = { .follow_link = nfs_follow_mountpoint, .getattr = nfs_getattr, }; static void nfs_expire_automounts(void *data) { struct list_head *list = (struct list_head *)data; mark_mounts_for_expiry(list); if (!list_empty(list)) schedule_delayed_work(&nfs_automount_task, nfs_mountpoint_expiry_timeout); } void nfs_release_automount_timer(void) { if (list_empty(&nfs_automount_list)) { cancel_delayed_work(&nfs_automount_task); flush_scheduled_work(); } }
fs/nfs/sysctl.c +10 −0 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/nfs4.h> #include <linux/nfs_idmap.h> #include <linux/nfs_fs.h> #include "callback.h" Loading Loading @@ -46,6 +47,15 @@ static ctl_table nfs_cb_sysctls[] = { .strategy = &sysctl_jiffies, }, #endif { .ctl_name = CTL_UNNUMBERED, .procname = "nfs_mountpoint_timeout", .data = &nfs_mountpoint_expiry_timeout, .maxlen = sizeof(nfs_mountpoint_expiry_timeout), .mode = 0644, .proc_handler = &proc_dointvec_jiffies, .strategy = &sysctl_jiffies, }, { .ctl_name = 0 } }; Loading
include/linux/nfs_fs.h +3 −0 Original line number Diff line number Diff line Loading @@ -405,7 +405,10 @@ extern void nfs_unregister_sysctl(void); /* * linux/fs/nfs/namespace.c */ extern struct list_head nfs_automount_list; extern struct inode_operations nfs_mountpoint_inode_operations; extern int nfs_mountpoint_expiry_timeout; extern void nfs_release_automount_timer(void); /* * linux/fs/nfs/unlink.c Loading