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;
+ }
}
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))
#include <lustre_export.h>
#include <lustre_update.h>
#include <lustre_disk.h>
+#include <lustre_lfsck.h>
struct lu_target {
struct obd_device *lut_obd;
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[];
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, \
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
*/
};
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 {
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,
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);
#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
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;
/* 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__ */
#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
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 */
/* 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;
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;
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;
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);
}
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);
}
&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,
.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 = {
.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)
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;
}
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);
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);
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)
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;
}
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);
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;
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,
.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,
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);
}
}
.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
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)
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);
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);
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: {
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",
.tos_hs = seq_handlers
},
{
+ .tos_opc_start = LFSCK_FIRST_OPC,
+ .tos_opc_end = LFSCK_LAST_OPC,
+ .tos_hs = tgt_lfsck_handlers
+ },
+ {
.tos_hs = NULL
}
};
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);
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:
&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,
&RQF_LLOG_ORIGIN_HANDLE_READ_HEADER,
&RQF_LLOG_ORIGIN_CONNECT,
&RQF_CONNECT,
+ &RQF_LFSCK_NOTIFY,
+ &RQF_LFSCK_QUERY,
};
struct req_msg_field {
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.
*/
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 */
{ FLD_QUERY, "fld_query" },
{ FLD_READ, "fld_read" },
{ UPDATE_OBJ, "update_obj" },
+ { LFSCK_NOTIFY, "lfsck_notify" },
+ { LFSCK_QUERY, "lfsck_query" },
};
struct ll_eopcode {
(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",
#include <obd_class.h>
#include <obd_cksum.h>
#include <md_object.h>
+#include <lustre_lfsck.h>
#include "tgt_internal.h"
};
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).
*/
#include <lustre_req_layout.h>
#include <lustre_sec.h>
+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);
#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.
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);
(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",