{"id":2224716,"url":"http://patchwork.ozlabs.org/api/1.2/patches/2224716/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-ext4/patch/20260417213723.74204-2-artem.blagodarenko@gmail.com/","project":{"id":8,"url":"http://patchwork.ozlabs.org/api/1.2/projects/8/?format=json","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":"<20260417213723.74204-2-artem.blagodarenko@gmail.com>","list_archive_url":null,"date":"2026-04-17T21:37:18","name":"[1/3] ext4: make dirdata work with metadata_csum","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"3295be3c7b57a9cdc3b69ad7c9ddcb545430a817","submitter":{"id":70973,"url":"http://patchwork.ozlabs.org/api/1.2/people/70973/?format=json","name":"Artem Blagodarenko","email":"artem.blagodarenko@gmail.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/linux-ext4/patch/20260417213723.74204-2-artem.blagodarenko@gmail.com/mbox/","series":[{"id":500406,"url":"http://patchwork.ozlabs.org/api/1.2/series/500406/?format=json","web_url":"http://patchwork.ozlabs.org/project/linux-ext4/list/?series=500406","date":"2026-04-17T21:37:18","name":"Data in direntry (dirdata) feature","version":1,"mbox":"http://patchwork.ozlabs.org/series/500406/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2224716/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2224716/checks/","tags":{},"related":[],"headers":{"Return-Path":"\n <SRS0=HmGV=CQ=vger.kernel.org=linux-ext4+bounces-15888-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 (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=WNp+DYZq;\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=hmgv=cq=vger.kernel.org=linux-ext4+bounces-15888-patchwork-incoming=ozlabs.org@ozlabs.org;\n receiver=patchwork.ozlabs.org)","gandalf.ozlabs.org;\n arc=pass smtp.remote-ip=\"2600:3c04:e001:36c::12fc:5321\"\n arc.chain=subspace.kernel.org","gandalf.ozlabs.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com","gandalf.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=WNp+DYZq;\n\tdkim-atps=neutral","gandalf.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=linux-ext4+bounces-15888-patchwork-incoming=ozlabs.org@vger.kernel.org;\n receiver=ozlabs.org)","smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com\n header.b=\"WNp+DYZq\"","smtp.subspace.kernel.org;\n arc=none smtp.client-ip=209.85.128.43","smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com","smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=gmail.com"],"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 4fy7XN5SBmz1yDF\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 18 Apr 2026 07:37:56 +1000 (AEST)","from mail.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3])\n\tby gandalf.ozlabs.org (Postfix) with ESMTP id 4fy7XM6jZVz4wKC\n\tfor <incoming@patchwork.ozlabs.org>; Sat, 18 Apr 2026 07:37:55 +1000 (AEST)","by gandalf.ozlabs.org (Postfix)\n\tid 4fy7XM6XVzz4wKx; Sat, 18 Apr 2026 07:37:55 +1000 (AEST)","from tor.lore.kernel.org (tor.lore.kernel.org\n [IPv6:2600:3c04:e001:36c::12fc:5321])\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 4fy7XJ2PXbz4wKC\n\tfor <patchwork-incoming@ozlabs.org>; Sat, 18 Apr 2026 07:37:52 +1000 (AEST)","from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id D15D3305BF06\n\tfor <patchwork-incoming@ozlabs.org>; Fri, 17 Apr 2026 21:37:43 +0000 (UTC)","from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id E9B28376466;\n\tFri, 17 Apr 2026 21:37:40 +0000 (UTC)","from mail-wm1-f43.google.com (mail-wm1-f43.google.com\n [209.85.128.43])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id F19C5342C80\n\tfor <linux-ext4@vger.kernel.org>; Fri, 17 Apr 2026 21:37:38 +0000 (UTC)","by mail-wm1-f43.google.com with SMTP id\n 5b1f17b1804b1-488af96f6b2so14434405e9.0\n        for <linux-ext4@vger.kernel.org>;\n Fri, 17 Apr 2026 14:37:38 -0700 (PDT)","from localhost.localdomain\n ([2a00:23c7:90c1:9201:f5b4:1568:453c:b849])\n        by smtp.gmail.com with ESMTPSA id\n 5b1f17b1804b1-488fb762f56sm25725645e9.15.2026.04.17.14.37.35\n        (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n        Fri, 17 Apr 2026 14:37:36 -0700 (PDT)"],"ARC-Seal":["i=2; a=rsa-sha256; d=ozlabs.org; s=201707; t=1776461875; cv=pass;\n\tb=jv9N4MqxXcl3atGqMetY/1FccoV5LdmQn0/nyvew5TRDHe+VIxvZ2T774LzrLDSt7htYc9fDhfRtj8c6h6GEgMK4pSemn3Fl6X0AnzyXFbEq+Os4oUavYlbgzt+teqMn/tkbZNPKf2KRMOUBsI2trXhJtV91E+VYKEhghWO8cDzwbzklqBVJE2Y/SkCl0kPbMumzzFkCrePPwLBRru78G2vLwMGT3DEZKUWmaTWoNrbymDM7Kt7sorvhZN8XGa9DcuDt9ccseN087wrwF5y4nLHfCWYC0Y01jHRVgK6HrSDN4zDHPC9APatFBQEpmoG5sYiV5OfSzZvIL+rOlAgYzA==","i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1776461860; cv=none;\n b=dt5rMjhlnQB7JQhuD+rg1DW8myOnf2+XQZkYlsL9sFG0WGH0hCJxrBVxiphBGYsh9NEgVvJw90kRJQHqshy949F97qdSJR7JD8iZGGOPwOmQPSs4iyXKlDnXs6lUVCL+XNR01JzX0sJsBVqaouDu9AObXE5FTeRHkOtcfskYM3c="],"ARC-Message-Signature":["i=2; a=rsa-sha256; d=ozlabs.org; s=201707;\n\tt=1776461875; c=relaxed/relaxed;\n\tbh=vaQDN4Yo+aCWIVuwO1Ffv7uu9lPnMVpiMPGxN3arduA=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=SU98njmhx0naB3tHszQwWt0F6wKJic8TiTHPBR5WgU/2bdo9cAnE8czot8VM9zLQJXdzs98HmaoHtw2cmENltYYJQFp+ZLjNmK3HbQMzOc4Fy31VujtX014D4r6F2lou77vsfr66O0QZ9q4fWFYUxqjyllLEDCXU8ntJZy9d5hV89l/Gilvo9I7l/idbVwctnQkl3gHRkMDpqr+eguwtNv0W6S/iIUydkDQSVOCHainL1X8UFmXIqqDAXSCh44d+6H8fniIH6h0d5Zwogy2wNsDM8Y5nJui9wzQn0IqDFT0Qg508a4GL66xTQoaGilArEvdkdrrioQDfkZ6dm2cd3A==","i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1776461860; c=relaxed/simple;\n\tbh=MhyVsmzNh3N09QKspt4804SsuZZ6rewljKuMNTozB98=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=Cj8dwwD6t7Rd66aQ/gJcgJfuVgdQPfsnyjeYTbzE/IpmyWJvCFMcvuqMB9wEXZ2YsPtCW28NgeDufDxwYsveZPAB3sIhPoHsb/UPi5I5TgEbPGrird3+A3HwQYCCALeB+fBkojzarNIlTv50ScfCbnHo3g3xLHq3g9utrI0YELw="],"ARC-Authentication-Results":["i=2; gandalf.ozlabs.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com; dkim=pass (2048-bit key;\n unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256\n header.s=20251104 header.b=WNp+DYZq; dkim-atps=neutral;\n spf=pass (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=linux-ext4+bounces-15888-patchwork-incoming=ozlabs.org@vger.kernel.org;\n receiver=ozlabs.org) smtp.mailfrom=vger.kernel.org","i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=none dis=none) header.from=gmail.com;\n spf=pass smtp.mailfrom=gmail.com;\n dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com\n header.b=WNp+DYZq; arc=none smtp.client-ip=209.85.128.43"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=gmail.com; s=20251104; t=1776461857; x=1777066657;\n darn=vger.kernel.org;\n        h=content-transfer-encoding:mime-version:references:in-reply-to\n         :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n         :message-id:reply-to;\n        bh=vaQDN4Yo+aCWIVuwO1Ffv7uu9lPnMVpiMPGxN3arduA=;\n        b=WNp+DYZqkl7NK92siNsBpzFNr+JdJKQ7SV0Ajcu3mBHaxQRVZNMTsOX2vJtjvXRlND\n         /ksmbKO/o088Fk+3dA5ZeDOuZt2Yx/bi+HHbqZXOZSgKN4a7jxqu/H/8YwwiftByNRFA\n         FsAGFh77znL2LCe93yilJC3aE/WwNA3P7afPQ07s3xGP2vd2ByqVhAM44u1bW3pFywKb\n         V19jqq3SYRZPCvxILTc3VHj+Tfe4Yl0QuMHTStuXlvfQBo8ilblaRZOulX0RBqKQANnV\n         cUm6SY0Ir/IvHq2to+tqx9pOIIqModox9d/IUcpqyUf3gTrRpzgzp4qg3g6b5RfH9VEQ\n         aX7w==","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n        d=1e100.net; s=20251104; t=1776461857; x=1777066657;\n        h=content-transfer-encoding:mime-version:references:in-reply-to\n         :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n         :to:cc:subject:date:message-id:reply-to;\n        bh=vaQDN4Yo+aCWIVuwO1Ffv7uu9lPnMVpiMPGxN3arduA=;\n        b=Uz8sNOYzbSQm7AC2KsRST99/bxQKplwn0rKtq5iB7NtfN7+Thz+AaoUXXS1gD7abX3\n         IJIABm7vy4aSghdWSNPvAFSFqlLOvJHqMhlognDM5PzYznbTItC8upc6O8CX94dq4Qbl\n         kOYRAvScxnXxsJeGgl/0HkWImu7s7XU3krLLRA0NA1fsg+AeL1Dfdl0ueWYzvWiMtxQA\n         EpHAZjp5wznVmRtEjQr85g6rUDM0NjIMmbYhJgLtfthzcWOjrWBSCrzNoAsfoG9rhOOK\n         vgfmRZ3BcR8SszLsGlpLtKSlpcqbAvqi3V+G7yRYOL5lKPQqCSt3/mk6jh9IfypOLw7N\n         1e4Q==","X-Gm-Message-State":"AOJu0YwJeqyh2WhHiMxDhIWEjVr2Kcq3Bg6s4auXlGK4CSYfBOika9Tl\n\tReJ8AzzXvhhNNnEE409dj0OJevZWLegIGWKri7nRdp0tY4JIV8sk87UcafV6yA==","X-Gm-Gg":"AeBDievZNSj6i/6ew4EptDakzwpGgTMTXyscJoi4f9tmYtnaD8TaIFrtsS1bSnedAeZ\n\tutp6gq/qjWLk4d+zxAOqp8ch1wyKYzlbSEJbm0yGCpH1vN4CZBSDNs2qjZSeNKLqj0z22pFV0hJ\n\tHvHEzCPdK9gJajz124z4LnLpWIDa+L30/8XgWIABwYG/Hwt1//fCGL9/67kGt5e0VUmsFSBbXyO\n\tXby/tIaTZ/A6YRxFsltTaP0Y7/BF3ou3JFXl99q6wNzEO4JL0KKk91xQVniTypblNxsE4Wb2MRe\n\t5d6r6rcp9zCQv7xwqv7tNDIAp0G3QUNYsYVQMYfySI5T7BEOL6QMXZB0gvL6W55Tpp506dYWxra\n\tovAcG5f3tpwQTyuQx9wxqF06re4ijfbQEIYX6WhyIAS2N7vijWCh9TIF6qSyCNTNuG4FkiWFWnY\n\tNkdYBaaixemzOPm3RMTu4c0KLqnQ/uvufvIXbyewcEq8/snvIFPCNXgG22a9pwIY5V3vXK9gWu2\n\tOC5VjFax3t1W/NSE4O0BHA=","X-Received":"by 2002:a05:600c:3546:b0:488:81b1:ae36 with SMTP id\n 5b1f17b1804b1-488fb7880camr67411125e9.23.1776461857054;\n        Fri, 17 Apr 2026 14:37:37 -0700 (PDT)","From":"Artem Blagodarenko <artem.blagodarenko@gmail.com>","To":"linux-ext4@vger.kernel.org","Cc":"adilger.kernel@dilger.ca,\n\tArtem Blagodarenko <artem.blagodarenko@gmail.com>,\n\tPravin Shelar <pravin.shelar@sun.com>,\n\tAndreas Dilger <adilger@dilger.ca>","Subject":"[PATCH 1/3] ext4: make dirdata work with metadata_csum","Date":"Fri, 17 Apr 2026 22:37:18 +0100","Message-ID":"<20260417213723.74204-2-artem.blagodarenko@gmail.com>","X-Mailer":"git-send-email 2.52.0","In-Reply-To":"<20260417213723.74204-1-artem.blagodarenko@gmail.com>","References":"<20260417213723.74204-1-artem.blagodarenko@gmail.com>","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-Spam-Status":"No, score=-1.2 required=5.0 tests=ARC_SIGNED,ARC_VALID,\n\tDKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DMARC_PASS,\n\tFREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,\n\tMAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS autolearn=disabled\n\tversion=4.0.1","X-Spam-Checker-Version":"SpamAssassin 4.0.1 (2024-03-25) on gandalf.ozlabs.org"},"content":"Split monolithic definition of dx_root struct to separate dx_root_info\nfrom fake struct ext4_dir_entry2 for improved code readability.\nThis allows \".\" and \"..\" dirents to have different sizes if necessary,\nsince we can't assume the rec_len 12 if dx_root dirents have dirdata.\nAdds dx_get_dx_info() accessor instead of complex typecast at callers.\nDoes not change any functionality.\n\nSigned-off-by: Pravin Shelar <pravin.shelar@sun.com>\nSigned-off-by: Artem Blagodarenko <artem.blagodarenko@gmail.com>\nReviewed-by: Andreas Dilger <adilger@dilger.ca>\n---\n fs/ext4/namei.c | 177 ++++++++++++++++++++++++------------------------\n 1 file changed, 89 insertions(+), 88 deletions(-)","diff":"diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c\nindex c4b5e252af0e..ab2b4bb4a93d 100644\n--- a/fs/ext4/namei.c\n+++ b/fs/ext4/namei.c\n@@ -244,22 +244,13 @@ struct dx_entry\n  * hash version mod 4 should never be 0.  Sincerely, the paranoia department.\n  */\n \n-struct dx_root\n+struct dx_root_info\n {\n-\tstruct fake_dirent dot;\n-\tchar dot_name[4];\n-\tstruct fake_dirent dotdot;\n-\tchar dotdot_name[4];\n-\tstruct dx_root_info\n-\t{\n-\t\t__le32 reserved_zero;\n-\t\tu8 hash_version;\n-\t\tu8 info_length; /* 8 */\n-\t\tu8 indirect_levels;\n-\t\tu8 unused_flags;\n-\t}\n-\tinfo;\n-\tstruct dx_entry\tentries[];\n+\t__le32 reserved_zero;\n+\tu8 hash_version;\n+\tu8 info_length; /* 8 */\n+\tu8 indirect_levels;\n+\tu8 unused_flags;\n };\n \n struct dx_node\n@@ -334,11 +325,7 @@ static struct ext4_dir_entry_tail *get_dirent_tail(struct inode *inode,\n \tt = EXT4_DIRENT_TAIL(bh->b_data, EXT4_BLOCK_SIZE(inode->i_sb));\n #endif\n \n-\tif (t->det_reserved_zero1 ||\n-\t    (ext4_rec_len_from_disk(t->det_rec_len, blocksize) !=\n-\t     sizeof(struct ext4_dir_entry_tail)) ||\n-\t    t->det_reserved_zero2 ||\n-\t    t->det_reserved_ft != EXT4_FT_DIR_CSUM)\n+\tif (!ext4_dir_entry_is_tail((struct ext4_dir_entry_2 *)t))\n \t\treturn NULL;\n \n \treturn t;\n@@ -413,7 +400,7 @@ static struct dx_countlimit *get_dx_countlimit(struct inode *inode,\n \t\t\t\t\t       struct ext4_dir_entry *dirent,\n \t\t\t\t\t       int *offset)\n {\n-\tstruct ext4_dir_entry *dp;\n+\tstruct ext4_dir_entry_2 *de;\n \tstruct dx_root_info *root;\n \tint count_offset;\n \tint blocksize = EXT4_BLOCK_SIZE(inode->i_sb);\n@@ -422,10 +409,10 @@ static struct dx_countlimit *get_dx_countlimit(struct inode *inode,\n \tif (rlen == blocksize)\n \t\tcount_offset = 8;\n \telse if (rlen == 12) {\n-\t\tdp = (struct ext4_dir_entry *)(((void *)dirent) + 12);\n-\t\tif (ext4_rec_len_from_disk(dp->rec_len, blocksize) != blocksize - 12)\n+\t\tde = (struct ext4_dir_entry_2 *)(((void *)dirent) + 12);\n+\t\tif (ext4_rec_len_from_disk(de->rec_len, blocksize) != blocksize - 12)\n \t\t\treturn NULL;\n-\t\troot = (struct dx_root_info *)(((void *)dp + 12));\n+\t\troot = (struct dx_root_info *)(((void *)de + 12));\n \t\tif (root->reserved_zero ||\n \t\t    root->info_length != sizeof(struct dx_root_info))\n \t\t\treturn NULL;\n@@ -533,6 +520,16 @@ ext4_next_entry(struct ext4_dir_entry_2 *p, unsigned long blocksize)\n  * Future: use high four bits of block for coalesce-on-delete flags\n  * Mask them off for now.\n  */\n+static struct dx_root_info *dx_get_dx_info(void *de_buf)\n+{\n+\t/* get dotdot first */\n+\tde_buf = de_buf + ext4_dirent_rec_len(1, NULL);\n+\n+\t/* dx root info is after dotdot entry */\n+\tde_buf = de_buf + ext4_dirent_rec_len(2, NULL);\n+\n+\treturn (struct dx_root_info *)de_buf;\n+}\n \n static inline ext4_lblk_t dx_get_block(struct dx_entry *entry)\n {\n@@ -574,11 +571,16 @@ static inline void dx_set_limit(struct dx_entry *entries, unsigned value)\n \t((struct dx_countlimit *) entries)->limit = cpu_to_le16(value);\n }\n \n-static inline unsigned dx_root_limit(struct inode *dir, unsigned infosize)\n+static inline unsigned dx_root_limit(struct inode *dir,\n+\tstruct ext4_dir_entry_2 *dot_de, unsigned infosize)\n {\n-\tunsigned int entry_space = dir->i_sb->s_blocksize -\n-\t\t\text4_dir_rec_len(1, NULL) -\n-\t\t\text4_dir_rec_len(2, NULL) - infosize;\n+\tstruct ext4_dir_entry_2 *dotdot_de;\n+\tunsigned entry_space;\n+\n+\tdotdot_de = ext4_next_entry(dot_de, dir->i_sb->s_blocksize);\n+\tentry_space = dir->i_sb->s_blocksize -\n+\t\text4_dir_entry_len(dot_de, NULL) -\n+\t\text4_dir_entry_len(dotdot_de, NULL) - infosize;\n \n \tif (ext4_has_feature_metadata_csum(dir->i_sb))\n \t\tentry_space -= sizeof(struct dx_tail);\n@@ -780,7 +782,7 @@ dx_probe(struct ext4_filename *fname, struct inode *dir,\n {\n \tunsigned count, indirect, level, i;\n \tstruct dx_entry *at, *entries, *p, *q, *m;\n-\tstruct dx_root *root;\n+\tstruct dx_root_info *info;\n \tstruct dx_frame *frame = frame_in;\n \tstruct dx_frame *ret_err = ERR_PTR(ERR_BAD_DX_DIR);\n \tu32 hash;\n@@ -792,23 +794,24 @@ dx_probe(struct ext4_filename *fname, struct inode *dir,\n \tif (IS_ERR(frame->bh))\n \t\treturn (struct dx_frame *) frame->bh;\n \n-\troot = (struct dx_root *) frame->bh->b_data;\n-\tif (root->info.hash_version != DX_HASH_TEA &&\n-\t    root->info.hash_version != DX_HASH_HALF_MD4 &&\n-\t    root->info.hash_version != DX_HASH_LEGACY &&\n-\t    root->info.hash_version != DX_HASH_SIPHASH) {\n-\t\text4_warning_inode(dir, \"Unrecognised inode hash code %u\",\n-\t\t\t\t   root->info.hash_version);\n+\tinfo = dx_get_dx_info((struct ext4_dir_entry_2 *)frame->bh->b_data);\n+\tif (info->hash_version != DX_HASH_TEA &&\n+\t    info->hash_version != DX_HASH_HALF_MD4 &&\n+\t    info->hash_version != DX_HASH_LEGACY &&\n+\t    info->hash_version != DX_HASH_SIPHASH) {\n+\t\text4_warning(dir->i_sb,\n+\t\t\t\"Unrecognised inode hash code %d for directory #%lu\",\n+\t\t\tinfo->hash_version, dir->i_ino);\n \t\tgoto fail;\n \t}\n \tif (ext4_hash_in_dirent(dir)) {\n-\t\tif (root->info.hash_version != DX_HASH_SIPHASH) {\n+\t\tif (info->hash_version != DX_HASH_SIPHASH) {\n \t\t\text4_warning_inode(dir,\n \t\t\t\t\"Hash in dirent, but hash is not SIPHASH\");\n \t\t\tgoto fail;\n \t\t}\n \t} else {\n-\t\tif (root->info.hash_version == DX_HASH_SIPHASH) {\n+\t\tif (info->hash_version == DX_HASH_SIPHASH) {\n \t\t\text4_warning_inode(dir,\n \t\t\t\t\"Hash code is SIPHASH, but hash not in dirent\");\n \t\t\tgoto fail;\n@@ -816,7 +819,7 @@ dx_probe(struct ext4_filename *fname, struct inode *dir,\n \t}\n \tif (fname)\n \t\thinfo = &fname->hinfo;\n-\thinfo->hash_version = root->info.hash_version;\n+\thinfo->hash_version = info->hash_version;\n \tif (hinfo->hash_version <= DX_HASH_TEA)\n \t\thinfo->hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;\n \thinfo->seed = EXT4_SB(dir->i_sb)->s_hash_seed;\n@@ -832,13 +835,13 @@ dx_probe(struct ext4_filename *fname, struct inode *dir,\n \t}\n \thash = hinfo->hash;\n \n-\tif (root->info.unused_flags & 1) {\n+\tif (info->unused_flags & 1) {\n \t\text4_warning_inode(dir, \"Unimplemented hash flags: %#06x\",\n-\t\t\t\t   root->info.unused_flags);\n+\t\t\t\t   info->unused_flags);\n \t\tgoto fail;\n \t}\n \n-\tindirect = root->info.indirect_levels;\n+\tindirect = info->indirect_levels;\n \tif (indirect >= ext4_dir_htree_level(dir->i_sb)) {\n \t\text4_warning(dir->i_sb,\n \t\t\t     \"Directory (ino: %lu) htree depth %#06x exceed\"\n@@ -851,14 +854,17 @@ dx_probe(struct ext4_filename *fname, struct inode *dir,\n \t\tgoto fail;\n \t}\n \n-\tentries = (struct dx_entry *)(((char *)&root->info) +\n-\t\t\t\t      root->info.info_length);\n+\tentries = (struct dx_entry *)(((char *)info) +\n+\t\t\t\t      info->info_length);\n \n-\tif (dx_get_limit(entries) != dx_root_limit(dir,\n-\t\t\t\t\t\t   root->info.info_length)) {\n+\tif (dx_get_limit(entries) !=\n+\t    dx_root_limit(dir, (struct ext4_dir_entry_2 *)frame->bh->b_data,\n+\t\t\t  info->info_length)) {\n \t\text4_warning_inode(dir, \"dx entry: limit %u != root limit %u\",\n \t\t\t\t   dx_get_limit(entries),\n-\t\t\t\t   dx_root_limit(dir, root->info.info_length));\n+\t\t\t\t   dx_root_limit(dir,\n+\t\t\t\t   (struct ext4_dir_entry_2 *)frame->bh->b_data,\n+\t\t\t\t   info->info_length));\n \t\tgoto fail;\n \t}\n \n@@ -944,7 +950,7 @@ static void dx_release(struct dx_frame *frames)\n \tif (frames[0].bh == NULL)\n \t\treturn;\n \n-\tinfo = &((struct dx_root *)frames[0].bh->b_data)->info;\n+\tinfo = dx_get_dx_info((struct ext4_dir_entry_2 *)frames[0].bh->b_data);\n \t/* save local copy, \"info\" may be freed after brelse() */\n \tindirect_levels = info->indirect_levels;\n \tfor (i = 0; i <= indirect_levels; i++) {\n@@ -2156,44 +2162,38 @@ static int add_dirent_to_buf(handle_t *handle, struct ext4_filename *fname,\n \treturn err ? err : err2;\n }\n \n-static bool ext4_check_dx_root(struct inode *dir, struct dx_root *root)\n+static bool ext4_check_dx_root(struct inode *dir,\n+\t\t\t       struct ext4_dir_entry_2 *dot_de,\n+\t\t\t       struct ext4_dir_entry_2 *dotdot_de,\n+\t\t\t       struct ext4_dir_entry_2 **entry)\n {\n-\tstruct fake_dirent *fde;\n \tconst char *error_msg;\n-\tunsigned int rlen;\n \tunsigned int blocksize = dir->i_sb->s_blocksize;\n-\tchar *blockend = (char *)root + dir->i_sb->s_blocksize;\n+\tstruct ext4_dir_entry_2 *de = NULL;\n \n-\tfde = &root->dot;\n-\tif (unlikely(fde->name_len != 1)) {\n+\tif (unlikely(dot_de->name_len != 1)) {\n \t\terror_msg = \"invalid name_len for '.'\";\n \t\tgoto corrupted;\n \t}\n-\tif (unlikely(strncmp(root->dot_name, \".\", fde->name_len))) {\n+\tif (unlikely(strncmp(dot_de->name, \".\", dot_de->name_len))) {\n \t\terror_msg = \"invalid name for '.'\";\n \t\tgoto corrupted;\n \t}\n-\trlen = ext4_rec_len_from_disk(fde->rec_len, blocksize);\n-\tif (unlikely((char *)fde + rlen >= blockend)) {\n-\t\terror_msg = \"invalid rec_len for '.'\";\n-\t\tgoto corrupted;\n-\t}\n \n-\tfde = &root->dotdot;\n-\tif (unlikely(fde->name_len != 2)) {\n+\tif (unlikely(dotdot_de->name_len != 2)) {\n \t\terror_msg = \"invalid name_len for '..'\";\n \t\tgoto corrupted;\n \t}\n-\tif (unlikely(strncmp(root->dotdot_name, \"..\", fde->name_len))) {\n+\tif (unlikely(strncmp(dotdot_de->name, \"..\", dotdot_de->name_len))) {\n \t\terror_msg = \"invalid name for '..'\";\n \t\tgoto corrupted;\n \t}\n-\trlen = ext4_rec_len_from_disk(fde->rec_len, blocksize);\n-\tif (unlikely((char *)fde + rlen >= blockend)) {\n+\tde = ext4_next_entry(dotdot_de, blocksize);\n+\tif ((char *)de >= (((char *)dot_de) + blocksize)) {\n \t\terror_msg = \"invalid rec_len for '..'\";\n \t\tgoto corrupted;\n \t}\n-\n+\t*entry = de;\n \treturn true;\n \n corrupted:\n@@ -2211,16 +2211,15 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,\n \t\t\t    struct inode *inode, struct buffer_head *bh)\n {\n \tstruct buffer_head *bh2;\n-\tstruct dx_root\t*root;\n \tstruct dx_frame\tframes[EXT4_HTREE_LEVEL], *frame;\n \tstruct dx_entry *entries;\n-\tstruct ext4_dir_entry_2\t*de, *de2;\n+\tstruct ext4_dir_entry_2\t*de, *de2, *dot_de, *dotdot_de;\n \tchar\t\t*data2, *top;\n \tunsigned\tlen;\n \tint\t\tretval;\n \tunsigned\tblocksize;\n \text4_lblk_t  block;\n-\tstruct fake_dirent *fde;\n+\tstruct dx_root_info *dx_info;\n \tint csum_size = 0;\n \n \tif (ext4_has_feature_metadata_csum(inode->i_sb))\n@@ -2237,17 +2236,15 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,\n \t\treturn retval;\n \t}\n \n-\troot = (struct dx_root *) bh->b_data;\n-\tif (!ext4_check_dx_root(dir, root)) {\n+\tdot_de = (struct ext4_dir_entry_2 *)bh->b_data;\n+\tdotdot_de = ext4_next_entry(dot_de, blocksize);\n+\tif (!ext4_check_dx_root(dir, dot_de, dotdot_de, &de)) {\n \t\tbrelse(bh);\n \t\treturn -EFSCORRUPTED;\n \t}\n \n \t/* The 0th block becomes the root, move the dirents out */\n-\tfde = &root->dotdot;\n-\tde = (struct ext4_dir_entry_2 *)((char *)fde +\n-\t\text4_rec_len_from_disk(fde->rec_len, blocksize));\n-\tlen = ((char *) root) + (blocksize - csum_size) - (char *) de;\n+\tlen = ((char *)dot_de) + (blocksize - csum_size) - (char *)de;\n \n \t/* Allocate new block for the 0th block's dirents */\n \tbh2 = ext4_append(handle, dir, &block);\n@@ -2278,24 +2275,27 @@ static int make_indexed_dir(handle_t *handle, struct ext4_filename *fname,\n \t\text4_initialize_dirent_tail(bh2, blocksize);\n \n \t/* Initialize the root; the dot dirents already exist */\n-\tde = (struct ext4_dir_entry_2 *) (&root->dotdot);\n-\tde->rec_len = ext4_rec_len_to_disk(\n-\t\t\tblocksize - ext4_dir_rec_len(2, NULL), blocksize);\n-\tmemset (&root->info, 0, sizeof(root->info));\n-\troot->info.info_length = sizeof(root->info);\n+\tdotdot_de->rec_len =\n+\t\text4_rec_len_to_disk(blocksize - le16_to_cpu(dot_de->rec_len),\n+\t\t\t\t     blocksize);\n+\n+\t/* initialize hashing info */\n+\tdx_info = dx_get_dx_info(dot_de);\n+\tmemset(dx_info, 0, sizeof(*dx_info));\n+\tdx_info->info_length = sizeof(*dx_info);\n \tif (ext4_hash_in_dirent(dir))\n-\t\troot->info.hash_version = DX_HASH_SIPHASH;\n+\t\tdx_info->hash_version = DX_HASH_SIPHASH;\n \telse\n-\t\troot->info.hash_version =\n+\t\tdx_info->hash_version =\n \t\t\t\tEXT4_SB(dir->i_sb)->s_def_hash_version;\n \n-\tentries = root->entries;\n+\tentries = (void *)dx_info + sizeof(*dx_info);\n \tdx_set_block(entries, 1);\n \tdx_set_count(entries, 1);\n-\tdx_set_limit(entries, dx_root_limit(dir, sizeof(root->info)));\n+\tdx_set_limit(entries, dx_root_limit(dir, dot_de, sizeof(*dx_info)));\n \n \t/* Initialize as for dx_probe */\n-\tfname->hinfo.hash_version = root->info.hash_version;\n+\tfname->hinfo.hash_version = dx_info->hash_version;\n \tif (fname->hinfo.hash_version <= DX_HASH_TEA)\n \t\tfname->hinfo.hash_version += EXT4_SB(dir->i_sb)->s_hash_unsigned;\n \tfname->hinfo.seed = EXT4_SB(dir->i_sb)->s_hash_seed;\n@@ -2598,7 +2598,7 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,\n \t\t\tif (restart || err)\n \t\t\t\tgoto journal_error;\n \t\t} else {\n-\t\t\tstruct dx_root *dxroot;\n+\t\t\tstruct dx_root_info *info;\n \t\t\tmemcpy((char *) entries2, (char *) entries,\n \t\t\t       icount * sizeof(struct dx_entry));\n \t\t\tdx_set_limit(entries2, dx_node_limit(dir));\n@@ -2606,8 +2606,9 @@ static int ext4_dx_add_entry(handle_t *handle, struct ext4_filename *fname,\n \t\t\t/* Set up root */\n \t\t\tdx_set_count(entries, 1);\n \t\t\tdx_set_block(entries + 0, newblock);\n-\t\t\tdxroot = (struct dx_root *)frames[0].bh->b_data;\n-\t\t\tdxroot->info.indirect_levels += 1;\n+\t\t\tinfo = dx_get_dx_info((struct ext4_dir_entry_2 *)\n+\t\t\t\t\t      frames[0].bh->b_data);\n+\t\t\tinfo->indirect_levels = 1;\n \t\t\tdxtrace(printk(KERN_DEBUG\n \t\t\t\t       \"Creating %d level index...\\n\",\n \t\t\t\t       dxroot->info.indirect_levels));\n","prefixes":["1/3"]}