X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fmdd%2Fmdd_orphans.c;h=1f5f819b01d85e7820a6c673fdd5deebade55dce;hb=ccabce23bd9e366c345c852f565766a799f61238;hp=77944c6cfa7819ef47f32272c072f4a395cb2e86;hpb=08aa217ce49aba1ded52e0f7adb8a607035123fd;p=fs%2Flustre-release.git diff --git a/lustre/mdd/mdd_orphans.c b/lustre/mdd/mdd_orphans.c index 77944c6..1f5f819 100644 --- a/lustre/mdd/mdd_orphans.c +++ b/lustre/mdd/mdd_orphans.c @@ -15,11 +15,7 @@ * * You should have received a copy of the GNU General Public License * version 2 along with this program; If not, see - * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf - * - * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * http://www.gnu.org/licenses/gpl-2.0.html * * GPL HEADER END */ @@ -27,7 +23,7 @@ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. * - * Copyright (c) 2011, 2012, Intel Corporation. + * Copyright (c) 2011, 2017, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -45,13 +41,12 @@ #include #include -#include #include #include #include "mdd_internal.h" const char orph_index_name[] = "PENDING"; -const char *dotdot = ".."; +static const char dotdot[] = ".."; enum { ORPH_OP_UNLINK, @@ -64,7 +59,7 @@ enum { static struct dt_key* orph_key_fill(const struct lu_env *env, const struct lu_fid *lf, __u32 op) { - char *key = mdd_env_info(env)->mti_orph_key; + char *key = mdd_env_info(env)->mti_key; int rc; LASSERT(key); @@ -80,7 +75,7 @@ static struct dt_key* orph_key_fill(const struct lu_env *env, static struct dt_key* orph_key_fill_18(const struct lu_env *env, const struct lu_fid *lf) { - char *key = mdd_env_info(env)->mti_orph_key; + char *key = mdd_env_info(env)->mti_key; int rc; LASSERT(key); @@ -93,36 +88,33 @@ static struct dt_key* orph_key_fill_18(const struct lu_env *env, } static inline void mdd_orphan_write_lock(const struct lu_env *env, - struct mdd_device *mdd) + struct mdd_device *mdd) { - - struct dt_object *dor = mdd->mdd_orphans; - dor->do_ops->do_write_lock(env, dor, MOR_TGT_ORPHAN); + struct dt_object *dor = mdd->mdd_orphans; + dt_write_lock(env, dor, MOR_TGT_ORPHAN); } static inline void mdd_orphan_write_unlock(const struct lu_env *env, - struct mdd_device *mdd) + struct mdd_device *mdd) { - - struct dt_object *dor = mdd->mdd_orphans; - dor->do_ops->do_write_unlock(env, dor); + struct dt_object *dor = mdd->mdd_orphans; + dt_write_unlock(env, dor); } 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 dt_insert(env, dor, (const struct dt_rec *)rec, key, th, 1); } static inline int mdd_orphan_delete_obj(const struct lu_env *env, @@ -130,83 +122,86 @@ static inline int mdd_orphan_delete_obj(const struct lu_env *env, struct dt_key *key, struct thandle *th) { - struct dt_object *dor = mdd->mdd_orphans; + struct dt_object *dor = mdd->mdd_orphans; - return dor->do_index_ops->dio_delete(env, dor, - key, th, - BYPASS_CAPA); + return dt_delete(env, dor, key, th); } -static inline void mdd_orphan_ref_add(const struct lu_env *env, - struct mdd_device *mdd, - struct thandle *th) +static inline int mdd_orphan_ref_add(const struct lu_env *env, + struct mdd_device *mdd, + struct thandle *th) { - struct dt_object *dor = mdd->mdd_orphans; - dor->do_ops->do_ref_add(env, dor, th); + struct dt_object *dor = mdd->mdd_orphans; + return dt_ref_add(env, dor, th); } -static inline void mdd_orphan_ref_del(const struct lu_env *env, - struct mdd_device *mdd, - struct thandle *th) +static inline int mdd_orphan_ref_del(const struct lu_env *env, + struct mdd_device *mdd, + struct thandle *th) { - struct dt_object *dor = mdd->mdd_orphans; - dor->do_ops->do_ref_del(env, dor, th); + struct dt_object *dor = mdd->mdd_orphans; + return dt_ref_del(env, dor, th); } int orph_declare_index_insert(const struct lu_env *env, - struct mdd_object *obj, - struct thandle *th) + struct mdd_object *obj, + umode_t mode, struct thandle *th) { - struct mdd_device *mdd = mdo2mdd(&obj->mod_obj); - struct dt_key *key; - int rc; + 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) - return 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); - if (rc) - return rc; + rc = mdo_declare_ref_add(env, obj, th); + if (rc) + return rc; - if (!S_ISDIR(mdd_object_type(obj))) - return 0; + if (!S_ISDIR(mode)) + return 0; - rc = mdo_declare_ref_add(env, obj, th); - if (rc) - return rc; + rc = mdo_declare_ref_add(env, obj, th); + if (rc) + return rc; - rc = dt_declare_ref_add(env, mdd->mdd_orphans, th); - if (rc) - return rc; + rc = dt_declare_ref_add(env, mdd->mdd_orphans, th); + if (rc) + return rc; - rc = mdo_declare_index_delete(env, obj, dotdot, th); - if (rc) - return rc; + rc = mdo_declare_index_delete(env, obj, dotdot, th); + 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; + 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); LASSERT(!(obj->mod_flags & ORPHAN_OBJ)); - LASSERT(obj->mod_count > 0); mdd_orphan_write_lock(env, mdd); @@ -216,7 +211,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); @@ -224,15 +219,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; - next->do_index_ops->dio_delete(env, next, - (const struct dt_key *)dotdot, - th, BYPASS_CAPA); + GOTO(out, rc = 0); + + dt_delete(env, next, (const struct dt_key *)dotdot, th); - next->do_index_ops->dio_insert(env, next, - (struct dt_rec *)lf_dor, - (const struct dt_key *)dotdot, - th, BYPASS_CAPA, 1); + rec->rec_fid = lf_dor; + rec->rec_type = S_IFDIR; + dt_insert(env, next, (const struct dt_rec *)rec, + (const struct dt_key *)dotdot, th, 1); out: if (rc == 0) @@ -318,36 +312,36 @@ static int orph_index_delete(const struct lu_env *env, } -static int orphan_object_destroy(const struct lu_env *env, - struct mdd_object *obj, - struct dt_key *key) +static int orphan_destroy(const struct lu_env *env, struct mdd_object *obj, + struct dt_key *key) { - struct thandle *th = NULL; - struct mdd_device *mdd = mdo2mdd(&obj->mod_obj); - int rc = 0; - ENTRY; + struct thandle *th = NULL; + struct mdd_device *mdd = mdo2mdd(&obj->mod_obj); + int rc = 0; + ENTRY; - th = mdd_trans_create(env, mdd); - if (IS_ERR(th)) { - CERROR("Cannot get thandle\n"); - RETURN(-ENOMEM); - } - rc = orph_declare_index_delete(env, obj, th); - if (rc) - GOTO(stop, rc); + th = mdd_trans_create(env, mdd); + if (IS_ERR(th)) { + CERROR("Cannot get thandle\n"); + RETURN(PTR_ERR(th)); + } + + rc = orph_declare_index_delete(env, obj, th); + if (rc) + GOTO(stop, rc); rc = mdo_declare_destroy(env, obj, th); - if (rc) - GOTO(stop, rc); + if (rc) + GOTO(stop, rc); - rc = mdd_trans_start(env, mdd, th); - if (rc) - GOTO(stop, rc); + rc = mdd_trans_start(env, mdd, th); + if (rc) + GOTO(stop, rc); - mdd_write_lock(env, obj, MOR_TGT_CHILD); - if (likely(obj->mod_count == 0)) { - mdd_orphan_write_lock(env, mdd); - rc = mdd_orphan_delete_obj(env, mdd, key, th); + mdd_write_lock(env, obj, MOR_TGT_CHILD); + if (likely(obj->mod_count == 0)) { + mdd_orphan_write_lock(env, mdd); + rc = mdd_orphan_delete_obj(env, mdd, key, th); if (rc == 0) { mdo_ref_del(env, obj, th); if (S_ISDIR(mdd_object_type(obj))) { @@ -356,15 +350,15 @@ static int orphan_object_destroy(const struct lu_env *env, } rc = mdo_destroy(env, obj, th); } else - CERROR("could not delete object: rc = %d\n",rc); - mdd_orphan_write_unlock(env, mdd); - } - mdd_write_unlock(env, obj); + CERROR("could not delete object: rc = %d\n", rc); + mdd_orphan_write_unlock(env, mdd); + } + mdd_write_unlock(env, obj); stop: - mdd_trans_stop(env, mdd, 0, th); + rc = mdd_trans_stop(env, mdd, 0, th); - RETURN(rc); + RETURN(rc); } /** @@ -378,25 +372,24 @@ stop: * \retval -ve error */ static int orph_key_test_and_del(const struct lu_env *env, - struct mdd_device *mdd, - struct lu_fid *lf, - struct dt_key *key) + struct mdd_device *mdd, struct lu_fid *lf, + struct dt_key *key) { - struct mdd_object *mdo; - int rc; + struct mdd_object *mdo; + int rc; - mdo = mdd_object_find(env, mdd, lf); + mdo = mdd_object_find(env, mdd, lf); - if (IS_ERR(mdo)) - return PTR_ERR(mdo); + if (IS_ERR(mdo)) + return PTR_ERR(mdo); - rc = -EBUSY; - if (mdo->mod_count == 0) { - CDEBUG(D_HA, "Found orphan "DFID", delete it\n", PFID(lf)); - rc = orphan_object_destroy(env, mdo, key); - if (rc) /* so replay-single.sh test_37 works */ - CERROR("%s: error unlinking orphan "DFID" from " - "PENDING: rc = %d\n", + rc = -EBUSY; + if (mdo->mod_count == 0) { + CDEBUG(D_HA, "Found orphan "DFID", delete it\n", PFID(lf)); + rc = orphan_destroy(env, mdo, key); + if (rc) /* so replay-single.sh test_37 works */ + CERROR("%s: error unlinking orphan "DFID" from " + "PENDING: rc = %d\n", mdd2obd_dev(mdd)->obd_name, PFID(lf), rc); } else { mdd_write_lock(env, mdo, MOR_TGT_CHILD); @@ -419,16 +412,17 @@ 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_orph_ent; + struct lu_dirent *ent = &mdd_env_info(env)->mti_ent; const struct dt_it_ops *iops; struct dt_it *it; struct lu_fid fid; @@ -437,9 +431,8 @@ 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); + it = iops->init(env, dor, LUDA_64BITHASH); if (IS_ERR(it)) { rc = PTR_ERR(it); CERROR("%s: cannot clean PENDING: rc = %d\n", @@ -458,6 +451,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) @@ -519,45 +515,97 @@ out: */ int orph_index_init(const struct lu_env *env, struct mdd_device *mdd) { - struct lu_fid fid; - struct dt_object *d; - int rc = 0; - ENTRY; - - d = dt_store_open(env, mdd->mdd_child, "", orph_index_name, &fid); - if (!IS_ERR(d)) { - mdd->mdd_orphans = d; - if (!dt_try_as_dir(env, d)) { - rc = -ENOTDIR; - CERROR("\"%s\" is not an index! : rc = %d\n", - orph_index_name, rc); - } - } else { - CERROR("cannot find \"%s\" obj %d\n", - orph_index_name, (int)PTR_ERR(d)); - rc = PTR_ERR(d); - } - - RETURN(rc); + struct lu_fid fid; + struct dt_object *d; + int rc = 0; + + ENTRY; + + /* create PENDING dir */ + fid_zero(&fid); + rc = mdd_local_file_create(env, mdd, &mdd->mdd_local_root_fid, + orph_index_name, S_IFDIR | S_IRUGO | + S_IWUSR | S_IXUGO, &fid); + if (rc < 0) + RETURN(rc); + + d = dt_locate(env, mdd->mdd_child, &fid); + if (IS_ERR(d)) + RETURN(PTR_ERR(d)); + LASSERT(lu_object_exists(&d->do_lu)); + if (!dt_try_as_dir(env, d)) { + CERROR("%s: \"%s\" is not an index: rc = %d\n", + mdd2obd_dev(mdd)->obd_name, orph_index_name, rc); + dt_object_put(env, d); + RETURN(-ENOTDIR); + } + mdd->mdd_orphans = d; + RETURN(0); } void orph_index_fini(const struct lu_env *env, struct mdd_device *mdd) { - ENTRY; - if (mdd->mdd_orphans != NULL) { - lu_object_put(env, &mdd->mdd_orphans->do_lu); - mdd->mdd_orphans = NULL; - } - EXIT; + ENTRY; + if (mdd->mdd_orphans != NULL) { + dt_object_put(env, mdd->mdd_orphans); + mdd->mdd_orphans = NULL; + } + 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; } /**