X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmdd%2Fmdd_orphans.c;h=442452c1f13e9754e13e452d0ec55f43312dca2b;hb=446eb3dda264c24acdeeea3158bba55a16c8c5e1;hp=9aa132b34f5c009241b8255bf0bc6176abdf30f3;hpb=2dc1bb8b7a53077fce8632aabe65b2ce8048a550;p=fs%2Flustre-release.git diff --git a/lustre/mdd/mdd_orphans.c b/lustre/mdd/mdd_orphans.c index 9aa132b..442452c 100644 --- a/lustre/mdd/mdd_orphans.c +++ b/lustre/mdd/mdd_orphans.c @@ -51,7 +51,7 @@ #include "mdd_internal.h" const char orph_index_name[] = "PENDING"; -const char *dotdot = ".."; +static const char dotdot[] = ".."; enum { ORPH_OP_UNLINK, @@ -109,20 +109,21 @@ static inline void mdd_orphan_write_unlock(const struct lu_env *env, } static inline int mdd_orphan_insert_obj(const struct lu_env *env, - struct mdd_device *mdd, - struct mdd_object *obj, - __u32 op, - struct thandle *th) + struct mdd_device *mdd, + struct mdd_object *obj, + __u32 op, struct thandle *th) { - struct dt_object *dor = mdd->mdd_orphans; - const struct lu_fid *lf = mdo2fid(obj); - struct dt_key *key = orph_key_fill(env, lf, op); - ENTRY; + struct dt_insert_rec *rec = &mdd_env_info(env)->mti_dt_rec; + struct dt_object *dor = mdd->mdd_orphans; + const struct lu_fid *lf = mdo2fid(obj); + struct dt_key *key = orph_key_fill(env, lf, op); - return dor->do_index_ops->dio_insert(env, dor, - (struct dt_rec *)lf, - key, th, - BYPASS_CAPA, 1); + rec->rec_fid = lf; + rec->rec_type = mdd_object_type(obj); + + return dor->do_index_ops->dio_insert(env, dor, + (const struct dt_rec *)rec, + key, th, BYPASS_CAPA, 1); } static inline int mdd_orphan_delete_obj(const struct lu_env *env, @@ -158,14 +159,18 @@ int orph_declare_index_insert(const struct lu_env *env, struct mdd_object *obj, umode_t mode, struct thandle *th) { + struct dt_insert_rec *rec = &mdd_env_info(env)->mti_dt_rec; struct mdd_device *mdd = mdo2mdd(&obj->mod_obj); struct dt_key *key; int rc; key = orph_key_fill(env, mdo2fid(obj), ORPH_OP_UNLINK); - rc = dt_declare_insert(env, mdd->mdd_orphans, NULL, key, th); - if (rc) + rec->rec_fid = mdo2fid(obj); + rec->rec_type = mode; + rc = dt_declare_insert(env, mdd->mdd_orphans, + (const struct dt_rec *)rec, key, th); + if (rc != 0) return rc; rc = mdo_declare_ref_add(env, obj, th); @@ -187,21 +192,23 @@ int orph_declare_index_insert(const struct lu_env *env, if (rc) return rc; - rc = mdo_declare_index_insert(env, obj, NULL, dotdot, th); + rc = mdo_declare_index_insert(env, obj, + lu_object_fid(&mdd->mdd_orphans->do_lu), + S_IFDIR, dotdot, th); return rc; } static int orph_index_insert(const struct lu_env *env, - struct mdd_object *obj, - __u32 op, - struct thandle *th) + struct mdd_object *obj, + __u32 op, struct thandle *th) { - struct mdd_device *mdd = mdo2mdd(&obj->mod_obj); - struct dt_object *dor = mdd->mdd_orphans; - const struct lu_fid *lf_dor = lu_object_fid(&dor->do_lu); - struct dt_object *next = mdd_object_child(obj); - int rc; + struct mdd_device *mdd = mdo2mdd(&obj->mod_obj); + struct dt_object *dor = mdd->mdd_orphans; + const struct lu_fid *lf_dor = lu_object_fid(&dor->do_lu); + struct dt_object *next = mdd_object_child(obj); + struct dt_insert_rec *rec = &mdd_env_info(env)->mti_dt_rec; + int rc; ENTRY; LASSERT(mdd_write_locked(env, obj) != 0); @@ -215,7 +222,7 @@ static int orph_index_insert(const struct lu_env *env, mdo_ref_add(env, obj, th); if (!S_ISDIR(mdd_object_type(obj))) - goto out; + GOTO(out, rc = 0); mdo_ref_add(env, obj, th); mdd_orphan_ref_add(env, mdd, th); @@ -223,13 +230,14 @@ static int orph_index_insert(const struct lu_env *env, /* try best to fixup directory, dont return errors * from here */ if (!dt_try_as_dir(env, next)) - goto out; + GOTO(out, rc = 0); next->do_index_ops->dio_delete(env, next, (const struct dt_key *)dotdot, th, BYPASS_CAPA); - next->do_index_ops->dio_insert(env, next, - (struct dt_rec *)lf_dor, + rec->rec_fid = lf_dor; + rec->rec_type = S_IFDIR; + next->do_index_ops->dio_insert(env, next, (const struct dt_rec *)rec, (const struct dt_key *)dotdot, th, BYPASS_CAPA, 1); @@ -419,14 +427,15 @@ static int orph_key_test_and_del(const struct lu_env *env, * have to be referenced (opened) by some client during recovery, or they * will be deleted here (for clients that did not complete recovery). * - * \param mdd MDD device finishing recovery + * \param thread info about orphan cleanup thread * * \retval 0 success * \retval -ve error */ static int orph_index_iterate(const struct lu_env *env, - struct mdd_device *mdd) + struct mdd_generic_thread *thread) { + struct mdd_device *mdd = (struct mdd_device *)thread->mgt_data; struct dt_object *dor = mdd->mdd_orphans; struct lu_dirent *ent = &mdd_env_info(env)->mti_ent; const struct dt_it_ops *iops; @@ -437,7 +446,6 @@ static int orph_index_iterate(const struct lu_env *env, __u64 cookie; ENTRY; - /* In recovery phase, do not need for any lock here */ iops = &dor->do_index_ops->dio_it; it = iops->init(env, dor, LUDA_64BITHASH, BYPASS_CAPA); if (IS_ERR(it)) { @@ -458,6 +466,9 @@ static int orph_index_iterate(const struct lu_env *env, } do { + if (thread->mgt_abort) + break; + key_sz = iops->key_size(env, it); /* filter out "." and ".." entries from PENDING dir. */ if (key_sz < 8) @@ -557,13 +568,59 @@ void orph_index_fini(const struct lu_env *env, struct mdd_device *mdd) EXIT; } +static int __mdd_orphan_cleanup(void *args) +{ + struct mdd_generic_thread *thread = (struct mdd_generic_thread *)args; + struct lu_env *env = NULL; + int rc; + ENTRY; + + complete(&thread->mgt_started); + + OBD_ALLOC_PTR(env); + if (env == NULL) + GOTO(out, rc = -ENOMEM); + + rc = lu_env_init(env, LCT_MD_THREAD); + if (rc) + GOTO(out, rc); + + rc = orph_index_iterate(env, thread); + + lu_env_fini(env); + GOTO(out, rc); +out: + if (env) + OBD_FREE_PTR(env); + complete(&thread->mgt_finished); + return rc; +} + /** * Iterate orphan index to cleanup orphan objects after recovery is done. * \param d mdd device in recovery. */ -int __mdd_orphan_cleanup(const struct lu_env *env, struct mdd_device *d) +int mdd_orphan_cleanup(const struct lu_env *env, struct mdd_device *d) { - return orph_index_iterate(env, d); + int rc = -ENOMEM; + char *name = NULL; + + OBD_ALLOC(name, MTI_NAME_MAXLEN); + if (name == NULL) + goto out; + + snprintf(name, MTI_NAME_MAXLEN, "orph_cleanup_%s", + mdd2obd_dev(d)->obd_name); + + rc = mdd_generic_thread_start(&d->mdd_orph_cleanup_thread, + __mdd_orphan_cleanup, (void *)d, name); +out: + if (rc) + CERROR("%s: start orphan cleanup thread failed:%d\n", + mdd2obd_dev(d)->obd_name, rc); + if (name) + OBD_FREE(name, MTI_NAME_MAXLEN); + return rc; } /**