--- a/fs/notify/dnotify/dnotify.c 2022-10-29 11:33:20.738540400 +0800 +++ b/fs/notify/dnotify/dnotify.c 2022-10-29 13:44:44.968617800 +0800 @@ -138,9 +138,21 @@ static void dnotify_free_mark(struct fsn kmem_cache_free(dnotify_mark_cache, dn_mark); } +static int dnotify_check_mark(struct fsnotify_mark *fsn_mark) +{ + struct dnotify_mark *dn_mark = container_of(fsn_mark, + struct dnotify_mark, + fsn_mark); + if (dn_mark->dn) + return 1; + else + return 0; +} + static const struct fsnotify_ops dnotify_fsnotify_ops = { .handle_inode_event = dnotify_handle_event, .free_mark = dnotify_free_mark, + .check_mark = dnotify_check_mark, }; /* --- a/fs/notify/mark.c 2022-10-29 11:32:48.394489200 +0800 +++ b/fs/notify/mark.c 2022-10-29 13:39:52.986357800 +0800 @@ -331,6 +331,9 @@ void fsnotify_put_mark(struct fsnotify_m spin_unlock(&destroy_lock); queue_work(system_unbound_wq, &connector_reaper_work); } + + if (mark->group->ops->check_mark) + WARN_ON_ONCE(mark->group->ops->check_mark(mark)); /* * Note that we didn't update flags telling whether inode cares about * what's happening with children. We update these flags from --- a/include/linux/fsnotify_backend.h 2022-10-29 13:35:58.637169500 +0800 +++ b/include/linux/fsnotify_backend.h 2022-10-29 13:37:12.518647400 +0800 @@ -165,6 +165,7 @@ struct fsnotify_ops { void (*free_event)(struct fsnotify_group *group, struct fsnotify_event *event); /* called on final put+free to free memory */ void (*free_mark)(struct fsnotify_mark *mark); + int (*check_mark)(struct fsnotify_mark *mark); }; /*