Whamcloud - gitweb
LU-11025 obdclass: add lu_device_operations::ldo_fid_alloc() 82/37282/10
authorLai Siyao <lai.siyao@whamcloud.com>
Mon, 6 Jan 2020 11:44:33 +0000 (19:44 +0800)
committerOleg Drokin <green@whamcloud.com>
Wed, 20 May 2020 08:22:30 +0000 (08:22 +0000)
Add an interface ldo_fid_alloc in lu_device_operations, which is to
allocate a FID by parent object and sub file name, this will be
used to migrate sub files for directory restripe.

The existing osd_fid_alloc() and osp_fid_alloc() will switch to this
interface from obd_ops::o_fid_alloc().

Signed-off-by: Lai Siyao <lai.siyao@whamcloud.com>
Change-Id: Ide480fe492fd2d4d5de675bbc61aee7e2a9e3ce3
Reviewed-on: https://review.whamcloud.com/37282
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Hongchao Zhang <hongchao@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
lustre/include/dt_object.h
lustre/include/lu_object.h
lustre/lod/lod_dev.c
lustre/lod/lod_object.c
lustre/lod/lod_qos.c
lustre/mdd/mdd_device.c
lustre/obdclass/llog_osd.c
lustre/osd-ldiskfs/osd_handler.c
lustre/osd-zfs/osd_handler.c
lustre/osp/osp_dev.c

index 79f6ac3..ab9a7c0 100644 (file)
@@ -2148,6 +2148,17 @@ static inline int dt_object_sync(const struct lu_env *env, struct dt_object *o,
        return o->do_ops->do_object_sync(env, o, start, end);
 }
 
+static inline int dt_fid_alloc(const struct lu_env *env,
+                              struct dt_device *d,
+                              struct lu_fid *fid,
+                              struct lu_object *parent,
+                              const struct lu_name *name)
+{
+       struct lu_device *l = dt2lu_dev(d);
+
+       return l->ld_ops->ldo_fid_alloc(env, l, fid, parent, name);
+}
+
 int dt_declare_version_set(const struct lu_env *env, struct dt_object *o,
                            struct thandle *th);
 void dt_version_set(const struct lu_env *env, struct dt_object *o,
index a9fa482..4bb797f 100644 (file)
@@ -102,6 +102,7 @@ struct lu_device;
 struct lu_object_header;
 struct lu_context;
 struct lu_env;
+struct lu_name;
 
 /**
  * Operations common for data and meta-data devices.
@@ -160,6 +161,27 @@ struct lu_device_operations {
                            struct lu_device *parent,
                            struct lu_device *dev);
 
+
+       /**
+        * Allocate new FID for file with @name under @parent
+        *
+        * \param[in] env       execution environment for this thread
+        * \param[in] dev       dt device
+        * \param[out] fid      new FID allocated
+        * \param[in] parent    parent object
+        * \param[in] name      lu_name
+        *
+        * \retval 0            on success
+        * \retval 0            0 FID allocated successfully.
+        * \retval 1            1 FID allocated successfully and new sequence
+        *                      requested from seq meta server
+        * \retval negative     negative errno if FID allocation failed.
+        */
+       int (*ldo_fid_alloc)(const struct lu_env *env,
+                            struct lu_device *dev,
+                            struct lu_fid *fid,
+                            struct lu_object *parent,
+                            const struct lu_name *name);
 };
 
 /**
index 78e0afa..5091b7a 100644 (file)
@@ -96,6 +96,7 @@
 #include <uapi/linux/lustre/lustre_param.h>
 #include <lustre_update.h>
 #include <lustre_log.h>
+#include <lustre_lmv.h>
 
 #include "lod_internal.h"
 
@@ -1229,11 +1230,68 @@ out_put:
        RETURN(rc);
 }
 
+/**
+ * Implementation of lu_device_operations::ldo_fid_alloc() for LOD
+ *
+ * Find corresponding device by passed parent and name, and allocate FID from
+ * there.
+ *
+ * see include/lu_object.h for the details.
+ */
+static int lod_fid_alloc(const struct lu_env *env, struct lu_device *d,
+                        struct lu_fid *fid, struct lu_object *parent,
+                        const struct lu_name *name)
+{
+       struct lod_device *lod = lu2lod_dev(d);
+       struct lod_object *lo = lu2lod_obj(parent);
+       struct dt_device *next;
+       int rc;
+
+       ENTRY;
+
+       /* if @parent is remote, we don't know whether its layout was changed,
+        * always reload layout.
+        */
+       if (lu_object_remote(parent))
+               lod_striping_free(env, lo);
+
+       rc = lod_striping_load(env, lo);
+       if (rc)
+               RETURN(rc);
+
+       if (lo->ldo_dir_stripe_count > 0 && name) {
+               struct dt_object *stripe;
+               int idx;
+
+               idx = __lmv_name_to_stripe_index(lo->ldo_dir_hash_type,
+                                                lo->ldo_dir_stripe_count,
+                                                lo->ldo_dir_migrate_hash,
+                                                lo->ldo_dir_migrate_offset,
+                                                name->ln_name,
+                                                name->ln_namelen, true);
+               if (idx < 0)
+                       RETURN(idx);
+
+               stripe = lo->ldo_stripe[idx];
+               if (!stripe || !dt_object_exists(stripe))
+                       RETURN(-ENODEV);
+
+               next = lu2dt_dev(stripe->do_lu.lo_dev);
+       } else {
+               next = lod->lod_child;
+       }
+
+       rc = dt_fid_alloc(env, next, fid, parent, name);
+
+       RETURN(rc);
+}
+
 const struct lu_device_operations lod_lu_ops = {
        .ldo_object_alloc       = lod_object_alloc,
        .ldo_process_config     = lod_process_config,
        .ldo_recovery_complete  = lod_recovery_complete,
        .ldo_prepare            = lod_prepare,
+       .ldo_fid_alloc          = lod_fid_alloc,
 };
 
 /**
index 726f09c..bef2d6d 100644 (file)
@@ -2058,11 +2058,11 @@ static int lod_mdt_alloc_specific(const struct lu_env *env,
 
                        if (idx == master_index) {
                                /* Allocate the FID locally */
-                               rc = obd_fid_alloc(env, lod->lod_child_exp,
-                                                  &fid, NULL);
+                               tgt_dt = lod->lod_child;
+                               rc = dt_fid_alloc(env, tgt_dt, &fid, NULL,
+                                                 NULL);
                                if (rc < 0)
                                        continue;
-                               tgt_dt = lod->lod_child;
                                break;
                        }
 
@@ -2076,7 +2076,7 @@ static int lod_mdt_alloc_specific(const struct lu_env *env,
                                /* this OSP doesn't feel well */
                                continue;
 
-                       rc = obd_fid_alloc(env, tgt->ltd_exp, &fid, NULL);
+                       rc = dt_fid_alloc(env, tgt_dt, &fid, NULL, NULL);
                        if (rc < 0)
                                continue;
 
@@ -2166,7 +2166,7 @@ static int lod_prep_md_striped_create(const struct lu_env *env,
                RETURN(-ENOMEM);
 
        /* Allocate the first stripe locally */
-       rc = obd_fid_alloc(env, lod->lod_child_exp, &fid, NULL);
+       rc = dt_fid_alloc(env, lod->lod_child, &fid, NULL, NULL);
        if (rc < 0)
                GOTO(out, rc);
 
index 69221ce..249d3cf 100644 (file)
@@ -1015,7 +1015,7 @@ repeat_find:
                }
                spin_unlock(&lqr->lqr_alloc);
 
-               rc = obd_fid_alloc(env, mdt->ltd_exp, &fid, NULL);
+               rc = dt_fid_alloc(env, mdt->ltd_tgt, &fid, NULL, NULL);
                if (rc < 0) {
                        QOS_DEBUG("#%d: alloc FID failed: %dl\n", mdt_idx, rc);
                        spin_lock(&lqr->lqr_alloc);
@@ -1762,7 +1762,7 @@ int lod_mdt_alloc_qos(const struct lu_env *env, struct lod_object *lo,
                        if (lod_qos_is_tgt_used(env, mdt_idx, stripe_idx))
                                continue;
 
-                       rc2 = obd_fid_alloc(env, mdt->ltd_exp, &fid, NULL);
+                       rc2 = dt_fid_alloc(env, mdt->ltd_tgt, &fid, NULL, NULL);
                        if (rc2 < 0) {
                                QOS_DEBUG("can't alloc FID on #%u: %d\n",
                                          mdt_idx, rc2);
index e915a94..a1b113c 100644 (file)
@@ -1317,11 +1317,30 @@ out_los:
        return rc;
 }
 
+/**
+ * Implementation of lu_device_operations::ldo_fid_alloc() for MDD.
+ *
+ * Find corresponding device by passed parent and name, and allocate FID from
+ * there.
+ *
+ * see include/lu_object.h for the details.
+ */
+static int mdd_fid_alloc(const struct lu_env *env, struct lu_device *d,
+                        struct lu_fid *fid, struct lu_object *parent,
+                        const struct lu_name *name)
+{
+       struct mdd_device *mdd = lu2mdd_dev(d);
+       struct lu_object *o = lu_object_next(parent);
+
+       return dt_fid_alloc(env, mdd->mdd_child, fid, o, name);
+}
+
 const struct lu_device_operations mdd_lu_ops = {
         .ldo_object_alloc      = mdd_object_alloc,
         .ldo_process_config    = mdd_process_config,
         .ldo_recovery_complete = mdd_recovery_complete,
         .ldo_prepare           = mdd_prepare,
+       .ldo_fid_alloc         = mdd_fid_alloc,
 };
 
 static int mdd_root_get(const struct lu_env *env,
index c634e45..de00b7a 100644 (file)
@@ -1247,8 +1247,7 @@ static int llog_osd_open(const struct lu_env *env, struct llog_handle *handle,
                } else {
                        /* If logid == NULL, then it means the caller needs
                         * to allocate new FID (llog_cat_declare_add_rec()). */
-                       rc = obd_fid_alloc(env, ctxt->loc_exp,
-                                          &lgi->lgi_fid, NULL);
+                       rc = dt_fid_alloc(env, dt, &lgi->lgi_fid, NULL, NULL);
                        if (rc < 0)
                                RETURN(rc);
                        rc = 0;
index 2f62ce5..109e985 100644 (file)
@@ -8062,10 +8062,18 @@ static int osd_prepare(const struct lu_env *env, struct lu_device *pdev,
        RETURN(result);
 }
 
-static int osd_fid_alloc(const struct lu_env *env, struct obd_export *exp,
-                        struct lu_fid *fid, struct md_op_data *op_data)
+/**
+ * Implementation of lu_device_operations::ldo_fid_alloc() for OSD
+ *
+ * Allocate FID.
+ *
+ * see include/lu_object.h for the details.
+ */
+static int osd_fid_alloc(const struct lu_env *env, struct lu_device *d,
+                        struct lu_fid *fid, struct lu_object *parent,
+                        const struct lu_name *name)
 {
-       struct osd_device *osd = osd_dev(exp->exp_obd->obd_lu_dev);
+       struct osd_device *osd = osd_dev(d);
 
        return seq_client_alloc_fid(env, osd->od_cl_seq, fid);
 }
@@ -8084,6 +8092,7 @@ const struct lu_device_operations osd_lu_ops = {
        .ldo_process_config    = osd_process_config,
        .ldo_recovery_complete = osd_recovery_complete,
        .ldo_prepare           = osd_prepare,
+       .ldo_fid_alloc         = osd_fid_alloc,
 };
 
 static const struct lu_device_type_operations osd_device_type_ops = {
@@ -8122,7 +8131,6 @@ static const struct obd_ops osd_obd_device_ops = {
        .o_owner = THIS_MODULE,
        .o_connect      = osd_obd_connect,
        .o_disconnect   = osd_obd_disconnect,
-       .o_fid_alloc    = osd_fid_alloc,
        .o_health_check = osd_health_check,
 };
 
index f60f549..833401e 100644 (file)
@@ -1563,11 +1563,28 @@ static int osd_prepare(const struct lu_env *env, struct lu_device *pdev,
        RETURN(rc);
 }
 
+/**
+ * Implementation of lu_device_operations::ldo_fid_alloc() for OSD
+ *
+ * Allocate FID.
+ *
+ * see include/lu_object.h for the details.
+ */
+static int osd_fid_alloc(const struct lu_env *env, struct lu_device *d,
+                        struct lu_fid *fid, struct lu_object *parent,
+                        const struct lu_name *name)
+{
+       struct osd_device *osd = osd_dev(d);
+
+       return seq_client_alloc_fid(env, osd->od_cl_seq, fid);
+}
+
 struct lu_device_operations osd_lu_ops = {
        .ldo_object_alloc       = osd_object_alloc,
        .ldo_process_config     = osd_process_config,
        .ldo_recovery_complete  = osd_recovery_complete,
        .ldo_prepare            = osd_prepare,
+       .ldo_fid_alloc          = osd_fid_alloc,
 };
 
 static void osd_type_start(struct lu_device_type *t)
@@ -1578,14 +1595,6 @@ static void osd_type_stop(struct lu_device_type *t)
 {
 }
 
-int osd_fid_alloc(const struct lu_env *env, struct obd_export *exp,
-                 struct lu_fid *fid, struct md_op_data *op_data)
-{
-       struct osd_device *osd = osd_dev(exp->exp_obd->obd_lu_dev);
-
-       return seq_client_alloc_fid(env, osd->od_cl_seq, fid);
-}
-
 static struct lu_device_type_operations osd_device_type_ops = {
        .ldto_init              = osd_type_init,
        .ldto_fini              = osd_type_fini,
@@ -1612,7 +1621,6 @@ static const struct obd_ops osd_obd_device_ops = {
        .o_owner       = THIS_MODULE,
        .o_connect      = osd_obd_connect,
        .o_disconnect   = osd_obd_disconnect,
-       .o_fid_alloc    = osd_fid_alloc
 };
 
 static int __init osd_init(void)
index 69643fa..e154556 100644 (file)
@@ -711,10 +711,41 @@ static int osp_recovery_complete(const struct lu_env *env,
        RETURN(0);
 }
 
+/**
+ * Implementation of lu_device_operations::ldo_fid_alloc() for OSP
+ *
+ * Allocate FID from remote MDT.
+ *
+ * see include/lu_object.h for the details.
+ */
+static int osp_fid_alloc(const struct lu_env *env, struct lu_device *d,
+                        struct lu_fid *fid, struct lu_object *parent,
+                        const struct lu_name *name)
+{
+       struct osp_device *osp = lu2osp_dev(d);
+       struct client_obd *cli = &osp->opd_obd->u.cli;
+       struct lu_client_seq *seq = cli->cl_seq;
+       int rc;
+
+       ENTRY;
+
+       /* Sigh, fid client is not ready yet */
+       if (!osp->opd_obd->u.cli.cl_seq)
+               RETURN(-ENOTCONN);
+
+       if (!osp->opd_obd->u.cli.cl_seq->lcs_exp)
+               RETURN(-ENOTCONN);
+
+       rc = seq_client_alloc_fid(env, seq, fid);
+
+       RETURN(rc);
+}
+
 const struct lu_device_operations osp_lu_ops = {
        .ldo_object_alloc       = osp_object_alloc,
        .ldo_process_config     = osp_process_config,
        .ldo_recovery_complete  = osp_recovery_complete,
+       .ldo_fid_alloc          = osp_fid_alloc,
 };
 
 /**
@@ -1789,44 +1820,6 @@ static int osp_obd_set_info_async(const struct lu_env *env,
        RETURN(0);
 }
 
-/**
- * Implementation of obd_ops: o_fid_alloc
- *
- * Allocate a FID. There are two cases in which OSP performs
- * FID allocation.
- *
- * 1. FID precreation for data objects, which is done in
- *    osp_precreate_fids() instead of this function.
- * 2. FID allocation for each sub-stripe of a striped directory.
- *    Similar to other FID clients, OSP requests the sequence
- *    from its corresponding remote MDT, which in turn requests
- *    sequences from the sequence controller (MDT0).
- *
- * \param[in] env      execution environment
- * \param[in] exp      export of the OSP
- * \param[out] fid     FID being allocated
- * \param[in] unused   necessary for the interface but unused.
- *
- * \retval 0           0 FID allocated successfully.
- * \retval 1           1 FID allocated successfully and new sequence
- *                      requested from seq meta server
- * \retval negative    negative errno if FID allocation failed.
- */
-static int osp_fid_alloc(const struct lu_env *env, struct obd_export *exp,
-                        struct lu_fid *fid, struct md_op_data *unused)
-{
-       struct client_obd       *cli = &exp->exp_obd->u.cli;
-       struct osp_device       *osp = lu2osp_dev(exp->exp_obd->obd_lu_dev);
-       struct lu_client_seq    *seq = cli->cl_seq;
-       ENTRY;
-
-       LASSERT(osp->opd_obd->u.cli.cl_seq != NULL);
-       /* Sigh, fid client is not ready yet */
-       LASSERT(osp->opd_obd->u.cli.cl_seq->lcs_exp != NULL);
-
-       RETURN(seq_client_alloc_fid(env, seq, fid));
-}
-
 /* context key constructor/destructor: mdt_key_init, mdt_key_fini */
 LU_KEY_INIT_FINI(osp, struct osp_thread_info);
 static void osp_key_exit(const struct lu_context *ctx,
@@ -1888,7 +1881,6 @@ static const struct obd_ops osp_obd_device_ops = {
        .o_statfs       = osp_obd_statfs,
        .o_fid_init     = client_fid_init,
        .o_fid_fini     = client_fid_fini,
-       .o_fid_alloc    = osp_fid_alloc,
 };
 
 /**