From patchwork Tue Nov 17 11:52:32 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 7636031 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 715E69F1D3 for ; Tue, 17 Nov 2015 11:53:41 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 74EFA20501 for ; Tue, 17 Nov 2015 11:53:40 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7A425204EC for ; Tue, 17 Nov 2015 11:53:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753510AbbKQLxg (ORCPT ); Tue, 17 Nov 2015 06:53:36 -0500 Received: from mail-qk0-f180.google.com ([209.85.220.180]:36812 "EHLO mail-qk0-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753444AbbKQLx2 (ORCPT ); Tue, 17 Nov 2015 06:53:28 -0500 Received: by qkda6 with SMTP id a6so1674707qkd.3 for ; Tue, 17 Nov 2015 03:53:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=poochiereds_net.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=dPeVj+gRRQyIAjaQWSUnG5n6e3wi4CfPfn3ZtRDMtkE=; b=nGcMYnQPB/OINhvE8ZHr3lRugWyK8Z0bu1GJFYPxMjsYK//0RZ0UubyF7qdDsEifE9 Bj5B+UU+gtyvSuw9tLVKdGVLSzYF+ehNnR8BtDQym+1S/qlUj6WvbpKyTXQYMhNx3o2n LxvSOLHgGVpFlrp1f1QjXlYgzx9tx7xA1vCNZ8avgIgHXYQpLCGUrEm+YJCk7ytvpcOg BsM7EuGrxTbUgbowH/MdsKj9G/wyUH4XPIgGRrEQWhlitW7dfH2GZJfV9pDiLr7y56oi FgD2UEkpJXiYJvjcNLpTGo7HdFY4sznziHTudDydJjae2ujkCQggGd9JGbWRD4zwoBqV Na5w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=dPeVj+gRRQyIAjaQWSUnG5n6e3wi4CfPfn3ZtRDMtkE=; b=lkPxtVmbLdyyck2FnLeOrs2axn7dFvtTZ0LrOhtk7OdahPnT0nqfbKJ9cN7bqPxAGY hFgr+jxQBPq68Fam/Y/mWZY9Z0uXJhj6RhzarUFgfaPtxqjVK6Hgt6LPmekTXl/K+wSI CA3LPxMPSOXp0pCObhG1KNSjKWHPStVfiGMvbwNsnzjDx2NudrdajkUJkE04iDdG0LSM h9qVoBqYHC2xK4mHU40QhxfDWm5lUktJuC3QZOOQfqZF7qVNJi0jiN10nY30Hi4Gm20v HT0tKCIKaJeswCN25hBIhbP2/Xu+Koo6JBWbkceiuhaYu6WXukRxzmvGTYzh+F+yO2Tg R3Rg== X-Gm-Message-State: ALoCoQnbLg3so8beOetek46jWWwi9AULD/TFPJF+RdUNQsNM8Ffu4hqgWl5RW+YISai5vKrzR4TN X-Received: by 10.55.21.65 with SMTP id f62mr41870232qkh.46.1447761208079; Tue, 17 Nov 2015 03:53:28 -0800 (PST) Received: from tlielax.poochiereds.net ([2606:a000:1125:4075::d5a]) by smtp.googlemail.com with ESMTPSA id w10sm1583910qhc.16.2015.11.17.03.53.27 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 17 Nov 2015 03:53:27 -0800 (PST) From: Jeff Layton X-Google-Original-From: Jeff Layton To: bfields@fieldses.org, trond.myklebust@primarydata.com Cc: linux-nfs@vger.kernel.org, Eric Paris , Alexander Viro , linux-fsdevel@vger.kernel.org Subject: [PATCH v1 10/38] locks: create a new notifier chain for lease attempts Date: Tue, 17 Nov 2015 06:52:32 -0500 Message-Id: <1447761180-4250-11-git-send-email-jeff.layton@primarydata.com> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1447761180-4250-1-git-send-email-jeff.layton@primarydata.com> References: <1447761180-4250-1-git-send-email-jeff.layton@primarydata.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP 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 any lease attempt is made. nfsd can then purge the nfsd_file cache of any entries associated with that inode, and use the fput_global infrastructure to make sure the final __fput is done. 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 --- fs/locks.c | 37 +++++++++++++++++++++++++++++++++++++ include/linux/fs.h | 1 + 2 files changed, 38 insertions(+) diff --git a/fs/locks.c b/fs/locks.c index 86c94674ab22..e463d585f77d 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -1786,6 +1786,40 @@ int generic_setlease(struct file *filp, long arg, struct file_lock **flp, } EXPORT_SYMBOL(generic_setlease); +#if IS_ENABLED(CONFIG_SRCU) +/* + * Kernel subsystems can 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. + */ +struct srcu_notifier_head lease_notifier_chain; +EXPORT_SYMBOL_GPL(lease_notifier_chain); + +static inline void +lease_notifier_chain_init(void) +{ + srcu_init_notifier_head(&lease_notifier_chain); +} + +static inline void +setlease_notifier(long arg, struct file_lock *lease) +{ + if (arg != F_UNLCK) + srcu_notifier_call_chain(&lease_notifier_chain, arg, lease); +} +#else /* !IS_ENABLED(CONFIG_SRCU) */ +static inline void +lease_notifier_chain_init(void) +{ +} + +static inline void +setlease_notifier(long arg, struct file_lock *lease) +{ +} +#endif /* IS_ENABLED(CONFIG_SRCU) */ + /** * vfs_setlease - sets a lease on an open file * @filp: file pointer @@ -1806,6 +1840,8 @@ EXPORT_SYMBOL(generic_setlease); int vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv) { + if (lease) + setlease_notifier(arg, *lease); if (filp->f_op->setlease) return filp->f_op->setlease(filp, arg, lease, priv); else @@ -2726,6 +2762,7 @@ static int __init filelock_init(void) for_each_possible_cpu(i) INIT_HLIST_HEAD(per_cpu_ptr(&file_lock_list, i)); + lease_notifier_chain_init(); return 0; } diff --git a/include/linux/fs.h b/include/linux/fs.h index cbf08d5c246e..0492ff432f01 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1042,6 +1042,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 srcu_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 *);