Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.2/patches/2186633/?format=api
{ "id": 2186633, "url": "http://patchwork.ozlabs.org/api/1.2/patches/2186633/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-ext4/patch/20260120112538.132774-4-me@linux.beauty/", "project": { "id": 8, "url": "http://patchwork.ozlabs.org/api/1.2/projects/8/?format=api", "name": "Linux ext4 filesystem development", "link_name": "linux-ext4", "list_id": "linux-ext4.vger.kernel.org", "list_email": "linux-ext4@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260120112538.132774-4-me@linux.beauty>", "list_archive_url": null, "date": "2026-01-20T11:25:32", "name": "[RFC,v4,3/7] ext4: fast commit: avoid waiting for FC_COMMITTING", "commit_ref": null, "pull_url": null, "state": "superseded", "archived": false, "hash": "549604a537ee06402d24f85a64b87d87f0c9ef17", "submitter": { "id": 84264, "url": "http://patchwork.ozlabs.org/api/1.2/people/84264/?format=api", "name": "Li Chen", "email": "me@linux.beauty" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-ext4/patch/20260120112538.132774-4-me@linux.beauty/mbox/", "series": [ { "id": 489032, "url": "http://patchwork.ozlabs.org/api/1.2/series/489032/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-ext4/list/?series=489032", "date": "2026-01-20T11:25:32", "name": "ext4: fast commit: snapshot inode state for FC log", "version": 4, "mbox": "http://patchwork.ozlabs.org/series/489032/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2186633/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2186633/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "\n <SRS0=nNWE=7Z=vger.kernel.org=linux-ext4+bounces-13101-patchwork-incoming=ozlabs.org@ozlabs.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linux-ext4@vger.kernel.org" ], "Delivered-To": [ "patchwork-incoming@legolas.ozlabs.org", "patchwork-incoming@ozlabs.org" ], "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=linux.beauty header.i=me@linux.beauty\n header.a=rsa-sha256 header.s=zmail header.b=NvPJEYap;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=ozlabs.org\n (client-ip=2404:9400:2221:ea00::3; helo=mail.ozlabs.org;\n envelope-from=srs0=nnwe=7z=vger.kernel.org=linux-ext4+bounces-13101-patchwork-incoming=ozlabs.org@ozlabs.org;\n receiver=patchwork.ozlabs.org)", "gandalf.ozlabs.org;\n arc=pass smtp.remote-ip=\"2a01:60a::1994:3:14\"\n arc.chain=\"subspace.kernel.org:zohomail.com\"", "gandalf.ozlabs.org;\n dmarc=none (p=none dis=none) header.from=linux.beauty", "gandalf.ozlabs.org;\n spf=fail smtp.mailfrom=vger.kernel.org", "gandalf.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=linux.beauty header.i=me@linux.beauty\n header.a=rsa-sha256 header.s=zmail header.b=NvPJEYap;\n\tdkim-atps=neutral", "gandalf.ozlabs.org;\n spf=softfail (domain owner discourages use of this host)\n smtp.mailfrom=vger.kernel.org (client-ip=2a01:60a::1994:3:14;\n helo=ams.mirrors.kernel.org;\n envelope-from=linux-ext4+bounces-13101-patchwork-incoming=ozlabs.org@vger.kernel.org;\n receiver=ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (1024-bit key) header.d=linux.beauty header.i=me@linux.beauty\n header.b=\"NvPJEYap\"", "smtp.subspace.kernel.org;\n arc=pass smtp.client-ip=136.143.188.112", "smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=linux.beauty", "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=linux.beauty" ], "Received": [ "from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1 raw public key)\n server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4dwQGL1q6dz1xsW\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 20 Jan 2026 22:34:32 +1100 (AEDT)", "from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3])\n\tby gandalf.ozlabs.org (Postfix) with ESMTP id 4dwQGC0DfCz4wB9\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 20 Jan 2026 22:34:27 +1100 (AEDT)", "by gandalf.ozlabs.org (Postfix)\n\tid 4dwQGC08Ccz4w8x; Tue, 20 Jan 2026 22:34:27 +1100 (AEDT)", "from ams.mirrors.kernel.org (ams.mirrors.kernel.org\n [IPv6:2a01:60a::1994:3:14])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby gandalf.ozlabs.org (Postfix) with ESMTPS id 4dwQG72s5gz4wB9\n\tfor <patchwork-incoming@ozlabs.org>; Tue, 20 Jan 2026 22:34:23 +1100 (AEDT)", "from smtp.subspace.kernel.org (relay.kernel.org [52.25.139.140])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ams.mirrors.kernel.org (Postfix) with ESMTPS id F0139607108\n\tfor <patchwork-incoming@ozlabs.org>; Tue, 20 Jan 2026 11:27:27 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id 5B9A04218B2;\n\tTue, 20 Jan 2026 11:26:44 +0000 (UTC)", "from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com\n [136.143.188.112])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id 3CDB63D7D70;\n\tTue, 20 Jan 2026 11:26:41 +0000 (UTC)", "by mx.zohomail.com with SMTPS id 1768908366190318.19128356582803;\n\tTue, 20 Jan 2026 03:26:06 -0800 (PST)" ], "ARC-Seal": [ "i=3; a=rsa-sha256; d=ozlabs.org; s=201707; t=1768908867; cv=pass;\n\tb=WPk50gUTg2GwCnU4EJSRSo9aLGW0QFICflGeqa6h7TEjNachsgoI/26dqCDElHBOU6r+fY+f0+a0eknINphEMs+JG1l6U7JeaZKOIyIJI1aJymYvJyNUTSYv/Dlo+LuzCkoPnpvnAVgjKfPm+ypkrmlql5JpZhrCsGaKHVt5/t+laIGzPmSjLtSSHbgMiuQWTwK8//RxxyhKs9aurhr81oL7B11BU3CIb/Pzqp402xN/Ax7eM0KUUv9fiOsnloCm21tWGk5hazcG2AMCM5Zbf61yIrGlatbh7NhDbj8Rl3S5pgA1wCQ6yFEF7fLY273LQNLdjk/bVoxyPH+GDV/TjA==", "i=2; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1768908404; cv=pass;\n b=fsQPgUAWqnNrrn5K9V/qmi7YDBTXz9oR2Utwxpa3Ew4kfqGZLieEzJGA7renmJ11sYvBAitIjk4Cu4uzFUPSfIF3MBtErEW/0hWLXSGJ+ne8390J+tw5to5bpNOxunEVNa4YI8k7izjDgHL7w4/u5R2OfcIf5/PpketkWMAItDg=", "i=1; a=rsa-sha256; t=1768908369; cv=none;\n\td=zohomail.com; s=zohoarc;\n\tb=HEFy1BNrturUfItF5xI1zmDEbMLuwiuL6QuhFtY4PVFIx8fc+UZxOUKiXBZsoQp7v+DXHlEJGJz67xNWAQot/M7qlCZNx1oiNrhSs3S/wrbAfI6rZrdSkF3IEk6hY1GDDH9oytykzuOBawfxC6phHSCmkWpnHl2rkaAo6/t4nNM=" ], "ARC-Message-Signature": [ "i=3; a=rsa-sha256; d=ozlabs.org; s=201707;\n\tt=1768908867; c=relaxed/relaxed;\n\tbh=HAF1RpwukyGeuc7wGeqNCkIU3/qoXem/XaVka3lV/3c=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=lDxMltCXeT02akyeIHaxIg1ONV0RK7cvX0ik3G2+pRt2RtK4kEKZ08ZKnWCxZ1dAWfd+60LlHGhP7NS/k3y22VBMkaZNkDVUdeVE+4OyeES14x2jW+iGFKGcC3xIXZHZk2l7mKxstMYRgFcAdBPJ7l6nqgTMjDSXdDKgi2sZ/MVn89rcGzI2/FRylkrWsO7jWyhecgtVWZFmOXNMT1n2RNmH+I0JHSKlzkAkS5MzKkqL+gLGWcHW55lUTTUPqn3QOgvq+l5hixfIkTXd9spF2p00c03Zag9++LdcA3R9ToGfPpCfEnO1i/OaA9ZjWIQU4hvIAooI4rkb7xvQB3sSbQ==", "i=2; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1768908404; c=relaxed/simple;\n\tbh=bxUU6eS+6sOG1Fyxecxje/jiO3ZgoB+3+tqldvMGRug=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=N5uI7oGG/uifnhNdSASdTN/M6VowgxJ6GxmyXiIOIQ+j20w3iV3eSxvbYw5wXqlDu9qLbvowkisBAYfkMvV1VuAdQ5nm+aCq/7LKf2PmUbg0QJFgtHE4Tk34/i/JyZsrYJkq6yJpfh+BpFxNY+bICcg3oaJATDtj4yFYWKu5hlE=", "i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com;\n s=zohoarc;\n\tt=1768908369;\n h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To;\n\tbh=HAF1RpwukyGeuc7wGeqNCkIU3/qoXem/XaVka3lV/3c=;\n\tb=Qt02LUFVt1KgdfT+ZZOQoXJNh7Q5+LZfsMW/6qeoFK8xsTC1qcaKVhgHwCSC5UF7io2d0NJwxGfQN5sZ4mXoULYPjWA0DWBXEDSiaTO4t8BOKx8TQz0TGrueyDVgcA6NWA6s0ncUKEoutmJH0cYA1wY/VNBQCAlr2BLq9AcwTlQ=" ], "ARC-Authentication-Results": [ "i=3; gandalf.ozlabs.org;\n dmarc=none (p=none dis=none) header.from=linux.beauty;\n spf=fail smtp.mailfrom=vger.kernel.org; dkim=pass (1024-bit key;\n unprotected) header.d=linux.beauty header.i=me@linux.beauty\n header.a=rsa-sha256 header.s=zmail header.b=NvPJEYap; dkim-atps=neutral;\n spf=softfail (client-ip=2a01:60a::1994:3:14; helo=ams.mirrors.kernel.org;\n envelope-from=linux-ext4+bounces-13101-patchwork-incoming=ozlabs.org@vger.kernel.org;\n receiver=ozlabs.org) smtp.mailfrom=vger.kernel.org", "i=2; smtp.subspace.kernel.org;\n dmarc=none (p=none dis=none) header.from=linux.beauty;\n spf=pass smtp.mailfrom=linux.beauty;\n dkim=pass (1024-bit key) header.d=linux.beauty header.i=me@linux.beauty\n header.b=NvPJEYap; arc=pass smtp.client-ip=136.143.188.112", "i=1; mx.zohomail.com;\n\tdkim=pass header.i=linux.beauty;\n\tspf=pass smtp.mailfrom=me@linux.beauty;\n\tdmarc=pass header.from=<me@linux.beauty>" ], "DKIM-Signature": "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1768908369;\n\ts=zmail; d=linux.beauty; i=me@linux.beauty;\n\th=From:From:To:To:Cc:Cc:Subject:Subject:Date:Date:Message-ID:In-Reply-To:References:MIME-Version:Content-Transfer-Encoding:Message-Id:Reply-To;\n\tbh=HAF1RpwukyGeuc7wGeqNCkIU3/qoXem/XaVka3lV/3c=;\n\tb=NvPJEYap8LC28FX9KnitKVhXKv/T3acOcq57raXhNzdMUxdFfPO3A/FyCqtKVkot\n\t2YufIyr6E2GAtUpcd6Caaqvx4lib5WWnAlydsxA7q2I43lGjfFPXhHhoN9UtEGDb6fE\n\t/lF1jL2qaJ+Zm9zEnGdV+1R9XRFjDPjt/HkSei8Q=", "From": "Li Chen <me@linux.beauty>", "To": "Zhang Yi <yi.zhang@huaweicloud.com>,\n\t\"Theodore Ts'o\" <tytso@mit.edu>,\n\tAndreas Dilger <adilger.kernel@dilger.ca>,\n\tlinux-ext4@vger.kernel.org,\n\tlinux-kernel@vger.kernel.org", "Cc": "Li Chen <me@linux.beauty>", "Subject": "[RFC v4 3/7] ext4: fast commit: avoid waiting for FC_COMMITTING", "Date": "Tue, 20 Jan 2026 19:25:32 +0800", "Message-ID": "<20260120112538.132774-4-me@linux.beauty>", "X-Mailer": "git-send-email 2.52.0", "In-Reply-To": "<20260120112538.132774-1-me@linux.beauty>", "References": "<20260120112538.132774-1-me@linux.beauty>", "Precedence": "bulk", "X-Mailing-List": "linux-ext4@vger.kernel.org", "List-Id": "<linux-ext4.vger.kernel.org>", "List-Subscribe": "<mailto:linux-ext4+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:linux-ext4+unsubscribe@vger.kernel.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-ZohoMailClient": "External", "X-Spam-Status": "No, score=-0.2 required=5.0 tests=ARC_SIGNED,ARC_VALID,\n\tDKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DMARC_MISSING,\n\tHEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,SPF_HELO_NONE,\n\tSPF_SOFTFAIL autolearn=disabled version=4.0.1", "X-Spam-Checker-Version": "SpamAssassin 4.0.1 (2024-03-25) on gandalf.ozlabs.org" }, "content": "ext4_fc_track_inode() can be called while holding i_data_sem (e.g.\nfallocate). Waiting for EXT4_STATE_FC_COMMITTING in that case risks an\nABBA deadlock: i_data_sem -> wait(FC_COMMITTING) vs FC_COMMITTING ->\nwait(i_data_sem) in the commit task.\n\nNow that fast commit snapshots inode state at commit time, updates during\nlog writing do not need to block. Drop the wait and lockdep assertion in\next4_fc_track_inode(), and make ext4_fc_del() wait for FC_COMMITTING so an\ninode cannot be removed while the commit thread is still using it.\n\nWhen an inode is modified during a fast commit, mark it with\nEXT4_STATE_FC_REQUEUE so cleanup keeps it queued for the next fast commit.\nThis is needed because jbd2_fc_end_commit() invokes the cleanup callback\nwith tid == 0, so tid-based requeue logic would requeue every inode.\n\nTesting: tracepoint ext4:ext4_fc_commit_stop with two fsyncs in the same\ntransaction. nblks is the number of journal blocks written for that fast\ncommit. Before this change, the second fsync still wrote almost the same\nfast commit log (nblks 10->9), because tid == 0 in jbd2_fc_end_commit()\ncaused the tid-based requeue logic to keep all inodes queued. After this\nchange, only inodes modified during the commit are requeued, and the\nsecond fsync wrote a nearly empty fast commit (nblks 10->1).\n\nSigned-off-by: Li Chen <me@linux.beauty>\n---\n fs/ext4/ext4.h | 1 +\n fs/ext4/fast_commit.c | 111 ++++++++++++++++++++----------------------\n 2 files changed, 53 insertions(+), 59 deletions(-)", "diff": "diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h\nindex 2e1681057196..68a64fa0be92 100644\n--- a/fs/ext4/ext4.h\n+++ b/fs/ext4/ext4.h\n@@ -2004,6 +2004,7 @@ enum {\n \tEXT4_STATE_FC_COMMITTING,\t/* Fast commit ongoing */\n \tEXT4_STATE_FC_FLUSHING_DATA,\t/* Fast commit flushing data */\n \tEXT4_STATE_ORPHAN_FILE,\t\t/* Inode orphaned in orphan file */\n+\tEXT4_STATE_FC_REQUEUE,\t\t/* Inode modified during fast commit */\n };\n \n #define EXT4_INODE_BIT_FNS(name, field, offset)\t\t\t\t\\\ndiff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c\nindex d5c28304e818..809170d46167 100644\n--- a/fs/ext4/fast_commit.c\n+++ b/fs/ext4/fast_commit.c\n@@ -61,9 +61,8 @@\n * setting \"EXT4_STATE_FC_COMMITTING\" state, and snapshot the inode state\n * needed for log writing.\n * [5] Unlock the journal by calling jbd2_journal_unlock_updates(). This allows\n- * starting of new handles. If new handles try to start an update on\n- * any of the inodes that are being committed, ext4_fc_track_inode()\n- * will block until those inodes have finished the fast commit.\n+ * starting of new handles. Updates to inodes being fast committed are\n+ * tracked for requeue rather than blocking.\n * [6] Commit all the directory entry updates in the fast commit space.\n * [7] Commit all the changed inodes in the fast commit space.\n * [8] Write tail tag (this tag ensures the atomicity, please read the following\n@@ -217,6 +216,7 @@ void ext4_fc_init_inode(struct inode *inode)\n \n \text4_fc_reset_inode(inode);\n \text4_clear_inode_state(inode, EXT4_STATE_FC_COMMITTING);\n+\text4_clear_inode_state(inode, EXT4_STATE_FC_REQUEUE);\n \tINIT_LIST_HEAD(&ei->i_fc_list);\n \tINIT_LIST_HEAD(&ei->i_fc_dilist);\n \tei->i_fc_snap = NULL;\n@@ -251,22 +251,30 @@ void ext4_fc_del(struct inode *inode)\n \t}\n \n \t/*\n-\t * Since ext4_fc_del is called from ext4_evict_inode while having a\n-\t * handle open, there is no need for us to wait here even if a fast\n-\t * commit is going on. That is because, if this inode is being\n-\t * committed, ext4_mark_inode_dirty would have waited for inode commit\n-\t * operation to finish before we come here. So, by the time we come\n-\t * here, inode's EXT4_STATE_FC_COMMITTING would have been cleared. So,\n-\t * we shouldn't see EXT4_STATE_FC_COMMITTING to be set on this inode\n-\t * here.\n-\t *\n-\t * We may come here without any handles open in the \"no_delete\" case of\n-\t * ext4_evict_inode as well. However, if that happens, we first mark the\n-\t * file system as fast commit ineligible anyway. So, even in that case,\n-\t * it is okay to remove the inode from the fc list.\n+\t * Wait for ongoing fast commit to finish. We cannot remove the inode\n+\t * from fast commit lists while it is being committed.\n \t */\n-\tWARN_ON(ext4_test_inode_state(inode, EXT4_STATE_FC_COMMITTING)\n-\t\t&& !ext4_test_mount_flag(inode->i_sb, EXT4_MF_FC_INELIGIBLE));\n+\twhile (ext4_test_inode_state(inode, EXT4_STATE_FC_COMMITTING)) {\n+#if (BITS_PER_LONG < 64)\n+\t\tDEFINE_WAIT_BIT(wait, &ei->i_state_flags,\n+\t\t\t\tEXT4_STATE_FC_COMMITTING);\n+\t\twq = bit_waitqueue(&ei->i_state_flags,\n+\t\t\t\t EXT4_STATE_FC_COMMITTING);\n+#else\n+\t\tDEFINE_WAIT_BIT(wait, &ei->i_flags,\n+\t\t\t\tEXT4_STATE_FC_COMMITTING);\n+\t\twq = bit_waitqueue(&ei->i_flags,\n+\t\t\t\t EXT4_STATE_FC_COMMITTING);\n+#endif\n+\t\tprepare_to_wait(wq, &wait.wq_entry, TASK_UNINTERRUPTIBLE);\n+\t\tif (ext4_test_inode_state(inode, EXT4_STATE_FC_COMMITTING)) {\n+\t\t\text4_fc_unlock(inode->i_sb, alloc_ctx);\n+\t\t\tschedule();\n+\t\t\talloc_ctx = ext4_fc_lock(inode->i_sb);\n+\t\t}\n+\t\tfinish_wait(wq, &wait.wq_entry);\n+\t}\n+\n \twhile (ext4_test_inode_state(inode, EXT4_STATE_FC_FLUSHING_DATA)) {\n #if (BITS_PER_LONG < 64)\n \t\tDEFINE_WAIT_BIT(wait, &ei->i_state_flags,\n@@ -287,19 +295,22 @@ void ext4_fc_del(struct inode *inode)\n \t\t}\n \t\tfinish_wait(wq, &wait.wq_entry);\n \t}\n+\n \text4_fc_free_inode_snap(inode);\n \tlist_del_init(&ei->i_fc_list);\n \n \t/*\n-\t * Since this inode is getting removed, let's also remove all FC\n-\t * dentry create references, since it is not needed to log it anyways.\n+\t * Since this inode is getting removed, let's also remove all FC dentry\n+\t * create references, since it is not needed to log it anyways.\n \t */\n \tif (list_empty(&ei->i_fc_dilist)) {\n \t\text4_fc_unlock(inode->i_sb, alloc_ctx);\n \t\treturn;\n \t}\n \n-\tfc_dentry = list_first_entry(&ei->i_fc_dilist, struct ext4_fc_dentry_update, fcd_dilist);\n+\tfc_dentry = list_first_entry(&ei->i_fc_dilist,\n+\t\t\t\t struct ext4_fc_dentry_update,\n+\t\t\t\t fcd_dilist);\n \tWARN_ON(fc_dentry->fcd_op != EXT4_FC_TAG_CREAT);\n \tlist_del_init(&fc_dentry->fcd_list);\n \tlist_del_init(&fc_dentry->fcd_dilist);\n@@ -371,6 +382,8 @@ static int ext4_fc_track_template(\n \n \ttid = handle->h_transaction->t_tid;\n \tspin_lock(&ei->i_fc_lock);\n+\tif (ext4_test_inode_state(inode, EXT4_STATE_FC_COMMITTING))\n+\t\text4_set_inode_state(inode, EXT4_STATE_FC_REQUEUE);\n \tif (tid == ei->i_sync_tid) {\n \t\tupdate = true;\n \t} else {\n@@ -557,8 +570,6 @@ static int __track_inode(handle_t *handle, struct inode *inode, void *arg,\n \n void ext4_fc_track_inode(handle_t *handle, struct inode *inode)\n {\n-\tstruct ext4_inode_info *ei = EXT4_I(inode);\n-\twait_queue_head_t *wq;\n \tint ret;\n \n \tif (S_ISDIR(inode->i_mode))\n@@ -577,29 +588,11 @@ void ext4_fc_track_inode(handle_t *handle, struct inode *inode)\n \t\treturn;\n \n \t/*\n-\t * If we come here, we may sleep while waiting for the inode to\n-\t * commit. We shouldn't be holding i_data_sem when we go to sleep since\n-\t * the commit path needs to grab the lock while committing the inode.\n+\t * Fast commit snapshots inode state at commit time, so there's no need\n+\t * to wait for EXT4_STATE_FC_COMMITTING here. If the inode is already\n+\t * on the commit queue, ext4_fc_cleanup() will requeue it for the new\n+\t * transaction once the current commit finishes.\n \t */\n-\tlockdep_assert_not_held(&ei->i_data_sem);\n-\n-\twhile (ext4_test_inode_state(inode, EXT4_STATE_FC_COMMITTING)) {\n-#if (BITS_PER_LONG < 64)\n-\t\tDEFINE_WAIT_BIT(wait, &ei->i_state_flags,\n-\t\t\t\tEXT4_STATE_FC_COMMITTING);\n-\t\twq = bit_waitqueue(&ei->i_state_flags,\n-\t\t\t\t EXT4_STATE_FC_COMMITTING);\n-#else\n-\t\tDEFINE_WAIT_BIT(wait, &ei->i_flags,\n-\t\t\t\tEXT4_STATE_FC_COMMITTING);\n-\t\twq = bit_waitqueue(&ei->i_flags,\n-\t\t\t\t EXT4_STATE_FC_COMMITTING);\n-#endif\n-\t\tprepare_to_wait(wq, &wait.wq_entry, TASK_UNINTERRUPTIBLE);\n-\t\tif (ext4_test_inode_state(inode, EXT4_STATE_FC_COMMITTING))\n-\t\t\tschedule();\n-\t\tfinish_wait(wq, &wait.wq_entry);\n-\t}\n \n \t/*\n \t * From this point on, this inode will not be committed either\n@@ -1525,32 +1518,32 @@ static void ext4_fc_cleanup(journal_t *journal, int full, tid_t tid)\n \n \talloc_ctx = ext4_fc_lock(sb);\n \twhile (!list_empty(&sbi->s_fc_q[FC_Q_MAIN])) {\n+\t\tbool requeue;\n+\n \t\tei = list_first_entry(&sbi->s_fc_q[FC_Q_MAIN],\n \t\t\t\t\tstruct ext4_inode_info,\n \t\t\t\t\ti_fc_list);\n \t\tlist_del_init(&ei->i_fc_list);\n \t\text4_fc_free_inode_snap(&ei->vfs_inode);\n+\t\tspin_lock(&ei->i_fc_lock);\n+\t\tif (full)\n+\t\t\trequeue = !tid_geq(tid, ei->i_sync_tid);\n+\t\telse\n+\t\t\trequeue = ext4_test_inode_state(&ei->vfs_inode,\n+\t\t\t\t\t\t\tEXT4_STATE_FC_REQUEUE);\n+\t\tif (!requeue)\n+\t\t\text4_fc_reset_inode(&ei->vfs_inode);\n+\t\text4_clear_inode_state(&ei->vfs_inode, EXT4_STATE_FC_REQUEUE);\n \t\text4_clear_inode_state(&ei->vfs_inode,\n \t\t\t\t EXT4_STATE_FC_COMMITTING);\n-\t\tif (tid_geq(tid, ei->i_sync_tid)) {\n-\t\t\text4_fc_reset_inode(&ei->vfs_inode);\n-\t\t} else if (full) {\n-\t\t\t/*\n-\t\t\t * We are called after a full commit, inode has been\n-\t\t\t * modified while the commit was running. Re-enqueue\n-\t\t\t * the inode into STAGING, which will then be splice\n-\t\t\t * back into MAIN. This cannot happen during\n-\t\t\t * fastcommit because the journal is locked all the\n-\t\t\t * time in that case (and tid doesn't increase so\n-\t\t\t * tid check above isn't reliable).\n-\t\t\t */\n+\t\tspin_unlock(&ei->i_fc_lock);\n+\t\tif (requeue)\n \t\t\tlist_add_tail(&ei->i_fc_list,\n \t\t\t\t &sbi->s_fc_q[FC_Q_STAGING]);\n-\t\t}\n \t\t/*\n \t\t * Make sure clearing of EXT4_STATE_FC_COMMITTING is\n \t\t * visible before we send the wakeup. Pairs with implicit\n-\t\t * barrier in prepare_to_wait() in ext4_fc_track_inode().\n+\t\t * barrier in prepare_to_wait() in ext4_fc_del().\n \t\t */\n \t\tsmp_mb();\n #if (BITS_PER_LONG < 64)\n", "prefixes": [ "RFC", "v4", "3/7" ] }