[{"id":3669170,"web_url":"http://patchwork.ozlabs.org/comment/3669170/","msgid":"<k6xv2tjyz7npkkqxctsfgomanv26rckxafsyopzpniuuw7gtn3@aszcrskw4r6k>","list_archive_url":null,"date":"2026-03-25T15:52:47","subject":"Re: [LTP] [PATCH v4] fanotify22.c: handle multiple asynchronous\n error events","submitter":{"id":363,"url":"http://patchwork.ozlabs.org/api/people/363/","name":"Jan Kara","email":"jack@suse.cz"},"content":"On Wed 25-03-26 12:43:57, Wei Gao wrote:\n> Since the introduction of the asynchronous fserror reporting framework\n> (kernel commit 81d2e13a57c9), fanotify22 has encountered sporadic failures\n> due to the non-deterministic nature of event delivery and merging:\n> \n> 1) tcase3 failure: A race condition occurs when the test reads the\n>    notification fd between two events. uses a poll() and read() loop to wait\n>    until the expected.\n> \n> 2) tcase4 failure: The kernel may deliver errors as independent events\n>    instead of a single merged event, since different worker kthread can\n>    end up generating each event so they won't be merged. As suggested by\n>    Jan Kara, this patch introduces a consolidate_events() helper. It iterates\n>    through the event buffer, accumulates the error_count from all independent\n>    events, and updates the first event's count in-place.\n> \n> Reported-by: kernel test robot <oliver.sang@intel.com>\n> Closes: https://lore.kernel.org/oe-lkp/202602042124.87bd00e3-lkp@intel.com\n> Suggested-by: Jan Kara <jack@suse.cz>\n> Signed-off-by: Wei Gao <wegao@suse.com>\n\n...\n\n> +static size_t consolidate_events(char *buf, size_t len, const struct test_case *ex)\n> +{\n> +\tstruct fanotify_event_metadata *metadata, *first = NULL;\n> +\tstruct fanotify_event_info_error *first_info = NULL;\n> +\tunsigned int total_count = 0;\n> +\tint event_num = 0;\n> +\n> +\tfor (metadata = (struct fanotify_event_metadata *)buf;\n> +\t\t\tFAN_EVENT_OK(metadata, len);\n> +\t\t\tmetadata = FAN_EVENT_NEXT(metadata, len)) {\n> +\n> +\t\tevent_num++;\n> +\t\tstruct fanotify_event_info_error *info = get_event_info_error(metadata);\n> +\n> +\t\tif (!info) {\n> +\t\t\ttst_res(TFAIL, \"%s: Event [%d] missing error info\",\n> +\t\t\t\t\tex->name, event_num);\n> +\t\t\tcontinue;\n> +\t\t}\n> +\n> +\t\tif (info->error != ex->error && (ex->error2 == 0 || info->error != ex->error2)) {\n> +\t\t\ttst_res(TFAIL, \"%s: Event [%d] unexpected errno (%d)\",\n> +\t\t\t\t\tex->name, event_num, info->error);\n\nShould we add 'continue' here similarly to the failure case above? So that\nwe skip over the event with invalid error code... Otherwise the test looks\ncorrect to me.\n\n\t\t\t\t\t\t\t\tHonza\n\n> +\t\t}\n> +\n> +\t\tif (!first) {\n> +\t\t\tfirst = metadata;\n> +\t\t\tfirst_info = info;\n> +\t\t}\n> +\t\ttotal_count += info->error_count;\n> +\n> +\t\ttst_res(TINFO, \"Event [%d]: errno=%d, error_count=%d\",\n> +\t\t\t\tevent_num, info->error, info->error_count);\n> +\t}\n> +\n> +\tif (first_info)\n> +\t\tfirst_info->error_count = total_count;\n> +\n> +\treturn (first) ? first->event_len : 0;\n> +}\n> +\n>  static int check_error_event_info_fid(struct fanotify_event_info_fid *fid,\n>  \t\t\t\t const struct test_case *ex)\n>  {\n> @@ -248,19 +291,54 @@ static void check_event(char *buf, size_t len, const struct test_case *ex)\n>  static void do_test(unsigned int i)\n>  {\n>  \tconst struct test_case *tcase = &testcases[i];\n> -\tsize_t read_len;\n> +\tsize_t read_len = 0;\n> +\tstruct pollfd pfd;\n> +\tunsigned int accumulated_count = 0;\n>  \n>  \tSAFE_FANOTIFY_MARK(fd_notify, FAN_MARK_ADD|FAN_MARK_FILESYSTEM,\n>  \t\t\t   FAN_FS_ERROR, AT_FDCWD, MOUNT_PATH);\n>  \n>  \ttcase->trigger_error();\n>  \n> -\tread_len = SAFE_READ(0, fd_notify, event_buf, BUF_SIZE);\n> +\tpfd.fd = fd_notify;\n> +\tpfd.events = POLLIN;\n> +\n> +\twhile (accumulated_count < tcase->error_count) {\n> +\t\tif (poll(&pfd, 1, 5000) <= 0) {\n> +\t\t\ttst_res(TFAIL, \"%s: Timeout waiting for events\", tcase->name);\n> +\t\t\tgoto out;\n> +\t\t}\n> +\n> +\t\tchar *current_pos = event_buf + read_len;\n> +\t\tint ret = read(fd_notify, current_pos, BUF_SIZE - read_len);\n> +\n> +\t\tif (ret < 0) {\n> +\t\t\ttst_res(TFAIL, \"%s: read failed: %s\", tcase->name, strerror(errno));\n> +\t\t\tgoto out;\n> +\t\t}\n> +\n> +\t\tstruct fanotify_event_metadata *m =\n> +\t\t\t(struct fanotify_event_metadata *)current_pos;\n> +\t\twhile (FAN_EVENT_OK(m, ret)) {\n> +\t\t\tstruct fanotify_event_info_error *e = get_event_info_error(m);\n> +\n> +\t\t\tif (e)\n> +\t\t\t\taccumulated_count += e->error_count;\n> +\n> +\t\t\tread_len += m->event_len;\n> +\t\t\tm = FAN_EVENT_NEXT(m, ret);\n> +\t\t}\n> +\t}\n> +\n> +\tread_len = consolidate_events(event_buf, read_len, tcase);\n> +\n> +\tcheck_event(event_buf, read_len, tcase);\n> +\n> +out:\n>  \n>  \tSAFE_FANOTIFY_MARK(fd_notify, FAN_MARK_REMOVE|FAN_MARK_FILESYSTEM,\n>  \t\t\t   FAN_FS_ERROR, AT_FDCWD, MOUNT_PATH);\n>  \n> -\tcheck_event(event_buf, read_len, tcase);\n>  \t/* Unmount and mount the filesystem to get it out of the error state */\n>  \tSAFE_UMOUNT(MOUNT_PATH);\n>  \tSAFE_MOUNT(tst_device->dev, MOUNT_PATH, tst_device->fs_type, 0, NULL);\n> -- \n> 2.52.0\n>","headers":{"Return-Path":"<ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it>","X-Original-To":["incoming@patchwork.ozlabs.org","ltp@lists.linux.it"],"Delivered-To":["patchwork-incoming@legolas.ozlabs.org","ltp@picard.linux.it"],"Authentication-Results":["legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.linux.it\n (client-ip=2001:1418:10:5::2; helo=picard.linux.it;\n envelope-from=ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it;\n receiver=patchwork.ozlabs.org)","smtp-out2.suse.de;\n\tnone"],"Received":["from picard.linux.it (picard.linux.it [IPv6:2001:1418:10:5::2])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fgrz42fZNz1yG1\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 26 Mar 2026 02:53:04 +1100 (AEDT)","from picard.linux.it (localhost [IPv6:::1])\n\tby picard.linux.it (Postfix) with ESMTP id 858643E5528\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 25 Mar 2026 16:53:01 +0100 (CET)","from in-2.smtp.seeweb.it (in-2.smtp.seeweb.it [217.194.8.2])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature ECDSA (secp384r1))\n (No client certificate requested)\n by picard.linux.it (Postfix) with ESMTPS id C6A483CBBCC\n for <ltp@lists.linux.it>; Wed, 25 Mar 2026 16:52:57 +0100 (CET)","from smtp-out2.suse.de (smtp-out2.suse.de\n [IPv6:2a07:de40:b251:101:10:150:64:2])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest\n SHA256)\n (No client certificate requested)\n by in-2.smtp.seeweb.it (Postfix) with ESMTPS id BCEB160223E\n for <ltp@lists.linux.it>; Wed, 25 Mar 2026 16:52:56 +0100 (CET)","from imap1.dmz-prg2.suse.org (imap1.dmz-prg2.suse.org\n [IPv6:2a07:de40:b281:104:10:150:64:97])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest\n SHA256)\n (No client certificate requested)\n by smtp-out2.suse.de (Postfix) with ESMTPS id A38DA5BCCB;\n Wed, 25 Mar 2026 15:52:55 +0000 (UTC)","from imap1.dmz-prg2.suse.org (localhost [127.0.0.1])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest\n SHA256)\n (No client certificate requested)\n by imap1.dmz-prg2.suse.org (Postfix) with ESMTPS id 9A6154449C;\n Wed, 25 Mar 2026 15:52:55 +0000 (UTC)","from dovecot-director2.suse.de ([2a07:de40:b281:106:10:150:64:167])\n by imap1.dmz-prg2.suse.org with ESMTPSA id 6DStJdcExGkAIgAAD6G6ig\n (envelope-from <jack@suse.cz>); Wed, 25 Mar 2026 15:52:55 +0000","by quack3.suse.cz (Postfix, from userid 1000)\n id 541F1A0B32; Wed, 25 Mar 2026 16:52:47 +0100 (CET)"],"Date":"Wed, 25 Mar 2026 16:52:47 +0100","From":"Jan Kara <jack@suse.cz>","To":"Wei Gao <wegao@suse.com>","Message-ID":"<k6xv2tjyz7npkkqxctsfgomanv26rckxafsyopzpniuuw7gtn3@aszcrskw4r6k>","References":"<20260318064630.1604-1-wegao@suse.com>\n <20260325124428.6497-1-wegao@suse.com>","MIME-Version":"1.0","Content-Disposition":"inline","In-Reply-To":"<20260325124428.6497-1-wegao@suse.com>","X-Rspamd-Pre-Result":["action=no action; module=replies;\n Message is reply to one we originated","action=no action; module=replies;\n Message is reply to one we originated"],"X-Rspamd-Server":"rspamd2.dmz-prg2.suse.org","X-Spamd-Result":"default: False [-4.00 / 50.00];\n\tREPLY(-4.00)[]","X-Rspamd-Queue-Id":"A38DA5BCCB","X-Rspamd-Action":"no action","X-Spam-Score":"-4.00","X-Spam-Level":"","X-Spam-Status":"No, score=0.0 required=7.0 tests=DMARC_MISSING,SPF_HELO_NONE,\n SPF_PASS shortcircuit=no autolearn=disabled version=4.0.1","X-Spam-Checker-Version":"SpamAssassin 4.0.1 (2024-03-25) on in-2.smtp.seeweb.it","X-Virus-Scanned":"clamav-milter 1.0.9 at in-2.smtp.seeweb.it","X-Virus-Status":"Clean","Subject":"Re: [LTP] [PATCH v4] fanotify22.c: handle multiple asynchronous\n error events","X-BeenThere":"ltp@lists.linux.it","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"Linux Test Project <ltp.lists.linux.it>","List-Unsubscribe":"<https://lists.linux.it/options/ltp>,\n <mailto:ltp-request@lists.linux.it?subject=unsubscribe>","List-Archive":"<http://lists.linux.it/pipermail/ltp/>","List-Post":"<mailto:ltp@lists.linux.it>","List-Help":"<mailto:ltp-request@lists.linux.it?subject=help>","List-Subscribe":"<https://lists.linux.it/listinfo/ltp>,\n <mailto:ltp-request@lists.linux.it?subject=subscribe>","Cc":"Jan Kara <jack@suse.cz>, kernel test robot <oliver.sang@intel.com>,\n ltp@lists.linux.it","Content-Type":"text/plain; charset=\"us-ascii\"","Content-Transfer-Encoding":"7bit","Errors-To":"ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it","Sender":"\"ltp\" <ltp-bounces+incoming=patchwork.ozlabs.org@lists.linux.it>"}}]