From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932397AbdJYIl6 (ORCPT ); Wed, 25 Oct 2017 04:41:58 -0400 Received: from mail-wr0-f193.google.com ([209.85.128.193]:46315 "EHLO mail-wr0-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932327AbdJYIlq (ORCPT ); Wed, 25 Oct 2017 04:41:46 -0400 X-Google-Smtp-Source: ABhQp+RYD5T9O7fQf+oEmGhLT9XvOZgeloL5m6JG7Ddrwc2n+DEseJ+OvsumTatmu2wJHp7eMYRVZA== From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Jan Kara , Amir Goldstein , Xiong Zhou , linux-kernel@vger.kernel.org Subject: [PATCH v2 4/7] fsnotify: skip unattached marks Date: Wed, 25 Oct 2017 10:41:36 +0200 Message-Id: <1508920899-8115-5-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-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org After having gone through a ref-unref for the mark, dereferencing the group (e.g. in fsnotify_compare_groups()) is wrong since the group may be completely gone by that time. So before continuing to traverse the mark list, check if the mark is still attached. This is done in the generic case, not just when we go through fsnotify_prepare_user_wait()/fsnotify_finish_user_wait(), otherwise it would introduce unnecessary complexity. And it shouldn't hurt to skip unattached marks anyway ("flags" is very likely in same cacheline as neighbouring "ignored_mask", which is pulled in anyway). Signed-off-by: Miklos Szeredi Fixes: 9385a84d7e1f ("fsnotify: Pass fsnotify_iter_info into handle_event handler") Cc: # v4.12 --- fs/notify/fsnotify.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 48ec61f4c4d5..0ab6a7179e4d 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c @@ -328,12 +328,16 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is, inode_mark = hlist_entry(srcu_dereference(inode_node, &fsnotify_mark_srcu), struct fsnotify_mark, obj_list); inode_group = inode_mark->group; + if (!(inode_mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)) + goto skip_inode; } if (vfsmount_node) { vfsmount_mark = hlist_entry(srcu_dereference(vfsmount_node, &fsnotify_mark_srcu), struct fsnotify_mark, obj_list); vfsmount_group = vfsmount_mark->group; + if (!(vfsmount_mark->flags & FSNOTIFY_MARK_FLAG_ATTACHED)) + goto skip_vfsmount; } iter_info.inode_mark = inode_mark; @@ -357,10 +361,11 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is, if (ret && (mask & ALL_FSNOTIFY_PERM_EVENTS)) goto out; - +skip_inode: if (inode_group) inode_node = srcu_dereference(inode_node->next, &fsnotify_mark_srcu); +skip_vfsmount: if (vfsmount_group) vfsmount_node = srcu_dereference(vfsmount_node->next, &fsnotify_mark_srcu); -- 2.5.5