From: Lai Siyao Date: Mon, 6 Jan 2020 11:44:33 +0000 (+0800) Subject: LU-11025 obdclass: add lu_device_operations::ldo_fid_alloc() X-Git-Tag: 2.13.54~74 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=736d2d62ab1f00926000f0c3aa31fcb6aa53050f LU-11025 obdclass: add lu_device_operations::ldo_fid_alloc() 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 Change-Id: Ide480fe492fd2d4d5de675bbc61aee7e2a9e3ce3 Reviewed-on: https://review.whamcloud.com/37282 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Hongchao Zhang Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/dt_object.h b/lustre/include/dt_object.h index 79f6ac3..ab9a7c0 100644 --- a/lustre/include/dt_object.h +++ b/lustre/include/dt_object.h @@ -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, diff --git a/lustre/include/lu_object.h b/lustre/include/lu_object.h index a9fa482..4bb797f 100644 --- a/lustre/include/lu_object.h +++ b/lustre/include/lu_object.h @@ -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); }; /** diff --git a/lustre/lod/lod_dev.c b/lustre/lod/lod_dev.c index 78e0afa..5091b7a 100644 --- a/lustre/lod/lod_dev.c +++ b/lustre/lod/lod_dev.c @@ -96,6 +96,7 @@ #include #include #include +#include #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, }; /** diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index 726f09c..bef2d6d 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -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); diff --git a/lustre/lod/lod_qos.c b/lustre/lod/lod_qos.c index 69221ce..249d3cf 100644 --- a/lustre/lod/lod_qos.c +++ b/lustre/lod/lod_qos.c @@ -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); diff --git a/lustre/mdd/mdd_device.c b/lustre/mdd/mdd_device.c index e915a94..a1b113c 100644 --- a/lustre/mdd/mdd_device.c +++ b/lustre/mdd/mdd_device.c @@ -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, diff --git a/lustre/obdclass/llog_osd.c b/lustre/obdclass/llog_osd.c index c634e45..de00b7a 100644 --- a/lustre/obdclass/llog_osd.c +++ b/lustre/obdclass/llog_osd.c @@ -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; diff --git a/lustre/osd-ldiskfs/osd_handler.c b/lustre/osd-ldiskfs/osd_handler.c index 2f62ce5..109e985 100644 --- a/lustre/osd-ldiskfs/osd_handler.c +++ b/lustre/osd-ldiskfs/osd_handler.c @@ -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, }; diff --git a/lustre/osd-zfs/osd_handler.c b/lustre/osd-zfs/osd_handler.c index f60f549..833401e 100644 --- a/lustre/osd-zfs/osd_handler.c +++ b/lustre/osd-zfs/osd_handler.c @@ -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) diff --git a/lustre/osp/osp_dev.c b/lustre/osp/osp_dev.c index 69643fa..e154556 100644 --- a/lustre/osp/osp_dev.c +++ b/lustre/osp/osp_dev.c @@ -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, }; /**