From: Fan Yong Date: Fri, 28 Feb 2014 20:35:09 +0000 (+0800) Subject: LU-4767 lfsck: sub-task thread should not change lc_link X-Git-Tag: 2.5.58~92 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=0045c0126beac0bcac514caa5ef47a9768c2ef85 LU-4767 lfsck: sub-task thread should not change lc_link The lfsck sub-task thread (for double scan) should not change the "lfsck_component:lc_link" which may cause the master lfsck engine thread to access some unexpected RAM space by race. LFSCK should not return -ENODEV to avoid to misguide ptlrpc. Signed-off-by: Fan Yong Change-Id: Ifb80eaf7c1c4ba9bf7fbd5213e9eae09efed7e28 Reviewed-on: http://review.whamcloud.com/9661 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Alex Zhuravlev Reviewed-by: Andreas Dilger Reviewed-by: Lai Siyao Reviewed-by: Oleg Drokin --- diff --git a/lustre/lfsck/lfsck_layout.c b/lustre/lfsck/lfsck_layout.c index 45247f2..0d5d7e2 100644 --- a/lustre/lfsck/lfsck_layout.c +++ b/lustre/lfsck/lfsck_layout.c @@ -1577,7 +1577,6 @@ static int lfsck_layout_double_scan_result(const struct lu_env *env, struct lfsck_bookmark *bk = &lfsck->li_bookmark_ram; down_write(&com->lc_sem); - lo->ll_run_time_phase2 += cfs_duration_sec(cfs_time_current() + HALF_SEC - lfsck->li_time_last_checkpoint); lo->ll_time_last_checkpoint = cfs_time_current_sec(); @@ -1601,15 +1600,7 @@ static int lfsck_layout_double_scan_result(const struct lu_env *env, lo->ll_status = LS_FAILED; } - if (lo->ll_status != LS_PAUSED) { - spin_lock(&lfsck->li_lock); - list_del_init(&com->lc_link); - list_add_tail(&com->lc_link, &lfsck->li_list_idle); - spin_unlock(&lfsck->li_lock); - } - rc = lfsck_layout_store(env, com); - up_write(&com->lc_sem); return rc; @@ -2049,7 +2040,7 @@ static int lfsck_layout_master_conditional_destroy(const struct lu_env *env, ltd = lfsck_tgt_get(&lfsck->li_ost_descs, index); if (unlikely(ltd == NULL)) - RETURN(-ENODEV); + RETURN(-ENXIO); exp = ltd->ltd_exp; if (!(exp_connect_flags(exp) & OBD_CONNECT_LFSCK)) @@ -3293,10 +3284,15 @@ repair: out: down_write(&com->lc_sem); if (rc < 0) { - /* If cannot touch the target server, - * mark the LFSCK as INCOMPLETE. */ - if (rc == -ENOTCONN || rc == -ESHUTDOWN || rc == -ETIMEDOUT || - rc == -EHOSTDOWN || rc == -EHOSTUNREACH) { + struct lfsck_layout_master_data *llmd = com->lc_data; + + if (unlikely(llmd->llmd_exit)) { + rc = 0; + } else if (rc == -ENOTCONN || rc == -ESHUTDOWN || + rc == -ETIMEDOUT || rc == -EHOSTDOWN || + rc == -EHOSTUNREACH) { + /* If cannot touch the target server, + * mark the LFSCK as INCOMPLETE. */ CERROR("%s: Fail to talk with OST %x: rc = %d.\n", lfsck_lfsck2name(lfsck), llr->llr_ost_idx, rc); lo->ll_flags |= LF_INCOMPLETE; @@ -3363,7 +3359,8 @@ static int lfsck_layout_assistant(void *args) while (!list_empty(&llmd->llmd_req_list)) { bool wakeup = false; - if (unlikely(llmd->llmd_exit)) + if (unlikely(llmd->llmd_exit || + !thread_is_running(mthread))) GOTO(cleanup1, rc = llmd->llmd_post_result); llr = list_entry(llmd->llmd_req_list.next, @@ -3576,7 +3573,7 @@ cleanup2: /* Under force exit case, some requests may be just freed without * verification, those objects should be re-handled when next run. * So not update the on-disk tracing file under such case. */ - if (!llmd->llmd_exit) + if (llmd->llmd_in_double_scan && !llmd->llmd_exit) rc1 = lfsck_layout_double_scan_result(env, com, rc); fini: @@ -5237,7 +5234,7 @@ static int lfsck_layout_master_in_notify(const struct lu_env *env, if (ltd == NULL) { spin_unlock(<ds->ltd_lock); - RETURN(-ENODEV); + RETURN(-ENXIO); } list_del_init(<d->ltd_layout_phase_list); @@ -5363,7 +5360,7 @@ static int lfsck_layout_slave_in_notify(const struct lu_env *env, llst = lfsck_layout_llst_find_and_del(llsd, lr->lr_index, true); if (llst == NULL) - RETURN(-ENODEV); + RETURN(-ENXIO); lfsck_layout_llst_put(llst); if (list_empty(&llsd->llsd_master_list)) @@ -5795,7 +5792,7 @@ static struct dt_it *lfsck_orphan_it_init(const struct lu_env *env, lfsck = lfsck_instance_find(dev, true, false); if (unlikely(lfsck == NULL)) - RETURN(ERR_PTR(-ENODEV)); + RETURN(ERR_PTR(-ENXIO)); com = lfsck_component_find(lfsck, LT_LAYOUT); if (unlikely(com == NULL)) @@ -5811,7 +5808,7 @@ static struct dt_it *lfsck_orphan_it_init(const struct lu_env *env, it->loi_llst = lfsck_layout_llst_find_and_del(llsd, attr, false); if (it->loi_llst == NULL) - GOTO(out, rc = -ENODEV); + GOTO(out, rc = -ENXIO); if (dev->dd_record_fid_accessed) { /* The first iteration against the rbtree, scan the whole rbtree diff --git a/lustre/lfsck/lfsck_lib.c b/lustre/lfsck/lfsck_lib.c index 6f1465c..c8e26f0 100644 --- a/lustre/lfsck/lfsck_lib.c +++ b/lustre/lfsck/lfsck_lib.c @@ -658,7 +658,7 @@ int lfsck_create_lpf(const struct lu_env *env, struct lfsck_instance *lfsck) ltd = lfsck_tgt_get(&lfsck->li_mdt_descs, 0); if (unlikely(ltd == NULL)) - RETURN(-ENODEV); + RETURN(-ENXIO); parent = lfsck_object_find_by_dev(env, ltd->ltd_tgt, &LU_LPF_FID); @@ -748,7 +748,7 @@ static int lfsck_fid_init(struct lfsck_instance *lfsck) ss = lu_site2seq(lfsck->li_bottom->dd_lu_dev.ld_site); if (unlikely(ss == NULL)) - RETURN(-ENODEV); + RETURN(-ENXIO); OBD_ALLOC_PTR(lfsck->li_seq); if (lfsck->li_seq == NULL) @@ -1444,6 +1444,7 @@ static void lfsck_interpret(const struct lu_env *env, struct lfsck_async_interpret_args *laia = args; struct lfsck_component *com; + LASSERT(laia->laia_com == NULL); LASSERT(laia->laia_shared); spin_lock(&lfsck->li_lock); @@ -1471,8 +1472,7 @@ int lfsck_double_scan(const struct lu_env *env, struct lfsck_instance *lfsck) int rc = 0; int rc1 = 0; - cfs_list_for_each_entry_safe(com, next, &lfsck->li_list_double_scan, - lc_link) { + list_for_each_entry(com, &lfsck->li_list_double_scan, lc_link) { if (lfsck->li_bookmark_ram.lb_param & LPF_DRYRUN) com->lc_journal = 0; @@ -1485,6 +1485,17 @@ int lfsck_double_scan(const struct lu_env *env, struct lfsck_instance *lfsck) atomic_read(&lfsck->li_double_scan_count) == 0, &lwi); + if (lfsck->li_status != LS_PAUSED && + lfsck->li_status != LS_CO_PAUSED) { + list_for_each_entry_safe(com, next, &lfsck->li_list_double_scan, + lc_link) { + spin_lock(&lfsck->li_lock); + list_del_init(&com->lc_link); + list_add_tail(&com->lc_link, &lfsck->li_list_idle); + spin_unlock(&lfsck->li_lock); + } + } + return rc1 != 0 ? rc1 : rc; } @@ -1539,12 +1550,23 @@ void lfsck_quit(const struct lu_env *env, struct lfsck_instance *lfsck) lc_link) { if (com->lc_ops->lfsck_quit != NULL) com->lc_ops->lfsck_quit(env, com); + + spin_lock(&lfsck->li_lock); + list_del_init(&com->lc_link); + list_del_init(&com->lc_link_dir); + list_add_tail(&com->lc_link, &lfsck->li_list_idle); + spin_unlock(&lfsck->li_lock); } list_for_each_entry_safe(com, next, &lfsck->li_list_double_scan, lc_link) { if (com->lc_ops->lfsck_quit != NULL) com->lc_ops->lfsck_quit(env, com); + + spin_lock(&lfsck->li_lock); + list_del_init(&com->lc_link); + list_add_tail(&com->lc_link, &lfsck->li_list_idle); + spin_unlock(&lfsck->li_lock); } } @@ -1637,7 +1659,7 @@ int lfsck_get_speed(struct dt_device *key, void *buf, int len) lfsck->li_bookmark_ram.lb_speed_limit); lfsck_instance_put(&env, lfsck); } else { - rc = -ENODEV; + rc = -ENXIO; } lu_env_fini(&env); @@ -1665,7 +1687,7 @@ int lfsck_set_speed(struct dt_device *key, int val) mutex_unlock(&lfsck->li_mutex); lfsck_instance_put(&env, lfsck); } else { - rc = -ENODEV; + rc = -ENXIO; } lu_env_fini(&env); @@ -1691,7 +1713,7 @@ int lfsck_get_windows(struct dt_device *key, void *buf, int len) lfsck->li_bookmark_ram.lb_async_windows); lfsck_instance_put(&env, lfsck); } else { - rc = -ENODEV; + rc = -ENXIO; } lu_env_fini(&env); @@ -1729,7 +1751,7 @@ int lfsck_set_windows(struct dt_device *key, int val) } lfsck_instance_put(&env, lfsck); } else { - rc = -ENODEV; + rc = -ENXIO; } lu_env_fini(&env); @@ -1762,7 +1784,7 @@ int lfsck_dump(struct dt_device *key, void *buf, int len, enum lfsck_type type) lfsck_instance_put(&env, lfsck); } else { - rc = -ENODEV; + rc = -ENXIO; } lu_env_fini(&env); @@ -1979,7 +2001,7 @@ int lfsck_start(const struct lu_env *env, struct dt_device *key, lfsck = lfsck_instance_find(key, true, false); if (unlikely(lfsck == NULL)) - RETURN(-ENODEV); + RETURN(-ENXIO); /* System is not ready, try again later. */ if (unlikely(lfsck->li_namespace == NULL)) @@ -2255,7 +2277,7 @@ int lfsck_stop(const struct lu_env *env, struct dt_device *key, lfsck = lfsck_instance_find(key, true, false); if (unlikely(lfsck == NULL)) - RETURN(-ENODEV); + RETURN(-ENXIO); thread = &lfsck->li_thread; /* release lfsck::li_mutex to avoid deadlock. */ @@ -2348,7 +2370,7 @@ int lfsck_in_notify(const struct lu_env *env, struct dt_device *key, lfsck = lfsck_instance_find(key, true, false); if (unlikely(lfsck == NULL)) - RETURN(-ENODEV); + RETURN(-ENXIO); com = lfsck_component_find(lfsck, lr->lr_active); if (likely(com != NULL)) { @@ -2377,7 +2399,7 @@ int lfsck_query(const struct lu_env *env, struct dt_device *key, lfsck = lfsck_instance_find(key, true, false); if (unlikely(lfsck == NULL)) - RETURN(-ENODEV); + RETURN(-ENXIO); com = lfsck_component_find(lfsck, lr->lr_active); if (likely(com != NULL)) { @@ -2397,7 +2419,7 @@ int lfsck_register_namespace(const struct lu_env *env, struct dt_device *key, struct ldlm_namespace *ns) { struct lfsck_instance *lfsck; - int rc = -ENODEV; + int rc = -ENXIO; lfsck = lfsck_instance_find(key, true, false); if (likely(lfsck != NULL)) { diff --git a/lustre/lfsck/lfsck_namespace.c b/lustre/lfsck/lfsck_namespace.c index 6fc08fb..c80fb48 100644 --- a/lustre/lfsck/lfsck_namespace.c +++ b/lustre/lfsck/lfsck_namespace.c @@ -1483,7 +1483,6 @@ fini: out: down_write(&com->lc_sem); - ns->ln_run_time_phase2 += cfs_duration_sec(cfs_time_current() + HALF_SEC - lfsck->li_time_last_checkpoint); ns->ln_time_last_checkpoint = cfs_time_current_sec(); @@ -1505,15 +1504,7 @@ out: ns->ln_status = LS_FAILED; } - if (ns->ln_status != LS_PAUSED) { - spin_lock(&lfsck->li_lock); - cfs_list_del_init(&com->lc_link); - cfs_list_add_tail(&com->lc_link, &lfsck->li_list_idle); - spin_unlock(&lfsck->li_lock); - } - rc = lfsck_namespace_store(env, com, false); - up_write(&com->lc_sem); if (atomic_dec_and_test(&lfsck->li_double_scan_count)) wake_up_all(&thread->t_ctl_waitq);