[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:
Related
is related to LU-14692 deprecate use of OST FID SEQ 0 for MD... Resolved
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.


Generated at Sat Feb 10 02:35:32 UTC 2024 using Jira 9.4.14#940014-sha1:734e6822bbf0d45eff9af51f82432957f73aa32c.