From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0BF96C10F14 for ; Thu, 11 Apr 2019 03:24:57 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CD41720873 for ; Thu, 11 Apr 2019 03:24:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726551AbfDKDY4 (ORCPT ); Wed, 10 Apr 2019 23:24:56 -0400 Received: from youngberry.canonical.com ([91.189.89.112]:40010 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726230AbfDKDY4 (ORCPT ); Wed, 10 Apr 2019 23:24:56 -0400 Received: from mail-pg1-f200.google.com ([209.85.215.200]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1hEQKc-0007Kf-7K for stable@vger.kernel.org; Thu, 11 Apr 2019 03:24:54 +0000 Received: by mail-pg1-f200.google.com with SMTP id 14so3476700pgf.22 for ; Wed, 10 Apr 2019 20:24:54 -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:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=s5beppC1x3K2Zd7gZx3yN/TiqLAryVWMkoZXI6z1zH8=; b=gd1MvmyfYiykmLZz38WlR88yntVV0rDVhH4Sp8CjonsTMer09SUtjJqKIpVBlNgoVw xutIJXTKMq9ddTYnuHuwsHqLaUHtgdk4SFGc4nFUewx6fbjQy9f/AoLQA3TDRvNjGPYZ r8IXzIFq9m+fVb+ZWLGgX91cdkhB058J0Nn4qfgW2z1W93oraj/NWCRN8ASGPCT8QE6S 2zr2TMiaZNYpNiAr1vbs5oiNNrrsjVMGmiRyfi8JTNpcfAAKug3mEzcpF0hqwtZmyOVj gqARjXLIVO7/3OnFlRcU0xG2dz7OaXy6NETZpZrK9XTO7nEWMK2w8U0aCnqbxbX1FzG3 OJCQ== X-Gm-Message-State: APjAAAXRSOvfd55ntvJmw6fe3TADPT/JKd6UKOidADnxS+MLpVtLuheP cI+LGKk1pX/2XiV1HIOPf5REqongzfmcG6VVnYp8CnY+3ao/vIEEZvtBnv3QEbSNk/aTCtlurSq yuI2fepUNr9Q59KCWKrmP7SUYXPTlBVqkzw== X-Received: by 2002:a63:30c5:: with SMTP id w188mr44212996pgw.76.1554953092672; Wed, 10 Apr 2019 20:24:52 -0700 (PDT) X-Google-Smtp-Source: APXvYqzqnn9AEKVkcB4ujOMN1oEwo3JBJ78sWSlvR8dkLJqrx6oXC18kB01J55bI8XFpK9eNdCNbnw== X-Received: by 2002:a63:30c5:: with SMTP id w188mr44212980pgw.76.1554953092418; Wed, 10 Apr 2019 20:24:52 -0700 (PDT) Received: from localhost.localdomain (222-154-101-5-fibre.sparkbb.co.nz. [222.154.101.5]) by smtp.gmail.com with ESMTPSA id s16sm50747170pgo.69.2019.04.10.20.24.50 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 10 Apr 2019 20:24:51 -0700 (PDT) From: Matthew Ruffell To: stable@vger.kernel.org Subject: [PATCH 4.9 2/3] fsnotify: Pass fsnotify_iter_info into handle_event handler Date: Thu, 11 Apr 2019 15:24:29 +1200 Message-Id: <20190411032430.17353-3-matthew.ruffell@canonical.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190411032430.17353-1-matthew.ruffell@canonical.com> References: <20190411032430.17353-1-matthew.ruffell@canonical.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Jan Kara commit 9385a84d7e1f658bb2d96ab798393e4b16268aaa upstream. Pass fsnotify_iter_info into ->handle_event() handler so that it can release and reacquire SRCU lock via fsnotify_prepare_user_wait() and fsnotify_finish_user_wait() functions. These functions also make sure current marks are appropriately pinned so that iteration protected by srcu in fsnotify() stays safe. Reviewed-by: Miklos Szeredi Reviewed-by: Amir Goldstein Signed-off-by: Jan Kara [mruffell: backport: removing const keyword and minor realignment] Signed-off-by: Matthew Ruffell --- fs/notify/dnotify/dnotify.c | 3 ++- fs/notify/fanotify/fanotify.c | 3 ++- fs/notify/fsnotify.c | 19 +++++++++++++------ fs/notify/inotify/inotify.h | 3 ++- fs/notify/inotify/inotify_fsnotify.c | 3 ++- fs/notify/inotify/inotify_user.c | 2 +- include/linux/fsnotify_backend.h | 3 ++- kernel/audit_fsnotify.c | 3 ++- kernel/audit_tree.c | 3 ++- kernel/audit_watch.c | 3 ++- 10 files changed, 30 insertions(+), 15 deletions(-) diff --git a/fs/notify/dnotify/dnotify.c b/fs/notify/dnotify/dnotify.c index 6faaf710e563..264bfd99a694 100644 --- a/fs/notify/dnotify/dnotify.c +++ b/fs/notify/dnotify/dnotify.c @@ -86,7 +86,8 @@ static int dnotify_handle_event(struct fsnotify_group *group, struct fsnotify_mark *inode_mark, struct fsnotify_mark *vfsmount_mark, u32 mask, void *data, int data_type, - const unsigned char *file_name, u32 cookie) + const unsigned char *file_name, u32 cookie, + struct fsnotify_iter_info *iter_info) { struct dnotify_mark *dn_mark; struct dnotify_struct *dn; diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 8a459b179183..4944956cdbd9 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c @@ -174,7 +174,8 @@ static int fanotify_handle_event(struct fsnotify_group *group, struct fsnotify_mark *inode_mark, struct fsnotify_mark *fanotify_mark, u32 mask, void *data, int data_type, - const unsigned char *file_name, u32 cookie) + const unsigned char *file_name, u32 cookie, + struct fsnotify_iter_info *iter_info) { int ret = 0; struct fanotify_event_info *event; diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 56b4f855fa9b..da8c6674990d 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -131,7 +131,8 @@ static int send_to_group(struct inode *to_tell, struct fsnotify_mark *vfsmount_mark, __u32 mask, void *data, int data_is, u32 cookie, - const unsigned char *file_name) + const unsigned char *file_name, + struct fsnotify_iter_info *iter_info) { struct fsnotify_group *group = NULL; __u32 inode_test_mask = 0; @@ -182,7 +183,7 @@ static int send_to_group(struct inode *to_tell, return group->ops->handle_event(group, to_tell, inode_mark, vfsmount_mark, mask, data, data_is, - file_name, cookie); + file_name, cookie, iter_info); } /* @@ -197,8 +198,9 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, struct hlist_node *inode_node = NULL, *vfsmount_node = NULL; struct fsnotify_mark *inode_mark = NULL, *vfsmount_mark = NULL; struct fsnotify_group *inode_group, *vfsmount_group; + struct fsnotify_iter_info iter_info; struct mount *mnt; - int idx, ret = 0; + int ret = 0; /* global tests shouldn't care about events on child only the specific event */ __u32 test_mask = (mask & ~FS_EVENT_ON_CHILD); @@ -231,7 +233,7 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, !(mnt && test_mask & mnt->mnt_fsnotify_mask)) return 0; - idx = srcu_read_lock(&fsnotify_mark_srcu); + iter_info.srcu_idx = srcu_read_lock(&fsnotify_mark_srcu); if ((mask & FS_MODIFY) || (test_mask & to_tell->i_fsnotify_mask)) @@ -280,8 +282,13 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, vfsmount_mark = NULL; } } + + iter_info.inode_mark = inode_mark; + iter_info.vfsmount_mark = vfsmount_mark; + ret = send_to_group(to_tell, inode_mark, vfsmount_mark, mask, - data, data_is, cookie, file_name); + data, data_is, cookie, file_name, + &iter_info); if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS)) goto out; @@ -295,7 +302,7 @@ int fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, } ret = 0; out: - srcu_read_unlock(&fsnotify_mark_srcu, idx); + srcu_read_unlock(&fsnotify_mark_srcu, iter_info.srcu_idx); return ret; } diff --git a/fs/notify/inotify/inotify.h b/fs/notify/inotify/inotify.h index ed855ef6f077..726b06b303b8 100644 --- a/fs/notify/inotify/inotify.h +++ b/fs/notify/inotify/inotify.h @@ -27,6 +27,7 @@ extern int inotify_handle_event(struct fsnotify_group *group, struct fsnotify_mark *inode_mark, struct fsnotify_mark *vfsmount_mark, u32 mask, void *data, int data_type, - const unsigned char *file_name, u32 cookie); + const unsigned char *file_name, u32 cookie, + struct fsnotify_iter_info *iter_info); extern const struct fsnotify_ops inotify_fsnotify_ops; diff --git a/fs/notify/inotify/inotify_fsnotify.c b/fs/notify/inotify/inotify_fsnotify.c index 2cd900c2c737..79a5f06b9100 100644 --- a/fs/notify/inotify/inotify_fsnotify.c +++ b/fs/notify/inotify/inotify_fsnotify.c @@ -67,7 +67,8 @@ int inotify_handle_event(struct fsnotify_group *group, struct fsnotify_mark *inode_mark, struct fsnotify_mark *vfsmount_mark, u32 mask, void *data, int data_type, - const unsigned char *file_name, u32 cookie) + const unsigned char *file_name, u32 cookie, + struct fsnotify_iter_info *iter_info) { struct inotify_inode_mark *i_mark; struct inotify_event_info *event; diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c index 69d1ea3d292a..25336bd8d9aa 100644 --- a/fs/notify/inotify/inotify_user.c +++ b/fs/notify/inotify/inotify_user.c @@ -494,7 +494,7 @@ void inotify_ignored_and_remove_idr(struct fsnotify_mark *fsn_mark, /* Queue ignore event for the watch */ inotify_handle_event(group, NULL, fsn_mark, NULL, FS_IN_IGNORED, - NULL, FSNOTIFY_EVENT_NONE, NULL, 0); + NULL, FSNOTIFY_EVENT_NONE, NULL, 0, NULL); i_mark = container_of(fsn_mark, struct inotify_inode_mark, fsn_mark); /* remove this mark from the idr */ diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h index 3de53a2b8944..4174d7e2898a 100644 --- a/include/linux/fsnotify_backend.h +++ b/include/linux/fsnotify_backend.h @@ -98,7 +98,8 @@ struct fsnotify_ops { struct fsnotify_mark *inode_mark, struct fsnotify_mark *vfsmount_mark, u32 mask, void *data, int data_type, - const unsigned char *file_name, u32 cookie); + const unsigned char *file_name, u32 cookie, + struct fsnotify_iter_info *iter_info); void (*free_group_priv)(struct fsnotify_group *group); void (*freeing_mark)(struct fsnotify_mark *mark, struct fsnotify_group *group); void (*free_event)(struct fsnotify_event *event); diff --git a/kernel/audit_fsnotify.c b/kernel/audit_fsnotify.c index f84f8d06e1f6..231c0f3cbf2b 100644 --- a/kernel/audit_fsnotify.c +++ b/kernel/audit_fsnotify.c @@ -169,7 +169,8 @@ static int audit_mark_handle_event(struct fsnotify_group *group, struct fsnotify_mark *inode_mark, struct fsnotify_mark *vfsmount_mark, u32 mask, void *data, int data_type, - const unsigned char *dname, u32 cookie) + const unsigned char *dname, u32 cookie, + struct fsnotify_iter_info *iter_info) { struct audit_fsnotify_mark *audit_mark; struct inode *inode = NULL; diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index 25772476fa4a..b0bdebaf811d 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c @@ -949,7 +949,8 @@ static int audit_tree_handle_event(struct fsnotify_group *group, struct fsnotify_mark *inode_mark, struct fsnotify_mark *vfsmount_mark, u32 mask, void *data, int data_type, - const unsigned char *file_name, u32 cookie) + const unsigned char *file_name, u32 cookie, + struct fsnotify_iter_info *iter_info) { return 0; } diff --git a/kernel/audit_watch.c b/kernel/audit_watch.c index f036b6ada6ef..160d52b662e2 100644 --- a/kernel/audit_watch.c +++ b/kernel/audit_watch.c @@ -485,7 +485,8 @@ static int audit_watch_handle_event(struct fsnotify_group *group, struct fsnotify_mark *inode_mark, struct fsnotify_mark *vfsmount_mark, u32 mask, void *data, int data_type, - const unsigned char *dname, u32 cookie) + const unsigned char *dname, u32 cookie, + struct fsnotify_iter_info *iter_info) { struct inode *inode; struct audit_parent *parent; -- 2.19.1