#include <obd_class.h>
#include <lustre_fid.h>
#include <lustre_param.h>
+#include <lustre_update.h>
#include "lod_internal.h"
* \param lod LOD to be lookup at.
* \param fid FID of object to find MDT/OST.
* \param tgt MDT/OST index to return.
- * \param flags indidcate the FID is on MDS or OST.
+ * \param type indidcate the FID is on MDS or OST.
**/
int lod_fld_lookup(const struct lu_env *env, struct lod_device *lod,
- const struct lu_fid *fid, __u32 *tgt, int flags)
+ const struct lu_fid *fid, __u32 *tgt, int type)
{
- struct lu_seq_range range;
+ struct lu_seq_range range = { 0 };
struct lu_server_fld *server_fld;
int rc = 0;
ENTRY;
RETURN(rc);
}
- if (!lod->lod_initialized || !fid_is_norm(fid)) {
+ if (!lod->lod_initialized || (!fid_seq_in_fldb(fid_seq(fid)))) {
LASSERT(lu_site2seq(lod2lu_dev(lod)->ld_site) != NULL);
*tgt = lu_site2seq(lod2lu_dev(lod)->ld_site)->ss_node_id;
RETURN(rc);
}
server_fld = lu_site2seq(lod2lu_dev(lod)->ld_site)->ss_server_fld;
- range.lsr_flags = flags;
+ fld_range_set_type(&range, type);
rc = fld_server_lookup(env, server_fld, fid_seq(fid), &range);
if (rc) {
CERROR("%s: Can't find tgt by seq "LPX64", rc %d\n",
GOTO(out, rc);
}
case LCFG_CLEANUP:
+ case LCFG_PRE_CLEANUP: {
lu_dev_del_linkage(dev->ld_site, dev);
lod_cleanup_desc_tgts(env, lod, &lod->lod_mdt_descs, lcfg);
lod_cleanup_desc_tgts(env, lod, &lod->lod_ost_descs, lcfg);
lod_seq_fini_cli(lod);
+
+ if (lcfg->lcfg_command == LCFG_PRE_CLEANUP)
+ break;
/*
* do cleanup on underlying storage only when
* all OSPs are cleaned up, as they use that OSD as well
if (rc)
CERROR("error in disconnect from storage: %d\n", rc);
break;
-
+ }
default:
CERROR("%s: unknown command %u\n", lod2obd(lod)->obd_name,
lcfg->lcfg_command);
static struct thandle *lod_trans_create(const struct lu_env *env,
struct dt_device *dev)
{
- return dt_trans_create(env, dt2lod_dev(dev)->lod_child);
+ struct thandle *th;
+
+ th = dt_trans_create(env, dt2lod_dev(dev)->lod_child);
+ if (IS_ERR(th))
+ return th;
+
+ CFS_INIT_LIST_HEAD(&th->th_remote_update_list);
+ return th;
+}
+
+static int lod_remote_sync(const struct lu_env *env, struct dt_device *dev,
+ struct thandle *th)
+{
+ struct update_request *update;
+ int rc = 0;
+ ENTRY;
+
+ if (cfs_list_empty(&th->th_remote_update_list))
+ RETURN(0);
+
+ cfs_list_for_each_entry(update, &th->th_remote_update_list,
+ ur_list) {
+ /* In DNE phase I, there should be only one OSP
+ * here, so we will do send/receive one by one,
+ * instead of sending them parallel, will fix this
+ * in Phase II */
+ th->th_current_request = update;
+ rc = dt_trans_start(env, update->ur_dt, th);
+ if (rc != 0) {
+ /* FIXME how to revert the partial results
+ * once error happened? Resolved by 2 Phase commit */
+ update->ur_rc = rc;
+ break;
+ }
+ }
+
+ RETURN(rc);
}
static int lod_trans_start(const struct lu_env *env, struct dt_device *dev,
struct thandle *th)
{
- return dt_trans_start(env, dt2lod_dev(dev)->lod_child, th);
+ struct lod_device *lod = dt2lod_dev((struct dt_device *) dev);
+ int rc;
+
+ rc = lod_remote_sync(env, dev, th);
+ if (rc)
+ return rc;
+
+ return dt_trans_start(env, lod->lod_child, th);
}
static int lod_trans_stop(const struct lu_env *env, struct thandle *th)
{
- /* XXX: we don't know next device, will be fixed with DNE */
- return dt_trans_stop(env, th->th_dev, th);
+ struct update_request *update;
+ struct update_request *tmp;
+ int rc = 0;
+ int rc2 = 0;
+
+ cfs_list_for_each_entry_safe(update, tmp,
+ &th->th_remote_update_list,
+ ur_list) {
+ th->th_current_request = update;
+ rc2 = dt_trans_stop(env, update->ur_dt, th);
+ if (unlikely(rc2 != 0 && rc == 0))
+ rc = rc2;
+ }
+
+ rc2 = dt_trans_stop(env, th->th_dev, th);
+
+ return rc2 != 0 ? rc2 : rc;
}
static void lod_conf_get(const struct lu_env *env,