+ id = d->opd_syn_last_used_id;
+
+ CDEBUG(D_OTHER, "%s: id: used %lu, processed %lu\n",
+ d->opd_obd->obd_name, id, d->opd_syn_last_processed_id);
+
+ /* wait till all-in-line are processed */
+ while (d->opd_syn_last_processed_id < id) {
+
+ old = d->opd_syn_last_processed_id;
+
+ /* make sure the connection is fine */
+ expire = cfs_time_shift(obd_timeout);
+ lwi = LWI_TIMEOUT(expire - cfs_time_current(),
+ osp_sync_timeout, d);
+ l_wait_event(d->opd_syn_barrier_waitq,
+ d->opd_syn_last_processed_id >= id,
+ &lwi);
+
+ if (d->opd_syn_last_processed_id >= id)
+ break;
+
+ if (d->opd_syn_last_processed_id != old) {
+ /* some progress have been made,
+ * keep trying... */
+ continue;
+ }
+
+ /* no changes and expired, something is wrong */
+ GOTO(out, rc = -ETIMEDOUT);
+ }
+
+ /* block new processing (barrier>0 - few callers are possible */
+ atomic_inc(&d->opd_syn_barrier);
+
+ CDEBUG(D_OTHER, "%s: %u in flight\n", d->opd_obd->obd_name,
+ d->opd_syn_rpc_in_flight);
+
+ /* wait till all-in-flight are replied, so executed by the target */
+ /* XXX: this is used by LFSCK at the moment, which doesn't require
+ * all the changes to be committed, but in general it'd be
+ * better to wait till commit */
+ while (d->opd_syn_rpc_in_flight > 0) {
+
+ old = d->opd_syn_rpc_in_flight;
+
+ expire = cfs_time_shift(obd_timeout);
+ lwi = LWI_TIMEOUT(expire - cfs_time_current(),
+ osp_sync_timeout, d);
+ l_wait_event(d->opd_syn_barrier_waitq,
+ d->opd_syn_rpc_in_flight == 0, &lwi);
+
+ if (d->opd_syn_rpc_in_flight == 0)
+ break;
+
+ if (d->opd_syn_rpc_in_flight != old) {
+ /* some progress have been made */
+ continue;
+ }
+
+ /* no changes and expired, something is wrong */
+ GOTO(out, rc = -ETIMEDOUT);
+ }
+
+ CDEBUG(D_OTHER, "%s: done in %lu\n", d->opd_obd->obd_name,
+ cfs_time_current() - start);
+out:
+ /* resume normal processing (barrier=0) */
+ atomic_dec(&d->opd_syn_barrier);
+ __osp_sync_check_for_work(d);
+
+ RETURN(rc);