Whamcloud - gitweb
LU-8667 osp: validate FID before initializing precreate seq 34/22934/7
authorDi Wang <di.wang@intel.com>
Sat, 1 Oct 2016 14:20:57 +0000 (10:20 -0400)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 25 Oct 2016 02:23:17 +0000 (02:23 +0000)
A few fixes for FID on OST...

Check if the OSP FID is valid before initializing
precreate sequence, in case the last_seq/oid file
is corrupted. Only MDT0 can use IDIF, and non-MDT0
can only use normal FID, which will also make sure
the following orphan cleanup will use the valid
sequence.

OFD will validate the object sequence to make sure
IDIF request will only operate on MDT0 group.

If MDT can not get new sequence from OST, it will
sleep 2 seconds before retry, to offer OSTs some
extra time to setup FID service with sequence
controller (MDT0).

Signed-off-by: Di Wang <di.wang@intel.com>
Change-Id: Id9bbfaf9170ff1a9240719eaee73ddcb4fd804e5
Reviewed-on: http://review.whamcloud.com/22934
Tested-by: Jenkins
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Reviewed-by: Mike Pershin <mike.pershin@intel.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/fid/fid_request.c
lustre/ofd/ofd_internal.h
lustre/ofd/ofd_obd.c
lustre/osp/osp_precreate.c

index a33ff82..2263f27 100644 (file)
@@ -194,6 +194,17 @@ static int seq_client_alloc_meta(const struct lu_env *env,
                         * (MDT0)yet */
                        rc = seq_client_rpc(seq, &seq->lcs_space,
                                            SEQ_ALLOC_META, "meta");
+                       if (rc == -EINPROGRESS || rc == -EAGAIN) {
+                               wait_queue_head_t waitq;
+                               struct l_wait_info  lwi;
+
+                               /* MDT0 is not ready, let's wait for 2
+                                * seconds and retry. */
+                               init_waitqueue_head(&waitq);
+                               lwi = LWI_TIMEOUT(cfs_time_seconds(2), NULL,
+                                                 NULL);
+                               l_wait_event(waitq, 0, &lwi);
+                       }
                } while (rc == -EINPROGRESS || rc == -EAGAIN);
         }
 
index 9006726..f19ac04 100644 (file)
@@ -569,4 +569,17 @@ static inline void ofd_prepare_fidea(struct filter_fid *ff,
        ff->ff_parent.f_ver = cpu_to_le32(oa->o_stripe_idx);
 }
 
+static inline int ofd_validate_seq(struct obd_export *exp, __u64 seq)
+{
+       struct filter_export_data *fed = &exp->exp_filter_data;
+
+       if (unlikely(seq == FID_SEQ_OST_MDT0 && fed->fed_group != 0)) {
+               /* IDIF request only operates on MDT0 group */
+               CERROR("%s: Invalid sequence %#llx for group %u\n",
+                      exp->exp_obd->obd_name, seq, fed->fed_group);
+               RETURN(-EINVAL);
+       }
+
+       return 0;
+}
 #endif /* _OFD_INTERNAL_H */
index d5c1af0..9e010b5 100644 (file)
@@ -1055,6 +1055,10 @@ static int ofd_echo_destroy(const struct lu_env *env, struct obd_export *exp,
 
        ofd_info_init(env, exp);
 
+       rc = ofd_validate_seq(exp, ostid_seq(&oa->o_oi));
+       if (rc != 0)
+               RETURN(rc);
+
        CDEBUG(D_HA, "%s: Destroy object "DFID"\n", ofd_name(ofd), PFID(fid));
 
        rc = ofd_destroy_by_fid(env, ofd, fid, 0);
@@ -1118,6 +1122,10 @@ static int ofd_echo_create(const struct lu_env *env, struct obd_export *exp,
        if (unlikely(ofd->ofd_lastid_rebuilding))
                GOTO(out_sem, rc = -ENOSPC);
 
+       rc = ofd_validate_seq(exp, seq);
+       if (rc != 0)
+               RETURN(rc);
+
        oseq = ofd_seq_load(env, ofd, seq);
        if (IS_ERR(oseq)) {
                CERROR("%s: Can't find FID Sequence %#llx: rc = %ld\n",
index 51dbcb5..435d618 100644 (file)
@@ -1038,9 +1038,27 @@ int osp_init_pre_fid(struct osp_device *osp)
 
        LASSERT(osp->opd_pre != NULL);
 
-       /* Return if last_used fid has been initialized */
+       /* Let's check if the current last_seq/fid is valid,
+        * otherwise request new sequence from the controller */
+       if (osp_is_fid_client(osp) && osp->opd_group != 0) {
+               /* Non-MDT0 can only use normal sequence for
+                * OST objects */
+               if (fid_is_norm(&osp->opd_last_used_fid))
+                       RETURN(0);
+       } else {
+               /* Initially MDT0 will start with IDIF, after
+                * that it will request new sequence from the
+                * controller */
+               if (fid_is_idif(&osp->opd_last_used_fid) ||
+                   fid_is_norm(&osp->opd_last_used_fid))
+                       RETURN(0);
+       }
+
        if (!fid_is_zero(&osp->opd_last_used_fid))
-               RETURN(0);
+               CWARN("%s: invalid last used fid "DFID
+                     ", try to get new sequence.\n",
+                     osp->opd_obd->obd_name,
+                     PFID(&osp->opd_last_used_fid));
 
        rc = lu_env_init(&env, osp->opd_dt_dev.dd_lu_dev.ld_type->ldt_ctx_tags);
        if (rc) {