X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Flfsck%2Flfsck_engine.c;h=ba65343aa057a39a54327b4ae119a07f3dfcadbc;hb=eebc3da214dfcbc01ba637f0925bfe8635b26138;hp=196eb43fd23df2a1100051f9bba562e21af40da1;hpb=4db8abadae3f8a393fe0d25e07575305ae3876da;p=fs%2Flustre-release.git diff --git a/lustre/lfsck/lfsck_engine.c b/lustre/lfsck/lfsck_engine.c index 196eb43..ba65343 100644 --- a/lustre/lfsck/lfsck_engine.c +++ b/lustre/lfsck/lfsck_engine.c @@ -20,7 +20,7 @@ * GPL HEADER END */ /* - * Copyright (c) 2012, 2013, Intel Corporation. + * Copyright (c) 2013, 2014, Intel Corporation. */ /* * lustre/lfsck/lfsck_engine.c @@ -98,7 +98,7 @@ static int lfsck_update_lma(const struct lu_env *env, { struct lfsck_thread_info *info = lfsck_env_info(env); struct lfsck_bookmark *bk = &lfsck->li_bookmark_ram; - struct dt_device *dt = lfsck->li_bottom; + struct dt_device *dev = lfsck_obj2dev(obj); struct lustre_mdt_attrs *lma = &info->lti_lma; struct lu_buf *buf; struct thandle *th; @@ -110,7 +110,7 @@ static int lfsck_update_lma(const struct lu_env *env, RETURN(0); buf = lfsck_buf_get(env, info->lti_lma_old, LMA_OLD_SIZE); - rc = dt_xattr_get(env, obj, buf, XATTR_NAME_LMA, BYPASS_CAPA); + rc = dt_xattr_get(env, obj, buf, XATTR_NAME_LMA); if (rc < 0) { if (rc != -ENODATA) RETURN(rc); @@ -129,7 +129,7 @@ static int lfsck_update_lma(const struct lu_env *env, } lustre_lma_swab(lma); - th = dt_trans_create(env, dt); + th = dt_trans_create(env, dev); if (IS_ERR(th)) RETURN(PTR_ERR(th)); @@ -138,16 +138,16 @@ static int lfsck_update_lma(const struct lu_env *env, if (rc != 0) GOTO(stop, rc); - rc = dt_trans_start(env, dt, th); + rc = dt_trans_start_local(env, dev, th); if (rc != 0) GOTO(stop, rc); - rc = dt_xattr_set(env, obj, buf, XATTR_NAME_LMA, fl, th, BYPASS_CAPA); + rc = dt_xattr_set(env, obj, buf, XATTR_NAME_LMA, fl, th); GOTO(stop, rc); stop: - dt_trans_stop(env, dt, th); + dt_trans_stop(env, dev, th); return rc; } @@ -159,7 +159,7 @@ static int lfsck_parent_fid(const struct lu_env *env, struct dt_object *obj, return -ENOTDIR; return dt_lookup(env, obj, (struct dt_rec *)fid, - (const struct dt_key *)"..", BYPASS_CAPA); + (const struct dt_key *)".."); } /** @@ -194,9 +194,8 @@ static int lfsck_needs_scan_dir(const struct lu_env *env, struct lfsck_thread_info *info = lfsck_env_info(env); struct lu_fid *fid = &info->lti_fid; struct lu_seq_range *range = &info->lti_range; - struct dt_device *dev = lfsck->li_bottom; - struct seq_server_site *ss = lu_site2seq(dev->dd_lu_dev.ld_site); - __u32 idx = lfsck_dev_idx(dev); + struct seq_server_site *ss = lfsck_dev_site(lfsck); + __u32 idx = lfsck_dev_idx(lfsck); int depth = 0; int rc = 0; @@ -237,7 +236,7 @@ static int lfsck_needs_scan_dir(const struct lu_env *env, return 1; if (obj == NULL) { - obj = lfsck_object_find(env, lfsck, fid); + obj = lfsck_object_find_bottom(env, lfsck, fid); if (IS_ERR(obj)) return PTR_ERR(obj); @@ -254,8 +253,7 @@ static int lfsck_needs_scan_dir(const struct lu_env *env, } rc = dt_xattr_get(env, obj, - lfsck_buf_get(env, NULL, 0), XATTR_NAME_LINK, - BYPASS_CAPA); + lfsck_buf_get(env, NULL, 0), XATTR_NAME_LINK); dt_read_unlock(env, obj); if (rc >= 0) GOTO(out, rc = 1); @@ -327,25 +325,14 @@ static int lfsck_load_stripe_lmv(const struct lu_env *env, RETURN(-ENOMEM); } - /* Find the object against the bottom device. */ - obj = lfsck_object_find_by_dev(env, lfsck->li_bottom, - lfsck_dto2fid(obj)); - if (IS_ERR(obj)) { - OBD_FREE_LARGE(lslr, sizeof(*lslr) * stripes); - OBD_FREE_PTR(llmv); - - RETURN(PTR_ERR(obj)); - } - llmv->ll_stripes_allocated = stripes; llmv->ll_hash_type = LMV_HASH_TYPE_UNKNOWN; llmv->ll_lslr = lslr; - lfsck->li_obj_dir = obj; } else { llmv->ll_lmv_slave = 1; - lfsck->li_obj_dir = lfsck_object_get(obj); } + lfsck->li_obj_dir = lfsck_object_get(obj); llmv->ll_lmv = *lmv; atomic_set(&llmv->ll_ref, 1); lfsck->li_lmv = llmv; @@ -428,7 +415,7 @@ int lfsck_open_dir(const struct lu_env *env, } iops = &obj->do_index_ops->dio_it; - di = iops->init(env, obj, lfsck->li_args_dir, BYPASS_CAPA); + di = iops->init(env, obj, lfsck->li_args_dir); if (IS_ERR(di)) GOTO(out, rc = PTR_ERR(di)); @@ -530,7 +517,7 @@ static int lfsck_prep(const struct lu_env *env, struct lfsck_instance *lfsck, GOTO(out, rc = 0); /* Find the directory for namespace-based traverse. */ - obj = lfsck_object_find(env, lfsck, &pos->lp_dir_parent); + obj = lfsck_object_find_bottom(env, lfsck, &pos->lp_dir_parent); if (IS_ERR(obj)) RETURN(PTR_ERR(obj)); @@ -621,13 +608,14 @@ out: static int lfsck_exec_dir(const struct lu_env *env, struct lfsck_instance *lfsck, + struct lfsck_assistant_object *lso, struct lu_dirent *ent, __u16 type) { struct lfsck_component *com; int rc; list_for_each_entry(com, &lfsck->li_list_scan, lc_link) { - rc = com->lc_ops->lfsck_exec_dir(env, com, ent, type); + rc = com->lc_ops->lfsck_exec_dir(env, com, lso, ent, type); if (rc != 0) return rc; } @@ -756,29 +744,20 @@ static int lfsck_master_dir_engine(const struct lu_env *env, (struct lu_dirent *)info->lti_key; struct lfsck_bookmark *bk = &lfsck->li_bookmark_ram; struct ptlrpc_thread *thread = &lfsck->li_thread; + struct lfsck_assistant_object *lso = NULL; int rc; __u16 type; ENTRY; do { - if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_DELAY2) && - cfs_fail_val > 0) { - struct l_wait_info lwi; - - lwi = LWI_TIMEOUT(cfs_time_seconds(cfs_fail_val), - NULL, NULL); - l_wait_event(thread->t_ctl_waitq, - !thread_is_running(thread), - &lwi); - - if (unlikely(!thread_is_running(thread))) { - CDEBUG(D_LFSCK, "%s: scan dir exit for engine " - "stop, parent "DFID", cookie "LPX64"\n", - lfsck_lfsck2name(lfsck), - PFID(lfsck_dto2fid(dir)), - lfsck->li_cookie_dir); - RETURN(0); - } + if (CFS_FAIL_TIMEOUT(OBD_FAIL_LFSCK_DELAY2, cfs_fail_val) && + unlikely(!thread_is_running(thread))) { + CDEBUG(D_LFSCK, "%s: scan dir exit for engine stop, " + "parent "DFID", cookie "LPX64"\n", + lfsck_lfsck2name(lfsck), + PFID(lfsck_dto2fid(dir)), lfsck->li_cookie_dir); + + GOTO(out, rc = 0); } lfsck->li_new_scanned++; @@ -796,25 +775,41 @@ static int lfsck_master_dir_engine(const struct lu_env *env, lfsck->li_cookie_dir, rc); lfsck_fail(env, lfsck, true); if (bk->lb_param & LPF_FAILOUT) - RETURN(rc); + GOTO(out, rc); else goto checkpoint; } - if (ent->lde_attrs & LUDA_IGNORE && - strcmp(ent->lde_name, dotdot) != 0) + if (ent->lde_attrs & LUDA_IGNORE) goto checkpoint; + /* skip dot entry. */ + if (ent->lde_namelen == 1 && ent->lde_name[0] == '.') + goto checkpoint; + + if (lso == NULL) { + lso = lfsck_assistant_object_init(env, + lfsck_dto2fid(dir), NULL, + lfsck->li_pos_current.lp_oit_cookie, true); + if (IS_ERR(lso)) { + if (bk->lb_param & LPF_FAILOUT) + RETURN(PTR_ERR(lso)); + + lso = NULL; + goto checkpoint; + } + } + /* The type in the @ent structure may has been overwritten, * so we need to pass the @type parameter independently. */ - rc = lfsck_exec_dir(env, lfsck, ent, type); + rc = lfsck_exec_dir(env, lfsck, lso, ent, type); if (rc != 0 && bk->lb_param & LPF_FAILOUT) - RETURN(rc); + GOTO(out, rc); checkpoint: rc = lfsck_checkpoint(env, lfsck); if (rc != 0 && bk->lb_param & LPF_FAILOUT) - RETURN(rc); + GOTO(out, rc); /* Rate control. */ lfsck_control_speed(lfsck); @@ -824,14 +819,14 @@ checkpoint: lfsck_lfsck2name(lfsck), PFID(lfsck_dto2fid(dir)), lfsck->li_cookie_dir); - RETURN(0); + GOTO(out, rc = 0); } if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_FATAL2)) { spin_lock(&lfsck->li_lock); thread_set_flags(thread, SVC_STOPPING); spin_unlock(&lfsck->li_lock); - RETURN(-EINVAL); + GOTO(out, rc = -EINVAL); } rc = iops->next(env, di); @@ -840,7 +835,13 @@ checkpoint: if (rc > 0 && !lfsck->li_oit_over) lfsck_close_dir(env, lfsck, rc); - RETURN(rc); + GOTO(out, rc); + +out: + if (lso != NULL) + lfsck_assistant_object_put(env, lso); + + return rc; } /** @@ -875,9 +876,8 @@ static int lfsck_master_oit_engine(const struct lu_env *env, struct lu_fid *fid = &info->lti_fid; struct lfsck_bookmark *bk = &lfsck->li_bookmark_ram; struct ptlrpc_thread *thread = &lfsck->li_thread; - struct dt_device *dev = lfsck->li_bottom; - struct seq_server_site *ss = lu_site2seq(dev->dd_lu_dev.ld_site); - __u32 idx = lfsck_dev_idx(dev); + struct seq_server_site *ss = lfsck_dev_site(lfsck); + __u32 idx = lfsck_dev_idx(lfsck); int rc; ENTRY; @@ -897,23 +897,13 @@ static int lfsck_master_oit_engine(const struct lu_env *env, if (unlikely(lfsck->li_oit_over)) RETURN(1); - if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_DELAY1) && - cfs_fail_val > 0) { - struct l_wait_info lwi; - - lwi = LWI_TIMEOUT(cfs_time_seconds(cfs_fail_val), - NULL, NULL); - l_wait_event(thread->t_ctl_waitq, - !thread_is_running(thread), - &lwi); + if (CFS_FAIL_TIMEOUT(OBD_FAIL_LFSCK_DELAY1, cfs_fail_val) && + unlikely(!thread_is_running(thread))) { + CDEBUG(D_LFSCK, "%s: OIT scan exit for engine stop, " + "cookie "LPU64"\n", + lfsck_lfsck2name(lfsck), iops->store(env, di)); - if (unlikely(!thread_is_running(thread))) { - CDEBUG(D_LFSCK, "%s: OIT scan exit for engine " - "stop, cookie "LPU64"\n", - lfsck_lfsck2name(lfsck), - iops->store(env, di)); - RETURN(0); - } + RETURN(0); } if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_CRASH)) @@ -953,6 +943,13 @@ static int lfsck_master_oit_engine(const struct lu_env *env, goto checkpoint; } + if (unlikely(!fid_is_sane(fid))) { + CDEBUG(D_LFSCK, "%s: OIT scan find invalid FID "DFID + ", skip it\n", + lfsck_lfsck2name(lfsck), PFID(fid)); + goto checkpoint; + } + if (fid_is_idif(fid)) { __u32 idx1 = fid_idif_ost_idx(fid); @@ -993,7 +990,7 @@ static int lfsck_master_oit_engine(const struct lu_env *env, } } - target = lfsck_object_find(env, lfsck, fid); + target = lfsck_object_find_bottom(env, lfsck, fid); if (IS_ERR(target)) { CDEBUG(D_LFSCK, "%s: OIT scan failed at find target " DFID", cookie "LPU64": rc = %d\n", @@ -1082,7 +1079,7 @@ int lfsck_master_engine(void *args) lfsck_lfsck2name(lfsck), rc); } - oit_di = oit_iops->init(env, oit_obj, lfsck->li_args_oit, BYPASS_CAPA); + oit_di = oit_iops->init(env, oit_obj, lfsck->li_args_oit); if (IS_ERR(oit_di)) { rc = PTR_ERR(oit_di); CDEBUG(D_LFSCK, "%s: master engine fail to init iteration: " @@ -1124,6 +1121,7 @@ int lfsck_master_engine(void *args) else rc = 1; + lfsck_pos_fill(env, lfsck, &lfsck->li_pos_checkpoint, false); CDEBUG(D_LFSCK, "LFSCK exit: oit_flags = %#x, dir_flags = %#x, " "oit_cookie = "LPU64", dir_cookie = "LPX64", parent = "DFID ", pid = %d, rc = %d\n", lfsck->li_args_oit, lfsck->li_args_dir, @@ -1207,7 +1205,6 @@ static int lfsck_assistant_query_others(const struct lu_env *env, lad->lad_touch_gen++; memset(lr, 0, sizeof(*lr)); - lr->lr_index = lfsck_dev_idx(lfsck->li_bottom); lr->lr_event = LE_QUERY; lr->lr_active = com->lc_type; laia->laia_com = com; @@ -1289,7 +1286,7 @@ out: } /** - * Notify the LFSCK event to the instatnces on remote servers. + * Notify the LFSCK event to the instances on remote servers. * * The LFSCK assistant thread notifies the LFSCK instances on other * servers (MDT/OST) about some events, such as start new scanning, @@ -1324,7 +1321,7 @@ static int lfsck_assistant_notify_others(const struct lu_env *env, if (set == NULL) RETURN(-ENOMEM); - lr->lr_index = lfsck_dev_idx(lfsck->li_bottom); + lr->lr_index = lfsck_dev_idx(lfsck); lr->lr_active = com->lc_type; laia->laia_com = com; laia->laia_lr = lr; @@ -1335,8 +1332,7 @@ static int lfsck_assistant_notify_others(const struct lu_env *env, if (com->lc_type != LFSCK_TYPE_LAYOUT) goto next; - lr->lr_valid = LSV_SPEED_LIMIT | LSV_ERROR_HANDLE | LSV_DRYRUN | - LSV_ASYNC_WINDOWS | LSV_CREATE_OSTOBJ; + lr->lr_valid = LSV_SPEED_LIMIT | LSV_ERROR_HANDLE | LSV_DRYRUN; lr->lr_speed = bk->lb_speed_limit; lr->lr_version = bk->lb_version; lr->lr_param |= bk->lb_param; @@ -1353,6 +1349,7 @@ static int lfsck_assistant_notify_others(const struct lu_env *env, laia->laia_ltd = ltd; ltd->ltd_layout_done = 0; + ltd->ltd_synced_failures = 0; rc = lfsck_async_request(env, ltd->ltd_exp, lr, set, lfsck_async_interpret_common, laia, LFSCK_NOTIFY); @@ -1383,7 +1380,7 @@ next: spin_lock(<ds->ltd_lock); if (com->lc_type == LFSCK_TYPE_LAYOUT) { cfs_foreach_bit(ltds->ltd_tgts_bitmap, idx) { - ltd = LTD_TGT(ltds, idx); + ltd = lfsck_ltd2tgt(ltds, idx); LASSERT(ltd != NULL); if (!list_empty(<d->ltd_layout_list)) @@ -1396,7 +1393,7 @@ next: } } else { cfs_foreach_bit(ltds->ltd_tgts_bitmap, idx) { - ltd = LTD_TGT(ltds, idx); + ltd = lfsck_ltd2tgt(ltds, idx); LASSERT(ltd != NULL); if (!list_empty(<d->ltd_namespace_list)) @@ -1547,7 +1544,7 @@ again: *gen = lad->lad_touch_gen; list_move_tail(list, &lad->lad_mdt_list); - if (ltd->ltd_namespace_failed) + if (ltd->ltd_synced_failures) continue; atomic_inc(<d->ltd_ref); @@ -1616,6 +1613,7 @@ int lfsck_assistant_engine(void *args) struct l_wait_info lwi = { 0 }; int rc = 0; int rc1 = 0; + int rc2; ENTRY; CDEBUG(D_LFSCK, "%s: %s LFSCK assistant thread start\n", @@ -1661,10 +1659,7 @@ int lfsck_assistant_engine(void *args) /* Wake up the main engine thread only when the list * is empty or half of the prefetched items have been * handled to avoid too frequent thread schedule. */ - if (lad->lad_prefetched == 0 || - (bk->lb_async_windows != 0 && - bk->lb_async_windows / 2 == - lad->lad_prefetched)) + if (lad->lad_prefetched <= (bk->lb_async_windows / 2)) wakeup = true; spin_unlock(&lad->lad_lock); if (wakeup) @@ -1698,18 +1693,18 @@ int lfsck_assistant_engine(void *args) lad->lad_to_post = 0; LASSERT(lad->lad_post_result > 0); + /* Wakeup the master engine to go ahead. */ + wake_up_all(&mthread->t_ctl_waitq); + memset(lr, 0, sizeof(*lr)); lr->lr_event = LE_PHASE1_DONE; lr->lr_status = lad->lad_post_result; rc = lfsck_assistant_notify_others(env, com, lr); - if (rc != 0) - CDEBUG(D_LFSCK, "%s: LFSCK assistant failed to " - "notify others for %s post: rc = %d\n", - lfsck_lfsck2name(lfsck), - lad->lad_name, rc); - /* Wakeup the master engine to go ahead. */ - wake_up_all(&mthread->t_ctl_waitq); + CDEBUG(D_LFSCK, "%s: LFSCK assistant notified " + "others for %s post: rc = %d\n", + lfsck_lfsck2name(lfsck), + lad->lad_name, rc); } if (lad->lad_to_double_scan) { @@ -1725,11 +1720,16 @@ int lfsck_assistant_engine(void *args) com->lc_time_last_checkpoint + cfs_time_seconds(LFSCK_CHECKPOINT_INTERVAL); + CDEBUG(D_LFSCK, "%s: LFSCK assistant sync before " + "the second-stage scaning\n", + lfsck_lfsck2name(lfsck)); + /* Flush async updates before handling orphan. */ - dt_sync(env, lfsck->li_next); + rc2 = dt_sync(env, lfsck->li_next); CDEBUG(D_LFSCK, "%s: LFSCK assistant phase2 " - "scan start\n", lfsck_lfsck2name(lfsck)); + "scan start, synced: rc = %d\n", + lfsck_lfsck2name(lfsck), rc2); if (OBD_FAIL_CHECK(OBD_FAIL_LFSCK_NO_DOUBLESCAN)) GOTO(cleanup2, rc = 0); @@ -1846,8 +1846,14 @@ cleanup2: rc = rc1; } + CDEBUG(D_LFSCK, "%s: LFSCK assistant sync before exit\n", + lfsck_lfsck2name(lfsck)); + /* Flush async updates before exit. */ - dt_sync(env, lfsck->li_next); + rc2 = dt_sync(env, lfsck->li_next); + + CDEBUG(D_LFSCK, "%s: LFSCK assistant synced before exit: rc = %d\n", + lfsck_lfsck2name(lfsck), rc2); /* Under force exit case, some requests may be just freed without * verification, those objects should be re-handled when next run.