Whamcloud - gitweb
LU-1267 lfsck: enhance RPCs (1) for MDT-OST consistency 23/8623/21
authorFan Yong <fan.yong@intel.com>
Fri, 24 Jan 2014 19:42:48 +0000 (03:42 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 3 Feb 2014 01:29:07 +0000 (01:29 +0000)
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 <fan.yong@intel.com>
Change-Id: I8529f1a3f5f7f9589101f456f0397c8ebe11df18
Reviewed-on: http://review.whamcloud.com/8623
Tested-by: Jenkins
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
23 files changed:
lustre/include/lprocfs_status.h
lustre/include/lu_target.h
lustre/include/lustre/lustre_idl.h
lustre/include/lustre_lfsck.h
lustre/include/lustre_lib.h
lustre/include/lustre_req_layout.h
lustre/include/obd_support.h
lustre/lfsck/lfsck_internal.h
lustre/lfsck/lfsck_layout.c
lustre/lfsck/lfsck_lib.c
lustre/lfsck/lfsck_namespace.c
lustre/mdd/mdd_device.c
lustre/mdt/mdt_handler.c
lustre/ofd/ofd_dev.c
lustre/ofd/ofd_obd.c
lustre/ptlrpc/layout.c
lustre/ptlrpc/lproc_ptlrpc.c
lustre/ptlrpc/wiretest.c
lustre/target/tgt_handler.c
lustre/target/tgt_internal.h
lustre/utils/req-layout.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index 70f10a9..ffb85ca 100644 (file)
@@ -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))
index 9d952bf..02f7e0b 100644 (file)
@@ -41,6 +41,7 @@
 #include <lustre_export.h>
 #include <lustre_update.h>
 #include <lustre_disk.h>
+#include <lustre_lfsck.h>
 
 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,     \
index 207fe8d..d1f867f 100644 (file)
@@ -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
  */
index ccf9fb5..7a14fdc 100644 (file)
@@ -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);
index 9ba7cd8..5a86378 100644 (file)
@@ -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
index 5bdfe0d..936476e 100644 (file)
@@ -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__ */
index 5ecdaab..24671c3 100644 (file)
@@ -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
index 038c350..5e2a144 100644 (file)
@@ -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;
index 39cffe3..908ed89 100644 (file)
@@ -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)
index 6939cde..d59a07a 100644 (file)
@@ -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;
 }
index d030528..36089aa 100644 (file)
@@ -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,
index 3a90cff..11f1a82 100644 (file)
@@ -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);
        }
         }
index ed52643..4c386b1 100644 (file)
@@ -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: {
index ea5d166..8664523 100644 (file)
@@ -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);
index ec55834..61b1610 100644 (file)
@@ -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:
index 008f49d..13b10e7 100644 (file)
@@ -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 */
index 720d580..8e5a397 100644 (file)
@@ -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 {
index f6569b3..94eebc2 100644 (file)
@@ -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",
index 6f65b62..0883c4f 100644 (file)
@@ -38,6 +38,7 @@
 #include <obd_class.h>
 #include <obd_cksum.h>
 #include <md_object.h>
+#include <lustre_lfsck.h>
 
 #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).
  */
index 130560f..cff6b41 100644 (file)
 #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);
index ddf7d46..5c2d555 100644 (file)
 #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.
index 0536384..ea07f4e 100644 (file)
@@ -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);
 
index 1dee792..0b54043 100644 (file)
@@ -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",