From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from omta034.useast.a.cloudfilter.net (omta034.useast.a.cloudfilter.net [44.202.169.33]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 22C0F19F421 for ; Wed, 29 Jan 2025 08:05:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=44.202.169.33 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738137953; cv=none; b=P5Uk2jMC3Io6bm/xSF79loi0Nfy80l11pED3viWfGOvphL8mESfwZQlghxmjPYNccfqkm7EcwBdzfYvbJKp2Dmi/Y/FIRiJtI8zyot/vMwATxAWsKnphQyRjr4thmy//CCOJ9hQibY3fOL4iuuRk5ID8ajuLpvfI5yRdUK8LDvA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1738137953; c=relaxed/simple; bh=oF30+J3IqzruAOpxJYIi5djwvudQtHK2lwBVZ4vPqeI=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=Mdj6HDGXFedKGNKulTjilzjibO99tGcIidkyCIEXBiOAC2JtSe0X4HZwvO49NFs0nn7x8/VclPZ6+MqJB/RDvoXYv/Vqdu9hHvOWESoXjnIWa5QZCodPlVIqEHaOnMvplCXCiG2KEIK7lKIO1LvY9VyphnTrLkktPUMJ9ozsH4c= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=embeddedor.com; spf=pass smtp.mailfrom=embeddedor.com; dkim=pass (2048-bit key) header.d=embeddedor.com header.i=@embeddedor.com header.b=hstIpoSI; arc=none smtp.client-ip=44.202.169.33 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=embeddedor.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=embeddedor.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=embeddedor.com header.i=@embeddedor.com header.b="hstIpoSI" Received: from eig-obgw-6007a.ext.cloudfilter.net ([10.0.30.247]) by cmsmtp with ESMTPS id coKptv1AkXshwd34wtweRX; Wed, 29 Jan 2025 08:05:43 +0000 Received: from gator4166.hostgator.com ([108.167.133.22]) by cmsmtp with ESMTPS id d34st3FtD3770d34stDcSa; Wed, 29 Jan 2025 08:05:38 +0000 X-Authority-Analysis: v=2.4 cv=WYoKaVhX c=1 sm=1 tr=0 ts=6799e152 a=1YbLdUo/zbTtOZ3uB5T3HA==:117 a=3GLQtCDrk5mhnYkuwPoHkA==:17 a=IkcTkHD0fZMA:10 a=VdSt8ZQiCzkA:10 a=7T7KSl7uo7wA:10 a=VwQbUJbxAAAA:8 a=KKAkSRfTAAAA:8 a=n4Tv2M7neSFVITN6eSkA:9 a=QEXdDO2ut3YA:10 a=cvBusfyB2V15izCimMoJ:22 a=Xt_RvD8W3m28Mn_h3AK8:22 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=embeddedor.com; s=default; h=Content-Transfer-Encoding:Content-Type: In-Reply-To:From:References:Cc:To:Subject:MIME-Version:Date:Message-ID:Sender :Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Id:List-Help: List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive; bh=dJNGaRuyb43KyPltLLyaM42uJkC8Bu7eSEAbbEuHpi8=; b=hstIpoSIJ1JEtZzYmgPkabvpfF vewCr2uyaWYPsQL1VMcI/JFT9EhN+mnyLm2Yav6CBKePf/0O5bZ1TgiJzurrvg6vKVXxvyYwuftt3 Phs8FHj71S77gnoz4FE9O97GBFj9FrkC+QP31HKy0F1MVAokZJW98l2DcBpNFW0v6t5Nk5CeIq1v1 1OXis5r+oh06nSgCmQpl6Ci4Qlw0a/QYSuvsDNp3J/UfgYEEIAu08TD41rwon3Nf8WPmvrX4dSeTj eyhtKibdTY4nS7gWunG4nO/1D5wSr10wMOekg2brDYcK2FtQcXcwWmZbTXtgPHssQoCEQL6dpziK1 RvaQr58g==; Received: from [45.124.203.141] (port=55427 helo=[192.168.0.153]) by gator4166.hostgator.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96.2) (envelope-from ) id 1td34q-0028o3-2J; Wed, 29 Jan 2025 02:05:37 -0600 Message-ID: Date: Wed, 29 Jan 2025 18:35:18 +1030 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v2][next] container_of: add container_first() macro To: Greg KH , "Gustavo A. R. Silva" Cc: Dan Carpenter , linux-kernel@vger.kernel.org, linux-hardening@vger.kernel.org References: <2025012955-hypnotic-patronize-8931@gregkh> Content-Language: en-US From: "Gustavo A. R. Silva" In-Reply-To: <2025012955-hypnotic-patronize-8931@gregkh> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - gator4166.hostgator.com X-AntiAbuse: Original Domain - vger.kernel.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - embeddedor.com X-BWhitelist: no X-Source-IP: 45.124.203.141 X-Source-L: No X-Exim-ID: 1td34q-0028o3-2J X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: ([192.168.0.153]) [45.124.203.141]:55427 X-Source-Auth: gustavo@embeddedor.com X-Email-Count: 2 X-Org: HG=hgshared;ORG=hostgator; X-Source-Cap: Z3V6aWRpbmU7Z3V6aWRpbmU7Z2F0b3I0MTY2Lmhvc3RnYXRvci5jb20= X-Local-Domain: yes X-CMAE-Envelope: MS4xfNTTifY5hX97xXPigCvyefffGE1hUmqleatFIFTtvjNDJlo0iMeWXyYjg0blnwXgMLRW2gVmWVpp6xb123ey5FlntNwVw7FYUv047zFWPXhlBeT9QLQZ Lw8L5N9OS+AuQ/Cr4v0pD5c1AjChZX7p/ZqjHpHh7vXFSs9stizUESqSfu2aCmDMG2iiOptL1yWczYtqGjBAzduVuVVP0o5NrE6zzZ9CngijvQv1Y2U4uTJX On 29/01/25 16:24, Greg KH wrote: > On Wed, Jan 29, 2025 at 03:56:01PM +1030, Gustavo A. R. Silva wrote: >> This is like container_of_const() but it contains an assert to >> ensure that it's using the first member in the structure. > > But why? If you "know" it's the first member, just do a normal cast. > If you don't, then you probably shouldn't be caring about this anyway, > right? This is more about the cases where the member _must_ be first in the structure. See below for an example related to -Wflex-array-member-not-at-end > >> >> Co-developed-by: Dan Carpenter >> Signed-off-by: Dan Carpenter >> Signed-off-by: Gustavo A. R. Silva >> --- >> >> I will be using this in my -Wflex-array-member-not-at-end patches. :) > > Confused, I'd like to see some users first please. When addressing the -Wflex-array-member-not-at-end warnings, the common scenario is when we have to separate the flexible-array member from the rest of the members in the flexible structure, as shown below [1]: struct bplus_header { struct_group_tagged(bplus_header_fixed, __hdr, u8 flags; /* bit 0 - high bit of first free entry offset bit 5 - we're pointed to by an fnode, the data btree or some ea or the main ea bootage pointer ea_secno bit 6 - suggest binary search (unused) bit 7 - 1 -> (internal) tree of anodes 0 -> (leaf) list of extents */ u8 fill[3]; u8 n_free_nodes; /* free nodes in following array */ u8 n_used_nodes; /* used nodes in following array */ __le16 first_free; /* offset from start of header to first free node in array */ ); union { /* (internal) 2-word entries giving subtree pointers */ DECLARE_FLEX_ARRAY(struct bplus_internal_node, internal); /* (external) 3-word entries giving sector runs */ DECLARE_FLEX_ARRAY(struct bplus_leaf_node, external); } u; }; struct_group_tagged() creates a new type: `struct bplus_header_fixed`, we then use the newly created type to change the type of the middle objects causing the warnings, and with that the warnings are gone: @@ -453,7 +455,7 @@ struct fnode __le16 flags; /* bit 1 set -> ea_secno is an anode */ /* bit 8 set -> directory. first & only extent points to dnode. */ - struct bplus_header btree; /* b+ tree, 8 extents or 12 subtrees */ + struct bplus_header_fixed btree; /* b+ tree, 8 extents or 12 subtrees */ union { struct bplus_leaf_node external[8]; struct bplus_internal_node internal[12]; @@ -495,7 +497,7 @@ struct anode __le32 self; /* pointer to this anode */ __le32 up; /* parent anode or fnode */ - struct bplus_header btree; /* b+tree, 40 extents or 60 subtrees */ + struct bplus_header_fixed btree; /* b+tree, 40 extents or 60 subtrees */ union { struct bplus_leaf_node external[40]; struct bplus_internal_node internal[60]; However, this newly created type, or rather the member `__hdr` (also created when calling struct_group_tagged()) _must_ always be the first member in the flexible struct `struct bplus_header`. Then we need to use container_first() to retrieve a pointer to the flexible structure [2], via which we can access the flexible-array member when necessary: diff --git a/fs/hpfs/anode.c b/fs/hpfs/anode.c index c14c9a035ee0c0..a366f6ac71e436 100644 --- a/fs/hpfs/anode.c +++ b/fs/hpfs/anode.c @@ -27,7 +27,7 @@ secno hpfs_bplus_lookup(struct super_block *s, struct inode *inode, a = le32_to_cpu(btree->u.internal[i].down); brelse(bh); if (!(anode = hpfs_map_anode(s, a, &bh))) return -1; - btree = &anode->btree; + btree = container_first(&anode->btree, struct bplus_header, __hdr); goto go_down; } hpfs_error(s, "sector %08x not found in internal anode %08x", sec, a); @@ -69,12 +69,16 @@ secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsi int n; unsigned fs; int c1, c2 = 0; + struct bplus_header *anode_btree = container_first(&anode->btree, struct bplus_header, __hdr); + struct bplus_header *ranode_btree = container_first(&ranode->btree, struct bplus_header, __hdr); + struct bplus_header *fnode_btree = container_first(&fnode->btree, struct bplus_header, __hdr); + So, if we use container_first() (or container_of_first(), you tell which name you prefer), we are asserting that that `__hdr` member is always the first member in `struct bplus_header`. I've explained all this at Plumbers last year. In any case, let me know if you need more clarification. :) Thanks! -- Gustavo [1] https://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux.git/diff/fs/hpfs/hpfs.h?h=testing/wfamnae-next20250124&id=f66219294267a2fba220f4f3118e11c5cda63d0b [2] https://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux.git/diff/fs/hpfs/anode.c?h=testing/wfamnae-next20250124&id=f66219294267a2fba220f4f3118e11c5cda63d0b