From patchwork Fri Sep 11 10:54:31 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 7159551 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 4CE1A9F380 for ; Fri, 11 Sep 2015 10:55:46 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 64F7E204CF for ; Fri, 11 Sep 2015 10:55:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 6692E203AA for ; Fri, 11 Sep 2015 10:55:44 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751915AbbIKKzB (ORCPT ); Fri, 11 Sep 2015 06:55:01 -0400 Received: from mail-yk0-f173.google.com ([209.85.160.173]:32871 "EHLO mail-yk0-f173.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752780AbbIKKy6 (ORCPT ); Fri, 11 Sep 2015 06:54:58 -0400 Received: by ykei199 with SMTP id i199so86957018yke.0 for ; Fri, 11 Sep 2015 03:54:57 -0700 (PDT) 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=6B9b3sPg1YBWTMIy/ejd3MQrcwqH0bBhYeHZhDncoZE=; b=MvQJPH95BNwOonezQF+eNWD5+g448MXySwIGrr3/zYxZlMmrNDkSsp9x1qqwRt+iVD PybER9UQCeKc8tcKrFsIyhoICW5meQm9YLFnSEfQTJlxUb5DegKjvfMp24FzdmpKQIaI AMr8lpJkuqPRUuTOxvleIs5d33dVxKNOvXpRZ+7ZoXKySzohvzKvfdTy7FDpxm1hViO2 yxK3bfW3u3Sk9yg9fkSyV94WhcfmEytN5dvdgco9hBHQgG1UKvm0gijc3FiAUTEVsZRq aFOP3Rrbec6TPAdeOJs5X+SJgb6Krdumx9k4hPA7HFPKPMC8n6s8ptKpRKygmX3rt5ua k7Wg== X-Gm-Message-State: ALoCoQmspmJna0nsQVeQIKsIyegg5rjteggLtR8JAo+aeEhXMpvyWL01xAw7DC5OZnGtloTSQDKj X-Received: by 10.129.80.215 with SMTP id e206mr54552221ywb.94.1441968897777; Fri, 11 Sep 2015 03:54:57 -0700 (PDT) Received: from tlielax.poochiereds.net ([2606:a000:1105:8e:3a60:77ff:fe93:a95d]) by smtp.googlemail.com with ESMTPSA id u8sm489915ywe.17.2015.09.11.03.54.56 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 11 Sep 2015 03:54:57 -0700 (PDT) From: Jeff Layton X-Google-Original-From: Jeff Layton To: bfields@fieldses.org Cc: linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org Subject: [PATCH v4 05/16] locks: create a new notifier chain for lease attempts Date: Fri, 11 Sep 2015 06:54:31 -0400 Message-Id: <1441968882-7851-6-git-send-email-jeff.layton@primarydata.com> X-Mailer: git-send-email 2.4.3 In-Reply-To: <1441968882-7851-1-git-send-email-jeff.layton@primarydata.com> References: <1441968882-7851-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=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 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 --- 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 2a54c800a223..a2d5794d713a 100644 --- a/fs/locks.c +++ b/fs/locks.c @@ -166,6 +166,7 @@ int lease_break_time = 45; DEFINE_STATIC_LGLOCK(file_lock_lglock); static DEFINE_PER_CPU(struct hlist_head, file_lock_list); + /* * The blocked_hash is used to find POSIX lock loops for deadlock detection. * It is protected by blocked_lock_lock. @@ -1780,6 +1781,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 @@ -1800,6 +1835,7 @@ EXPORT_SYMBOL(generic_setlease); int vfs_setlease(struct file *filp, long arg, struct file_lock **lease, void **priv) { + setlease_notifier(arg, *lease); if (filp->f_op->setlease) return filp->f_op->setlease(filp, arg, lease, priv); else @@ -2696,6 +2732,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 9a9d314f7b27..e5fcf56c5ba1 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 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 *);