From: Jeff Layton <jlayton@poochiereds.net>
To: bfields@fieldses.org
Cc: linux-nfs@vger.kernel.org, hch@lst.de, kinglongmee@gmail.com
Subject: [PATCH v3 06/20] locks/nfsd: create a new notifier chain for lease attempts
Date: Thu, 20 Aug 2015 07:17:06 -0400 [thread overview]
Message-ID: <1440069440-27454-7-git-send-email-jeff.layton@primarydata.com> (raw)
In-Reply-To: <1440069440-27454-1-git-send-email-jeff.layton@primarydata.com>
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 we don't really want to block.
Fix this by running a blocking notifier call chain whenever on any
lease attempt. nfsd can then purge the cache for that inode before
returning.
Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
---
fs/locks.c | 15 +++++++++++++++
fs/nfsd/filecache.c | 27 +++++++++++++++++++++++++++
include/linux/fs.h | 1 +
3 files changed, 43 insertions(+)
diff --git a/fs/locks.c b/fs/locks.c
index d3d558ba4da7..c81b96159e5c 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -167,6 +167,13 @@ DEFINE_STATIC_LGLOCK(file_lock_lglock);
static DEFINE_PER_CPU(struct hlist_head, file_lock_list);
/*
+ * Some subsystems would like to be notified if someone attempts to set a
+ * lease on a file. This notifier chain will be called whenever this occurs.
+ */
+BLOCKING_NOTIFIER_HEAD(lease_notifier_chain);
+EXPORT_SYMBOL_GPL(lease_notifier_chain);
+
+/*
* The blocked_hash is used to find POSIX lock loops for deadlock detection.
* It is protected by blocked_lock_lock.
*
@@ -1795,10 +1802,18 @@ EXPORT_SYMBOL(generic_setlease);
*
* The "priv" pointer is passed directly to the lm_setup function as-is. It
* may be NULL if the lm_setup operation doesn't require it.
+ *
+ * Kernel subsystems can also register to be notified on any attempt to set
+ * a new lease with the lease_notifier_chain. This is used by (e.g.) nfsd
+ * to close files that it may have cached when there is an attempt to set a
+ * conflicting lease.
*/
int
vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv)
{
+ if (arg != F_UNLCK)
+ blocking_notifier_call_chain(&lease_notifier_chain, arg, *lease);
+
if (filp->f_op->setlease)
return filp->f_op->setlease(filp, arg, lease, priv);
else
diff --git a/fs/nfsd/filecache.c b/fs/nfsd/filecache.c
index 669e62f6f4f6..77041967d8ff 100644
--- a/fs/nfsd/filecache.c
+++ b/fs/nfsd/filecache.c
@@ -158,6 +158,22 @@ static struct shrinker nfsd_file_shrinker = {
.seeks = 1,
};
+static int
+nfsd_file_lease_notifier_call(struct notifier_block *nb, unsigned long arg,
+ void *data)
+{
+ struct file_lock *fl = data;
+
+ /* Don't close files if we're the one trying to set the lease */
+ if (fl->fl_type == FL_LEASE)
+ nfsd_file_close_inode(file_inode(fl->fl_file));
+ return 0;
+}
+
+static struct notifier_block nfsd_file_lease_notifier = {
+ .notifier_call = nfsd_file_lease_notifier_call,
+};
+
int
nfsd_file_cache_init(void)
{
@@ -186,12 +202,21 @@ nfsd_file_cache_init(void)
goto out_lru;
}
+ ret = blocking_notifier_chain_register(&lease_notifier_chain,
+ &nfsd_file_lease_notifier);
+ if (ret) {
+ pr_err("nfsd: unable to register lease notifier: %d\n", ret);
+ goto out_shrinker;
+ }
+
for (i = 0; i < NFSD_FILE_HASH_SIZE; i++) {
INIT_HLIST_HEAD(&nfsd_file_hashtbl[i].nfb_head);
spin_lock_init(&nfsd_file_hashtbl[i].nfb_lock);
}
out:
return ret;
+out_shrinker:
+ unregister_shrinker(&nfsd_file_shrinker);
out_lru:
list_lru_destroy(&nfsd_file_lru);
out_err:
@@ -207,6 +232,8 @@ nfsd_file_cache_shutdown(void)
struct nfsd_file *nf;
LIST_HEAD(dispose);
+ blocking_notifier_chain_unregister(&lease_notifier_chain,
+ &nfsd_file_lease_notifier);
unregister_shrinker(&nfsd_file_shrinker);
for (i = 0; i < NFSD_FILE_HASH_SIZE; i++) {
spin_lock(&nfsd_file_hashtbl[i].nfb_lock);
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 9a9d314f7b27..01bb82eae684 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1041,6 +1041,7 @@ extern int fcntl_setlease(unsigned int fd, struct file *filp, long arg);
extern int fcntl_getlease(struct file *filp);
/* fs/locks.c */
+extern struct blocking_notifier_head lease_notifier_chain;
void locks_free_lock_context(struct file_lock_context *ctx);
void locks_free_lock(struct file_lock *fl);
extern void locks_init_lock(struct file_lock *);
--
2.4.3
next prev parent reply other threads:[~2015-08-20 11:17 UTC|newest]
Thread overview: 39+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-08-20 11:17 [PATCH v3 00/20] nfsd: open file caching Jeff Layton
2015-08-20 11:17 ` [PATCH v3 01/20] nfsd: allow more than one laundry job to run at a time Jeff Layton
2015-08-20 11:17 ` [PATCH v3 02/20] nfsd: add a new struct file caching facility to nfsd Jeff Layton
2015-08-20 23:11 ` Peng Tao
2015-08-20 23:43 ` Jeff Layton
2015-08-20 11:17 ` [PATCH v3 03/20] list_lru: add list_lru_rotate Jeff Layton
2015-08-21 9:36 ` Vladimir Davydov
2015-08-20 11:17 ` [PATCH v3 04/20] nfsd: add a LRU list for nfsd_files Jeff Layton
2015-08-20 11:17 ` [PATCH v3 05/20] nfsd: add a shrinker to the nfsd_file cache Jeff Layton
2015-08-20 11:17 ` Jeff Layton [this message]
2015-08-26 19:49 ` [PATCH v3 06/20] locks/nfsd: create a new notifier chain for lease attempts J. Bruce Fields
2015-08-26 22:39 ` Jeff Layton
2015-08-20 11:17 ` [PATCH v3 07/20] nfsd: hook up nfsd_write to the new nfsd_file cache Jeff Layton
2015-08-26 19:53 ` J. Bruce Fields
2015-08-26 22:40 ` Jeff Layton
2015-08-20 11:17 ` [PATCH v3 08/20] nfsd: hook up nfsd_read to the " Jeff Layton
2015-08-20 11:17 ` [PATCH v3 09/20] sunrpc: add a new cache_detail operation for when a cache is flushed Jeff Layton
2015-08-20 11:17 ` [PATCH v3 10/20] nfsd: handle NFSD_MAY_NOT_BREAK_LEASE in open file cache Jeff Layton
2015-08-20 11:17 ` [PATCH v3 11/20] nfsd: hook nfsd_commit up to the nfsd_file cache Jeff Layton
2015-08-20 11:17 ` [PATCH v3 12/20] nfsd: move include of state.h from trace.c to trace.h Jeff Layton
2015-08-20 11:17 ` [PATCH v3 13/20] nfsd: add new tracepoints for nfsd_file cache Jeff Layton
2015-08-20 11:17 ` [PATCH v3 14/20] nfsd: close cached files prior to a REMOVE or RENAME that would replace target Jeff Layton
2015-08-26 20:00 ` J. Bruce Fields
2015-08-26 22:53 ` Jeff Layton
2015-08-27 13:38 ` J. Bruce Fields
2015-08-28 12:19 ` Jeff Layton
2015-08-28 17:58 ` J. Bruce Fields
2015-08-31 16:50 ` Jeff Layton
2015-08-20 11:17 ` [PATCH v3 15/20] nfsd: call flush_delayed_fput from nfsd_file_close_fh Jeff Layton
2015-08-21 1:01 ` Peng Tao
2015-08-21 2:18 ` Peng Tao
2015-08-21 11:21 ` Jeff Layton
2015-08-20 11:17 ` [PATCH v3 16/20] nfsd: convert nfs4_file->fi_fds array to use nfsd_files Jeff Layton
2015-08-20 11:17 ` [PATCH v3 17/20] nfsd: have nfsd_test_lock use the nfsd_file cache Jeff Layton
2015-08-20 11:17 ` [PATCH v3 18/20] nfsd: convert fi_deleg_file and ls_file fields to nfsd_file Jeff Layton
2015-08-20 11:17 ` [PATCH v3 19/20] nfsd: hook up nfs4_preprocess_stateid_op to the nfsd_file cache Jeff Layton
2015-08-21 1:28 ` Peng Tao
2015-08-21 11:23 ` Jeff Layton
2015-08-20 11:17 ` [PATCH v3 20/20] nfsd: rip out the raparms cache Jeff Layton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1440069440-27454-7-git-send-email-jeff.layton@primarydata.com \
--to=jlayton@poochiereds.net \
--cc=bfields@fieldses.org \
--cc=hch@lst.de \
--cc=kinglongmee@gmail.com \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).