#include <linux/lustre_cmobd.h>
#include <linux/lprocfs_status.h>
#include <linux/obd_lov.h>
+#include <linux/obd_ost.h>
#include <linux/obd_lmv.h>
#include "cm_internal.h"
return lprocfs_obd_detach(obd);
}
-static inline int cmobd_lmv_obd(struct obd_device *obd)
+static inline int cmobd_md_obd(struct obd_device *obd)
{
- if (!strcmp(obd->obd_type->typ_name, LUSTRE_MDC_NAME) ||
+ if (!strcmp(obd->obd_type->typ_name, OBD_MDC_DEVICENAME) ||
!strcmp(obd->obd_type->typ_name, OBD_LMV_DEVICENAME))
return 1;
return 0;
}
-static inline int cmobd_lov_obd(struct obd_device *obd)
+static inline int cmobd_dt_obd(struct obd_device *obd)
{
- if (!strcmp(obd->obd_type->typ_name, OBD_LOV_DEVICENAME))
+ if (!strcmp(obd->obd_type->typ_name, OBD_LOV_DEVICENAME) ||
+ !strcmp(obd->obd_type->typ_name, OBD_OSC_DEVICENAME))
return 1;
return 0;
}
-static void cmobd_init_ea_size(struct obd_device *obd)
+static int cmobd_init_dt_desc(struct obd_device *obd)
{
- int ost_count = 1, easize, cookiesize;
+ struct cm_obd *cmobd = &obd->u.cm;
+ __u32 valsize;
+ int rc = 0;
+ ENTRY;
+
+ /* as CMOBD is stand alone device, that is has not to be connected, we
+ * have no other way to init EAs correctly but ask master device about
+ * it. Thus both, DT and MD layers should be able to answer with correct
+ * lov_desc. LOV knows it explicitly and LMV/MDC have to ask MDS server
+ * of it. */
+ valsize = sizeof(cmobd->master_desc);
+ memset(&cmobd->master_desc, 0, sizeof(cmobd->master_desc));
+
+ rc = obd_get_info(cmobd->master_exp, strlen("lovdesc") + 1,
+ "lovdesc", &valsize, &cmobd->master_desc);
+ RETURN(rc);
+}
+
+static int cmobd_init_ea_size(struct obd_device *obd)
+{
+ int rc = 0, tgt_count, easize, cookiesize;
struct cm_obd *cmobd = &obd->u.cm;
ENTRY;
- /*
- * here we should also take into account that there is possible to have
- * few OSTs. --umka
- */
- easize = lov_mds_md_size(ost_count);
- cookiesize = ost_count * sizeof(struct llog_cookie);
+ if (!cmobd->master_exp)
+ RETURN(-EINVAL);
- obd_init_ea_size(cmobd->master_exp, easize, cookiesize);
+ tgt_count = cmobd->master_desc.ld_tgt_count;
- cmobd->master_exp->exp_obd->u.cli.cl_max_mds_easize = easize;
- cmobd->master_exp->exp_obd->u.cli.cl_max_mds_cookiesize = cookiesize;
-
- EXIT;
+ /* no EA setup is needed as there is single OST with no LOV */
+ if (tgt_count == 0)
+ RETURN(0);
+
+ easize = lov_mds_md_size(tgt_count);
+ cookiesize = tgt_count * sizeof(struct llog_cookie);
+ rc = obd_init_ea_size(cmobd->master_exp, easize, cookiesize);
+ RETURN(rc);
}
+static char *types[] = {
+ OBD_LMV_DEVICENAME, OBD_MDC_DEVICENAME,
+ OBD_LOV_DEVICENAME, OBD_OSC_DEVICENAME
+};
+
static struct obd_device *
-find_master_obd(struct obd_device *obd, struct obd_uuid *uuid)
+cmobd_find_obd(struct obd_device *obd, struct obd_uuid *uuid)
{
- struct obd_device *master;
+ struct obd_device *res;
+ int i = 0;
+ ENTRY;
CWARN("%s: looking for client obd %s\n",
obd->obd_uuid.uuid, uuid->uuid);
- master = class_find_client_obd(NULL, OBD_LOV_DEVICENAME,
- uuid);
- if (master)
- return master;
-
- master = class_find_client_obd(NULL, OBD_LMV_DEVICENAME,
- uuid);
- if (master)
- return master;
-
- return class_find_client_obd(NULL, LUSTRE_MDC_NAME,
- uuid);
+ for (i = 0; i < sizeof(types) / sizeof(char *); i++) {
+ res = class_find_client_obd(NULL, types[i], uuid);
+ if (res)
+ RETURN(res);
+ }
+ RETURN(NULL);
}
static int cmobd_setup(struct obd_device *obd, obd_count len, void *buf)
struct cm_obd *cmobd = &obd->u.cm;
struct lustre_cfg* lcfg = buf;
struct lustre_id mid, lid;
- int valsize, rc;
+ __u32 valsize;
+ int rc;
ENTRY;
if (LUSTRE_CFG_BUFLEN(lcfg, 1) < 1) {
obd_str2uuid(&cache_uuid, lustre_cfg_string(lcfg, 2));
/* getting master obd */
- cmobd->master_obd = find_master_obd(obd, &master_uuid);
+ cmobd->master_obd = cmobd_find_obd(obd, &master_uuid);
if (!cmobd->master_obd) {
- CERROR("can't find master obd by uuid %s\n",
+ CERROR("can't find master client obd by uuid %s\n",
master_uuid.uuid);
RETURN(-EINVAL);
}
/* connecting master */
memset(&conn, 0, sizeof(conn));
- rc = obd_connect(&conn, cmobd->master_obd, &obd->obd_uuid, NULL, 0);
+ rc = obd_connect(&conn, cmobd->master_obd, &obd->obd_uuid,
+ NULL, OBD_OPT_REAL_CLIENT);
if (rc)
RETURN(rc);
cmobd->master_exp = class_conn2export(&conn);
if (rc)
GOTO(put_master, rc);
cmobd->cache_exp = class_conn2export(&conn);
-
- if (cmobd_lov_obd(cmobd->master_exp->exp_obd)) {
- /* for master osc remove the recovery flag. */
+
+ /* initialing DT desc. Both, data and metadata layers should be able to
+ * serve this call. */
+ rc = cmobd_init_dt_desc(obd);
+ if (rc != 0 && rc != -EPROTO) {
+ CERROR("cannot get DT layer desc from master device %s, "
+ "err %d.\n", cmobd->master_exp->exp_obd->obd_name,
+ rc);
+ GOTO(put_cache, rc);
+ }
+
+ if (cmobd_dt_obd(cmobd->master_exp->exp_obd)) {
+ /* for master dt device remove the recovery flag. */
rc = obd_set_info(cmobd->master_exp, strlen("unrecovery"),
"unrecovery", 0, NULL);
if (rc)
rc = cmobd_init_write_srv(obd);
if (rc)
GOTO(put_cache, rc);
- } else {
- cmobd_init_ea_size(obd);
- cmobd->write_srv = NULL;
}
- if (cmobd_lmv_obd(cmobd->master_exp->exp_obd)) {
- /*
- * making sure, that both obds are ready. This is especially
- * important in the case of using LMV as master.
- */
- rc = obd_getready(cmobd->master_exp);
+ if (cmobd_md_obd(cmobd->master_exp->exp_obd)) {
+ rc = cmobd_init_ea_size(obd);
if (rc) {
- CERROR("can't get %s obd ready.\n",
- master_uuid.uuid);
+ CERROR("can't init MD layer EA size, "
+ "err %d\n", rc);
GOTO(put_cache, rc);
}
-
- rc = obd_getready(cmobd->cache_exp);
- if (rc) {
- CERROR("can't get %s obd ready.\n",
- cache_uuid.uuid);
- GOTO(put_cache, rc);
- }
-
- /*
- * requesting master obd to have its root inode store cookie to
- * be able to save it to local root inode EA.
- */
+ cmobd->write_srv = NULL;
+
+ /* requesting master obd to have its root inode store cookie to
+ * be able to save it to local root inode EA. */
valsize = sizeof(struct lustre_id);
rc = obd_get_info(cmobd->master_exp, strlen("rootid"),
GOTO(put_cache, rc);
}
- /*
- * getting rootid from cache MDS. It is needed to update local
- * (cache) root inode by rootid value from master obd.
- */
+ /* getting rootid from cache MDS. It is needed to update local
+ * (cache) root inode by rootid value from master obd. */
rc = obd_get_info(cmobd->cache_exp, strlen("rootid"),
"rootid", &valsize, &lid);
if (rc) {
rc = obd_disconnect(cmobd->master_exp, flags);
if (rc) {
- CERROR("error disconnecting master, err %d\n",
- rc);
+ CERROR("error disconnecting master %s, err %d\n",
+ cmobd->master_exp->exp_obd->obd_name, rc);
}
rc = class_disconnect(cmobd->cache_exp, flags);
if (rc) {
- CERROR("error disconnecting cache, err %d\n",
- rc);
+ CERROR("error disconnecting cache %s, err %d\n",
+ cmobd->cache_exp->exp_obd->obd_name, rc);
}
RETURN(0);
}
static struct obd_ops cmobd_ops = {
- o_owner: THIS_MODULE,
- o_attach: cmobd_attach,
- o_detach: cmobd_detach,
- o_setup: cmobd_setup,
- o_cleanup: cmobd_cleanup,
- o_iocontrol: cmobd_iocontrol,
+ .o_owner = THIS_MODULE,
+ .o_attach = cmobd_attach,
+ .o_detach = cmobd_detach,
+ .o_setup = cmobd_setup,
+ .o_cleanup = cmobd_cleanup,
+ .o_iocontrol = cmobd_iocontrol,
};
kmem_cache_t *cmobd_extent_slab;
lprocfs_init_vars(cmobd, &lvars);
rc = class_register_type(&cmobd_ops, NULL, lvars.module_vars,
- LUSTRE_CMOBD_NAME);
+ OBD_CMOBD_DEVICENAME);
if (rc)
RETURN(rc);
cmobd_extent_slab = kmem_cache_create("cmobd_extents",
sizeof(struct cmobd_extent_info), 0,
SLAB_HWCACHE_ALIGN, NULL, NULL);
if (cmobd_extent_slab == NULL) {
- class_unregister_type(LUSTRE_CMOBD_NAME);
+ class_unregister_type(OBD_CMOBD_DEVICENAME);
RETURN(-ENOMEM);
}
RETURN(0);
static void __exit cmobd_exit(void)
{
- class_unregister_type(LUSTRE_CMOBD_NAME);
+ class_unregister_type(OBD_CMOBD_DEVICENAME);
if (kmem_cache_destroy(cmobd_extent_slab) != 0)
CERROR("couldn't free cmobd extent slab\n");
}