list_add_tail(&mc->mc_linkage, &cm->cmm_targets);
cm->cmm_tgt_count++;
spin_unlock(&cm->cmm_tgt_guard);
-
+
lu_device_get(cmm2lu_dev(cm));
fld_client_add_export(&cm->cmm_fld,
int err = 0;
ENTRY;
-
+
spin_lock_init(&m->cmm_tgt_guard);
INIT_LIST_HEAD(&m->cmm_targets);
m->cmm_tgt_count = 0;
err = fld_client_init(&m->cmm_fld, LUSTRE_CLI_FLD_HASH_RRB);
if (err) {
CERROR("can't init FLD, err %d\n", err);
- }
+ } else
+ m->cmm_flags |= CMM_INITIALIZED;
RETURN(err);
}
struct cmm_device *cm = lu2cmm_dev(ld);
struct mdc_device *mc, *tmp;
ENTRY;
-
+
fld_client_fini(&cm->cmm_fld);
/* finish all mdc devices */
list_for_each_entry_safe(mc, tmp, &cm->cmm_targets, mc_linkage) {
struct cmm_device {
struct md_device cmm_md_dev;
+ /* device flags, taken from enum cmm_flags */
+ __u32 cmm_flags;
/* underlaying device in MDS stack, usually MDD */
struct md_device *cmm_child;
/* other MD servers in cluster */
struct lu_client_fld cmm_fld;
};
+enum cmm_flags {
+ /*
+ * Device initialization complete.
+ */
+ CMM_INITIALIZED = 1 << 0
+};
+
static inline struct md_device_operations *cmm_child_ops(struct cmm_device *d)
{
return (d->cmm_child->md_ops);
{
struct lu_object *lo = NULL;
const struct lu_fid *fid = &loh->loh_fid;
+ struct cmm_device *cd;
int mdsnum;
ENTRY;
- /* get object location */
- mdsnum = cmm_fld_lookup(lu2cmm_dev(ld), fid);
+ cd = lu2cmm_dev(ld);
+ if (cd->cmm_flags & CMM_INITIALIZED) {
+ /* get object location */
+ mdsnum = cmm_fld_lookup(lu2cmm_dev(ld), fid);
+ if (mdsnum < 0)
+ RETURN(ERR_PTR(mdsnum));
+ } else
+ /*
+ * Device is not yet initialized, cmm_object is being created
+ * as part of early bootstrap procedure (it is /ROOT, or /fld,
+ * etc.). Such object *has* to be local.
+ */
+ mdsnum = cd->cmm_local_num;
/* select the proper set of operations based on object location */
- if (mdsnum == lu2cmm_dev(ld)->cmm_local_num) {
+ if (mdsnum == cd->cmm_local_num) {
struct cml_object *clo;
OBD_ALLOC_PTR(clo);
}
} else {
struct cmr_object *cro;
-
+
OBD_ALLOC_PTR(cro);
if (cro != NULL) {
lo = &cro->cmm_obj.cmo_obj.mo_lu;
}
/*
- * CMM has two types of objects - local and remote. They have different set
+ * CMM has two types of objects - local and remote. They have different set
* of operations so we are avoiding multiple checks in code.
*/
}
rc = mdo_rename(ctx, cmm2child_obj(md2cmm_obj(mo_po)),
- cmm2child_obj(md2cmm_obj(mo_pn)), lf, s_name,
+ cmm2child_obj(md2cmm_obj(mo_pn)), lf, s_name,
cmm2child_obj(md2cmm_obj(mo_t)), t_name);
RETURN(rc);
{
struct lu_device *next = NULL;
struct mdc_device *mdc;
-
+
spin_lock(&d->cmm_tgt_guard);
list_for_each_entry(mdc, &d->cmm_targets, mc_linkage) {
if (mdc->mc_num == num) {
int rc;
ENTRY;
-
+
c_dev = cmr_child_dev(cd, lu2cmr_obj(lo)->cmo_num);
if (c_dev == NULL) {
rc = -ENOENT;
{
/*this can happens while rename()
* If new parent is remote dir, lookup will happens here */
-
+
RETURN(-EREMOTE);
}
rc = mdo_rename_tgt(ctx, cmm2child_obj(md2cmm_obj(mo_pn)), NULL/* mo_t */,
lf, t_name);
/* only old name is removed localy */
- if (rc == 0)
+ if (rc == 0)
rc = mdo_name_remove(ctx, cmm2child_obj(md2cmm_obj(mo_po)),
- s_name);
+ s_name);
RETURN(rc);
}