Whamcloud - gitweb
LU-9442 osp: can't create IDIF fid number > 0xFFFFFFFF 27/28227/2
authorSergey Cheremencev <sergey.cheremencev@seagate.com>
Thu, 15 Jun 2017 05:14:07 +0000 (08:14 +0300)
committerJohn L. Hammond <john.hammond@intel.com>
Thu, 3 Aug 2017 21:41:23 +0000 (21:41 +0000)
fid_is_last_id didn't recognize IDIFes. This caused OST
to allocate new sequence despite of MDT still used
initial FID_SEQ_IDIF. Finally allocation failed with -115
returned from osd_check_lma:
osd_check_lma()) lustre-OST0000-osd: FID [0x100000001:0x0:0x0] != self_fid [0x100000000:0x0:0x0]

Patch has several typical "IDIF" fixes. Also it has lov_objid
fix to store all 48 IDIF bits instead of 32.
Finally it changes union fields order in ost_id.
Before the fix oi_fid.f_seq addressed oi_id instead of oi_seq.

Lustre-change: https://review.whamcloud.com/27225
Lustre-commit: 2dde01f1edac9e330f853c3ffee64eb43d82b7c1

Change-Id: Ifbda97a5b228254aedcb050c3d94d2ecb3a9590c
Seagate-bug-id: MRP-4392
Signed-off-by: Sergey Cheremencev <sergey.cheremencev@seagate.com>
Reviewed-by: Fan Yong <fan.yong@intel.com>
Reviewed-by: Mike Pershin <mike.pershin@intel.com>
Signed-off-by: Minh Diep <minh.diep@intel.com>
Reviewed-on: https://review.whamcloud.com/28227
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: John L. Hammond <john.hammond@intel.com>
lustre/include/uapi/linux/lustre_fid.h
lustre/lfsck/lfsck_layout.c
lustre/osp/lproc_osp.c
lustre/osp/osp_dev.c
lustre/osp/osp_internal.h
lustre/osp/osp_object.c
lustre/osp/osp_precreate.c

index 608f733..a43507e 100644 (file)
@@ -258,8 +258,17 @@ static inline __u32 fid_idif_ost_idx(const struct lu_fid *fid)
 /* Check whether the fid is for LAST_ID */
 static inline bool fid_is_last_id(const struct lu_fid *fid)
 {
-       return !fid_oid(fid) && fid_seq(fid) != FID_SEQ_UPDATE_LOG &&
-              fid_seq(fid) != FID_SEQ_UPDATE_LOG_DIR;
+       if (fid_oid(fid) != 0)
+               return false;
+
+       if (fid_is_idif(fid) && ((fid_seq(fid) & 0xFFFF) != 0))
+               return false;
+
+       if (fid_seq(fid) == FID_SEQ_UPDATE_LOG ||
+           fid_seq(fid) == FID_SEQ_UPDATE_LOG_DIR)
+               return false;
+
+       return true;
 }
 
 /**
index a2c25d4..c445303 100644 (file)
@@ -3096,7 +3096,6 @@ static int lfsck_layout_scan_orphan(const struct lu_env *env,
        struct lfsck_instance           *lfsck  = com->lc_lfsck;
        struct lfsck_bookmark           *bk     = &lfsck->li_bookmark_ram;
        struct lfsck_thread_info        *info   = lfsck_env_info(env);
-       struct ost_id                   *oi     = &info->lti_oi;
        struct lu_fid                   *fid    = &info->lti_fid;
        struct dt_object                *obj;
        const struct dt_it_ops          *iops;
@@ -3116,14 +3115,8 @@ static int lfsck_layout_scan_orphan(const struct lu_env *env,
                RETURN(0);
        }
 
-       ostid_set_seq(oi, FID_SEQ_IDIF);
-       rc = ostid_set_id(oi, 0);
-       if (rc)
-               GOTO(log, rc);
-
-       rc = ostid_to_fid(fid, oi, ltd->ltd_index);
-       if (rc != 0)
-               GOTO(log, rc);
+       fid->f_seq = fid_idif_seq(0, ltd->ltd_index);
+       fid->f_oid = fid->f_ver = 0;
 
        obj = lfsck_object_find_by_dev(env, ltd->ltd_tgt, fid);
        if (unlikely(IS_ERR(obj)))
index 4bd59f6..5fc7a02 100644 (file)
@@ -444,11 +444,22 @@ static int osp_prealloc_next_id_seq_show(struct seq_file *m, void *data)
 {
        struct obd_device *obd = m->private;
        struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
+       struct lu_fid *fid;
+       __u64 id;
 
        if (osp == NULL || osp->opd_pre == NULL)
                return 0;
 
-       seq_printf(m, "%u\n", fid_oid(&osp->opd_pre_used_fid) + 1);
+       fid = &osp->opd_pre_used_fid;
+       if (fid_is_idif(fid)) {
+               id = fid_idif_id(fid_seq(fid), fid_oid(fid), fid_ver(fid));
+               id++;
+       } else {
+               id = unlikely(fid_oid(fid) == LUSTRE_DATA_SEQ_MAX_WIDTH) ?
+                       1 : fid_oid(fid) + 1;
+       }
+
+       seq_printf(m, "%llu\n", id);
        return 0;
 }
 LPROC_SEQ_FOPS_RO(osp_prealloc_next_id);
@@ -465,11 +476,17 @@ static int osp_prealloc_last_id_seq_show(struct seq_file *m, void *data)
 {
        struct obd_device *obd = m->private;
        struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
+       struct lu_fid *fid;
+       __u64 id;
 
        if (osp == NULL || osp->opd_pre == NULL)
                return 0;
+       fid = &osp->opd_pre_last_created_fid;
+       id = fid_is_idif(fid) ?
+                        fid_idif_id(fid_seq(fid), fid_oid(fid), fid_ver(fid)) :
+                        fid_oid(fid);
 
-       seq_printf(m, "%u\n", fid_oid(&osp->opd_pre_last_created_fid));
+       seq_printf(m, "%llu\n", id);
        return 0;
 }
 LPROC_SEQ_FOPS_RO(osp_prealloc_last_id);
@@ -486,11 +503,15 @@ static int osp_prealloc_next_seq_seq_show(struct seq_file *m, void *data)
 {
        struct obd_device *obd = m->private;
        struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
+       struct lu_fid *fid;
 
        if (osp == NULL || osp->opd_pre == NULL)
                return 0;
 
-       seq_printf(m, "%#llx\n", fid_seq(&osp->opd_pre_used_fid));
+       fid = &osp->opd_pre_used_fid;
+       seq_printf(m, "%#llx\n", fid_is_idif(fid) ?
+                  fid_seq(fid) & (~0xffff) : fid_seq(fid));
+
        return 0;
 }
 LPROC_SEQ_FOPS_RO(osp_prealloc_next_seq);
@@ -507,12 +528,15 @@ static int osp_prealloc_last_seq_seq_show(struct seq_file *m, void *data)
 {
        struct obd_device *obd = m->private;
        struct osp_device *osp = lu2osp_dev(obd->obd_lu_dev);
+       struct lu_fid *fid;
 
        if (osp == NULL || osp->opd_pre == NULL)
                return 0;
 
-       seq_printf(m, "%#llx\n",
-                  fid_seq(&osp->opd_pre_last_created_fid));
+       fid = &osp->opd_pre_last_created_fid;
+       seq_printf(m, "%#llx\n", fid_is_idif(fid) ?
+                  fid_seq(fid) & (~0xffff) : fid_seq(fid));
+
        return 0;
 }
 LPROC_SEQ_FOPS_RO(osp_prealloc_last_seq);
index 7e3819f..982a46f 100644 (file)
@@ -261,16 +261,21 @@ static int osp_init_last_objid(const struct lu_env *env, struct osp_device *osp)
        /* object will be released in device cleanup path */
        if (osi->osi_attr.la_size >=
            sizeof(osi->osi_id) * (osp->opd_index + 1)) {
-               osp_objid_buf_prep(&osi->osi_lb, &osi->osi_off, &fid->f_oid,
+               osp_objid_buf_prep(&osi->osi_lb, &osi->osi_off, &osi->osi_id,
                                   osp->opd_index);
                rc = dt_record_read(env, dto, &osi->osi_lb, &osi->osi_off);
                if (rc != 0 && rc != -EFAULT)
                        GOTO(out, rc);
+               /* In case of idif bits 32-48 go to f_seq
+                * (see osp_init_last_seq). So don't care
+                * about u64->u32 convertion. */
+               fid->f_oid = osi->osi_id;
        }
 
        if (rc == -EFAULT) { /* fresh LAST_ID */
+               osi->osi_id = 0;
                fid->f_oid = 0;
-               osp_objid_buf_prep(&osi->osi_lb, &osi->osi_off, &fid->f_oid,
+               osp_objid_buf_prep(&osi->osi_lb, &osi->osi_off, &osi->osi_id,
                                   osp->opd_index);
                rc = osp_write_local_file(env, osp, dto, &osi->osi_lb,
                                          osi->osi_off);
@@ -323,6 +328,8 @@ static int osp_init_last_seq(const struct lu_env *env, struct osp_device *osp)
                rc = dt_record_read(env, dto, &osi->osi_lb, &osi->osi_off);
                if (rc != 0 && rc != -EFAULT)
                        GOTO(out, rc);
+               if (fid_is_idif(fid))
+                       fid->f_seq = fid_idif_seq(osi->osi_id, osp->opd_index);
        }
 
        if (rc == -EFAULT) { /* fresh OSP */
@@ -374,7 +381,7 @@ static int osp_last_used_init(const struct lu_env *env, struct osp_device *osp)
 
        rc = osp_init_last_seq(env, osp);
        if (rc < 0) {
-               CERROR("%s: Can not get ids %d from old objid!\n",
+               CERROR("%s: Can not get sequence %d from old objseq!\n",
                       osp->opd_obd->obd_name, rc);
                GOTO(out, rc);
        }
index 49ea455..6a95d9a 100644 (file)
@@ -394,7 +394,7 @@ static inline bool is_only_remote_trans(struct thandle *th)
 }
 
 static inline void osp_objid_buf_prep(struct lu_buf *buf, loff_t *off,
-                                     __u32 *id, int index)
+                                     __u64 *id, int index)
 {
        /* Note: through id is only 32 bits, it will also write 64 bits
         * for oid to keep compatibility with the previous version. */
@@ -547,6 +547,7 @@ static inline int osp_fid_diff(const struct lu_fid *fid1,
 static inline void osp_update_last_fid(struct osp_device *d, struct lu_fid *fid)
 {
        int diff = osp_fid_diff(fid, &d->opd_last_used_fid);
+       struct lu_fid *gap_start = &d->opd_gap_start_fid;
        /*
         * we might have lost precreated objects due to VBR and precreate
         * orphans, the gap in objid can be calculated properly only here
@@ -554,7 +555,13 @@ static inline void osp_update_last_fid(struct osp_device *d, struct lu_fid *fid)
        if (diff > 0) {
                if (diff > 1) {
                        d->opd_gap_start_fid = d->opd_last_used_fid;
-                       d->opd_gap_start_fid.f_oid++;
+                       if (fid_oid(gap_start) == LUSTRE_DATA_SEQ_MAX_WIDTH) {
+                               gap_start->f_seq++;
+                               gap_start->f_oid = fid_is_idif(gap_start) ?
+                                                              0 : 1;
+                       } else {
+                               gap_start->f_oid++;
+                       }
                        d->opd_gap_count = diff - 1;
                        CDEBUG(D_HA, "Gap in objids: start="DFID", count =%d\n",
                               PFID(&d->opd_gap_start_fid), d->opd_gap_count);
index 9ba9051..446f55a 100644 (file)
@@ -1417,6 +1417,7 @@ static int osp_create(const struct lu_env *env, struct dt_object *dt,
        int                     rc = 0;
        struct lu_fid           *fid = &osi->osi_fid;
        struct thandle          *local_th;
+       struct lu_fid           *last_fid = &d->opd_last_used_fid;
        ENTRY;
 
        if (is_only_remote_trans(th) &&
@@ -1496,8 +1497,13 @@ static int osp_create(const struct lu_env *env, struct dt_object *dt,
 
        /* Only need update last_used oid file, seq file will only be update
         * during seq rollover */
+       if (fid_is_idif((last_fid)))
+               osi->osi_id = fid_idif_id(fid_seq(last_fid),
+                                         fid_oid(last_fid), fid_ver(last_fid));
+       else
+               osi->osi_id = fid_oid(last_fid);
        osp_objid_buf_prep(&osi->osi_lb, &osi->osi_off,
-                          &d->opd_last_used_fid.f_oid, d->opd_index);
+                          &osi->osi_id, d->opd_index);
 
        rc = dt_record_write(env, d->opd_last_used_oid_file, &osi->osi_lb,
                             &osi->osi_off, local_th);
index 5e0c8c7..e3d2ee1 100644 (file)
@@ -1475,6 +1475,7 @@ int osp_precreate_reserve(const struct lu_env *env, struct osp_device *d)
 int osp_precreate_get_fid(const struct lu_env *env, struct osp_device *d,
                          struct lu_fid *fid)
 {
+       struct lu_fid *pre_used_fid = &d->opd_pre_used_fid;
        /* grab next id from the pool */
        spin_lock(&d->opd_pre_lock);
 
@@ -1484,6 +1485,20 @@ int osp_precreate_get_fid(const struct lu_env *env, struct osp_device *d,
                 PFID(&d->opd_pre_used_fid),
                 PFID(&d->opd_pre_last_created_fid));
 
+       /*
+        * When sequence is used up, new one should be allocated in
+        * osp_precreate_rollover_new_seq. So ASSERT here to avoid
+        * objid overflow.
+        */
+       LASSERTF(osp_fid_end_seq(env, pre_used_fid) == 0,
+                "next fid "DFID" last created fid "DFID"\n",
+                PFID(&d->opd_pre_used_fid),
+                PFID(&d->opd_pre_last_created_fid));
+       /* Non IDIF fids shoulnd't get here with oid == 0xFFFFFFFF. */
+       if (fid_is_idif(pre_used_fid) &&
+           unlikely(fid_oid(pre_used_fid) == LUSTRE_DATA_SEQ_MAX_WIDTH))
+               pre_used_fid->f_seq++;
+
        d->opd_pre_used_fid.f_oid++;
        memcpy(fid, &d->opd_pre_used_fid, sizeof(*fid));
        d->opd_pre_reserved--;