X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fosp%2Fosp_dev.c;h=45aff9f9906935364b3f22456d3d156e87e59f32;hp=27e301176e03a12dcdc3f19b9bfd6050f91c70f0;hb=d0ba82e44038b2658bbd1a06d52641fda9fc1fe7;hpb=9c255853668ed64dfdd8eec9b157f05c2b7832ed diff --git a/lustre/osp/osp_dev.c b/lustre/osp/osp_dev.c index 27e3011..45aff9f 100644 --- a/lustre/osp/osp_dev.c +++ b/lustre/osp/osp_dev.c @@ -471,15 +471,95 @@ static int osp_statfs(const struct lu_env *env, struct dt_device *dev, RETURN(0); } +static int osp_sync_timeout(void *data) +{ + return 1; +} + static int osp_sync(const struct lu_env *env, struct dt_device *dev) { + struct osp_device *d = dt2osp_dev(dev); + cfs_time_t expire; + struct l_wait_info lwi = { 0 }; + unsigned long id, old; + int rc = 0; + unsigned long start = cfs_time_current(); ENTRY; - /* - * XXX: wake up sync thread, command it to start flushing asap? - */ + if (unlikely(d->opd_imp_active == 0)) + RETURN(-ENOTCONN); - RETURN(0); + 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); } const struct dt_device_operations osp_dt_ops = {