aboutsummaryrefslogtreecommitdiffstats
path: root/fs/locks.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/locks.c')
-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);