diff --git a/lustre/include/lustre_export.h b/lustre/include/lustre_export.h index c0074241f6331e47ad43d46719878d54cc3a7f3c..291e85c3f25721f82484cada33723b3af247d5fe 100644 --- a/lustre/include/lustre_export.h +++ b/lustre/include/lustre_export.h @@ -101,6 +101,12 @@ typedef struct nid_stat { int nid_exp_ref_count; } nid_stat_t; +enum obd_option { + OBD_OPT_FORCE = 0x0001, + OBD_OPT_FAILOVER = 0x0002, + OBD_OPT_ABORT_RECOV = 0x0004, +}; + struct obd_export { struct portals_handle exp_handle; atomic_t exp_refcount; @@ -126,7 +132,7 @@ struct obd_export { spinlock_t exp_lock; /* protects flags int below */ /* ^ protects exp_outstanding_replies too */ __u64 exp_connect_flags; - int exp_flags; + enum obd_option exp_flags; unsigned long exp_failed:1, exp_disconnected:1, exp_connecting:1, diff --git a/lustre/include/obd.h b/lustre/include/obd.h index 314e6959440430c10f1dbd296893c338f4294b9b..71f38ad345b87d694054361ab8e93cee8538d6ec 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -904,9 +904,6 @@ struct obd_device { __u64 obd_pool_slv; }; -#define OBD_OPT_FORCE 0x0001 -#define OBD_OPT_FAILOVER 0x0002 - #define OBD_LLOG_FL_SENDNOW 0x0001 enum obd_cleanup_stage { diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h index babf7eb02a5126a6f932f30afe07fa3cd9231e9d..67aca5f79c1233996f32903de6954e815a943ade 100644 --- a/lustre/include/obd_class.h +++ b/lustre/include/obd_class.h @@ -220,9 +220,18 @@ int class_connect(struct lustre_handle *conn, struct obd_device *obd, int class_disconnect(struct obd_export *exp); void class_fail_export(struct obd_export *exp); void class_disconnect_exports(struct obd_device *obddev); -void class_disconnect_stale_exports(struct obd_device *obddev); +void class_disconnect_stale_exports(struct obd_device *obddev, + enum obd_option flags); int class_manual_cleanup(struct obd_device *obd); +static inline enum obd_option exp_flags_from_obd(struct obd_device *obd) +{ + return ((obd->obd_fail ? OBD_OPT_FAILOVER : 0) | + (obd->obd_force ? OBD_OPT_FORCE : 0) | + (obd->obd_abort_recovery ? OBD_OPT_ABORT_RECOV : 0) | + 0); +} + /* obdo.c */ void obdo_cpy_md(struct obdo *dst, struct obdo *src, obd_flag valid); void obdo_to_ioobj(struct obdo *oa, struct obd_ioobj *ioobj); diff --git a/lustre/ldlm/ldlm_lib.c b/lustre/ldlm/ldlm_lib.c index c91c71d76e440a0cf1b8c2e5256bede432296913..52f69b8ec939da38978b40ce34da62b88dd1cb85 100644 --- a/lustre/ldlm/ldlm_lib.c +++ b/lustre/ldlm/ldlm_lib.c @@ -1131,6 +1131,7 @@ void target_cleanup_recovery(struct obd_device *obd) void target_abort_recovery(void *data) { struct obd_device *obd = data; + enum obd_option flags; ENTRY; spin_lock_bh(&obd->obd_processing_task_lock); @@ -1139,6 +1140,7 @@ void target_abort_recovery(void *data) EXIT; return; } + flags = exp_flags_from_obd(obd) | OBD_OPT_ABORT_RECOV; obd->obd_recovering = obd->obd_abort_recovery = 0; target_cancel_recovery_timer(obd); spin_unlock_bh(&obd->obd_processing_task_lock); @@ -1148,7 +1150,7 @@ void target_abort_recovery(void *data) obd->obd_name, obd->obd_recoverable_clients, cfs_time_current_sec()- obd->obd_recovery_start, obd->obd_connected_clients); - class_disconnect_stale_exports(obd); + class_disconnect_stale_exports(obd, flags); abort_recovery_queue(obd); target_finish_recovery(obd); diff --git a/lustre/mds/mds_fs.c b/lustre/mds/mds_fs.c index d317a57602b02fdeef161a6a17421abef11a23e6..1dd0c34b4709fa32ed9bb0cf91cf89055cbf99b1 100644 --- a/lustre/mds/mds_fs.c +++ b/lustre/mds/mds_fs.c @@ -220,12 +220,13 @@ int mds_client_add(struct obd_device *obd, struct obd_export *exp, return 0; } +struct lsd_client_data zero_lcd; /* globals are implicitly zeroed */ + int mds_client_free(struct obd_export *exp) { struct mds_export_data *med = &exp->exp_mds_data; struct mds_obd *mds = &exp->exp_obd->u.mds; struct obd_device *obd = exp->exp_obd; - struct lsd_client_data zero_lcd; struct lvfs_run_ctxt *saved = NULL; int rc; loff_t off; @@ -263,22 +264,32 @@ int mds_client_free(struct obd_export *exp) } if (!(exp->exp_flags & OBD_OPT_FAILOVER)) { + /* Don't force sync on each disconnect if aborting recovery, + * or it does num_clients * num_osts syncs. b=17194 */ + int need_sync = (!exp->exp_libclient || exp->exp_need_sync) && + !(exp->exp_flags & OBD_OPT_ABORT_RECOV); + OBD_SLAB_ALLOC_PTR(saved, obd_lvfs_ctxt_cache); if (saved == NULL) { CERROR("cannot allocate memory for run ctxt\n"); GOTO(free, rc = -ENOMEM); } - memset(&zero_lcd, 0, sizeof(zero_lcd)); push_ctxt(saved, &obd->obd_lvfs_ctxt, NULL); rc = fsfilt_write_record(obd, mds->mds_rcvd_filp, &zero_lcd, - sizeof(zero_lcd), &off, - (!exp->exp_libclient || - exp->exp_need_sync)); + sizeof(zero_lcd), &off, 0); + + /* Make sure the server's last_transno is up to date. Do this + * after the client is freed so we know all the client's + * transactions have been committed. */ + if (rc == 0) + mds_update_server_data(exp->exp_obd, need_sync); + pop_ctxt(saved, &obd->obd_lvfs_ctxt, NULL); CDEBUG(rc == 0 ? D_INFO : D_ERROR, - "zeroing out client %s idx %u in %s rc %d\n", - med->med_lcd->lcd_uuid, med->med_lr_idx, LAST_RCVD, rc); + "zero out client %s at idx %u/%llu in %s %ssync rc %d\n", + med->med_lcd->lcd_uuid, med->med_lr_idx, med->med_lr_off, + LAST_RCVD, need_sync ? "" : "a", rc); } if (!test_and_clear_bit(med->med_lr_idx, mds->mds_client_bitmap)) { @@ -287,12 +298,6 @@ int mds_client_free(struct obd_export *exp) LBUG(); } - - /* Make sure the server's last_transno is up to date. Do this - * after the client is freed so we know all the client's - * transactions have been committed. */ - mds_update_server_data(exp->exp_obd, 0); - EXIT; free: if (saved) diff --git a/lustre/obdclass/genops.c b/lustre/obdclass/genops.c index 76d56762c3a2b36c3efbc15790239e8116274e2d..975414d08d523246d02248d91fcf889145ff0dfe 100644 --- a/lustre/obdclass/genops.c +++ b/lustre/obdclass/genops.c @@ -960,7 +960,8 @@ int class_disconnect(struct obd_export *export) RETURN(0); } -static void class_disconnect_export_list(struct list_head *list, int flags) +static void class_disconnect_export_list(struct list_head *list, + enum obd_option flags) { int rc; struct lustre_handle fake_conn; @@ -1010,12 +1011,6 @@ static void class_disconnect_export_list(struct list_head *list, int flags) EXIT; } -static inline int get_exp_flags_from_obd(struct obd_device *obd) -{ - return ((obd->obd_fail ? OBD_OPT_FAILOVER : 0) | - (obd->obd_force ? OBD_OPT_FORCE : 0)); -} - void class_disconnect_exports(struct obd_device *obd) { struct list_head work_list; @@ -1029,14 +1024,15 @@ void class_disconnect_exports(struct obd_device *obd) CDEBUG(D_HA, "OBD device %d (%p) has exports, " "disconnecting them\n", obd->obd_minor, obd); - class_disconnect_export_list(&work_list, get_exp_flags_from_obd(obd)); + class_disconnect_export_list(&work_list, exp_flags_from_obd(obd)); EXIT; } EXPORT_SYMBOL(class_disconnect_exports); /* Remove exports that have not completed recovery. */ -void class_disconnect_stale_exports(struct obd_device *obd) +void class_disconnect_stale_exports(struct obd_device *obd, + enum obd_option flags) { struct list_head work_list; struct list_head *pos, *n; @@ -1058,7 +1054,7 @@ void class_disconnect_stale_exports(struct obd_device *obd) CDEBUG(D_ERROR, "%s: disconnecting %d stale clients\n", obd->obd_name, cnt); - class_disconnect_export_list(&work_list, get_exp_flags_from_obd(obd)); + class_disconnect_export_list(&work_list, flags); EXIT; } EXPORT_SYMBOL(class_disconnect_stale_exports); diff --git a/lustre/obdclass/obd_config.c b/lustre/obdclass/obd_config.c index ccb7a69c9c8311df04c632e5633b02507b9938e1..8745560d0f13259739d11065fa7756e04f8d45b4 100644 --- a/lustre/obdclass/obd_config.c +++ b/lustre/obdclass/obd_config.c @@ -537,9 +537,7 @@ void class_decref(struct obd_device *obd) obd->obd_name, err); spin_lock(&obd->obd_self_export->exp_lock); - obd->obd_self_export->exp_flags |= - (obd->obd_fail ? OBD_OPT_FAILOVER : 0) | - (obd->obd_force ? OBD_OPT_FORCE : 0); + obd->obd_self_export->exp_flags |= exp_flags_from_obd(obd); spin_unlock(&obd->obd_self_export->exp_lock); /* note that we'll recurse into class_decref again */ diff --git a/lustre/obdfilter/filter.c b/lustre/obdfilter/filter.c index 2573ceea404ab04bda7b0a0c817dc96a9e136a85..f10f7e5eaf7eca7d7bd321aa38255df9494fdbcb 100644 --- a/lustre/obdfilter/filter.c +++ b/lustre/obdfilter/filter.c @@ -359,12 +359,13 @@ static int filter_client_add(struct obd_device *obd, struct obd_export *exp, RETURN(0); } +struct lsd_client_data zero_lcd; /* globals are implicitly zeroed */ + static int filter_client_free(struct obd_export *exp) { struct filter_export_data *fed = &exp->exp_filter_data; struct filter_obd *filter = &exp->exp_obd->u.filter; struct obd_device *obd = exp->exp_obd; - struct lsd_client_data zero_lcd; struct lvfs_run_ctxt saved; int rc; loff_t off; @@ -401,24 +402,27 @@ static int filter_client_free(struct obd_export *exp) } if (!(exp->exp_flags & OBD_OPT_FAILOVER)) { - memset(&zero_lcd, 0, sizeof(zero_lcd)); + /* Don't force sync on disconnect if aborting recovery, + * or it does num_clients * num_osts. b=17194 */ + int need_sync = (!exp->exp_libclient || exp->exp_need_sync) && + !(exp->exp_flags&OBD_OPT_ABORT_RECOV); + push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); rc = fsfilt_write_record(obd, filter->fo_rcvd_filp, &zero_lcd, - sizeof(zero_lcd), &off, - (!exp->exp_libclient || - exp->exp_need_sync)); + sizeof(zero_lcd), &off, 0); + /* Make sure the server's last_transno is up to date. Do this + * after the client is freed so we know all the client's + * transactions have been committed. */ if (rc == 0) - /* update server's transno */ filter_update_server_data(obd, filter->fo_rcvd_filp, - filter->fo_fsd, - !exp->exp_libclient); + filter->fo_fsd, need_sync); pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL); CDEBUG(rc == 0 ? D_INFO : D_ERROR, - "zeroing out client %s at idx %u (%llu) in %s rc %d\n", + "zero out client %s at idx %u/%llu in %s %ssync rc %d\n", fed->fed_lcd->lcd_uuid, fed->fed_lr_idx, fed->fed_lr_off, - LAST_RCVD, rc); + LAST_RCVD, need_sync ? "" : "a", rc); } if (!test_and_clear_bit(fed->fed_lr_idx, filter->fo_last_rcvd_slots)) {