* [PATCH][next] NFSD: Avoid multiple -Wflex-array-member-not-at-end warnings @ 2025-05-06 20:58 Gustavo A. R. Silva 2025-05-06 23:31 ` NeilBrown 0 siblings, 1 reply; 3+ messages in thread From: Gustavo A. R. Silva @ 2025-05-06 20:58 UTC (permalink / raw) To: Chuck Lever, Jeff Layton, NeilBrown, Olga Kornievskaia, Dai Ngo, Tom Talpey Cc: linux-nfs, linux-kernel, Gustavo A. R. Silva, linux-hardening -Wflex-array-member-not-at-end was introduced in GCC-14, and we are getting ready to enable it, globally. Move the conflicting declaration to the end of the corresponding structures. Notice that `struct knfsd_fh` is a flexible structure --a structure that contains a flexible-array member. Fix the following warnings: fs/nfsd/nfsfh.h:79:33: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] fs/nfsd/state.h:763:33: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] fs/nfsd/state.h:669:33: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] fs/nfsd/state.h:549:33: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] fs/nfsd/xdr4.h:705:33: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] fs/nfsd/xdr4.h:678:33: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org> --- fs/nfsd/nfsfh.h | 4 +++- fs/nfsd/state.h | 12 +++++++++--- fs/nfsd/xdr4.h | 8 ++++++-- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h index 5103c2f4d225..bbee43674a2a 100644 --- a/fs/nfsd/nfsfh.h +++ b/fs/nfsd/nfsfh.h @@ -76,7 +76,6 @@ static inline ino_t u32_to_ino_t(__u32 uino) * pre_mtime/post_version will be used to support wcc_attr's in NFSv3. */ typedef struct svc_fh { - struct knfsd_fh fh_handle; /* FH data */ int fh_maxsize; /* max size for fh_handle */ struct dentry * fh_dentry; /* validated dentry */ struct svc_export * fh_export; /* export pointer */ @@ -107,6 +106,9 @@ typedef struct svc_fh { /* Post-op attributes saved in fh_fill_post_attrs() */ struct kstat fh_post_attr; /* full attrs after operation */ u64 fh_post_change; /* nfsv4 change; see above */ + + /* Must be last -ends in a flexible-array member. */ + struct knfsd_fh fh_handle; /* FH data */ } svc_fh; #define NFSD4_FH_FOREIGN (1<<0) #define SET_FH_FLAG(c, f) ((c)->fh_flags |= (f)) diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h index 1995bca158b8..ffd3fd8c34a0 100644 --- a/fs/nfsd/state.h +++ b/fs/nfsd/state.h @@ -546,9 +546,11 @@ struct nfs4_replay { __be32 rp_status; unsigned int rp_buflen; char *rp_buf; - struct knfsd_fh rp_openfh; int rp_locked; char rp_ibuf[NFSD4_REPLAY_ISIZE]; + + /* Must be last -ends in a flexible-array member. */ + struct knfsd_fh rp_openfh; }; struct nfs4_stateowner; @@ -666,12 +668,14 @@ struct nfs4_file { u32 fi_share_deny; struct nfsd_file *fi_deleg_file; int fi_delegees; - struct knfsd_fh fi_fhandle; bool fi_had_conflict; #ifdef CONFIG_NFSD_PNFS struct list_head fi_lo_states; atomic_t fi_lo_recalls; #endif + + /* Must be last -ends in a flexible-array member. */ + struct knfsd_fh fi_fhandle; }; /* @@ -760,9 +764,11 @@ struct nfsd4_blocked_lock { struct list_head nbl_lru; time64_t nbl_time; struct file_lock nbl_lock; - struct knfsd_fh nbl_fh; struct nfsd4_callback nbl_cb; struct kref nbl_kref; + + /* Must be last -ends in a flexible-array member. */ + struct knfsd_fh nbl_fh; }; struct nfsd4_compound_state; diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index aa2a356da784..e453ea5ebab6 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -675,11 +675,13 @@ struct nfsd4_cb_offload { struct nfsd42_write_res co_res; __be32 co_nfserr; unsigned int co_retries; - struct knfsd_fh co_fh; struct nfs4_sessionid co_referring_sessionid; u32 co_referring_slotid; u32 co_referring_seqno; + + /* Must be last -ends in a flexible-array member. */ + struct knfsd_fh co_fh; }; struct nfsd4_copy { @@ -702,7 +704,6 @@ struct nfsd4_copy { /* response */ __be32 nfserr; struct nfsd42_write_res cp_res; - struct knfsd_fh fh; /* offload callback */ struct nfsd4_cb_offload cp_cb_offload; @@ -723,6 +724,9 @@ struct nfsd4_copy { struct nfs_fh c_fh; nfs4_stateid stateid; struct nfsd_net *cp_nn; + + /* Must be last -ends in a flexible-array member. */ + struct knfsd_fh fh; }; static inline void nfsd4_copy_set_sync(struct nfsd4_copy *copy, bool sync) -- 2.43.0 ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH][next] NFSD: Avoid multiple -Wflex-array-member-not-at-end warnings 2025-05-06 20:58 [PATCH][next] NFSD: Avoid multiple -Wflex-array-member-not-at-end warnings Gustavo A. R. Silva @ 2025-05-06 23:31 ` NeilBrown 2025-05-07 6:04 ` Christoph Hellwig 0 siblings, 1 reply; 3+ messages in thread From: NeilBrown @ 2025-05-06 23:31 UTC (permalink / raw) To: Gustavo A. R. Silva Cc: Chuck Lever, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey, linux-nfs, linux-kernel, Gustavo A. R. Silva, linux-hardening On Wed, 07 May 2025, Gustavo A. R. Silva wrote: > -Wflex-array-member-not-at-end was introduced in GCC-14, and we are > getting ready to enable it, globally. > > Move the conflicting declaration to the end of the corresponding > structures. Notice that `struct knfsd_fh` is a flexible structure --a > structure that contains a flexible-array member. I don't really like this solution. struct knfsd_fh has a fixed size determined by NFS4_FHSIZE. The fact that fh_fsid is "flexible" doesn't mean it is unlimited in size. So moving it to the end of other structures is silencing a warning but leaving the code as potentially confusing. Maybe just make it u32 fh_fsid[4]; /* in practice the size varies but is always * limited by fh_raw above */ There are places was [0] [1] and [2] are explictly indexed, so size needs to be atleast 3 else we invite warnings. But maybe other memcpy etc will trigger warnings anyway?? Maybe u32 fh_fsid[NFS4_FHSIZE/4-1]; That will always fit in the available space and we never use anywhere close to that size. I'd really rather use [] and have some way to tell the compiler that we have the size under control and it doesn't need to worry. Thanks, NeilBrown > > Fix the following warnings: > > fs/nfsd/nfsfh.h:79:33: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] > fs/nfsd/state.h:763:33: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] > fs/nfsd/state.h:669:33: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] > fs/nfsd/state.h:549:33: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] > fs/nfsd/xdr4.h:705:33: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] > fs/nfsd/xdr4.h:678:33: warning: structure containing a flexible array member is not at the end of another structure [-Wflex-array-member-not-at-end] > > Signed-off-by: Gustavo A. R. Silva <gustavoars@kernel.org> > --- > fs/nfsd/nfsfh.h | 4 +++- > fs/nfsd/state.h | 12 +++++++++--- > fs/nfsd/xdr4.h | 8 ++++++-- > 3 files changed, 18 insertions(+), 6 deletions(-) > > diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h > index 5103c2f4d225..bbee43674a2a 100644 > --- a/fs/nfsd/nfsfh.h > +++ b/fs/nfsd/nfsfh.h > @@ -76,7 +76,6 @@ static inline ino_t u32_to_ino_t(__u32 uino) > * pre_mtime/post_version will be used to support wcc_attr's in NFSv3. > */ > typedef struct svc_fh { > - struct knfsd_fh fh_handle; /* FH data */ > int fh_maxsize; /* max size for fh_handle */ > struct dentry * fh_dentry; /* validated dentry */ > struct svc_export * fh_export; /* export pointer */ > @@ -107,6 +106,9 @@ typedef struct svc_fh { > /* Post-op attributes saved in fh_fill_post_attrs() */ > struct kstat fh_post_attr; /* full attrs after operation */ > u64 fh_post_change; /* nfsv4 change; see above */ > + > + /* Must be last -ends in a flexible-array member. */ > + struct knfsd_fh fh_handle; /* FH data */ > } svc_fh; > #define NFSD4_FH_FOREIGN (1<<0) > #define SET_FH_FLAG(c, f) ((c)->fh_flags |= (f)) > diff --git a/fs/nfsd/state.h b/fs/nfsd/state.h > index 1995bca158b8..ffd3fd8c34a0 100644 > --- a/fs/nfsd/state.h > +++ b/fs/nfsd/state.h > @@ -546,9 +546,11 @@ struct nfs4_replay { > __be32 rp_status; > unsigned int rp_buflen; > char *rp_buf; > - struct knfsd_fh rp_openfh; > int rp_locked; > char rp_ibuf[NFSD4_REPLAY_ISIZE]; > + > + /* Must be last -ends in a flexible-array member. */ > + struct knfsd_fh rp_openfh; > }; > > struct nfs4_stateowner; > @@ -666,12 +668,14 @@ struct nfs4_file { > u32 fi_share_deny; > struct nfsd_file *fi_deleg_file; > int fi_delegees; > - struct knfsd_fh fi_fhandle; > bool fi_had_conflict; > #ifdef CONFIG_NFSD_PNFS > struct list_head fi_lo_states; > atomic_t fi_lo_recalls; > #endif > + > + /* Must be last -ends in a flexible-array member. */ > + struct knfsd_fh fi_fhandle; > }; > > /* > @@ -760,9 +764,11 @@ struct nfsd4_blocked_lock { > struct list_head nbl_lru; > time64_t nbl_time; > struct file_lock nbl_lock; > - struct knfsd_fh nbl_fh; > struct nfsd4_callback nbl_cb; > struct kref nbl_kref; > + > + /* Must be last -ends in a flexible-array member. */ > + struct knfsd_fh nbl_fh; > }; > > struct nfsd4_compound_state; > diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h > index aa2a356da784..e453ea5ebab6 100644 > --- a/fs/nfsd/xdr4.h > +++ b/fs/nfsd/xdr4.h > @@ -675,11 +675,13 @@ struct nfsd4_cb_offload { > struct nfsd42_write_res co_res; > __be32 co_nfserr; > unsigned int co_retries; > - struct knfsd_fh co_fh; > > struct nfs4_sessionid co_referring_sessionid; > u32 co_referring_slotid; > u32 co_referring_seqno; > + > + /* Must be last -ends in a flexible-array member. */ > + struct knfsd_fh co_fh; > }; > > struct nfsd4_copy { > @@ -702,7 +704,6 @@ struct nfsd4_copy { > /* response */ > __be32 nfserr; > struct nfsd42_write_res cp_res; > - struct knfsd_fh fh; > > /* offload callback */ > struct nfsd4_cb_offload cp_cb_offload; > @@ -723,6 +724,9 @@ struct nfsd4_copy { > struct nfs_fh c_fh; > nfs4_stateid stateid; > struct nfsd_net *cp_nn; > + > + /* Must be last -ends in a flexible-array member. */ > + struct knfsd_fh fh; > }; > > static inline void nfsd4_copy_set_sync(struct nfsd4_copy *copy, bool sync) > -- > 2.43.0 > > ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH][next] NFSD: Avoid multiple -Wflex-array-member-not-at-end warnings 2025-05-06 23:31 ` NeilBrown @ 2025-05-07 6:04 ` Christoph Hellwig 0 siblings, 0 replies; 3+ messages in thread From: Christoph Hellwig @ 2025-05-07 6:04 UTC (permalink / raw) To: NeilBrown Cc: Gustavo A. R. Silva, Chuck Lever, Jeff Layton, Olga Kornievskaia, Dai Ngo, Tom Talpey, linux-nfs, linux-kernel, linux-hardening On Wed, May 07, 2025 at 09:31:56AM +1000, NeilBrown wrote: > struct knfsd_fh has a fixed size determined by NFS4_FHSIZE. > The fact that fh_fsid is "flexible" doesn't mean it is unlimited in > size. So moving it to the end of other structures is silencing a > warning but leaving the code as potentially confusing. > > Maybe just make it > u32 fh_fsid[4]; /* in practice the size varies but is always > * limited by fh_raw above Don't make this more complicated than needed. Just killing the magic union overlay over the raw array just complicates things, so just use indices into it. Below is a simple version, but this can use some more work to split things up and to entirely avoid the not exactly natural u32-based addressing in various helpers. diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c index 0363720280d4..804aa679a992 100644 --- a/fs/nfsd/export.c +++ b/fs/nfsd/export.c @@ -1230,7 +1230,7 @@ rqst_exp_get_by_name(struct svc_rqst *rqstp, struct path *path) struct svc_export * rqst_exp_find(struct cache_req *reqp, struct net *net, struct auth_domain *cl, struct auth_domain *gsscl, - int fsid_type, u32 *fsidv) + int fsid_type, void *fsidv) { struct nfsd_net *nn = net_generic(net, nfsd_net_id); struct svc_export *gssexp, *exp = ERR_PTR(-ENOENT); diff --git a/fs/nfsd/export.h b/fs/nfsd/export.h index 4d92b99c1ffd..9b2719d8a3e2 100644 --- a/fs/nfsd/export.h +++ b/fs/nfsd/export.h @@ -131,6 +131,6 @@ static inline struct svc_export *exp_get(struct svc_export *exp) } struct svc_export *rqst_exp_find(struct cache_req *reqp, struct net *net, struct auth_domain *cl, struct auth_domain *gsscl, - int fsid_type, u32 *fsidv); + int fsid_type, void *fsidv); #endif /* NFSD_EXPORT_H */ diff --git a/fs/nfsd/nfs4layouts.c b/fs/nfsd/nfs4layouts.c index 290271ac4245..6dcd2c9ec15b 100644 --- a/fs/nfsd/nfs4layouts.c +++ b/fs/nfsd/nfs4layouts.c @@ -56,7 +56,7 @@ static void nfsd4_alloc_devid_map(const struct svc_fh *fhp) { const struct knfsd_fh *fh = &fhp->fh_handle; - size_t fsid_len = key_len(fh->fh_fsid_type); + size_t fsid_len = key_len(fh->fh_raw[FH_FSID_TYPE]); struct nfsd4_deviceid_map *map, *old; int i; @@ -64,8 +64,8 @@ nfsd4_alloc_devid_map(const struct svc_fh *fhp) if (!map) return; - map->fsid_type = fh->fh_fsid_type; - memcpy(&map->fsid, fh->fh_fsid, fsid_len); + map->fsid_type = fh->fh_raw[FH_FSID_TYPE]; + memcpy(&map->fsid, fh->fh_raw + FH_FSID, fsid_len); spin_lock(&nfsd_devid_lock); if (fhp->fh_export->ex_devid_map) @@ -73,9 +73,9 @@ nfsd4_alloc_devid_map(const struct svc_fh *fhp) for (i = 0; i < DEVID_HASH_SIZE; i++) { list_for_each_entry(old, &nfsd_devid_hash[i], hash) { - if (old->fsid_type != fh->fh_fsid_type) + if (old->fsid_type != map->fsid_type) continue; - if (memcmp(old->fsid, fh->fh_fsid, + if (memcmp(old->fsid, map->fsid, key_len(old->fsid_type))) continue; diff --git a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c index aef474f1b84b..f58da563d4fd 100644 --- a/fs/nfsd/nfsfh.c +++ b/fs/nfsd/nfsfh.c @@ -161,37 +161,40 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct net *net, if (fh->fh_size == 0) return nfserr_nofilehandle; - if (fh->fh_version != 1) + if (fh->fh_raw[FH_VERSION] != 1) return error; if (--data_left < 0) return error; - if (fh->fh_auth_type != 0) + if (fh->fh_raw[FH_AUTH_TYPE] != 0) return error; - len = key_len(fh->fh_fsid_type) / 4; + len = key_len(fh->fh_raw[FH_FSID_TYPE]) / 4; if (len == 0) return error; - if (fh->fh_fsid_type == FSID_MAJOR_MINOR) { + if (fh->fh_raw[FH_FSID_TYPE] == FSID_MAJOR_MINOR) { /* deprecated, convert to type 3 */ + u32 *fsidv = (u32 *)(fh->fh_raw + FH_FSID); + len = key_len(FSID_ENCODE_DEV)/4; - fh->fh_fsid_type = FSID_ENCODE_DEV; + fh->fh_raw[FH_FSID_TYPE] = FSID_ENCODE_DEV; /* * struct knfsd_fh uses host-endian fields, which are * sometimes used to hold net-endian values. This * confuses sparse, so we must use __force here to * keep it from complaining. */ - fh->fh_fsid[0] = new_encode_dev(MKDEV(ntohl((__force __be32)fh->fh_fsid[0]), - ntohl((__force __be32)fh->fh_fsid[1]))); - fh->fh_fsid[1] = fh->fh_fsid[2]; + fsidv[0] = new_encode_dev(MKDEV( + ntohl((__force __be32)fsidv[0]), + ntohl((__force __be32)fsidv[1]))); + fsidv[1] = fsidv[2]; } data_left -= len; if (data_left < 0) return error; exp = rqst_exp_find(rqstp ? &rqstp->rq_chandle : NULL, net, client, gssclient, - fh->fh_fsid_type, fh->fh_fsid); - fid = (struct fid *)(fh->fh_fsid + len); + fh->fh_raw[FH_FSID_TYPE], fh->fh_raw + FH_FSID); + fid = (struct fid *)(fh->fh_raw + FH_FSID + len); error = nfserr_stale; if (IS_ERR(exp)) { @@ -233,7 +236,7 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct net *net, */ error = nfserr_badhandle; - fileid_type = fh->fh_fileid_type; + fileid_type = fh->fh_raw[FH_FILEID_TYPE]; if (fileid_type == FILEID_ROOT) dentry = dget(exp->ex_path.dentry); @@ -463,18 +466,19 @@ static void _fh_update(struct svc_fh *fhp, struct svc_export *exp, { if (dentry != exp->ex_path.dentry) { struct fid *fid = (struct fid *) - (fhp->fh_handle.fh_fsid + fhp->fh_handle.fh_size/4 - 1); + (fhp->fh_handle.fh_raw + FH_FSID + + fhp->fh_handle.fh_size - 1); int maxsize = (fhp->fh_maxsize - fhp->fh_handle.fh_size)/4; int fh_flags = (exp->ex_flags & NFSEXP_NOSUBTREECHECK) ? 0 : EXPORT_FH_CONNECTABLE; int fileid_type = exportfs_encode_fh(dentry, fid, &maxsize, fh_flags); - fhp->fh_handle.fh_fileid_type = + fhp->fh_handle.fh_raw[FH_FILEID_TYPE] = fileid_type > 0 ? fileid_type : FILEID_INVALID; fhp->fh_handle.fh_size += maxsize * 4; } else { - fhp->fh_handle.fh_fileid_type = FILEID_ROOT; + fhp->fh_handle.fh_raw[FH_FILEID_TYPE] = FILEID_ROOT; } } @@ -520,8 +524,8 @@ static void set_version_and_fsid_type(struct svc_fh *fhp, struct svc_export *exp retry: version = 1; if (ref_fh && ref_fh->fh_export == exp) { - version = ref_fh->fh_handle.fh_version; - fsid_type = ref_fh->fh_handle.fh_fsid_type; + version = ref_fh->fh_handle.fh_raw[FH_VERSION]; + fsid_type = ref_fh->fh_handle.fh_raw[FH_FSID_TYPE]; ref_fh = NULL; @@ -562,9 +566,9 @@ static void set_version_and_fsid_type(struct svc_fh *fhp, struct svc_export *exp fsid_type = FSID_ENCODE_DEV; else fsid_type = FSID_DEV; - fhp->fh_handle.fh_version = version; + fhp->fh_handle.fh_raw[FH_VERSION] = version; if (version) - fhp->fh_handle.fh_fsid_type = fsid_type; + fhp->fh_handle.fh_raw[FH_FSID_TYPE] = fsid_type; } __be32 @@ -610,18 +614,18 @@ fh_compose(struct svc_fh *fhp, struct svc_export *exp, struct dentry *dentry, fhp->fh_export = exp_get(exp); fhp->fh_handle.fh_size = - key_len(fhp->fh_handle.fh_fsid_type) + 4; - fhp->fh_handle.fh_auth_type = 0; + key_len(fhp->fh_handle.fh_raw[FH_FSID_TYPE]) + 4; + fhp->fh_handle.fh_raw[FH_AUTH_TYPE] = 0; - mk_fsid(fhp->fh_handle.fh_fsid_type, - fhp->fh_handle.fh_fsid, + mk_fsid(fhp->fh_handle.fh_raw[FH_FSID_TYPE], + fhp->fh_handle.fh_raw + FH_FSID, ex_dev, d_inode(exp->ex_path.dentry)->i_ino, exp->ex_fsid, exp->ex_uuid); if (inode) _fh_update(fhp, exp, dentry); - if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) { + if (fhp->fh_handle.fh_raw[FH_FILEID_TYPE] == FILEID_INVALID) { fh_put(fhp); return nfserr_stale; } @@ -644,11 +648,11 @@ fh_update(struct svc_fh *fhp) dentry = fhp->fh_dentry; if (d_really_is_negative(dentry)) goto out_negative; - if (fhp->fh_handle.fh_fileid_type != FILEID_ROOT) + if (fhp->fh_handle.fh_raw[FH_FILEID_TYPE] != FILEID_ROOT) return 0; _fh_update(fhp, fhp->fh_export, dentry); - if (fhp->fh_handle.fh_fileid_type == FILEID_INVALID) + if (fhp->fh_handle.fh_raw[FH_FILEID_TYPE] == FILEID_INVALID) return nfserr_stale; return 0; out_bad: @@ -776,9 +780,9 @@ char * SVCFH_fmt(struct svc_fh *fhp) enum fsid_source fsid_source(const struct svc_fh *fhp) { - if (fhp->fh_handle.fh_version != 1) + if (fhp->fh_handle.fh_raw[FH_VERSION] != 1) return FSIDSOURCE_DEV; - switch(fhp->fh_handle.fh_fsid_type) { + switch(fhp->fh_handle.fh_raw[FH_FSID_TYPE]) { case FSID_DEV: case FSID_ENCODE_DEV: case FSID_MAJOR_MINOR: diff --git a/fs/nfsd/nfsfh.h b/fs/nfsd/nfsfh.h index 5103c2f4d225..26975ede465a 100644 --- a/fs/nfsd/nfsfh.h +++ b/fs/nfsd/nfsfh.h @@ -43,22 +43,17 @@ * filesystems must not use the values '0' or '0xff'. 'See enum fid_type' * in include/linux/exportfs.h for currently registered values. */ - struct knfsd_fh { unsigned int fh_size; /* * Points to the current size while * building a new file handle. */ - union { - char fh_raw[NFS4_FHSIZE]; - struct { - u8 fh_version; /* == 1 */ - u8 fh_auth_type; /* deprecated */ - u8 fh_fsid_type; - u8 fh_fileid_type; - u32 fh_fsid[]; /* flexible-array member */ - }; - }; + char fh_raw[NFS4_FHSIZE]; +#define FH_VERSION 0 +#define FH_AUTH_TYPE 1 +#define FH_FSID_TYPE 2 +#define FH_FILEID_TYPE 3 +#define FH_FSID 4 }; static inline __u32 ino_t_to_u32(ino_t ino) @@ -141,10 +136,12 @@ extern enum fsid_source fsid_source(const struct svc_fh *fhp); * sparse from complaining. Since these values are opaque to the * client, that shouldn't be a problem. */ -static inline void mk_fsid(int vers, u32 *fsidv, dev_t dev, ino_t ino, - u32 fsid, unsigned char *uuid) +static inline void mk_fsid(int vers, void *fsid, dev_t dev, ino_t ino, + u32 fsid_num, unsigned char *uuid) { + u32 *fsidv = fsid; u32 *up; + switch(vers) { case FSID_DEV: fsidv[0] = (__force __u32)htonl((MAJOR(dev)<<16) | @@ -152,7 +149,7 @@ static inline void mk_fsid(int vers, u32 *fsidv, dev_t dev, ino_t ino, fsidv[1] = ino_t_to_u32(ino); break; case FSID_NUM: - fsidv[0] = fsid; + fsidv[0] = fsid_num; break; case FSID_MAJOR_MINOR: fsidv[0] = (__force __u32)htonl(MAJOR(dev)); @@ -260,9 +257,10 @@ static inline bool fh_match(const struct knfsd_fh *fh1, static inline bool fh_fsid_match(const struct knfsd_fh *fh1, const struct knfsd_fh *fh2) { - if (fh1->fh_fsid_type != fh2->fh_fsid_type) + if (fh1->fh_raw[FH_FSID_TYPE] != fh2->fh_raw[FH_FSID_TYPE]) return false; - if (memcmp(fh1->fh_fsid, fh2->fh_fsid, key_len(fh1->fh_fsid_type)) != 0) + if (memcmp(fh1->fh_raw + FH_FSID, fh2->fh_raw + FH_FSID, + key_len(fh1->fh_raw[FH_FSID_TYPE])) != 0) return false; return true; } ^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-05-07 6:04 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-05-06 20:58 [PATCH][next] NFSD: Avoid multiple -Wflex-array-member-not-at-end warnings Gustavo A. R. Silva 2025-05-06 23:31 ` NeilBrown 2025-05-07 6:04 ` Christoph Hellwig
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox