static void osd_conf_get (const struct lu_env *env,
const struct dt_device *dev,
struct dt_device_param *param);
-static void osd_trans_stop (const struct lu_env *env,
+static int osd_trans_stop (const struct lu_env *env,
struct thandle *th);
static int osd_object_is_root(const struct osd_object *obj);
struct dt_device *dt);
static int osd_trans_start(const struct lu_env *env, struct dt_device *d,
struct thandle *th);
-static void osd_trans_stop(const struct lu_env *env, struct thandle *th);
static struct osd_object *osd_obj (const struct lu_object *o);
static struct osd_device *osd_dev (const struct lu_device *d);
/*
* Concurrency: shouldn't matter.
*/
-static void osd_trans_stop(const struct lu_env *env, struct thandle *th)
+static int osd_trans_stop(const struct lu_env *env, struct thandle *th)
{
struct osd_device *osd = osd_dt_dev(th->th_dev);
struct osd_thandle *oh;
udmu_tx_commit(oh->ot_tx);
if (0 && oh->ot_sync)
udmu_wait_synced(&osd->od_objset, oh->ot_tx);
- EXIT;
+
+ RETURN(result);
}
/*
/**
* Finish previously started transaction.
*/
- void (*dt_trans_stop)(const struct lu_env *env,
+ int (*dt_trans_stop)(const struct lu_env *env,
struct thandle *th);
/**
* Return fid of root index object.
return d->dd_ops->dt_trans_start(env, d, th);
}
-static inline void dt_trans_stop(const struct lu_env *env,
+static inline int dt_trans_stop(const struct lu_env *env,
struct dt_device *d,
struct thandle *th)
{
static void osd_conf_get (const struct lu_env *env,
const struct dt_device *dev,
struct dt_device_param *param);
-static void osd_trans_stop (const struct lu_env *env,
+static int osd_trans_stop (const struct lu_env *env,
struct thandle *th);
static int osd_object_is_root(const struct osd_object *obj);
/*
* Concurrency: shouldn't matter.
*/
-static void osd_trans_stop(const struct lu_env *env, struct thandle *th)
+static int osd_trans_stop(const struct lu_env *env, struct thandle *th)
{
- int result;
- struct osd_thandle *oh;
+ int result;
+ struct osd_thandle *oh;
struct osd_thread_info *oti = osd_oti_get(env);
+ struct filter_iobuf *iobuf = &oti->oti_iobuf;
ENTRY;
} else {
OBD_FREE_PTR(oh);
}
- EXIT;
+
+ /* as we want IO to journal and data IO be concurrent, we don't block
+ * awaiting data IO completion in osd_do_bio(), instead we wait here
+ * once transaction is submitted to the journal.
+ *
+ * IMPORTANT: we have to wait till any IO submited by the thread is
+ * completed otherwise iobuf may be corrupted by different request
+ */
+ wait_event(iobuf->dr_wait, atomic_read(&iobuf->dr_numreqs) == 0);
+ if (!result)
+ result = iobuf->dr_error;
+
+ RETURN(result);
}
/*
}
out:
- wait_event(iobuf->dr_wait, atomic_read(&iobuf->dr_numreqs) == 0);
+ /* in order to achieve better IO throughput, we don't wait for writes
+ * completion here. instead we proceed with transaction commit in
+ * parallel and wait for IO completion once transaction is stopped
+ * see osd_trans_stop() for more details -bzzz */
+ if (rw == OBD_BRW_WRITE)
+ wait_event(iobuf->dr_wait, atomic_read(&iobuf->dr_numreqs) == 0);
if (rc == 0)
rc = iobuf->dr_error;
/* preceding filemap_write_and_wait() should have clean pages */
#if 0
+ /* XXX */
if (fo->fo_writethrough_cache)
clear_page_dirty_for_io(lb[i].page);
#endif