Details
-
Bug
-
Resolution: Unresolved
-
Minor
-
None
-
None
-
3
-
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.
Attachments
Issue Links
- is related to
-
LU-14692 deprecate use of OST FID SEQ 0 for MDT0000
- Resolved