4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 only,
8 * as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License version 2 for more details. A copy is
14 * included in the COPYING file that accompanied this code.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 * Copyright (c) 2012, 2013, Intel Corporation.
26 * lustre/lfsck/lfsck_lib.c
28 * Author: Fan, Yong <fan.yong@intel.com>
31 #define DEBUG_SUBSYSTEM S_LFSCK
33 #include <libcfs/list.h>
34 #include <lu_object.h>
35 #include <dt_object.h>
36 #include <md_object.h>
37 #include <lustre_fld.h>
38 #include <lustre_lib.h>
39 #include <lustre_net.h>
40 #include <lustre_lfsck.h>
41 #include <lustre/lustre_lfsck_user.h>
43 #include "lfsck_internal.h"
45 /* define lfsck thread key */
46 LU_KEY_INIT(lfsck, struct lfsck_thread_info);
48 static void lfsck_key_fini(const struct lu_context *ctx,
49 struct lu_context_key *key, void *data)
51 struct lfsck_thread_info *info = data;
53 lu_buf_free(&info->lti_linkea_buf);
57 LU_CONTEXT_KEY_DEFINE(lfsck, LCT_MD_THREAD | LCT_DT_THREAD);
58 LU_KEY_INIT_GENERIC(lfsck);
60 static CFS_LIST_HEAD(lfsck_instance_list);
61 static DEFINE_SPINLOCK(lfsck_instance_lock);
63 static const char *lfsck_status_names[] = {
65 [LS_SCANNING_PHASE1] = "scanning-phase1",
66 [LS_SCANNING_PHASE2] = "scanning-phase2",
67 [LS_COMPLETED] = "completed",
68 [LS_FAILED] = "failed",
69 [LS_STOPPED] = "stopped",
70 [LS_PAUSED] = "paused",
71 [LS_CRASHED] = "crashed",
72 [LS_PARTIAL] = "partial"
75 const char *lfsck_flags_names[] = {
83 const char *lfsck_param_names[] = {
90 const char *lfsck_status2names(enum lfsck_status status)
92 if (unlikely(status < 0 || status >= LS_MAX))
95 return lfsck_status_names[status];
98 static inline struct lfsck_component *
99 __lfsck_component_find(struct lfsck_instance *lfsck, __u16 type, cfs_list_t *list)
101 struct lfsck_component *com;
103 cfs_list_for_each_entry(com, list, lc_link) {
104 if (com->lc_type == type)
110 static struct lfsck_component *
111 lfsck_component_find(struct lfsck_instance *lfsck, __u16 type)
113 struct lfsck_component *com;
115 spin_lock(&lfsck->li_lock);
116 com = __lfsck_component_find(lfsck, type, &lfsck->li_list_scan);
120 com = __lfsck_component_find(lfsck, type,
121 &lfsck->li_list_double_scan);
125 com = __lfsck_component_find(lfsck, type, &lfsck->li_list_idle);
129 lfsck_component_get(com);
130 spin_unlock(&lfsck->li_lock);
134 void lfsck_component_cleanup(const struct lu_env *env,
135 struct lfsck_component *com)
137 if (!cfs_list_empty(&com->lc_link))
138 cfs_list_del_init(&com->lc_link);
139 if (!cfs_list_empty(&com->lc_link_dir))
140 cfs_list_del_init(&com->lc_link_dir);
142 lfsck_component_put(env, com);
145 void lfsck_instance_cleanup(const struct lu_env *env,
146 struct lfsck_instance *lfsck)
148 struct ptlrpc_thread *thread = &lfsck->li_thread;
149 struct lfsck_component *com;
152 LASSERT(list_empty(&lfsck->li_link));
153 LASSERT(thread_is_init(thread) || thread_is_stopped(thread));
155 if (lfsck->li_obj_oit != NULL) {
156 lu_object_put_nocache(env, &lfsck->li_obj_oit->do_lu);
157 lfsck->li_obj_oit = NULL;
160 LASSERT(lfsck->li_obj_dir == NULL);
162 while (!cfs_list_empty(&lfsck->li_list_scan)) {
163 com = cfs_list_entry(lfsck->li_list_scan.next,
164 struct lfsck_component,
166 lfsck_component_cleanup(env, com);
169 LASSERT(cfs_list_empty(&lfsck->li_list_dir));
171 while (!cfs_list_empty(&lfsck->li_list_double_scan)) {
172 com = cfs_list_entry(lfsck->li_list_double_scan.next,
173 struct lfsck_component,
175 lfsck_component_cleanup(env, com);
178 while (!cfs_list_empty(&lfsck->li_list_idle)) {
179 com = cfs_list_entry(lfsck->li_list_idle.next,
180 struct lfsck_component,
182 lfsck_component_cleanup(env, com);
185 if (lfsck->li_bookmark_obj != NULL) {
186 lu_object_put_nocache(env, &lfsck->li_bookmark_obj->do_lu);
187 lfsck->li_bookmark_obj = NULL;
190 if (lfsck->li_los != NULL) {
191 local_oid_storage_fini(env, lfsck->li_los);
192 lfsck->li_los = NULL;
198 static inline struct lfsck_instance *lfsck_instance_find(struct dt_device *key,
199 bool ref, bool unlink)
201 struct lfsck_instance *lfsck;
203 spin_lock(&lfsck_instance_lock);
204 cfs_list_for_each_entry(lfsck, &lfsck_instance_list, li_link) {
205 if (lfsck->li_bottom == key) {
207 lfsck_instance_get(lfsck);
209 list_del_init(&lfsck->li_link);
210 spin_unlock(&lfsck_instance_lock);
214 spin_unlock(&lfsck_instance_lock);
218 static inline int lfsck_instance_add(struct lfsck_instance *lfsck)
220 struct lfsck_instance *tmp;
222 spin_lock(&lfsck_instance_lock);
223 cfs_list_for_each_entry(tmp, &lfsck_instance_list, li_link) {
224 if (lfsck->li_bottom == tmp->li_bottom) {
225 spin_unlock(&lfsck_instance_lock);
230 cfs_list_add_tail(&lfsck->li_link, &lfsck_instance_list);
231 spin_unlock(&lfsck_instance_lock);
235 int lfsck_bits_dump(char **buf, int *len, int bits, const char *names[],
243 rc = snprintf(*buf, *len, "%s:%c", prefix, bits != 0 ? ' ' : '\n');
249 for (i = 0, flag = 1; bits != 0; i++, flag = 1 << i) {
252 if (names[i] != NULL) {
253 rc = snprintf(*buf, *len, "%s%c", names[i],
254 bits != 0 ? ',' : '\n');
266 int lfsck_time_dump(char **buf, int *len, __u64 time, const char *prefix)
271 rc = snprintf(*buf, *len, "%s: "LPU64" seconds\n", prefix,
272 cfs_time_current_sec() - time);
274 rc = snprintf(*buf, *len, "%s: N/A\n", prefix);
283 int lfsck_pos_dump(char **buf, int *len, struct lfsck_position *pos,
288 if (fid_is_zero(&pos->lp_dir_parent)) {
289 if (pos->lp_oit_cookie == 0)
290 rc = snprintf(*buf, *len, "%s: N/A, N/A, N/A\n",
293 rc = snprintf(*buf, *len, "%s: "LPU64", N/A, N/A\n",
294 prefix, pos->lp_oit_cookie);
296 rc = snprintf(*buf, *len, "%s: "LPU64", "DFID", "LPU64"\n",
297 prefix, pos->lp_oit_cookie,
298 PFID(&pos->lp_dir_parent), pos->lp_dir_cookie);
308 void lfsck_pos_fill(const struct lu_env *env, struct lfsck_instance *lfsck,
309 struct lfsck_position *pos, bool init)
311 const struct dt_it_ops *iops = &lfsck->li_obj_oit->do_index_ops->dio_it;
313 if (unlikely(lfsck->li_di_oit == NULL)) {
314 memset(pos, 0, sizeof(*pos));
318 pos->lp_oit_cookie = iops->store(env, lfsck->li_di_oit);
319 if (!lfsck->li_current_oit_processed && !init)
320 pos->lp_oit_cookie--;
322 LASSERT(pos->lp_oit_cookie > 0);
324 if (lfsck->li_di_dir != NULL) {
325 struct dt_object *dto = lfsck->li_obj_dir;
327 pos->lp_dir_cookie = dto->do_index_ops->dio_it.store(env,
330 if (pos->lp_dir_cookie >= MDS_DIR_END_OFF) {
331 fid_zero(&pos->lp_dir_parent);
332 pos->lp_dir_cookie = 0;
334 pos->lp_dir_parent = *lfsck_dto2fid(dto);
337 fid_zero(&pos->lp_dir_parent);
338 pos->lp_dir_cookie = 0;
342 static void __lfsck_set_speed(struct lfsck_instance *lfsck, __u32 limit)
344 lfsck->li_bookmark_ram.lb_speed_limit = limit;
345 if (limit != LFSCK_SPEED_NO_LIMIT) {
347 lfsck->li_sleep_rate = limit / HZ;
348 lfsck->li_sleep_jif = 1;
350 lfsck->li_sleep_rate = 1;
351 lfsck->li_sleep_jif = HZ / limit;
354 lfsck->li_sleep_jif = 0;
355 lfsck->li_sleep_rate = 0;
359 void lfsck_control_speed(struct lfsck_instance *lfsck)
361 struct ptlrpc_thread *thread = &lfsck->li_thread;
362 struct l_wait_info lwi;
364 if (lfsck->li_sleep_jif > 0 &&
365 lfsck->li_new_scanned >= lfsck->li_sleep_rate) {
366 lwi = LWI_TIMEOUT_INTR(lfsck->li_sleep_jif, NULL,
367 LWI_ON_SIGNAL_NOOP, NULL);
369 l_wait_event(thread->t_ctl_waitq,
370 !thread_is_running(thread),
372 lfsck->li_new_scanned = 0;
376 void lfsck_control_speed_by_self(struct lfsck_component *com)
378 struct lfsck_instance *lfsck = com->lc_lfsck;
379 struct ptlrpc_thread *thread = &lfsck->li_thread;
380 struct l_wait_info lwi;
382 if (lfsck->li_sleep_jif > 0 &&
383 com->lc_new_scanned >= lfsck->li_sleep_rate) {
384 lwi = LWI_TIMEOUT_INTR(lfsck->li_sleep_jif, NULL,
385 LWI_ON_SIGNAL_NOOP, NULL);
387 l_wait_event(thread->t_ctl_waitq,
388 !thread_is_running(thread),
390 com->lc_new_scanned = 0;
394 static int lfsck_parent_fid(const struct lu_env *env, struct dt_object *obj,
397 if (unlikely(!S_ISDIR(lfsck_object_type(obj)) ||
398 !dt_try_as_dir(env, obj)))
401 return dt_lookup(env, obj, (struct dt_rec *)fid,
402 (const struct dt_key *)"..", BYPASS_CAPA);
405 static int lfsck_needs_scan_dir(const struct lu_env *env,
406 struct lfsck_instance *lfsck,
407 struct dt_object *obj)
409 struct lu_fid *fid = &lfsck_env_info(env)->lti_fid;
413 if (!lfsck->li_master || !S_ISDIR(lfsck_object_type(obj)) ||
414 cfs_list_empty(&lfsck->li_list_dir))
418 /* XXX: Currently, we do not scan the "/REMOTE_PARENT_DIR",
419 * which is the agent directory to manage the objects
420 * which name entries reside on remote MDTs. Related
421 * consistency verification will be processed in LFSCK
423 if (lu_fid_eq(lfsck_dto2fid(obj), &lfsck->li_global_root_fid)) {
425 lfsck_object_put(env, obj);
429 /* .lustre doesn't contain "real" user objects, no need lfsck */
430 if (fid_is_dot_lustre(lfsck_dto2fid(obj))) {
432 lfsck_object_put(env, obj);
436 dt_read_lock(env, obj, MOR_TGT_CHILD);
437 if (unlikely(lfsck_is_dead_obj(obj))) {
438 dt_read_unlock(env, obj);
440 lfsck_object_put(env, obj);
444 rc = dt_xattr_get(env, obj,
445 lfsck_buf_get(env, NULL, 0), XATTR_NAME_LINK,
447 dt_read_unlock(env, obj);
450 lfsck_object_put(env, obj);
454 if (rc < 0 && rc != -ENODATA) {
456 lfsck_object_put(env, obj);
460 rc = lfsck_parent_fid(env, obj, fid);
462 lfsck_object_put(env, obj);
466 if (unlikely(lu_fid_eq(fid, &lfsck->li_local_root_fid)))
469 obj = lfsck_object_find(env, lfsck, fid);
472 else if (IS_ERR(obj))
475 if (!dt_object_exists(obj)) {
476 lfsck_object_put(env, obj);
480 /* Currently, only client visible directory can be remote. */
481 if (dt_object_remote(obj)) {
482 lfsck_object_put(env, obj);
491 struct lfsck_thread_args *lfsck_thread_args_init(struct lfsck_instance *lfsck,
492 struct lfsck_component *com)
494 struct lfsck_thread_args *lta;
499 return ERR_PTR(-ENOMEM);
501 rc = lu_env_init(<a->lta_env, LCT_MD_THREAD | LCT_DT_THREAD);
507 lta->lta_lfsck = lfsck_instance_get(lfsck);
509 lta->lta_com = lfsck_component_get(com);
514 void lfsck_thread_args_fini(struct lfsck_thread_args *lta)
516 if (lta->lta_com != NULL)
517 lfsck_component_put(<a->lta_env, lta->lta_com);
518 lfsck_instance_put(<a->lta_env, lta->lta_lfsck);
519 lu_env_fini(<a->lta_env);
523 /* LFSCK wrap functions */
525 void lfsck_fail(const struct lu_env *env, struct lfsck_instance *lfsck,
528 struct lfsck_component *com;
530 cfs_list_for_each_entry(com, &lfsck->li_list_scan, lc_link) {
531 com->lc_ops->lfsck_fail(env, com, new_checked);
535 int lfsck_checkpoint(const struct lu_env *env, struct lfsck_instance *lfsck)
537 struct lfsck_component *com;
541 if (likely(cfs_time_beforeq(cfs_time_current(),
542 lfsck->li_time_next_checkpoint)))
545 lfsck_pos_fill(env, lfsck, &lfsck->li_pos_current, false);
546 cfs_list_for_each_entry(com, &lfsck->li_list_scan, lc_link) {
547 rc = com->lc_ops->lfsck_checkpoint(env, com, false);
552 lfsck->li_time_last_checkpoint = cfs_time_current();
553 lfsck->li_time_next_checkpoint = lfsck->li_time_last_checkpoint +
554 cfs_time_seconds(LFSCK_CHECKPOINT_INTERVAL);
555 return rc1 != 0 ? rc1 : rc;
558 int lfsck_prep(const struct lu_env *env, struct lfsck_instance *lfsck)
560 struct dt_object *obj = NULL;
561 struct lfsck_component *com;
562 struct lfsck_component *next;
563 struct lfsck_position *pos = NULL;
564 const struct dt_it_ops *iops =
565 &lfsck->li_obj_oit->do_index_ops->dio_it;
570 LASSERT(lfsck->li_obj_dir == NULL);
571 LASSERT(lfsck->li_di_dir == NULL);
573 lfsck->li_current_oit_processed = 0;
574 cfs_list_for_each_entry_safe(com, next, &lfsck->li_list_scan, lc_link) {
575 com->lc_new_checked = 0;
576 if (lfsck->li_bookmark_ram.lb_param & LPF_DRYRUN)
579 rc = com->lc_ops->lfsck_prep(env, com);
584 (!lfsck_pos_is_zero(&com->lc_pos_start) &&
585 lfsck_pos_is_eq(pos, &com->lc_pos_start) > 0))
586 pos = &com->lc_pos_start;
589 /* Init otable-based iterator. */
591 rc = iops->load(env, lfsck->li_di_oit, 0);
593 lfsck->li_oit_over = 1;
600 rc = iops->load(env, lfsck->li_di_oit, pos->lp_oit_cookie);
604 lfsck->li_oit_over = 1;
606 if (!lfsck->li_master || fid_is_zero(&pos->lp_dir_parent))
609 /* Find the directory for namespace-based traverse. */
610 obj = lfsck_object_find(env, lfsck, &pos->lp_dir_parent);
613 else if (IS_ERR(obj))
614 RETURN(PTR_ERR(obj));
616 /* XXX: Currently, skip remote object, the consistency for
617 * remote object will be processed in LFSCK phase III. */
618 if (!dt_object_exists(obj) || dt_object_remote(obj) ||
619 unlikely(!S_ISDIR(lfsck_object_type(obj))))
622 if (unlikely(!dt_try_as_dir(env, obj)))
623 GOTO(out, rc = -ENOTDIR);
625 /* Init the namespace-based directory traverse. */
626 iops = &obj->do_index_ops->dio_it;
627 di = iops->init(env, obj, lfsck->li_args_dir, BYPASS_CAPA);
629 GOTO(out, rc = PTR_ERR(di));
631 LASSERT(pos->lp_dir_cookie < MDS_DIR_END_OFF);
633 rc = iops->load(env, di, pos->lp_dir_cookie);
634 if ((rc == 0) || (rc > 0 && pos->lp_dir_cookie > 0))
635 rc = iops->next(env, di);
645 lfsck->li_obj_dir = lfsck_object_get(obj);
646 lfsck->li_cookie_dir = iops->store(env, di);
647 spin_lock(&lfsck->li_lock);
648 lfsck->li_di_dir = di;
649 spin_unlock(&lfsck->li_lock);
655 lfsck_object_put(env, obj);
658 cfs_list_for_each_entry_safe(com, next, &lfsck->li_list_scan,
660 com->lc_ops->lfsck_post(env, com, rc, true);
666 lfsck_pos_fill(env, lfsck, &lfsck->li_pos_current, true);
667 cfs_list_for_each_entry(com, &lfsck->li_list_scan, lc_link) {
668 rc = com->lc_ops->lfsck_checkpoint(env, com, true);
673 lfsck->li_time_last_checkpoint = cfs_time_current();
674 lfsck->li_time_next_checkpoint = lfsck->li_time_last_checkpoint +
675 cfs_time_seconds(LFSCK_CHECKPOINT_INTERVAL);
679 int lfsck_exec_oit(const struct lu_env *env, struct lfsck_instance *lfsck,
680 struct dt_object *obj)
682 struct lfsck_component *com;
683 const struct dt_it_ops *iops;
688 LASSERT(lfsck->li_obj_dir == NULL);
690 cfs_list_for_each_entry(com, &lfsck->li_list_scan, lc_link) {
691 rc = com->lc_ops->lfsck_exec_oit(env, com, obj);
696 rc = lfsck_needs_scan_dir(env, lfsck, obj);
700 if (unlikely(!dt_try_as_dir(env, obj)))
701 GOTO(out, rc = -ENOTDIR);
703 iops = &obj->do_index_ops->dio_it;
704 di = iops->init(env, obj, lfsck->li_args_dir, BYPASS_CAPA);
706 GOTO(out, rc = PTR_ERR(di));
708 rc = iops->load(env, di, 0);
710 rc = iops->next(env, di);
720 lfsck->li_obj_dir = lfsck_object_get(obj);
721 lfsck->li_cookie_dir = iops->store(env, di);
722 spin_lock(&lfsck->li_lock);
723 lfsck->li_di_dir = di;
724 spin_unlock(&lfsck->li_lock);
730 lfsck_fail(env, lfsck, false);
731 return (rc > 0 ? 0 : rc);
734 int lfsck_exec_dir(const struct lu_env *env, struct lfsck_instance *lfsck,
735 struct dt_object *obj, struct lu_dirent *ent)
737 struct lfsck_component *com;
740 cfs_list_for_each_entry(com, &lfsck->li_list_scan, lc_link) {
741 rc = com->lc_ops->lfsck_exec_dir(env, com, obj, ent);
748 int lfsck_post(const struct lu_env *env, struct lfsck_instance *lfsck,
751 struct lfsck_component *com;
752 struct lfsck_component *next;
756 lfsck_pos_fill(env, lfsck, &lfsck->li_pos_current, false);
757 cfs_list_for_each_entry_safe(com, next, &lfsck->li_list_scan, lc_link) {
758 rc = com->lc_ops->lfsck_post(env, com, result, false);
763 lfsck->li_time_last_checkpoint = cfs_time_current();
764 lfsck->li_time_next_checkpoint = lfsck->li_time_last_checkpoint +
765 cfs_time_seconds(LFSCK_CHECKPOINT_INTERVAL);
767 /* Ignore some component post failure to make other can go ahead. */
771 int lfsck_double_scan(const struct lu_env *env, struct lfsck_instance *lfsck)
773 struct lfsck_component *com;
774 struct lfsck_component *next;
777 cfs_list_for_each_entry_safe(com, next, &lfsck->li_list_double_scan,
779 if (lfsck->li_bookmark_ram.lb_param & LPF_DRYRUN)
782 rc = com->lc_ops->lfsck_double_scan(env, com);
789 /* external interfaces */
791 int lfsck_get_speed(struct dt_device *key, void *buf, int len)
794 struct lfsck_instance *lfsck;
798 rc = lu_env_init(&env, LCT_MD_THREAD | LCT_DT_THREAD);
802 lfsck = lfsck_instance_find(key, true, false);
803 if (likely(lfsck != NULL)) {
804 rc = snprintf(buf, len, "%u\n",
805 lfsck->li_bookmark_ram.lb_speed_limit);
806 lfsck_instance_put(&env, lfsck);
815 EXPORT_SYMBOL(lfsck_get_speed);
817 int lfsck_set_speed(struct dt_device *key, int val)
820 struct lfsck_instance *lfsck;
824 rc = lu_env_init(&env, LCT_MD_THREAD | LCT_DT_THREAD);
828 lfsck = lfsck_instance_find(key, true, false);
829 if (likely(lfsck != NULL)) {
830 mutex_lock(&lfsck->li_mutex);
831 __lfsck_set_speed(lfsck, val);
832 rc = lfsck_bookmark_store(&env, lfsck);
833 mutex_unlock(&lfsck->li_mutex);
834 lfsck_instance_put(&env, lfsck);
843 EXPORT_SYMBOL(lfsck_set_speed);
845 int lfsck_dump(struct dt_device *key, void *buf, int len, enum lfsck_type type)
848 struct lfsck_instance *lfsck;
849 struct lfsck_component *com;
853 rc = lu_env_init(&env, LCT_MD_THREAD | LCT_DT_THREAD);
857 lfsck = lfsck_instance_find(key, true, false);
858 if (likely(lfsck != NULL)) {
859 com = lfsck_component_find(lfsck, type);
860 if (likely(com != NULL)) {
861 rc = com->lc_ops->lfsck_dump(&env, com, buf, len);
862 lfsck_component_put(&env, com);
867 lfsck_instance_put(&env, lfsck);
876 EXPORT_SYMBOL(lfsck_dump);
878 int lfsck_start(const struct lu_env *env, struct dt_device *key,
879 struct lfsck_start_param *lsp)
881 struct lfsck_start *start = lsp->lsp_start;
882 struct lfsck_instance *lfsck;
883 struct lfsck_bookmark *bk;
884 struct ptlrpc_thread *thread;
885 struct lfsck_component *com;
886 struct l_wait_info lwi = { 0 };
887 struct lfsck_thread_args *lta;
895 lfsck = lfsck_instance_find(key, true, false);
896 if (unlikely(lfsck == NULL))
899 /* start == NULL means auto trigger paused LFSCK. */
900 if ((start == NULL) &&
901 (cfs_list_empty(&lfsck->li_list_scan) ||
902 OBD_FAIL_CHECK(OBD_FAIL_LFSCK_NO_AUTO)))
905 bk = &lfsck->li_bookmark_ram;
906 thread = &lfsck->li_thread;
907 mutex_lock(&lfsck->li_mutex);
908 spin_lock(&lfsck->li_lock);
909 if (!thread_is_init(thread) && !thread_is_stopped(thread)) {
911 while (start->ls_active != 0) {
912 if (type & start->ls_active) {
913 com = __lfsck_component_find(lfsck, type,
914 &lfsck->li_list_scan);
916 com = __lfsck_component_find(lfsck,
918 &lfsck->li_list_double_scan);
923 start->ls_active &= ~type;
928 spin_unlock(&lfsck->li_lock);
931 spin_unlock(&lfsck->li_lock);
933 lfsck->li_namespace = lsp->lsp_namespace;
934 lfsck->li_paused = 0;
935 lfsck->li_oit_over = 0;
936 lfsck->li_drop_dryrun = 0;
937 lfsck->li_new_scanned = 0;
939 /* For auto trigger. */
943 start->ls_version = bk->lb_version;
944 if (start->ls_valid & LSV_SPEED_LIMIT) {
945 __lfsck_set_speed(lfsck, start->ls_speed_limit);
949 if (start->ls_valid & LSV_ERROR_HANDLE) {
950 valid |= DOIV_ERROR_HANDLE;
951 if (start->ls_flags & LPF_FAILOUT)
952 flags |= DOIF_FAILOUT;
954 if ((start->ls_flags & LPF_FAILOUT) &&
955 !(bk->lb_param & LPF_FAILOUT)) {
956 bk->lb_param |= LPF_FAILOUT;
958 } else if (!(start->ls_flags & LPF_FAILOUT) &&
959 (bk->lb_param & LPF_FAILOUT)) {
960 bk->lb_param &= ~LPF_FAILOUT;
965 if (start->ls_valid & LSV_DRYRUN) {
966 valid |= DOIV_DRYRUN;
967 if (start->ls_flags & LPF_DRYRUN)
968 flags |= DOIF_DRYRUN;
970 if ((start->ls_flags & LPF_DRYRUN) &&
971 !(bk->lb_param & LPF_DRYRUN)) {
972 bk->lb_param |= LPF_DRYRUN;
974 } else if (!(start->ls_flags & LPF_DRYRUN) &&
975 (bk->lb_param & LPF_DRYRUN)) {
976 bk->lb_param &= ~LPF_DRYRUN;
977 lfsck->li_drop_dryrun = 1;
983 rc = lfsck_bookmark_store(env, lfsck);
988 if (start->ls_flags & LPF_RESET)
991 if (start->ls_active != 0) {
992 struct lfsck_component *next;
994 if (start->ls_active == LFSCK_TYPES_ALL)
995 start->ls_active = LFSCK_TYPES_SUPPORTED;
997 if (start->ls_active & ~LFSCK_TYPES_SUPPORTED) {
998 start->ls_active &= ~LFSCK_TYPES_SUPPORTED;
999 GOTO(out, rc = -ENOTSUPP);
1002 cfs_list_for_each_entry_safe(com, next,
1003 &lfsck->li_list_scan, lc_link) {
1004 if (!(com->lc_type & start->ls_active)) {
1005 rc = com->lc_ops->lfsck_post(env, com, 0,
1012 while (start->ls_active != 0) {
1013 if (type & start->ls_active) {
1014 com = __lfsck_component_find(lfsck, type,
1015 &lfsck->li_list_idle);
1017 /* The component status will be updated
1018 * when its prep() is called later by
1019 * the LFSCK main engine. */
1020 cfs_list_del_init(&com->lc_link);
1021 cfs_list_add_tail(&com->lc_link,
1022 &lfsck->li_list_scan);
1024 start->ls_active &= ~type;
1030 cfs_list_for_each_entry(com, &lfsck->li_list_scan, lc_link) {
1031 start->ls_active |= com->lc_type;
1032 if (flags & DOIF_RESET) {
1033 rc = com->lc_ops->lfsck_reset(env, com, false);
1040 lfsck->li_args_dir = LUDA_64BITHASH | LUDA_VERIFY;
1041 if (bk->lb_param & LPF_DRYRUN) {
1042 lfsck->li_args_dir |= LUDA_VERIFY_DRYRUN;
1043 valid |= DOIV_DRYRUN;
1044 flags |= DOIF_DRYRUN;
1047 if (bk->lb_param & LPF_FAILOUT) {
1048 valid |= DOIV_ERROR_HANDLE;
1049 flags |= DOIF_FAILOUT;
1052 if (!cfs_list_empty(&lfsck->li_list_scan))
1053 flags |= DOIF_OUTUSED;
1055 lfsck->li_args_oit = (flags << DT_OTABLE_IT_FLAGS_SHIFT) | valid;
1056 thread_set_flags(thread, 0);
1057 lta = lfsck_thread_args_init(lfsck, NULL);
1059 GOTO(out, rc = PTR_ERR(lta));
1061 rc = PTR_ERR(kthread_run(lfsck_master_engine, lta, "lfsck"));
1062 if (IS_ERR_VALUE(rc)) {
1063 CERROR("%s: cannot start LFSCK thread: rc = %ld\n",
1064 lfsck_lfsck2name(lfsck), rc);
1065 lfsck_thread_args_fini(lta);
1068 l_wait_event(thread->t_ctl_waitq,
1069 thread_is_running(thread) ||
1070 thread_is_stopped(thread),
1077 mutex_unlock(&lfsck->li_mutex);
1079 lfsck_instance_put(env, lfsck);
1080 return (rc < 0 ? rc : 0);
1082 EXPORT_SYMBOL(lfsck_start);
1084 int lfsck_stop(const struct lu_env *env, struct dt_device *key, bool pause)
1086 struct lfsck_instance *lfsck;
1087 struct ptlrpc_thread *thread;
1088 struct l_wait_info lwi = { 0 };
1091 lfsck = lfsck_instance_find(key, true, false);
1092 if (unlikely(lfsck == NULL))
1095 thread = &lfsck->li_thread;
1096 mutex_lock(&lfsck->li_mutex);
1097 spin_lock(&lfsck->li_lock);
1098 if (thread_is_init(thread) || thread_is_stopped(thread)) {
1099 spin_unlock(&lfsck->li_lock);
1100 mutex_unlock(&lfsck->li_mutex);
1101 lfsck_instance_put(env, lfsck);
1106 lfsck->li_paused = 1;
1107 thread_set_flags(thread, SVC_STOPPING);
1108 spin_unlock(&lfsck->li_lock);
1110 wake_up_all(&thread->t_ctl_waitq);
1111 l_wait_event(thread->t_ctl_waitq,
1112 thread_is_stopped(thread),
1114 mutex_unlock(&lfsck->li_mutex);
1115 lfsck_instance_put(env, lfsck);
1119 EXPORT_SYMBOL(lfsck_stop);
1121 int lfsck_register(const struct lu_env *env, struct dt_device *key,
1122 struct dt_device *next, bool master)
1124 struct lfsck_instance *lfsck;
1125 struct dt_object *root = NULL;
1126 struct dt_object *obj;
1127 struct lu_fid *fid = &lfsck_env_info(env)->lti_fid;
1131 lfsck = lfsck_instance_find(key, false, false);
1132 if (unlikely(lfsck != NULL))
1135 OBD_ALLOC_PTR(lfsck);
1139 mutex_init(&lfsck->li_mutex);
1140 spin_lock_init(&lfsck->li_lock);
1141 CFS_INIT_LIST_HEAD(&lfsck->li_link);
1142 CFS_INIT_LIST_HEAD(&lfsck->li_list_scan);
1143 CFS_INIT_LIST_HEAD(&lfsck->li_list_dir);
1144 CFS_INIT_LIST_HEAD(&lfsck->li_list_double_scan);
1145 CFS_INIT_LIST_HEAD(&lfsck->li_list_idle);
1146 atomic_set(&lfsck->li_ref, 1);
1147 init_waitqueue_head(&lfsck->li_thread.t_ctl_waitq);
1148 lfsck->li_next = next;
1149 lfsck->li_bottom = key;
1151 fid->f_seq = FID_SEQ_LOCAL_NAME;
1154 rc = local_oid_storage_init(env, lfsck->li_bottom, fid, &lfsck->li_los);
1158 rc = dt_root_get(env, key, fid);
1162 root = dt_locate(env, lfsck->li_bottom, fid);
1164 GOTO(out, rc = PTR_ERR(root));
1166 if (unlikely(!dt_try_as_dir(env, root)))
1167 GOTO(out, rc = -ENOTDIR);
1169 lfsck->li_local_root_fid = *fid;
1171 lfsck->li_master = 1;
1172 if (lfsck_dev_idx(lfsck->li_bottom) == 0) {
1173 rc = dt_lookup(env, root,
1174 (struct dt_rec *)(&lfsck->li_global_root_fid),
1175 (const struct dt_key *)"ROOT", BYPASS_CAPA);
1181 fid->f_seq = FID_SEQ_LOCAL_FILE;
1182 fid->f_oid = OTABLE_IT_OID;
1184 obj = dt_locate(env, lfsck->li_bottom, fid);
1186 GOTO(out, rc = PTR_ERR(obj));
1188 lfsck->li_obj_oit = obj;
1189 rc = obj->do_ops->do_index_try(env, obj, &dt_otable_features);
1191 if (rc == -ENOTSUPP)
1197 rc = lfsck_bookmark_setup(env, lfsck);
1202 rc = lfsck_namespace_setup(env, lfsck);
1207 rc = lfsck_layout_setup(env, lfsck);
1211 /* XXX: more LFSCK components initialization to be added here. */
1214 rc = lfsck_instance_add(lfsck);
1216 if (root != NULL && !IS_ERR(root))
1217 lu_object_put(env, &root->do_lu);
1219 lfsck_instance_cleanup(env, lfsck);
1222 EXPORT_SYMBOL(lfsck_register);
1224 void lfsck_degister(const struct lu_env *env, struct dt_device *key)
1226 struct lfsck_instance *lfsck;
1228 lfsck = lfsck_instance_find(key, false, true);
1230 lfsck_instance_put(env, lfsck);
1232 EXPORT_SYMBOL(lfsck_degister);
1234 static int __init lfsck_init(void)
1238 lfsck_key_init_generic(&lfsck_thread_key, NULL);
1239 rc = lu_context_key_register(&lfsck_thread_key);
1243 static void __exit lfsck_exit(void)
1245 LASSERT(cfs_list_empty(&lfsck_instance_list));
1247 lu_context_key_degister(&lfsck_thread_key);
1250 MODULE_AUTHOR("Intel Corporation <http://www.intel.com/>");
1251 MODULE_DESCRIPTION("LFSCK");
1252 MODULE_LICENSE("GPL");
1254 cfs_module(lfsck, LUSTRE_VERSION_STRING, lfsck_init, lfsck_exit);