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)) {