aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Layton <jeff.layton@primarydata.com>2019-08-18 14:18:45 -0400
committerJ. Bruce Fields <bfields@redhat.com>2019-08-19 11:00:39 -0400
commit18f6622ebbdea56a83f8e553c159ce2d62d3ad0c (patch)
treedb96f78e192180c2b3460c426e2f7864e802a9d2 /fs
parentf69d6d8eef7807f8d937b81da24bebd2e926e4d2 (diff)
locks: create a new notifier chain for lease attempts
With the new file caching infrastructure in nfsd, we can end up holding files open for an indefinite period of time, even when they are still idle. This may prevent the kernel from handing out leases on the file, which is something we don't want to block. Fix this by running a SRCU notifier call chain whenever on any lease attempt. nfsd can then purge the cache for that inode before returning. Since SRCU is only conditionally compiled in, we must only define the new chain if it's enabled, and users of the chain must ensure that SRCU is enabled. Signed-off-by: Jeff Layton <jeff.layton@primarydata.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com> Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/locks.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/fs/locks.c b/fs/locks.c
index 686eae21daf6..1913481bfbf7 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1990,6 +1990,64 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp,
1990} 1990}
1991EXPORT_SYMBOL(generic_setlease); 1991EXPORT_SYMBOL(generic_setlease);
1992 1992
1993#if IS_ENABLED(CONFIG_SRCU)
1994/*
1995 * Kernel subsystems can register to be notified on any attempt to set
1996 * a new lease with the lease_notifier_chain. This is used by (e.g.) nfsd
1997 * to close files that it may have cached when there is an attempt to set a
1998 * conflicting lease.
1999 */
2000static struct srcu_notifier_head lease_notifier_chain;
2001
2002static inline void
2003lease_notifier_chain_init(void)
2004{
2005 srcu_init_notifier_head(&lease_notifier_chain);
2006}
2007
2008static inline void
2009setlease_notifier(long arg, struct file_lock *lease)
2010{
2011 if (arg != F_UNLCK)
2012 srcu_notifier_call_chain(&lease_notifier_chain, arg, lease);
2013}
2014
2015int lease_register_notifier(struct notifier_block *nb)
2016{
2017 return srcu_notifier_chain_register(&lease_notifier_chain, nb);
2018}
2019EXPORT_SYMBOL_GPL(lease_register_notifier);
2020
2021void lease_unregister_notifier(struct notifier_block *nb)
2022{
2023 srcu_notifier_chain_unregister(&lease_notifier_chain, nb);
2024}
2025EXPORT_SYMBOL_GPL(lease_unregister_notifier);
2026
2027#else /* !IS_ENABLED(CONFIG_SRCU) */
2028static inline void
2029lease_notifier_chain_init(void)
2030{
2031}
2032
2033static inline void
2034setlease_notifier(long arg, struct file_lock *lease)
2035{
2036}
2037
2038int lease_register_notifier(struct notifier_block *nb)
2039{
2040 return 0;
2041}
2042EXPORT_SYMBOL_GPL(lease_register_notifier);
2043
2044void lease_unregister_notifier(struct notifier_block *nb)
2045{
2046}
2047EXPORT_SYMBOL_GPL(lease_unregister_notifier);
2048
2049#endif /* IS_ENABLED(CONFIG_SRCU) */
2050
1993/** 2051/**
1994 * vfs_setlease - sets a lease on an open file 2052 * vfs_setlease - sets a lease on an open file
1995 * @filp: file pointer 2053 * @filp: file pointer
@@ -2010,6 +2068,8 @@ EXPORT_SYMBOL(generic_setlease);
2010int 2068int
2011vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv) 2069vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv)
2012{ 2070{
2071 if (lease)
2072 setlease_notifier(arg, *lease);
2013 if (filp->f_op->setlease) 2073 if (filp->f_op->setlease)
2014 return filp->f_op->setlease(filp, arg, lease, priv); 2074 return filp->f_op->setlease(filp, arg, lease, priv);
2015 else 2075 else
@@ -2923,6 +2983,7 @@ static int __init filelock_init(void)
2923 INIT_HLIST_HEAD(&fll->hlist); 2983 INIT_HLIST_HEAD(&fll->hlist);
2924 } 2984 }
2925 2985
2986 lease_notifier_chain_init();
2926 return 0; 2987 return 0;
2927} 2988}
2928core_initcall(filelock_init); 2989core_initcall(filelock_init);