From: Fan Yong Date: Fri, 24 Jan 2014 19:42:48 +0000 (+0800) Subject: LU-1267 lfsck: enhance RPCs (1) for MDT-OST consistency X-Git-Tag: 2.5.55~9 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=refs%2Fchanges%2F23%2F8623%2F21;p=fs%2Flustre-release.git LU-1267 lfsck: enhance RPCs (1) for MDT-OST consistency Introduce new RPC LFSCK_NOTIFY for the LFSCK instance on the server_1 to notify the LFSCK instance on the server_2 about the event such as: lfsck start/stop/pause/fail/phaseX_done, and so on. Introduce new RPC LFSCK_QUERY for the LFSCK instance on the server_1 to query the LFSCK status on the server_2. The two new RPCs are used not only for MDT-OST consistency, but also for DNE consistency in the future. Test-Parameters: allwaysuploadlogs Signed-off-by: Fan Yong Change-Id: I8529f1a3f5f7f9589101f456f0397c8ebe11df18 Reviewed-on: http://review.whamcloud.com/8623 Tested-by: Jenkins Reviewed-by: Alex Zhuravlev Reviewed-by: Andreas Dilger Tested-by: Maloo Reviewed-by: Oleg Drokin --- diff --git a/lustre/include/lprocfs_status.h b/lustre/include/lprocfs_status.h index 70f10a9..ffb85ca 100644 --- a/lustre/include/lprocfs_status.h +++ b/lustre/include/lprocfs_status.h @@ -315,10 +315,24 @@ static inline int opcode_offset(__u32 opc) { OPC_RANGE(LDLM) + OPC_RANGE(MDS) + OPC_RANGE(OST)); + } else if (opc < LFSCK_LAST_OPC) { + /* LFSCK opcode */ + return (opc - LFSCK_FIRST_OPC + + OPC_RANGE(UPDATE) + + OPC_RANGE(FLD) + + OPC_RANGE(SEC) + + OPC_RANGE(SEQ) + + OPC_RANGE(QUOTA) + + OPC_RANGE(LLOG) + + OPC_RANGE(OBD) + + OPC_RANGE(MGS) + + OPC_RANGE(LDLM) + + OPC_RANGE(MDS) + + OPC_RANGE(OST)); } else { - /* Unknown Opcode */ - return -1; - } + /* Unknown Opcode */ + return -1; + } } @@ -332,7 +346,8 @@ static inline int opcode_offset(__u32 opc) { OPC_RANGE(SEQ) + \ OPC_RANGE(SEC) + \ OPC_RANGE(FLD) + \ - OPC_RANGE(UPDATE)) + OPC_RANGE(UPDATE) + \ + OPC_RANGE(LFSCK)) #define EXTRA_MAX_OPCODES ((PTLRPC_LAST_CNTR - PTLRPC_FIRST_CNTR) + \ OPC_RANGE(EXTRA)) diff --git a/lustre/include/lu_target.h b/lustre/include/lu_target.h index 9d952bf..02f7e0b 100644 --- a/lustre/include/lu_target.h +++ b/lustre/include/lu_target.h @@ -41,6 +41,7 @@ #include #include #include +#include struct lu_target { struct obd_device *lut_obd; @@ -281,8 +282,18 @@ void tgt_brw_unlock(struct obd_ioobj *obj, struct niobuf_remote *niob, int tgt_brw_read(struct tgt_session_info *tsi); int tgt_brw_write(struct tgt_session_info *tsi); int tgt_hpreq_handler(struct ptlrpc_request *req); +void tgt_register_lfsck_start(int (*start)(const struct lu_env *, + struct dt_device *, + struct lfsck_start_param *)); +void tgt_register_lfsck_in_notify(int (*notify)(const struct lu_env *, + struct dt_device *, + struct lfsck_request *)); +void tgt_register_lfsck_query(int (*query)(const struct lu_env *, + struct dt_device *, + struct lfsck_request *)); extern struct tgt_handler tgt_sec_ctx_handlers[]; +extern struct tgt_handler tgt_lfsck_handlers[]; extern struct tgt_handler tgt_obd_handlers[]; extern struct tgt_handler tgt_dlm_handlers[]; extern struct tgt_handler tgt_llog_handlers[]; @@ -453,6 +464,11 @@ static inline void tgt_drop_id(struct obd_export *exp, struct obdo *oa) TGT_RPC_HANDLER(FLD_QUERY, flags, name, fn, NULL, \ LUSTRE_MDS_VERSION) +/* LFSCK handlers */ +#define TGT_LFSCK_HDL(flags, name, fn) \ + TGT_RPC_HANDLER(LFSCK_FIRST_OPC, flags, name, fn, \ + &RQF_ ## name, LUSTRE_OBD_VERSION) + /* Request with a format known in advance */ #define TGT_UPDATE_HDL(flags, name, fn) \ TGT_RPC_HANDLER(UPDATE_OBJ, flags, name, fn, &RQF_ ## name, \ diff --git a/lustre/include/lustre/lustre_idl.h b/lustre/include/lustre/lustre_idl.h index 207fe8d..d1f867f 100644 --- a/lustre/include/lustre/lustre_idl.h +++ b/lustre/include/lustre/lustre_idl.h @@ -2762,6 +2762,14 @@ enum fld_op { FLD_LOOKUP = 2, }; +/* LFSCK opcodes */ +typedef enum { + LFSCK_NOTIFY = 1101, + LFSCK_QUERY = 1102, + LFSCK_LAST_OPC, + LFSCK_FIRST_OPC = LFSCK_NOTIFY +} lfsck_cmd_t; + /* * LOV data structures */ diff --git a/lustre/include/lustre_lfsck.h b/lustre/include/lustre_lfsck.h index ccf9fb5..7a14fdc 100644 --- a/lustre/include/lustre_lfsck.h +++ b/lustre/include/lustre_lfsck.h @@ -111,8 +111,10 @@ enum lfsck_status { }; struct lfsck_start_param { - struct lfsck_start *lsp_start; struct ldlm_namespace *lsp_namespace; + struct lfsck_start *lsp_start; + __u32 lsp_index; + unsigned int lsp_index_valid:1; }; enum lfsck_events { @@ -122,6 +124,13 @@ enum lfsck_events { LE_PHASE2_DONE = 4, LE_START = 5, LE_STOP = 6, + LE_QUERY = 7, +}; + +enum lfsck_event_flags { + LEF_TO_OST = 0x00000001, + LEF_FROM_OST = 0x00000002, + LEF_FORCE_STOP = 0x00000004, }; typedef int (*lfsck_out_notify)(const struct lu_env *env, void *data, @@ -141,7 +150,11 @@ void lfsck_del_target(const struct lu_env *env, struct dt_device *key, int lfsck_start(const struct lu_env *env, struct dt_device *key, struct lfsck_start_param *lsp); int lfsck_stop(const struct lu_env *env, struct dt_device *key, - bool pause); + struct lfsck_stop *stop); +int lfsck_in_notify(const struct lu_env *env, struct dt_device *key, + struct lfsck_request *lr); +int lfsck_query(const struct lu_env *env, struct dt_device *key, + struct lfsck_request *lr); int lfsck_get_speed(struct dt_device *key, void *buf, int len); int lfsck_set_speed(struct dt_device *key, int val); diff --git a/lustre/include/lustre_lib.h b/lustre/include/lustre_lib.h index 9ba7cd8..5a86378 100644 --- a/lustre/include/lustre_lib.h +++ b/lustre/include/lustre_lib.h @@ -561,7 +561,6 @@ static inline void obd_ioctl_freedata(char *buf, int len) #define OBD_IOC_ECHO_ALLOC_SEQ _IOWR('f', 222, struct obd_ioctl_data) #define OBD_IOC_START_LFSCK _IOWR('f', 230, OBD_IOC_DATA_TYPE) #define OBD_IOC_STOP_LFSCK _IOW('f', 231, OBD_IOC_DATA_TYPE) -#define OBD_IOC_PAUSE_LFSCK _IOW('f', 232, OBD_IOC_DATA_TYPE) /* XXX _IOWR('f', 250, long) has been defined in * libcfs/include/libcfs/libcfs_private.h for debug, don't use it diff --git a/lustre/include/lustre_req_layout.h b/lustre/include/lustre_req_layout.h index 5bdfe0d..936476e 100644 --- a/lustre/include/lustre_req_layout.h +++ b/lustre/include/lustre_req_layout.h @@ -250,6 +250,10 @@ extern struct req_format RQF_LLOG_ORIGIN_CONNECT; extern struct req_format RQF_CONNECT; +/* LFSCK req_format */ +extern struct req_format RQF_LFSCK_NOTIFY; +extern struct req_format RQF_LFSCK_QUERY; + extern struct req_msg_field RMF_GENERIC_DATA; extern struct req_msg_field RMF_PTLRPC_BODY; extern struct req_msg_field RMF_MDT_BODY; @@ -337,6 +341,10 @@ extern struct req_msg_field RMF_U32; /* OBJ update format */ extern struct req_msg_field RMF_UPDATE; extern struct req_msg_field RMF_UPDATE_REPLY; + +/* LFSCK format */ +extern struct req_msg_field RMF_LFSCK_REQUEST; +extern struct req_msg_field RMF_LFSCK_REPLY; /** @} req_layout */ #endif /* _LUSTRE_REQ_LAYOUT_H__ */ diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h index 5ecdaab..24671c3 100644 --- a/lustre/include/obd_support.h +++ b/lustre/include/obd_support.h @@ -501,6 +501,9 @@ int obd_alloc_fail(const void *ptr, const char *name, const char *type, #define OBD_FAIL_LFSCK_SKIP_LASTID 0x160d #define OBD_FAIL_LFSCK_DELAY4 0x160e +#define OBD_FAIL_LFSCK_NOTIFY_NET 0x16f0 +#define OBD_FAIL_LFSCK_QUERY_NET 0x16f1 + /* UPDATE */ #define OBD_FAIL_UPDATE_OBJ_NET 0x1700 #define OBD_FAIL_UPDATE_OBJ_NET_REP 0x1701 diff --git a/lustre/lfsck/lfsck_internal.h b/lustre/lfsck/lfsck_internal.h index 038c350..5e2a144 100644 --- a/lustre/lfsck/lfsck_internal.h +++ b/lustre/lfsck/lfsck_internal.h @@ -296,6 +296,13 @@ struct lfsck_operations { void (*lfsck_quit)(const struct lu_env *env, struct lfsck_component *com); + + int (*lfsck_in_notify)(const struct lu_env *env, + struct lfsck_component *com, + struct lfsck_request *lr); + + int (*lfsck_query)(const struct lu_env *env, + struct lfsck_component *com); }; #define TGT_PTRS 256 /* number of pointers at 1st level */ @@ -458,8 +465,10 @@ struct lfsck_instance { /* How many objects have been scanned since last sleep. */ __u32 li_new_scanned; - unsigned int li_paused:1, /* The lfsck is paused. */ - li_oit_over:1, /* oit is finished. */ + /* The status when the LFSCK stopped or paused. */ + __u32 li_status; + + unsigned int li_oit_over:1, /* oit is finished. */ li_drop_dryrun:1, /* Ever dryrun, not now. */ li_master:1, /* Master instance or not. */ li_current_oit_processed:1; diff --git a/lustre/lfsck/lfsck_layout.c b/lustre/lfsck/lfsck_layout.c index 39cffe3..908ed89 100644 --- a/lustre/lfsck/lfsck_layout.c +++ b/lustre/lfsck/lfsck_layout.c @@ -667,9 +667,8 @@ static int lfsck_layout_double_scan_result(const struct lu_env *env, lo->ll_time_last_complete = lo->ll_time_last_checkpoint; lo->ll_success_count++; } else if (rc == 0) { - if (lfsck->li_paused) - lo->ll_status = LS_PAUSED; - else + lo->ll_status = lfsck->li_status; + if (lo->ll_status == 0) lo->ll_status = LS_STOPPED; } else { lo->ll_status = LS_FAILED; @@ -879,10 +878,14 @@ cleanup2: lr->lr_status = rc; } else if (rc == 0) { lr->lr_event = LE_STOP; - if (lfsck->li_paused) + if (lfsck->li_status == LS_PAUSED || + lfsck->li_status == LS_CO_PAUSED) lr->lr_status = LS_CO_PAUSED; - else + else if (lfsck->li_status == LS_STOPPED || + lfsck->li_status == LS_CO_STOPPED) lr->lr_status = LS_CO_STOPPED; + else + LBUG(); } else { lr->lr_event = LE_STOP; lr->lr_status = LS_CO_FAILED; @@ -1305,10 +1308,10 @@ static int lfsck_layout_master_post(const struct lu_env *env, list_del_init(&com->lc_link); list_add_tail(&com->lc_link, &lfsck->li_list_double_scan); } else if (result == 0) { - if (lfsck->li_paused) { - lo->ll_status = LS_PAUSED; - } else { + lo->ll_status = lfsck->li_status; + if (lo->ll_status == 0) lo->ll_status = LS_STOPPED; + if (lo->ll_status != LS_PAUSED) { list_del_init(&com->lc_link); list_add_tail(&com->lc_link, &lfsck->li_list_idle); } @@ -1365,10 +1368,10 @@ static int lfsck_layout_slave_post(const struct lu_env *env, list_del_init(&com->lc_link); list_add_tail(&com->lc_link, &lfsck->li_list_double_scan); } else if (result == 0) { - if (lfsck->li_paused) { - lo->ll_status = LS_PAUSED; - } else { + lo->ll_status = lfsck->li_status; + if (lo->ll_status == 0) lo->ll_status = LS_STOPPED; + if (lo->ll_status != LS_PAUSED) { list_del_init(&com->lc_link); list_add_tail(&com->lc_link, &lfsck->li_list_idle); } @@ -1681,6 +1684,30 @@ static void lfsck_layout_master_quit(const struct lu_env *env, &lwi); } +static int lfsck_layout_master_in_notify(const struct lu_env *env, + struct lfsck_component *com, + struct lfsck_request *lr) +{ + /* XXX: to record the event from layout slave on the OST. */ + return 0; +} + +static int lfsck_layout_slave_in_notify(const struct lu_env *env, + struct lfsck_component *com, + struct lfsck_request *lr) +{ + /* XXX: to record the event from layout master on the MDT. */ + return 0; +} + +static int lfsck_layout_query(const struct lu_env *env, + struct lfsck_component *com) +{ + struct lfsck_layout *lo = com->lc_file_ram; + + return lo->ll_status; +} + static struct lfsck_operations lfsck_layout_master_ops = { .lfsck_reset = lfsck_layout_reset, .lfsck_fail = lfsck_layout_fail, @@ -1693,6 +1720,8 @@ static struct lfsck_operations lfsck_layout_master_ops = { .lfsck_double_scan = lfsck_layout_master_double_scan, .lfsck_data_release = lfsck_layout_master_data_release, .lfsck_quit = lfsck_layout_master_quit, + .lfsck_in_notify = lfsck_layout_master_in_notify, + .lfsck_query = lfsck_layout_query, }; static struct lfsck_operations lfsck_layout_slave_ops = { @@ -1706,6 +1735,8 @@ static struct lfsck_operations lfsck_layout_slave_ops = { .lfsck_dump = lfsck_layout_dump, .lfsck_double_scan = lfsck_layout_slave_double_scan, .lfsck_data_release = lfsck_layout_slave_data_release, + .lfsck_in_notify = lfsck_layout_slave_in_notify, + .lfsck_query = lfsck_layout_query, }; int lfsck_layout_setup(const struct lu_env *env, struct lfsck_instance *lfsck) diff --git a/lustre/lfsck/lfsck_lib.c b/lustre/lfsck/lfsck_lib.c index 6939cde..d59a07a 100644 --- a/lustre/lfsck/lfsck_lib.c +++ b/lustre/lfsck/lfsck_lib.c @@ -1211,7 +1211,7 @@ int lfsck_start(const struct lu_env *env, struct dt_device *key, spin_unlock(&lfsck->li_lock); lfsck->li_namespace = lsp->lsp_namespace; - lfsck->li_paused = 0; + lfsck->li_status = 0; lfsck->li_oit_over = 0; lfsck->li_drop_dryrun = 0; lfsck->li_new_scanned = 0; @@ -1367,11 +1367,13 @@ put: } EXPORT_SYMBOL(lfsck_start); -int lfsck_stop(const struct lu_env *env, struct dt_device *key, bool pause) +int lfsck_stop(const struct lu_env *env, struct dt_device *key, + struct lfsck_stop *stop) { struct lfsck_instance *lfsck; struct ptlrpc_thread *thread; struct l_wait_info lwi = { 0 }; + int rc = 0; ENTRY; lfsck = lfsck_instance_find(key, true, false); @@ -1383,13 +1385,14 @@ int lfsck_stop(const struct lu_env *env, struct dt_device *key, bool pause) spin_lock(&lfsck->li_lock); if (thread_is_init(thread) || thread_is_stopped(thread)) { spin_unlock(&lfsck->li_lock); - mutex_unlock(&lfsck->li_mutex); - lfsck_instance_put(env, lfsck); - RETURN(-EALREADY); + GOTO(out, rc = -EALREADY); } - if (pause) - lfsck->li_paused = 1; + if (stop != NULL) + lfsck->li_status = stop->ls_status; + else + lfsck->li_status = LS_STOPPED; + thread_set_flags(thread, SVC_STOPPING); spin_unlock(&lfsck->li_lock); @@ -1397,13 +1400,78 @@ int lfsck_stop(const struct lu_env *env, struct dt_device *key, bool pause) l_wait_event(thread->t_ctl_waitq, thread_is_stopped(thread), &lwi); + + GOTO(out, rc = 0); + +out: mutex_unlock(&lfsck->li_mutex); lfsck_instance_put(env, lfsck); - RETURN(0); + return rc; } EXPORT_SYMBOL(lfsck_stop); +int lfsck_in_notify(const struct lu_env *env, struct dt_device *key, + struct lfsck_request *lr) +{ + struct lfsck_instance *lfsck; + struct lfsck_component *com; + int rc; + ENTRY; + + switch (lr->lr_event) { + case LE_STOP: + case LE_PHASE1_DONE: + case LE_PHASE2_DONE: + break; + default: + RETURN(-EOPNOTSUPP); + } + + lfsck = lfsck_instance_find(key, true, false); + if (unlikely(lfsck == NULL)) + RETURN(-ENODEV); + + com = lfsck_component_find(lfsck, lr->lr_active); + if (likely(com != NULL)) { + rc = com->lc_ops->lfsck_in_notify(env, com, lr); + lfsck_component_put(env, com); + } else { + rc = -ENOTSUPP; + } + + lfsck_instance_put(env, lfsck); + + RETURN(rc); +} +EXPORT_SYMBOL(lfsck_in_notify); + +int lfsck_query(const struct lu_env *env, struct dt_device *key, + struct lfsck_request *lr) +{ + struct lfsck_instance *lfsck; + struct lfsck_component *com; + int rc; + ENTRY; + + lfsck = lfsck_instance_find(key, true, false); + if (unlikely(lfsck == NULL)) + RETURN(-ENODEV); + + com = lfsck_component_find(lfsck, lr->lr_active); + if (likely(com != NULL)) { + rc = com->lc_ops->lfsck_query(env, com); + lfsck_component_put(env, com); + } else { + rc = -ENOTSUPP; + } + + lfsck_instance_put(env, lfsck); + + RETURN(rc); +} +EXPORT_SYMBOL(lfsck_query); + int lfsck_register(const struct lu_env *env, struct dt_device *key, struct dt_device *next, lfsck_out_notify notify, void *notify_data, bool master) @@ -1666,6 +1734,11 @@ static int __init lfsck_init(void) INIT_LIST_HEAD(&lfsck_mdt_orphan_list); lfsck_key_init_generic(&lfsck_thread_key, NULL); rc = lu_context_key_register(&lfsck_thread_key); + if (rc == 0) { + tgt_register_lfsck_start(lfsck_start); + tgt_register_lfsck_in_notify(lfsck_in_notify); + tgt_register_lfsck_query(lfsck_query); + } return rc; } diff --git a/lustre/lfsck/lfsck_namespace.c b/lustre/lfsck/lfsck_namespace.c index d030528..36089aa 100644 --- a/lustre/lfsck/lfsck_namespace.c +++ b/lustre/lfsck/lfsck_namespace.c @@ -1055,10 +1055,10 @@ static int lfsck_namespace_post(const struct lu_env *env, cfs_list_del_init(&com->lc_link_dir); cfs_list_add_tail(&com->lc_link, &lfsck->li_list_double_scan); } else if (result == 0) { - if (lfsck->li_paused) { - ns->ln_status = LS_PAUSED; - } else { + ns->ln_status = lfsck->li_status; + if (ns->ln_status == 0) ns->ln_status = LS_STOPPED; + if (ns->ln_status != LS_PAUSED) { cfs_list_del_init(&com->lc_link); cfs_list_del_init(&com->lc_link_dir); cfs_list_add_tail(&com->lc_link, &lfsck->li_list_idle); @@ -1497,9 +1497,8 @@ out: ns->ln_time_last_complete = ns->ln_time_last_checkpoint; ns->ln_success_count++; } else if (rc == 0) { - if (lfsck->li_paused) - ns->ln_status = LS_PAUSED; - else + ns->ln_status = lfsck->li_status; + if (ns->ln_status == 0) ns->ln_status = LS_STOPPED; } else { ns->ln_status = LS_FAILED; @@ -1554,6 +1553,21 @@ static int lfsck_namespace_double_scan(const struct lu_env *env, RETURN(rc); } +static int lfsck_namespace_in_notify(const struct lu_env *env, + struct lfsck_component *com, + struct lfsck_request *lr) +{ + return 0; +} + +static int lfsck_namespace_query(const struct lu_env *env, + struct lfsck_component *com) +{ + struct lfsck_namespace *ns = com->lc_file_ram; + + return ns->ln_status; +} + static struct lfsck_operations lfsck_namespace_ops = { .lfsck_reset = lfsck_namespace_reset, .lfsck_fail = lfsck_namespace_fail, @@ -1564,6 +1578,8 @@ static struct lfsck_operations lfsck_namespace_ops = { .lfsck_post = lfsck_namespace_post, .lfsck_dump = lfsck_namespace_dump, .lfsck_double_scan = lfsck_namespace_double_scan, + .lfsck_in_notify = lfsck_namespace_in_notify, + .lfsck_query = lfsck_namespace_query, }; int lfsck_namespace_setup(const struct lu_env *env, diff --git a/lustre/mdd/mdd_device.c b/lustre/mdd/mdd_device.c index 3a90cff..11f1a82 100644 --- a/lustre/mdd/mdd_device.c +++ b/lustre/mdd/mdd_device.c @@ -1412,11 +1412,8 @@ static int mdd_iocontrol(const struct lu_env *env, struct md_device *m, RETURN(rc); } case OBD_IOC_STOP_LFSCK: { - rc = lfsck_stop(env, mdd->mdd_bottom, false); - RETURN(rc); - } - case OBD_IOC_PAUSE_LFSCK: { - rc = lfsck_stop(env, mdd->mdd_bottom, true); + rc = lfsck_stop(env, mdd->mdd_bottom, + (struct lfsck_stop *)karg); RETURN(rc); } } diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index ed52643..4c386b1 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -4182,6 +4182,11 @@ static struct tgt_opc_slice mdt_common_slice[] = { .tos_opc_end = LLOG_LAST_OPC, .tos_hs = tgt_llog_handlers }, + { + .tos_opc_start = LFSCK_FIRST_OPC, + .tos_opc_end = LFSCK_LAST_OPC, + .tos_hs = tgt_lfsck_handlers + }, { .tos_hs = NULL @@ -4190,15 +4195,14 @@ static struct tgt_opc_slice mdt_common_slice[] = { static void mdt_fini(const struct lu_env *env, struct mdt_device *m) { - struct md_device *next = m->mdt_child; - struct lu_device *d = &m->mdt_lu_dev; - struct obd_device *obd = mdt2obd_dev(m); - ENTRY; - - target_recovery_fini(obd); - - ping_evictor_stop(); + struct md_device *next = m->mdt_child; + struct lu_device *d = &m->mdt_lu_dev; + struct obd_device *obd = mdt2obd_dev(m); + struct lfsck_stop stop; + ENTRY; + target_recovery_fini(obd); + ping_evictor_stop(); mdt_stack_pre_fini(env, m, md2lu_dev(m->mdt_child)); if (m->mdt_opts.mo_coordinator) @@ -4233,7 +4237,8 @@ static void mdt_fini(const struct lu_env *env, struct mdt_device *m) m->mdt_nosquash_strlen = 0; } - next->md_ops->mdo_iocontrol(env, next, OBD_IOC_PAUSE_LFSCK, 0, NULL); + stop.ls_status = LS_PAUSED; + next->md_ops->mdo_iocontrol(env, next, OBD_IOC_STOP_LFSCK, 0, &stop); mdt_seq_fini(env, m); mdt_fld_fini(env, m); @@ -4700,8 +4705,9 @@ static int mdt_prepare(const struct lu_env *env, if (rc) RETURN(rc); - lsp.lsp_start = NULL; lsp.lsp_namespace = mdt->mdt_namespace; + lsp.lsp_start = NULL; + lsp.lsp_index_valid = 0; rc = mdt->mdt_child->md_ops->mdo_iocontrol(env, mdt->mdt_child, OBD_IOC_START_LFSCK, 0, &lsp); @@ -5555,15 +5561,18 @@ static int mdt_iocontrol(unsigned int cmd, struct obd_export *exp, int len, break; } - lsp.lsp_start = (struct lfsck_start *)(data->ioc_inlbuf1); lsp.lsp_namespace = mdt->mdt_namespace; + lsp.lsp_start = (struct lfsck_start *)(data->ioc_inlbuf1); + lsp.lsp_index_valid = 0; rc = next->md_ops->mdo_iocontrol(&env, next, cmd, 0, &lsp); break; } case OBD_IOC_STOP_LFSCK: { - struct md_device *next = mdt->mdt_child; + struct md_device *next = mdt->mdt_child; + struct lfsck_stop stop; - rc = next->md_ops->mdo_iocontrol(&env, next, cmd, 0, NULL); + stop.ls_status = LS_STOPPED; + rc = next->md_ops->mdo_iocontrol(&env, next, cmd, 0, &stop); break; } case OBD_IOC_GET_OBJ_VERSION: { diff --git a/lustre/ofd/ofd_dev.c b/lustre/ofd/ofd_dev.c index ea5d166..8664523 100644 --- a/lustre/ofd/ofd_dev.c +++ b/lustre/ofd/ofd_dev.c @@ -442,8 +442,9 @@ static int ofd_prepare(const struct lu_env *env, struct lu_device *pdev, RETURN(rc); } - lsp.lsp_start = NULL; lsp.lsp_namespace = ofd->ofd_namespace; + lsp.lsp_start = NULL; + lsp.lsp_index_valid = 0; rc = lfsck_start(env, ofd->ofd_osd, &lsp); if (rc != 0) { CWARN("%s: auto trigger paused LFSCK failed: rc = %d\n", @@ -2068,6 +2069,11 @@ static struct tgt_opc_slice ofd_common_slice[] = { .tos_hs = seq_handlers }, { + .tos_opc_start = LFSCK_FIRST_OPC, + .tos_opc_end = LFSCK_LAST_OPC, + .tos_hs = tgt_lfsck_handlers + }, + { .tos_hs = NULL } }; @@ -2237,10 +2243,12 @@ err_fini_proc: static void ofd_fini(const struct lu_env *env, struct ofd_device *m) { - struct obd_device *obd = ofd_obd(m); - struct lu_device *d = &m->ofd_dt_dev.dd_lu_dev; + struct obd_device *obd = ofd_obd(m); + struct lu_device *d = &m->ofd_dt_dev.dd_lu_dev; + struct lfsck_stop stop; - lfsck_stop(env, m->ofd_osd, true); + stop.ls_status = LS_PAUSED; + lfsck_stop(env, m->ofd_osd, &stop); lfsck_degister(env, m->ofd_osd); target_recovery_fini(obd); obd_exports_barrier(obd); diff --git a/lustre/ofd/ofd_obd.c b/lustre/ofd/ofd_obd.c index ec55834..61b1610 100644 --- a/lustre/ofd/ofd_obd.c +++ b/lustre/ofd/ofd_obd.c @@ -1023,13 +1023,17 @@ int ofd_iocontrol(unsigned int cmd, struct obd_export *exp, int len, break; } - lsp.lsp_start = (struct lfsck_start *)(data->ioc_inlbuf1); lsp.lsp_namespace = ofd->ofd_namespace; + lsp.lsp_start = (struct lfsck_start *)(data->ioc_inlbuf1); + lsp.lsp_index_valid = 0; rc = lfsck_start(&env, ofd->ofd_osd, &lsp); break; } case OBD_IOC_STOP_LFSCK: { - rc = lfsck_stop(&env, ofd->ofd_osd, false); + struct lfsck_stop stop; + + stop.ls_status = LS_STOPPED; + rc = lfsck_stop(&env, ofd->ofd_osd, &stop); break; } case OBD_IOC_GET_OBJ_VERSION: diff --git a/lustre/ptlrpc/layout.c b/lustre/ptlrpc/layout.c index 008f49d..13b10e7 100644 --- a/lustre/ptlrpc/layout.c +++ b/lustre/ptlrpc/layout.c @@ -694,6 +694,16 @@ static const struct req_msg_field *mdt_hsm_request[] = { &RMF_GENERIC_DATA, }; +static const struct req_msg_field *obd_lfsck_request[] = { + &RMF_PTLRPC_BODY, + &RMF_LFSCK_REQUEST, +}; + +static const struct req_msg_field *obd_lfsck_reply[] = { + &RMF_PTLRPC_BODY, + &RMF_LFSCK_REPLY, +}; + static struct req_format *req_formats[] = { &RQF_OBD_PING, &RQF_OBD_SET_INFO, @@ -791,6 +801,8 @@ static struct req_format *req_formats[] = { &RQF_LLOG_ORIGIN_HANDLE_READ_HEADER, &RQF_LLOG_ORIGIN_CONNECT, &RQF_CONNECT, + &RQF_LFSCK_NOTIFY, + &RQF_LFSCK_QUERY, }; struct req_msg_field { @@ -1191,6 +1203,17 @@ struct req_msg_field RMF_SWAP_LAYOUTS = DEFINE_MSGF("swap_layouts", 0, sizeof(struct mdc_swap_layouts), lustre_swab_swap_layouts, NULL); EXPORT_SYMBOL(RMF_SWAP_LAYOUTS); + +struct req_msg_field RMF_LFSCK_REQUEST = + DEFINE_MSGF("lfsck_request", 0, sizeof(struct lfsck_request), + lustre_swab_lfsck_request, NULL); +EXPORT_SYMBOL(RMF_LFSCK_REQUEST); + +struct req_msg_field RMF_LFSCK_REPLY = + DEFINE_MSGF("lfsck_reply", 0, sizeof(struct lfsck_reply), + lustre_swab_lfsck_reply, NULL); +EXPORT_SYMBOL(RMF_LFSCK_REPLY); + /* * Request formats. */ @@ -1663,6 +1686,14 @@ struct req_format RQF_OST_GET_INFO_FIEMAP = ost_get_fiemap_server); EXPORT_SYMBOL(RQF_OST_GET_INFO_FIEMAP); +struct req_format RQF_LFSCK_NOTIFY = + DEFINE_REQ_FMT0("LFSCK_NOTIFY", obd_lfsck_request, empty); +EXPORT_SYMBOL(RQF_LFSCK_NOTIFY); + +struct req_format RQF_LFSCK_QUERY = + DEFINE_REQ_FMT0("LFSCK_QUERY", obd_lfsck_request, obd_lfsck_reply); +EXPORT_SYMBOL(RQF_LFSCK_QUERY); + #if !defined(__REQ_LAYOUT_USER__) /* Convenience macro */ diff --git a/lustre/ptlrpc/lproc_ptlrpc.c b/lustre/ptlrpc/lproc_ptlrpc.c index 720d580..8e5a397 100644 --- a/lustre/ptlrpc/lproc_ptlrpc.c +++ b/lustre/ptlrpc/lproc_ptlrpc.c @@ -138,6 +138,8 @@ struct ll_rpc_opcode { { FLD_QUERY, "fld_query" }, { FLD_READ, "fld_read" }, { UPDATE_OBJ, "update_obj" }, + { LFSCK_NOTIFY, "lfsck_notify" }, + { LFSCK_QUERY, "lfsck_query" }, }; struct ll_eopcode { diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index f6569b3..94eebc2 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -289,6 +289,14 @@ void lustre_assert_wire_constants(void) (long long)SEQ_FIRST_OPC); LASSERTF(SEQ_LAST_OPC == 701, "found %lld\n", (long long)SEQ_LAST_OPC); + LASSERTF(LFSCK_NOTIFY == 1101, "found %lld\n", + (long long)LFSCK_NOTIFY); + LASSERTF(LFSCK_QUERY == 1102, "found %lld\n", + (long long)LFSCK_QUERY); + LASSERTF(LFSCK_FIRST_OPC == 1101, "found %lld\n", + (long long)LFSCK_FIRST_OPC); + LASSERTF(LFSCK_LAST_OPC == 1103, "found %lld\n", + (long long)LFSCK_LAST_OPC); LASSERTF(SEQ_ALLOC_SUPER == 0, "found %lld\n", (long long)SEQ_ALLOC_SUPER); LASSERTF(SEQ_ALLOC_META == 1, "found %lld\n", diff --git a/lustre/target/tgt_handler.c b/lustre/target/tgt_handler.c index 6f65b62..0883c4f 100644 --- a/lustre/target/tgt_handler.c +++ b/lustre/target/tgt_handler.c @@ -38,6 +38,7 @@ #include #include #include +#include #include "tgt_internal.h" @@ -1362,6 +1363,121 @@ TGT_SEC_HDL_VAR(0, SEC_CTX_FINI, tgt_sec_ctx_handle), }; EXPORT_SYMBOL(tgt_sec_ctx_handlers); +static int (*tgt_lfsck_start)(const struct lu_env *env, + struct dt_device *key, + struct lfsck_start_param *lsp) = NULL; + +void tgt_register_lfsck_start(int (*start)(const struct lu_env *, + struct dt_device *, + struct lfsck_start_param *)) +{ + tgt_lfsck_start = start; +} +EXPORT_SYMBOL(tgt_register_lfsck_start); + +int (*tgt_lfsck_in_notify)(const struct lu_env *env, + struct dt_device *key, + struct lfsck_request *lr) = NULL; + +void tgt_register_lfsck_in_notify(int (*notify)(const struct lu_env *, + struct dt_device *, + struct lfsck_request *)) +{ + tgt_lfsck_in_notify = notify; +} +EXPORT_SYMBOL(tgt_register_lfsck_in_notify); + +static int (*tgt_lfsck_query)(const struct lu_env *env, + struct dt_device *key, + struct lfsck_request *lr) = NULL; + +void tgt_register_lfsck_query(int (*query)(const struct lu_env *, + struct dt_device *, + struct lfsck_request *)) +{ + tgt_lfsck_query = query; +} +EXPORT_SYMBOL(tgt_register_lfsck_query); + +/* LFSCK request handlers */ +static int tgt_handle_lfsck_notify(struct tgt_session_info *tsi) +{ + const struct lu_env *env = tsi->tsi_env; + struct dt_device *key = tsi->tsi_tgt->lut_bottom; + struct lfsck_request *lr; + int rc; + ENTRY; + + lr = req_capsule_client_get(tsi->tsi_pill, &RMF_LFSCK_REQUEST); + if (lr == NULL) + RETURN(-EPROTO); + + switch (lr->lr_event) { + case LE_START: { + struct lfsck_start start; + struct lfsck_start_param lsp; + + start.ls_valid = lr->lr_valid; + start.ls_speed_limit = lr->lr_speed; + start.ls_version = lr->lr_version; + start.ls_active = lr->lr_active; + start.ls_flags = lr->lr_param; + start.ls_async_windows = lr->lr_async_windows; + + lsp.lsp_namespace = tsi->tsi_exp->exp_obd->obd_namespace; + lsp.lsp_start = &start; + lsp.lsp_index = lr->lr_index; + if (lr->lr_flags & LEF_TO_OST) + lsp.lsp_index_valid = 1; + else + lsp.lsp_index_valid = 0; + rc = tgt_lfsck_start(env, key, &lsp); + break; + } + case LE_STOP: + case LE_PHASE1_DONE: + case LE_PHASE2_DONE: + rc = tgt_lfsck_in_notify(env, key, lr); + break; + default: + CERROR("%s: unsupported lfsck_event: rc = %d\n", + tgt_name(tsi->tsi_tgt), lr->lr_event); + rc = -EOPNOTSUPP; + break; + } + + RETURN(rc); +} + +static int tgt_handle_lfsck_query(struct tgt_session_info *tsi) +{ + struct lfsck_request *request; + struct lfsck_reply *reply; + int rc = 0; + ENTRY; + + request = req_capsule_client_get(tsi->tsi_pill, &RMF_LFSCK_REQUEST); + if (request == NULL) + RETURN(-EPROTO); + + reply = req_capsule_server_get(tsi->tsi_pill, &RMF_LFSCK_REPLY); + if (reply == NULL) + RETURN(-ENOMEM); + + reply->lr_status = tgt_lfsck_query(tsi->tsi_env, + tsi->tsi_tgt->lut_bottom, request); + if (reply->lr_status < 0) + rc = reply->lr_status; + + RETURN(rc); +} + +struct tgt_handler tgt_lfsck_handlers[] = { +TGT_LFSCK_HDL(HABEO_REFERO, LFSCK_NOTIFY, tgt_handle_lfsck_notify), +TGT_LFSCK_HDL(HABEO_REFERO, LFSCK_QUERY, tgt_handle_lfsck_query), +}; +EXPORT_SYMBOL(tgt_lfsck_handlers); + /* * initialize per-thread page pool (bug 5137). */ diff --git a/lustre/target/tgt_internal.h b/lustre/target/tgt_internal.h index 130560f..cff6b41 100644 --- a/lustre/target/tgt_internal.h +++ b/lustre/target/tgt_internal.h @@ -43,6 +43,10 @@ #include #include +extern int (*tgt_lfsck_in_notify)(const struct lu_env *env, + struct dt_device *key, + struct lfsck_request *lr); + struct tx_arg; typedef int (*tx_exec_func_t)(const struct lu_env *env, struct thandle *th, struct tx_arg *ta); diff --git a/lustre/utils/req-layout.c b/lustre/utils/req-layout.c index ddf7d46..5c2d555 100644 --- a/lustre/utils/req-layout.c +++ b/lustre/utils/req-layout.c @@ -101,6 +101,8 @@ #define dump_ost_body NULL #define dump_rcs NULL #define lustre_swab_lmv_user_md NULL +#define lustre_swab_lfsck_request NULL +#define lustre_swab_lfsck_reply NULL /* * Yes, include .c file. diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index 0536384..ea07f4e 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -2259,6 +2259,11 @@ main(int argc, char **argv) CHECK_VALUE(SEQ_FIRST_OPC); CHECK_VALUE(SEQ_LAST_OPC); + CHECK_VALUE(LFSCK_NOTIFY); + CHECK_VALUE(LFSCK_QUERY); + CHECK_VALUE(LFSCK_FIRST_OPC); + CHECK_VALUE(LFSCK_LAST_OPC); + CHECK_VALUE(SEQ_ALLOC_SUPER); CHECK_VALUE(SEQ_ALLOC_META); diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 1dee792..0b54043 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -298,6 +298,14 @@ void lustre_assert_wire_constants(void) (long long)SEQ_FIRST_OPC); LASSERTF(SEQ_LAST_OPC == 701, "found %lld\n", (long long)SEQ_LAST_OPC); + LASSERTF(LFSCK_NOTIFY == 1101, "found %lld\n", + (long long)LFSCK_NOTIFY); + LASSERTF(LFSCK_QUERY == 1102, "found %lld\n", + (long long)LFSCK_QUERY); + LASSERTF(LFSCK_FIRST_OPC == 1101, "found %lld\n", + (long long)LFSCK_FIRST_OPC); + LASSERTF(LFSCK_LAST_OPC == 1103, "found %lld\n", + (long long)LFSCK_LAST_OPC); LASSERTF(SEQ_ALLOC_SUPER == 0, "found %lld\n", (long long)SEQ_ALLOC_SUPER); LASSERTF(SEQ_ALLOC_META == 1, "found %lld\n",