From nobody Mon Feb 9 19:00:09 2026 Received: from mail-pl1-f175.google.com (mail-pl1-f175.google.com [209.85.214.175]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 250525FDA7 for ; Sun, 8 Feb 2026 08:39:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.214.175 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770539961; cv=none; b=cBVIxb0AMDAMxNhOOpBxpAaIW9jXI9f12wT9Mn0uzb3Q+BN9+vkw9p/Ml/0Pji4v4K1cYEKsOkrN4vR5uxDwKkvWQ2Uh3C5AITyOino7dhZSHslvmLDfIer6TRL/7/095RK2j3ncmFdciUa61oD+LhzZfFnZWkNLMNVFD3ABIg0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1770539961; c=relaxed/simple; bh=5Gofe3JYudNHC5bZVSfnr5pSqqCz7TEfiMd79zW2xow=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=AQ4TJgv0/5y6EkBdNwVL+UYoZJl+jtwH1g/LIN3L0iCoYBa3A2WTo7zH4OvvcLOUy1VOLyvT/PfLQRqJnhDK48tet28KAHx1VlpuIZtV5Of1QS3LctaXgSpKXsbA5e1BLXIFkAOsUrrb/GFVmEIQHw6Lc6JB1Po96RFbasQYEzI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=kx3+fcB6; arc=none smtp.client-ip=209.85.214.175 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kx3+fcB6" Received: by mail-pl1-f175.google.com with SMTP id d9443c01a7336-2a7bced39cfso34883755ad.1 for ; Sun, 08 Feb 2026 00:39:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1770539960; x=1771144760; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=wczPQcNeq+o/LnDXbTOVuB5R7oCXG1RMbfUuUACD98w=; b=kx3+fcB6jzd+sqoX/D93n1Xkd90agEIlxny3TNGyNNnXeesIHEdRVrEw2mm2eW+Ppy tGje+lftAfQvKmPwDLM9F6SlvdUFxcHJICqAp8rwwDMRIPWOUEhPxmD+A2yLDDhtgkom grd0E+x5fuGkqzqjVwx0Bpf1y7cyJjir5NqzECYC1RtJVXjQ3TcG36EjmojQKTWuOiGQ e+N/+RTsp1M92b7X8gijLcTUwRuspG0KVT0UKyeoPWnyf+3ZhHmUdOI1ieHMEPmGwHQR 7+iC32yoz6pUHY6fePbjilUM3zS/DhroOQ6cUW8KMVw0zm8o+4aw5EJgh0uikpLb6MrC RmZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1770539960; x=1771144760; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=wczPQcNeq+o/LnDXbTOVuB5R7oCXG1RMbfUuUACD98w=; b=EPt2ssjZ6kNkTir4zioaJQ1pv/7Gr0FNjaO+uJvJmKHGa1AiKbj8KXRcAbYIs0/tEi fOiyDal3B6nZLXClzdte3yMke2zGkpGETIv5J+Lfjvmf9DOW1z5XdmPhydfrxujqU9Mi BGjopHkY0DexYlw61iA1myvtgqVYnGUZnqrA7T/SalzgtrFwGYM79MlZuZ2THLU+XPSd kUlKDiawmqUDLDbYuLy47KqmD3A6RnpbN2pFtKdis/7j+p/TQu7KZ2uPCvT2GLmLgjvQ v/RQOPBvfNC2e95xOO6DLtGXlSZrSL2+ufxiogSqKDw7cnll8TJnxjAHy/rIA9ZRxgs2 2bPQ== X-Forwarded-Encrypted: i=1; AJvYcCUlxBQtrragjs5m7cuG9ddhIpQFfB1dD0oLiRgt0j4LnV+NfImbzJX/bXyiAcow38SW3gXptgEnGqLQA6Y=@vger.kernel.org X-Gm-Message-State: AOJu0YwiuuGGfe8mJok0tWIfILt/3MiJ46xfONJt+XpJuMZsVII4M2jT 6Ye77AhUOzus41H8Xv/tg5HQd+xSIBK6PdHZGaUozh47fgdv1yVSI+/m X-Gm-Gg: AZuq6aKyJDgXmC3C0C53Ed5+5KzmaqzPWBDrOmvQoCxD3Sucz1NqZpTk7qgTWlKIr5q v60UL11q/aOB9zGdqbTenSqFzQ5INH8KVMS8Py8aov3GKpXAwSXEjdqJ49FiGAX3E+TgxoFY2xb 0meAWiZT930/UQcmdagrd0aEGjbWhNB+TB+SMTVeI1u74i/o/Maq9oAIbQG7qremxywGXNmFXdv fr+3bxyIuIk79pLz2prdtOpsCKgcnWRm3ebqjAn5tQqtzd1aVJizKS6CM0K18Te9YhhOQqMxi/8 ClhqNggqgTljRwKGZ23nZVKsjGWJPc/5JD53j9VM6goqiTp1SY10Jgbrlb1GYSm15TGHrP8DLqV zsdfo5WJR1NZEtahIHTT5XzuUZYtwQVopuijRbVmREcaUpnOOlvVXkl7uCVrO+bqvn3VVsUyb1V jNoEVkk/AKlhwn/9TALJms X-Received: by 2002:a17:902:db07:b0:2a5:8c1c:7451 with SMTP id d9443c01a7336-2a9519f5b02mr91484815ad.58.1770539960242; Sun, 08 Feb 2026 00:39:20 -0800 (PST) Received: from archlinux ([45.119.31.85]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2aadc397d8dsm20530655ad.1.2026.02.08.00.39.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 08 Feb 2026 00:39:19 -0800 (PST) From: Adarsh Das To: Konstantin Komarov Cc: ntfs3@lists.linux.de, linux-kernel@vger.kernel.org, Adarsh Das Subject: [PATCH] fs/ntfs3: resolve compare function in public index APIs Date: Sun, 8 Feb 2026 14:09:04 +0530 Message-ID: <20260208083904.63963-1-adarshdas950@gmail.com> X-Mailer: git-send-email 2.53.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Previously the comparator was stored in struct ntfs_index and used by low-level helpers such as hdr_find_e(). This creates a dependency on index state in private helpers. Resolve the compare function in the public index APIs and pass it explicitly to internal helpers. This should make the ownership of the comparator explicit and keeps low-level index code independent of index-root policy. This also resolves the TODO comment about dropping the stored comparator from struct ntfs_index. Signed-off-by: Adarsh Das --- fs/ntfs3/index.c | 76 ++++++++++++++++++++++++++++++---------------- fs/ntfs3/ntfs_fs.h | 5 +-- 2 files changed, 50 insertions(+), 31 deletions(-) diff --git a/fs/ntfs3/index.c b/fs/ntfs3/index.c index 7157cfd70fdc..f04a8e13f8b8 100644 --- a/fs/ntfs3/index.c +++ b/fs/ntfs3/index.c @@ -716,10 +716,10 @@ static bool fnd_is_empty(struct ntfs_fnd *fnd) */ static struct NTFS_DE *hdr_find_e(const struct ntfs_index *indx, const struct INDEX_HDR *hdr, const void *key, - size_t key_len, const void *ctx, int *diff) + size_t key_len, const void *ctx, int *diff, + NTFS_CMP_FUNC cmp) { struct NTFS_DE *e, *found =3D NULL; - NTFS_CMP_FUNC cmp =3D indx->cmp; int min_idx =3D 0, mid_idx, max_idx =3D 0; int diff2; int table_size =3D 8; @@ -729,9 +729,6 @@ static struct NTFS_DE *hdr_find_e(const struct ntfs_ind= ex *indx, u32 total =3D le32_to_cpu(hdr->total); u16 offs[128]; =20 - if (unlikely(!cmp)) - return NULL; - fill_table: if (end > total) return NULL; @@ -802,7 +799,8 @@ static struct NTFS_DE *hdr_find_e(const struct ntfs_ind= ex *indx, static struct NTFS_DE *hdr_insert_de(const struct ntfs_index *indx, struct INDEX_HDR *hdr, const struct NTFS_DE *de, - struct NTFS_DE *before, const void *ctx) + struct NTFS_DE *before, const void *ctx, + NTFS_CMP_FUNC cmp) { int diff; size_t off =3D PtrOffset(hdr, before); @@ -825,7 +823,7 @@ static struct NTFS_DE *hdr_insert_de(const struct ntfs_= index *indx, } /* No insert point is applied. Get it manually. */ before =3D hdr_find_e(indx, hdr, de + 1, le16_to_cpu(de->key_size), ctx, - &diff); + &diff, cmp); if (!before) return NULL; off =3D PtrOffset(hdr, before); @@ -917,10 +915,6 @@ int indx_init(struct ntfs_index *indx, struct ntfs_sb_= info *sbi, =20 init_rwsem(&indx->run_lock); =20 - indx->cmp =3D get_cmp_func(root); - if (!indx->cmp) - goto out; - return 0; =20 out: @@ -1142,6 +1136,7 @@ int indx_find(struct ntfs_index *indx, struct ntfs_in= ode *ni, int err; struct NTFS_DE *e; struct indx_node *node; + NTFS_CMP_FUNC cmp; =20 if (!root) root =3D indx_get_root(&ni->dir, ni, NULL, NULL); @@ -1151,10 +1146,16 @@ int indx_find(struct ntfs_index *indx, struct ntfs_= inode *ni, return -EINVAL; } =20 + cmp =3D get_cmp_func(root); + if (unlikely(!cmp)) { + WARN_ON_ONCE(1); + return -EINVAL; + } + /* Check cache. */ e =3D fnd->level ? fnd->de[fnd->level - 1] : fnd->root_de; if (e && !de_is_last(e) && - !(*indx->cmp)(key, key_len, e + 1, le16_to_cpu(e->key_size), ctx)) { + !(*cmp)(key, key_len, e + 1, le16_to_cpu(e->key_size), ctx)) { *entry =3D e; *diff =3D 0; return 0; @@ -1164,7 +1165,7 @@ int indx_find(struct ntfs_index *indx, struct ntfs_in= ode *ni, fnd_clear(fnd); =20 /* Lookup entry that is <=3D to the search value. */ - e =3D hdr_find_e(indx, &root->ihdr, key, key_len, ctx, diff); + e =3D hdr_find_e(indx, &root->ihdr, key, key_len, ctx, diff, cmp); if (!e) return -EINVAL; =20 @@ -1184,7 +1185,7 @@ int indx_find(struct ntfs_index *indx, struct ntfs_in= ode *ni, =20 /* Lookup entry that is <=3D to the search value. */ e =3D hdr_find_e(indx, &node->index->ihdr, key, key_len, ctx, - diff); + diff, cmp); if (!e) { put_indx_node(node); return -EINVAL; @@ -1583,7 +1584,7 @@ static int indx_add_allocate(struct ntfs_index *indx,= struct ntfs_inode *ni, static int indx_insert_into_root(struct ntfs_index *indx, struct ntfs_inod= e *ni, const struct NTFS_DE *new_de, struct NTFS_DE *root_de, const void *ctx, - struct ntfs_fnd *fnd, bool undo) + struct ntfs_fnd *fnd, bool undo, NTFS_CMP_FUNC cmp) { int err =3D 0; struct NTFS_DE *e, *e0, *re; @@ -1624,7 +1625,7 @@ static int indx_insert_into_root(struct ntfs_index *i= ndx, struct ntfs_inode *ni, if ((undo || asize + ds_root < sbi->max_bytes_per_attr) && mi_resize_attr(mi, attr, ds_root)) { hdr->total =3D cpu_to_le32(hdr_total + ds_root); - e =3D hdr_insert_de(indx, hdr, new_de, root_de, ctx); + e =3D hdr_insert_de(indx, hdr, new_de, root_de, ctx, cmp); WARN_ON(!e); fnd_clear(fnd); fnd->root_de =3D e; @@ -1765,7 +1766,7 @@ static int indx_insert_into_root(struct ntfs_index *i= ndx, struct ntfs_inode *ni, * Now root is a parent for new index buffer. * Insert NewEntry a new buffer. */ - e =3D hdr_insert_de(indx, hdr, new_de, NULL, ctx); + e =3D hdr_insert_de(indx, hdr, new_de, NULL, ctx, cmp); if (!e) { err =3D -EINVAL; goto out_put_n; @@ -1795,7 +1796,7 @@ static int indx_insert_into_root(struct ntfs_index *i= ndx, struct ntfs_inode *ni, static int indx_insert_into_buffer(struct ntfs_index *indx, struct ntfs_inode *ni, struct INDEX_ROOT *root, const struct NTFS_DE *new_de, - const void *ctx, int level, struct ntfs_fnd *fnd) + const void *ctx, int level, struct ntfs_fnd *fnd, NTFS_CMP_FUNC cmp) { int err; const struct NTFS_DE *sp; @@ -1812,7 +1813,7 @@ indx_insert_into_buffer(struct ntfs_index *indx, stru= ct ntfs_inode *ni, =20 /* Try the most easy case. */ e =3D fnd->level - 1 =3D=3D level ? fnd->de[level] : NULL; - e =3D hdr_insert_de(indx, hdr1, new_de, e, ctx); + e =3D hdr_insert_de(indx, hdr1, new_de, e, ctx, cmp); fnd->de[level] =3D e; if (e) { /* Just write updated index into disk. */ @@ -1889,12 +1890,12 @@ indx_insert_into_buffer(struct ntfs_index *indx, st= ruct ntfs_inode *ni, * (depending on sp <=3D> new_de). */ hdr_insert_de(indx, - (*indx->cmp)(new_de + 1, le16_to_cpu(new_de->key_size), + (*cmp)(new_de + 1, le16_to_cpu(new_de->key_size), up_e + 1, le16_to_cpu(up_e->key_size), ctx) < 0 ? hdr2 : hdr1, - new_de, NULL, ctx); + new_de, NULL, ctx, cmp); =20 indx_mark_used(indx, ni, new_vbn >> indx->idx2vbn_bits); =20 @@ -1909,14 +1910,14 @@ indx_insert_into_buffer(struct ntfs_index *indx, st= ruct ntfs_inode *ni, */ if (!level) { /* Insert in root. */ - err =3D indx_insert_into_root(indx, ni, up_e, NULL, ctx, fnd, 0); + err =3D indx_insert_into_root(indx, ni, up_e, NULL, ctx, fnd, 0, cmp); } else { /* * The target buffer's parent is another index buffer. * TODO: Remove recursion. */ err =3D indx_insert_into_buffer(indx, ni, root, up_e, ctx, - level - 1, fnd); + level - 1, fnd, cmp); } =20 if (err) { @@ -1950,6 +1951,7 @@ int indx_insert_entry(struct ntfs_index *indx, struct= ntfs_inode *ni, struct NTFS_DE *e; struct ntfs_fnd *fnd_a =3D NULL; struct INDEX_ROOT *root; + NTFS_CMP_FUNC cmp; =20 if (!fnd) { fnd_a =3D fnd_get(); @@ -1966,6 +1968,12 @@ int indx_insert_entry(struct ntfs_index *indx, struc= t ntfs_inode *ni, goto out; } =20 + cmp =3D get_cmp_func(root); + if (unlikely(!cmp)) { + WARN_ON_ONCE(1); + return -EINVAL; + } + if (fnd_is_empty(fnd)) { /* * Find the spot the tree where we want to @@ -1989,13 +1997,13 @@ int indx_insert_entry(struct ntfs_index *indx, stru= ct ntfs_inode *ni, * new entry into it. */ err =3D indx_insert_into_root(indx, ni, new_de, fnd->root_de, ctx, - fnd, undo); + fnd, undo, cmp); } else { /* * Found a leaf buffer, so we'll insert the new entry into it. */ err =3D indx_insert_into_buffer(indx, ni, root, new_de, ctx, - fnd->level - 1, fnd); + fnd->level - 1, fnd, cmp); } =20 out: @@ -2288,6 +2296,7 @@ int indx_delete_entry(struct ntfs_index *indx, struct= ntfs_inode *ni, u32 e_size, root_size, new_root_size; size_t trim_bit; const struct INDEX_NAMES *in; + NTFS_CMP_FUNC cmp; =20 fnd =3D fnd_get(); if (!fnd) { @@ -2307,6 +2316,12 @@ int indx_delete_entry(struct ntfs_index *indx, struc= t ntfs_inode *ni, goto out; } =20 + cmp =3D get_cmp_func(root); + if (unlikely(!cmp)) { + WARN_ON_ONCE(1); + return -EINVAL; + } + /* Locate the entry to remove. */ err =3D indx_find(indx, ni, root, key, key_len, ctx, &diff, &e, fnd); if (err) @@ -2372,9 +2387,9 @@ int indx_delete_entry(struct ntfs_index *indx, struct= ntfs_inode *ni, err =3D level ? indx_insert_into_buffer(indx, ni, root, re, ctx, fnd->level - 1, - fnd) : + fnd, cmp) : indx_insert_into_root(indx, ni, re, e, - ctx, fnd, 0); + ctx, fnd, 0, cmp); kfree(re); =20 if (err) @@ -2668,6 +2683,7 @@ int indx_update_dup(struct ntfs_inode *ni, struct ntf= s_sb_info *sbi, struct INDEX_ROOT *root; struct mft_inode *mi; struct ntfs_index *indx =3D &ni->dir; + NTFS_CMP_FUNC cmp; =20 fnd =3D fnd_get(); if (!fnd) @@ -2679,6 +2695,12 @@ int indx_update_dup(struct ntfs_inode *ni, struct nt= fs_sb_info *sbi, goto out; } =20 + cmp =3D get_cmp_func(root); + if (unlikely(!cmp)) { + WARN_ON_ONCE(1); + return -EINVAL; + } + /* Find entry in directory. */ err =3D indx_find(indx, ni, root, fname, fname_full_size(fname), sbi, &diff, &e, fnd); diff --git a/fs/ntfs3/ntfs_fs.h b/fs/ntfs3/ntfs_fs.h index a4559c9f64e6..63d3b76e7d06 100644 --- a/fs/ntfs3/ntfs_fs.h +++ b/fs/ntfs3/ntfs_fs.h @@ -192,9 +192,6 @@ struct ntfs_index { /* read/write access to 'bitmap_run'/'alloc_run' while ntfs_readdir */ struct rw_semaphore run_lock; =20 - /*TODO: Remove 'cmp'. */ - NTFS_CMP_FUNC cmp; - u8 index_bits; // log2(root->index_block_size) u8 idx2vbn_bits; // log2(root->index_block_clst) u8 vbn2vbo_bits; // index_block_size < cluster? 9 : cluster_bits @@ -378,7 +375,7 @@ struct ntfs_inode { */ u8 mi_loaded; =20 - /*=20 + /* * Use this field to avoid any write(s). * If inode is bad during initialization - use make_bad_inode * If inode is bad during operations - use this field --=20 2.53.0