X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Flfsck%2Flfsck_lib.c;h=891becc9bdb63496aa56085eb8832e2f8fa4060c;hb=08e888a20ec87b3e9dfccbae34cc2cfe98f848e6;hp=5b5491a991e1838922c17e5bbe3abf4a3e9a5b02;hpb=0209add4a5099817111c8576afe930d1e2daef03;p=fs%2Flustre-release.git diff --git a/lustre/lfsck/lfsck_lib.c b/lustre/lfsck/lfsck_lib.c index 5b5491a..891becc 100644 --- a/lustre/lfsck/lfsck_lib.c +++ b/lustre/lfsck/lfsck_lib.c @@ -92,6 +92,9 @@ const char *lfsck_param_names[] = { "failout", "dryrun", "all_targets", + "broadcast", + "orphan", + "create_ostobj", NULL }; @@ -658,7 +661,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 +751,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) @@ -904,8 +907,9 @@ int lfsck_bits_dump(char **buf, int *len, int bits, const char *names[], int flag; int rc; int i; + bool newline = (bits != 0 ? false : true); - rc = snprintf(*buf, *len, "%s:%c", prefix, bits != 0 ? ' ' : '\n'); + rc = snprintf(*buf, *len, "%s:%c", prefix, newline ? '\n' : ' '); if (rc <= 0) return -ENOSPC; @@ -915,8 +919,11 @@ int lfsck_bits_dump(char **buf, int *len, int bits, const char *names[], if (flag & bits) { bits &= ~flag; if (names[i] != NULL) { + if (bits == 0) + newline = true; + rc = snprintf(*buf, *len, "%s%c", names[i], - bits != 0 ? ',' : '\n'); + newline ? '\n' : ','); if (rc <= 0) return -ENOSPC; @@ -925,6 +932,16 @@ int lfsck_bits_dump(char **buf, int *len, int bits, const char *names[], } } } + + if (!newline) { + rc = snprintf(*buf, *len, "\n"); + if (rc <= 0) + return -ENOSPC; + + *buf += rc; + *len -= rc; + } + return save - *len; } @@ -1004,9 +1021,10 @@ void lfsck_pos_fill(const struct lu_env *env, struct lfsck_instance *lfsck, } } -static void __lfsck_set_speed(struct lfsck_instance *lfsck, __u32 limit) +bool __lfsck_set_speed(struct lfsck_instance *lfsck, __u32 limit) { - lfsck->li_bookmark_ram.lb_speed_limit = limit; + bool dirty = false; + if (limit != LFSCK_SPEED_NO_LIMIT) { if (limit > HZ) { lfsck->li_sleep_rate = limit / HZ; @@ -1019,6 +1037,13 @@ static void __lfsck_set_speed(struct lfsck_instance *lfsck, __u32 limit) lfsck->li_sleep_jif = 0; lfsck->li_sleep_rate = 0; } + + if (lfsck->li_bookmark_ram.lb_speed_limit != limit) { + lfsck->li_bookmark_ram.lb_speed_limit = limit; + dirty = true; + } + + return dirty; } void lfsck_control_speed(struct lfsck_instance *lfsck) @@ -1091,8 +1116,8 @@ static int lfsck_needs_scan_dir(const struct lu_env *env, return 1; } - /* .lustre doesn't contain "real" user objects, no need lfsck */ - if (fid_is_dot_lustre(lfsck_dto2fid(obj))) { + /* No need to check .lustre and its children. */ + if (fid_seq_is_dot_lustre(fid_seq(lfsck_dto2fid(obj)))) { if (depth > 0) lfsck_object_put(env, obj); return 0; @@ -1142,10 +1167,16 @@ static int lfsck_needs_scan_dir(const struct lu_env *env, return 0; } - /* Currently, only client visible directory can be remote. */ if (dt_object_remote(obj)) { + /* .lustre/lost+found/MDTxxx can be remote directory. */ + if (fid_seq_is_dot_lustre(fid_seq(lfsck_dto2fid(obj)))) + rc = 0; + else + /* Other remote directory should be client + * visible and need to be checked. */ + rc = 1; lfsck_object_put(env, obj); - return 1; + return rc; } depth++; @@ -1444,6 +1475,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 +1503,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 +1516,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 +1581,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); } } @@ -1577,9 +1630,6 @@ int lfsck_async_request(const struct lu_env *env, struct obd_export *exp, struct req_format *format; int rc; - if (!(exp_connect_flags(exp) & OBD_CONNECT_LFSCK)) - return -EOPNOTSUPP; - switch (request) { case LFSCK_NOTIFY: format = &RQF_LFSCK_NOTIFY; @@ -1637,7 +1687,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); @@ -1660,12 +1710,12 @@ int lfsck_set_speed(struct dt_device *key, int val) lfsck = lfsck_instance_find(key, true, false); if (likely(lfsck != NULL)) { mutex_lock(&lfsck->li_mutex); - __lfsck_set_speed(lfsck, val); - rc = lfsck_bookmark_store(&env, lfsck); + if (__lfsck_set_speed(lfsck, val)) + rc = lfsck_bookmark_store(&env, lfsck); mutex_unlock(&lfsck->li_mutex); lfsck_instance_put(&env, lfsck); } else { - rc = -ENODEV; + rc = -ENXIO; } lu_env_fini(&env); @@ -1691,7 +1741,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); @@ -1714,12 +1764,12 @@ int lfsck_set_windows(struct dt_device *key, int val) lfsck = lfsck_instance_find(key, true, false); if (likely(lfsck != NULL)) { if (val > LFSCK_ASYNC_WIN_MAX) { - CERROR("%s: Too large async windows size, which " - "may cause memory issues. The valid range " - "is [0 - %u]. If you do not want to restrict " - "the windows size for async requests pipeline, " - "just set it as 0.\n", - lfsck_lfsck2name(lfsck), LFSCK_ASYNC_WIN_MAX); + CWARN("%s: Too large async window size, which " + "may cause memory issues. The valid range " + "is [0 - %u]. If you do not want to restrict " + "the window size for async requests pipeline, " + "just set it as 0.\n", + lfsck_lfsck2name(lfsck), LFSCK_ASYNC_WIN_MAX); rc = -EINVAL; } else if (lfsck->li_bookmark_ram.lb_async_windows != val) { mutex_lock(&lfsck->li_mutex); @@ -1729,7 +1779,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 +1812,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); @@ -1970,7 +2020,6 @@ int lfsck_start(const struct lu_env *env, struct dt_device *key, struct lfsck_component *com; struct l_wait_info lwi = { 0 }; struct lfsck_thread_args *lta; - bool dirty = false; long rc = 0; __u16 valid = 0; __u16 flags = 0; @@ -1979,7 +2028,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)) @@ -2044,78 +2093,6 @@ int lfsck_start(const struct lu_env *env, struct dt_device *key, } start->ls_version = bk->lb_version; - if (start->ls_valid & LSV_SPEED_LIMIT) { - __lfsck_set_speed(lfsck, start->ls_speed_limit); - dirty = true; - } - - if (start->ls_valid & LSV_ASYNC_WINDOWS && - bk->lb_async_windows != start->ls_async_windows) { - bk->lb_async_windows = start->ls_async_windows; - dirty = true; - } - - if (start->ls_valid & LSV_ERROR_HANDLE) { - valid |= DOIV_ERROR_HANDLE; - if (start->ls_flags & LPF_FAILOUT) - flags |= DOIF_FAILOUT; - - if ((start->ls_flags & LPF_FAILOUT) && - !(bk->lb_param & LPF_FAILOUT)) { - bk->lb_param |= LPF_FAILOUT; - dirty = true; - } else if (!(start->ls_flags & LPF_FAILOUT) && - (bk->lb_param & LPF_FAILOUT)) { - bk->lb_param &= ~LPF_FAILOUT; - dirty = true; - } - } - - if (start->ls_valid & LSV_DRYRUN) { - valid |= DOIV_DRYRUN; - if (start->ls_flags & LPF_DRYRUN) - flags |= DOIF_DRYRUN; - - if ((start->ls_flags & LPF_DRYRUN) && - !(bk->lb_param & LPF_DRYRUN)) { - bk->lb_param |= LPF_DRYRUN; - dirty = true; - } else if (!(start->ls_flags & LPF_DRYRUN) && - (bk->lb_param & LPF_DRYRUN)) { - bk->lb_param &= ~LPF_DRYRUN; - lfsck->li_drop_dryrun = 1; - dirty = true; - } - } - - if (bk->lb_param & LPF_ALL_TGT && - !(start->ls_flags & LPF_ALL_TGT)) { - bk->lb_param &= ~LPF_ALL_TGT; - dirty = true; - } else if (!(bk->lb_param & LPF_ALL_TGT) && - start->ls_flags & LPF_ALL_TGT) { - bk->lb_param |= LPF_ALL_TGT; - dirty = true; - } - - if (bk->lb_param & LPF_ORPHAN && - !(start->ls_flags & LPF_ORPHAN)) { - bk->lb_param &= ~LPF_ORPHAN; - dirty = true; - } else if (!(bk->lb_param & LPF_ORPHAN) && - start->ls_flags & LPF_ORPHAN) { - bk->lb_param |= LPF_ORPHAN; - dirty = true; - } - - if (dirty) { - rc = lfsck_bookmark_store(env, lfsck); - if (rc != 0) - GOTO(out, rc); - } - - if (start->ls_flags & LPF_RESET) - flags |= DOIF_RESET; if (start->ls_active != 0) { struct lfsck_component *next; @@ -2128,8 +2105,8 @@ int lfsck_start(const struct lu_env *env, struct dt_device *key, GOTO(out, rc = -ENOTSUPP); } - cfs_list_for_each_entry_safe(com, next, - &lfsck->li_list_scan, lc_link) { + list_for_each_entry_safe(com, next, + &lfsck->li_list_scan, lc_link) { if (!(com->lc_type & start->ls_active)) { rc = com->lc_ops->lfsck_post(env, com, 0, false); @@ -2146,9 +2123,9 @@ int lfsck_start(const struct lu_env *env, struct dt_device *key, /* The component status will be updated * when its prep() is called later by * the LFSCK main engine. */ - cfs_list_del_init(&com->lc_link); - cfs_list_add_tail(&com->lc_link, - &lfsck->li_list_scan); + list_del_init(&com->lc_link); + list_add_tail(&com->lc_link, + &lfsck->li_list_scan); } start->ls_active &= ~type; } @@ -2156,7 +2133,28 @@ int lfsck_start(const struct lu_env *env, struct dt_device *key, } } - cfs_list_for_each_entry(com, &lfsck->li_list_scan, lc_link) { + if (list_empty(&lfsck->li_list_scan)) { + /* The speed limit will be used to control both the LFSCK and + * low layer scrub (if applied), need to be handled firstly. */ + if (start->ls_valid & LSV_SPEED_LIMIT) { + if (__lfsck_set_speed(lfsck, start->ls_speed_limit)) { + rc = lfsck_bookmark_store(env, lfsck); + if (rc != 0) + GOTO(out, rc); + } + } + + goto trigger; + } + + if (start->ls_flags & LPF_RESET) + flags |= DOIF_RESET; + + rc = lfsck_set_param(env, lfsck, start, !!(flags & DOIF_RESET)); + if (rc != 0) + GOTO(out, rc); + + list_for_each_entry(com, &lfsck->li_list_scan, lc_link) { start->ls_active |= com->lc_type; if (flags & DOIF_RESET) { rc = com->lc_ops->lfsck_reset(env, com, false); @@ -2167,18 +2165,22 @@ int lfsck_start(const struct lu_env *env, struct dt_device *key, trigger: lfsck->li_args_dir = LUDA_64BITHASH | LUDA_VERIFY; - if (bk->lb_param & LPF_DRYRUN) { + if (bk->lb_param & LPF_DRYRUN) lfsck->li_args_dir |= LUDA_VERIFY_DRYRUN; - valid |= DOIV_DRYRUN; - flags |= DOIF_DRYRUN; - } - if (bk->lb_param & LPF_FAILOUT) { + if (start != NULL && start->ls_valid & LSV_ERROR_HANDLE) { valid |= DOIV_ERROR_HANDLE; - flags |= DOIF_FAILOUT; + if (start->ls_flags & LPF_FAILOUT) + flags |= DOIF_FAILOUT; + } + + if (start != NULL && start->ls_valid & LSV_DRYRUN) { + valid |= DOIV_DRYRUN; + if (start->ls_flags & LPF_DRYRUN) + flags |= DOIF_DRYRUN; } - if (!cfs_list_empty(&lfsck->li_list_scan)) + if (!list_empty(&lfsck->li_list_scan)) flags |= DOIF_OUTUSED; lfsck->li_args_oit = (flags << DT_OTABLE_IT_FLAGS_SHIFT) | valid; @@ -2187,6 +2189,7 @@ trigger: if (IS_ERR(lta)) GOTO(out, rc = PTR_ERR(lta)); + __lfsck_set_speed(lfsck, bk->lb_speed_limit); rc = PTR_ERR(kthread_run(lfsck_master_engine, lta, "lfsck")); if (IS_ERR_VALUE(rc)) { CERROR("%s: cannot start LFSCK thread: rc = %ld\n", @@ -2255,7 +2258,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. */ @@ -2341,13 +2344,14 @@ int lfsck_in_notify(const struct lu_env *env, struct dt_device *key, case LE_PHASE2_DONE: case LE_FID_ACCESSED: case LE_PEER_EXIT: - case LE_CONDITIONAL_DESTROY: { + case LE_CONDITIONAL_DESTROY: + case LE_PAIRS_VERIFY: { struct lfsck_instance *lfsck; struct lfsck_component *com; 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)) { @@ -2376,7 +2380,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)) { @@ -2396,7 +2400,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)) {