From patchwork Wed Oct 25 08:41:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 10026051 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 9C57860375 for ; Wed, 25 Oct 2017 08:44:38 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8C64128A37 for ; Wed, 25 Oct 2017 08:44:38 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 80BD928A4F; Wed, 25 Oct 2017 08:44:38 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.4 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RCVD_IN_SORBS_SPAM autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 25E6728A37 for ; Wed, 25 Oct 2017 08:44:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932348AbdJYInc (ORCPT ); Wed, 25 Oct 2017 04:43:32 -0400 Received: from mail-wr0-f194.google.com ([209.85.128.194]:48188 "EHLO mail-wr0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932246AbdJYIln (ORCPT ); Wed, 25 Oct 2017 04:41:43 -0400 Received: by mail-wr0-f194.google.com with SMTP id 15so9321206wrb.5 for ; Wed, 25 Oct 2017 01:41:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=v11T7EF6S5tVp9dKamJwl2x7BbRHLf0mCcmqsI3CqX8=; b=ntXe3m8nAZgZ7bCzf1zogKAvd+KS6PQSctWA6oiggU7DZ8diC1YYs9oRq64Q6iGStK d2PEE4qMJDJ67yTd1Jm+vTLv0VLS7SAsA2yKmMalKYMDAwFLerN9uMg+65qg8/vj00wa hluzgBH2UbSpzJe70ATs9h1/8uS8ZOg311L2YAn1CpUU1lfNYN7EJQ9C2bktksW46Ifk 1mdIbf5lgE2q7eDSR20IxsTcgrizVoaGjgjXe7MCXioSfBCYhIWyLewalit9tWwwVGws QOgcsL1rSA/nMHxPEmhZxNssWDaE793nqD7KBWhTByBG/7jW7ohxlm8YZaYqGbM0XxSB DC9g== X-Gm-Message-State: AMCzsaUXoFY/RYqE+ow+WbDgaI7OAK9Sov06WkU7/M2QZXuuDI2wPJgI FvLV3GLwRXeVmX37DZf3nwkA6JIu+EQ= X-Google-Smtp-Source: ABhQp+RaVuh10OlU1xHZ5dlh0S+AEsldah4z4vAF1raKC59DR2vqqm+DmU1+zDQeKL0Nh93VSpaAOw== X-Received: by 10.223.155.208 with SMTP id e16mr1401631wrc.161.1508920902193; Wed, 25 Oct 2017 01:41:42 -0700 (PDT) Received: from veci.piliscsaba.szeredi.hu (C2B0E321.catv.pool.telekom.hu. [194.176.227.33]) by smtp.gmail.com with ESMTPSA id 31sm1732312wrm.0.2017.10.25.01.41.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 25 Oct 2017 01:41:41 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Jan Kara , Amir Goldstein , Xiong Zhou , linux-kernel@vger.kernel.org Subject: [PATCH v2 1/7] fsnotify: clean up fsnotify_prepare/finish_user_wait() Date: Wed, 25 Oct 2017 10:41:33 +0200 Message-Id: <1508920899-8115-2-git-send-email-mszeredi@redhat.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1508920899-8115-1-git-send-email-mszeredi@redhat.com> References: <1508920899-8115-1-git-send-email-mszeredi@redhat.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP This patch doesn't actually fix any bug, just paves the way for fixing mark and group pinning. Signed-off-by: Miklos Szeredi Cc: # v4.12 --- fs/notify/mark.c | 89 ++++++++++++++++++++++++++------------------------------ 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/fs/notify/mark.c b/fs/notify/mark.c index 9991f8826734..982527ce6a58 100644 --- a/fs/notify/mark.c +++ b/fs/notify/mark.c @@ -109,16 +109,6 @@ void fsnotify_get_mark(struct fsnotify_mark *mark) atomic_inc(&mark->refcnt); } -/* - * Get mark reference when we found the mark via lockless traversal of object - * list. Mark can be already removed from the list by now and on its way to be - * destroyed once SRCU period ends. - */ -static bool fsnotify_get_mark_safe(struct fsnotify_mark *mark) -{ - return atomic_inc_not_zero(&mark->refcnt); -} - static void __fsnotify_recalc_mask(struct fsnotify_mark_connector *conn) { u32 new_mask = 0; @@ -256,32 +246,56 @@ void fsnotify_put_mark(struct fsnotify_mark *mark) FSNOTIFY_REAPER_DELAY); } -bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info) +/* + * Get mark reference when we found the mark via lockless traversal of object + * list. Mark can be already removed from the list by now and on its way to be + * destroyed once SRCU period ends. + */ +static bool fsnotify_get_mark_safe(struct fsnotify_mark *mark) { struct fsnotify_group *group; - if (WARN_ON_ONCE(!iter_info->inode_mark && !iter_info->vfsmount_mark)) - return false; - - if (iter_info->inode_mark) - group = iter_info->inode_mark->group; - else - group = iter_info->vfsmount_mark->group; + if (!mark) + return true; + group = mark->group; /* * Since acquisition of mark reference is an atomic op as well, we can * be sure this inc is seen before any effect of refcount increment. */ atomic_inc(&group->user_waits); + if (atomic_inc_not_zero(&mark->refcnt)) + return true; + + if (atomic_dec_and_test(&group->user_waits) && group->shutdown) + wake_up(&group->notification_waitq); - if (iter_info->inode_mark) { - /* This can fail if mark is being removed */ - if (!fsnotify_get_mark_safe(iter_info->inode_mark)) - goto out_wait; + return false; +} + +static void fsnotify_put_mark_wait(struct fsnotify_mark *mark) +{ + if (mark) { + struct fsnotify_group *group = mark->group; + + fsnotify_put_mark(mark); + /* + * We abuse notification_waitq on group shutdown for waiting for + * all marks pinned when waiting for userspace. + */ + if (atomic_dec_and_test(&group->user_waits) && group->shutdown) + wake_up(&group->notification_waitq); } - if (iter_info->vfsmount_mark) { - if (!fsnotify_get_mark_safe(iter_info->vfsmount_mark)) - goto out_inode; +} + +bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info) +{ + /* This can fail if mark is being removed */ + if (!fsnotify_get_mark_safe(iter_info->inode_mark)) + return false; + if (!fsnotify_get_mark_safe(iter_info->vfsmount_mark)) { + fsnotify_put_mark_wait(iter_info->inode_mark); + return false; } /* @@ -292,34 +306,13 @@ bool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info) srcu_read_unlock(&fsnotify_mark_srcu, iter_info->srcu_idx); return true; -out_inode: - if (iter_info->inode_mark) - fsnotify_put_mark(iter_info->inode_mark); -out_wait: - if (atomic_dec_and_test(&group->user_waits) && group->shutdown) - wake_up(&group->notification_waitq); - return false; } void fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info) { - struct fsnotify_group *group = NULL; - iter_info->srcu_idx = srcu_read_lock(&fsnotify_mark_srcu); - if (iter_info->inode_mark) { - group = iter_info->inode_mark->group; - fsnotify_put_mark(iter_info->inode_mark); - } - if (iter_info->vfsmount_mark) { - group = iter_info->vfsmount_mark->group; - fsnotify_put_mark(iter_info->vfsmount_mark); - } - /* - * We abuse notification_waitq on group shutdown for waiting for all - * marks pinned when waiting for userspace. - */ - if (atomic_dec_and_test(&group->user_waits) && group->shutdown) - wake_up(&group->notification_waitq); + fsnotify_put_mark_wait(iter_info->inode_mark); + fsnotify_put_mark_wait(iter_info->vfsmount_mark); } /*