[LU-10487] ostid_set_{seq,id}() badness Created: 10/Jan/18 Updated: 27/May/21 |
|
| Status: | Open |
| Project: | Lustre |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Minor |
| Reporter: | John Hammond | Assignee: | WC Triage |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | medium | ||
| Issue Links: |
|
||||||||
| Severity: | 3 | ||||||||
| Rank (Obsolete): | 9223372036854775807 | ||||||||
| Description |
|
Reviewing https://review.whamcloud.com/#/c/30376/ I noticed several issues with ostid_set_seq() and ostid_set_id(). The normal use of these functions looks like: struct ost_id oi; ... ostid_set_seq(&oi, ...); rc = ostid_set_id(&oi, ...); ... 1. In ostid_set_seq() we (sometimes) make decisions based on oi_fid.f_oid and oi_fid.f_ver which may be uninitialized: static inline void ostid_set_seq(struct ost_id *oi, __u64 seq) { if (fid_seq_is_mdt0(seq) || fid_seq_is_default(seq)) { oi->oi.oi_seq = seq; } else { oi->oi_fid.f_seq = seq; /* * Note: if f_oid + f_ver is zero, we need init it * to be 1, otherwise, ostid_seq will treat this * as old ostid (oi_seq == 0) */ if (!oi->oi_fid.f_oid && !oi->oi_fid.f_ver) oi->oi_fid.f_oid = LUSTRE_FID_INIT_OID; } } 2. In ostid_set_id() we make decisions based on fid_is_idif(&oi->oi_fid) === fid_seq_is_idif(oi->oi_fid.f_seq) which may not have been initialized by ostid_set_seq(): static inline int ostid_set_id(struct ost_id *oi, __u64 oid) { if (fid_seq_is_mdt0(oi->oi.oi_seq)) { if (oid >= IDIF_MAX_OID) return -E2BIG; oi->oi.oi_id = oid; } else if (fid_is_idif(&oi->oi_fid)) { if (oid >= IDIF_MAX_OID) return -E2BIG; oi->oi_fid.f_seq = fid_idif_seq(oid, fid_idif_ost_idx(&oi->oi_fid)); oi->oi_fid.f_oid = oid; oi->oi_fid.f_ver = oid >> 48; } else { if (oid >= OBIF_MAX_OID) return -E2BIG; oi->oi_fid.f_oid = oid; } return 0; } 3. In the IDIF case, setting f_ver = oid >> 48 seems broken. We have already rejected OIDs greater than or equal to IDIF_MAX_OID === 1UL << 48. So we must have oid < (1UL << 48) and therefore oid >> 48 is always zero. Perhaps it would be safer (and clearer) to have a single function that takes seq and oid and initializes the ostid completely. |