static struct md_device_operations cmm_md_ops = {
.mdo_root_get = cmm_root_get,
+ .mdo_config = cmm_config,
.mdo_statfs = cmm_statfs,
.mdo_mkdir = cmm_mkdir,
// .mdo_rename = cmm_rename,
int cmm_object_print(struct seq_file *f, const struct lu_object *o);
/* cmm md operations */
+int cmm_config(struct md_device *md, const char *name,
+ void *buf, int size, int mode);
int cmm_root_get(struct md_device *m, struct lu_fid *f);
int cmm_statfs(struct md_device *m, struct kstatfs *sfs);
int cmm_mkdir(struct md_object *o, const char *name,
return result;
}
+int cmm_config(struct md_device *md, const char *name,
+ void *buf, int size, int mode)
+{
+ struct cmm_device *cmm_dev = md2cmm_dev(md);
+ int result = -EOPNOTSUPP;
+ ENTRY;
+
+ if (CMM_CHILD_OPS(cmm_dev) && CMM_CHILD_OPS(cmm_dev)->mdo_statfs)
+ result = CMM_CHILD_OPS(cmm_dev)->mdo_config(cmm_dev->cmm_child,
+ name, buf, size, mode);
+
+ RETURN(result);
+}
+
int cmm_statfs(struct md_device *md, struct kstatfs *sfs) {
struct cmm_device *cmm_dev = md2cmm_dev(md);
int result = -EOPNOTSUPP;
struct dt_device;
struct dt_device_operations {
+ /* method for getting/setting device wide back stored config data, like
+ * last used meta-sequence, etc. */
+ int (*dt_config) (struct dt_device *dev, const char *name,
+ void *buf, int size, int mode);
+
int (*dt_statfs)(struct dt_device *dev, struct kstatfs *sfs);
void (*dt_object_lock)(struct dt_object *dt, enum dt_lock_mode mode);
void (*dt_object_unlock)(struct dt_object *dt, enum dt_lock_mode mode);
#define OBD_OCD_VERSION_PATCH(version) ((int)((version)>>8)&255)
#define OBD_OCD_VERSION_FIX(version) ((int)(version)&255)
-/* This structure is used for both request and reply.
- *
- * If we eventually have separate connect data for different types, which we
- * almost certainly will, then perhaps we stick a union in here. */
-struct obd_connect_data {
- __u64 ocd_connect_flags; /* OBD_CONNECT_* per above */
- __u32 ocd_version; /* lustre release version number */
- __u32 ocd_grant; /* initial cache grant amount (bytes) */
- __u32 ocd_index; /* LOV index to connect to */
- __u32 ocd_unused;
- __u64 ocd_ibits_known; /* inode bits this client understands */
- __u64 padding2; /* also fix lustre_swab_connect */
- __u64 padding3; /* also fix lustre_swab_connect */
- __u64 padding4; /* also fix lustre_swab_connect */
- __u64 padding5; /* also fix lustre_swab_connect */
- __u64 padding6; /* also fix lustre_swab_connect */
-};
-
-extern void lustre_swab_connect(struct obd_connect_data *ocd);
-
/*
* OST requests: OBDO & OBD request records
*/
/* This FULL lock is useful to take on unlink sort of operations */
#define MDS_INODELOCK_FULL ((1<<(MDS_INODELOCK_MAXSHIFT+1))-1)
+#define LUSTRE_CONFIG_SET 0
+#define LUSTRE_CONFIG_GET 1
+
+/* meta-sequence */
+struct lu_msq {
+ __u64 m_ran; /* holds number of ranges allocated to clients. Thus,
+ * server allocates 2 ^ 64 ranges. */
+
+ __u32 m_seq; /* holds number of sequences allocated in a range. Thus,
+ * each client may use 2 ^ 32 sequences before asking
+ * server to allocate new. */
+
+ __u32 m_pad; /* padding */
+};
+
+extern void lustre_swab_msq(struct lu_msq *msq);
+
+static inline __u64 msq_ran(struct lu_msq *msq)
+{
+ return msq->m_ran;
+}
+
+static inline __u32 msq_seq(struct lu_msq *msq)
+{
+ return msq->m_seq;
+}
+
+#define DSEQ "["LPU64"/%u]"
+
+#define PSEQ(seq) \
+ msq_ran(seq), \
+ msq_seq(seq)
+
+#define LUSTRE_CONFIG_METASEQ "metaseq"
+#define LUSTRE_CONFIG_TRANSNO "transno"
+
struct lu_fid {
__u64 f_seq; /* holds fid sequence. Lustre should support 2 ^ 64
* objects, thus even if one sequence has one object we
return f_ver | fid_oid(fid);
}
-/* show sequence, object id and version */
-#define DFID3 LPU64"/%u:%u"
+#define DFID3 "["LPU64"/%u:%u]"
#define PFID3(fid) \
fid_seq(fid), \
return memcmp(f0, f1, sizeof *f0) == 0;
}
+/* This structure is used for both request and reply.
+ *
+ * If we eventually have separate connect data for different types, which we
+ * almost certainly will, then perhaps we stick a union in here. */
+struct obd_connect_data {
+ __u64 ocd_connect_flags; /* OBD_CONNECT_* per above */
+ __u32 ocd_version; /* lustre release version number */
+ __u32 ocd_grant; /* initial cache grant amount (bytes) */
+ __u32 ocd_index; /* LOV index to connect to */
+ __u32 ocd_unused;
+ __u64 ocd_ibits_known; /* inode bits this client understands */
+ struct lu_msq ocd_msq; /* meta-sequence info */
+ __u64 padding2; /* also fix lustre_swab_connect */
+ __u64 padding3; /* also fix lustre_swab_connect */
+ __u64 padding4; /* also fix lustre_swab_connect */
+};
+
+extern void lustre_swab_connect(struct obd_connect_data *ocd);
#define MDS_STATUS_CONN 1
#define MDS_STATUS_LOV 2
};
struct md_device_operations {
+
+ /* method for getting/setting device wide back stored config data, like
+ * last used meta-sequence, etc. */
+ int (*mdo_config) (struct md_device *m, const char *name,
+ void *buf, int size, int mode);
+
+ /* meta-data device related handlers. */
int (*mdo_root_get)(struct md_device *m, struct lu_fid *f);
int (*mdo_statfs)(struct md_device *m, struct kstatfs *sfs);
+
+ /* meta-data object operations related handlers */
int (*mdo_mkdir)(struct md_object *obj, const char *name,
struct md_object *child);
const char *name, struct context *uctxt);
int (*mdo_attr_set)(struct md_object *obj, void *buf, int buf_len,
const char *name, struct context *uctxt);
+
+ /* FLD maintanence related handlers */
int (*mdo_index_insert)(struct md_object *pobj, struct md_object *obj,
const char *name, struct context *uctxt);
int (*mdo_index_delete)(struct md_object *pobj, struct md_object *obj,
static int mdd_root_get(struct md_device *m, struct lu_fid *f)
{
struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev);
+ ENTRY;
*f = mdd->mdd_rootfid;
- return 0;
+ RETURN(0);
+}
+
+static int mdd_config(struct md_device *m, const char *name,
+ void *buf, int size, int mode)
+{
+ struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev);
+ int rc = -EOPNOTSUPP;
+ ENTRY;
+
+ if (mdd_child_ops(mdd)->dt_config) {
+ rc = mdd_child_ops(mdd)->dt_config(mdd->mdd_child,
+ name, buf, size,
+ mode);
+ }
+
+ RETURN(rc);
}
static int mdd_statfs(struct md_device *m, struct kstatfs *sfs) {
struct mdd_device *mdd = lu2mdd_dev(&m->md_lu_dev);
- int result = -EOPNOTSUPP;
+ int rc = -EOPNOTSUPP;
ENTRY;
- if (mdd_child_ops(mdd) && mdd_child_ops(mdd)->dt_statfs) {
- result = mdd_child_ops(mdd)->dt_statfs(mdd->mdd_child, sfs);
- }
+
+ if (mdd_child_ops(mdd) && mdd_child_ops(mdd)->dt_statfs)
+ rc = mdd_child_ops(mdd)->dt_statfs(mdd->mdd_child, sfs);
- RETURN(result);
+ RETURN(rc);
}
struct md_device_operations mdd_ops = {
.mdo_root_get = mdd_root_get,
+ .mdo_config = mdd_config,
.mdo_statfs = mdd_statfs,
.mdo_mkdir = mdd_mkdir,
.mdo_rename = mdd_rename,
result = child->md_ops->mdo_statfs(child, &sfs);
statfs_pack(osfs, &sfs);
}
-out:
+
RETURN(result);
}
#if 0
}
static int mdt_readpage(struct mdt_thread_info *info,
- struct ptlrpc_request *req, int offset)
+ struct ptlrpc_request *req, int offset)
{
return -EOPNOTSUPP;
}
return container_of(o, struct mdt_object, mot_obj.mo_lu);
}
-static struct mdt_object *mdt_object_find(struct mdt_device *d,
- struct lu_fid *f)
+struct mdt_object *mdt_object_find(struct mdt_device *d,
+ struct lu_fid *f)
{
struct lu_object *o;
return mdt_obj(o);
}
-static void mdt_object_put(struct mdt_object *o)
+void mdt_object_put(struct mdt_object *o)
{
lu_object_put(&o->mot_obj.mo_lu);
}
-static struct lu_fid *mdt_object_fid(struct mdt_object *o)
+struct lu_fid *mdt_object_fid(struct mdt_object *o)
{
return lu_object_fid(&o->mot_obj.mo_lu);
}
-static int mdt_object_lock(struct ldlm_namespace *ns, struct mdt_object *o,
- struct mdt_lock_handle *lh, __u64 ibits)
+int mdt_object_lock(struct ldlm_namespace *ns, struct mdt_object *o,
+ struct mdt_lock_handle *lh, __u64 ibits)
{
ldlm_policy_data_t p = {
.l_inodebits = {
return fid_lock(ns, mdt_object_fid(o), &lh->mlh_lh, lh->mlh_mode, &p);
}
-static void mdt_object_unlock(struct ldlm_namespace *ns, struct mdt_object *o,
+void mdt_object_unlock(struct ldlm_namespace *ns, struct mdt_object *o,
struct mdt_lock_handle *lh)
{
if (lustre_handle_is_used(&lh->mlh_lh)) {
}
}
-static struct mdt_object *mdt_object_find_lock(struct mdt_device *d,
- struct lu_fid *f,
- struct mdt_lock_handle *lh,
- __u64 ibits)
+struct mdt_object *mdt_object_find_lock(struct mdt_device *d,
+ struct lu_fid *f,
+ struct mdt_lock_handle *lh,
+ __u64 ibits)
{
struct mdt_object *o;
prntfn, c->psc_num_threads);
}
+/* default meta-sequenve values */
+#define LUSTRE_METASEQ_DEFAULT_RAN 0
+#define LUSTRE_METASEQ_DEFAULT_SEQ 0
+
+/* allocate meta-sequence to client */
+int mdt_alloc_metaseq(struct mdt_device *m, struct lu_msq *msq)
+{
+ ENTRY;
+
+ LASSERT(m != NULL);
+ LASSERT(msq != NULL);
+
+ spin_lock(&m->mdt_msq_lock);
+
+ /* to be continued */
+
+ spin_unlock(&m->mdt_msq_lock);
+
+ RETURN(0);
+}
+
+/* initialize meta-sequence. First of all try to get it from lower layer down to
+ * back store one. In the case this is first run and there is not meta-sequence
+ * initialized yet - store it to backstore. */
+static int mdt_init_metaseq(struct mdt_device *m)
+{
+ struct md_device *child = m->mdt_child;
+ int rc;
+ ENTRY;
+
+ m->mdt_msq.m_ran = LUSTRE_METASEQ_DEFAULT_RAN;
+ m->mdt_msq.m_seq = LUSTRE_METASEQ_DEFAULT_SEQ;
+
+ if (!child->md_ops->mdo_config)
+ GOTO(out, rc = 0);
+
+ rc = child->md_ops->mdo_config(child, LUSTRE_CONFIG_METASEQ,
+ &m->mdt_msq, sizeof(m->mdt_msq),
+ LUSTRE_CONFIG_GET);
+ if (rc == -EOPNOTSUPP) {
+ /* provide zero error and let contnibnue with default values of
+ * meta-sequence. */
+ GOTO(out, rc = 0);
+ } else if (rc == -ENODATA) {
+ CWARN("initialize new meta-sequence\n");
+
+ /*initialize new meta-sequence config as it is not yet
+ * created. */
+ rc = child->md_ops->mdo_config(child, LUSTRE_CONFIG_METASEQ,
+ &m->mdt_msq, sizeof(m->mdt_msq),
+ LUSTRE_CONFIG_SET);
+ if (rc) {
+ CERROR("can't update config %s, rc %d\n",
+ LUSTRE_CONFIG_METASEQ, rc);
+ GOTO(out, rc);
+ }
+ } else {
+ CERROR("can't get config %s, rc %d\n",
+ LUSTRE_CONFIG_METASEQ, rc);
+ GOTO(out, rc);
+ }
+
+ EXIT;
+out:
+ if (rc == 0) {
+ CWARN("initialized meta-sequence: "DSEQ"\n",
+ PSEQ(&m->mdt_msq));
+ }
+ return rc;
+}
+
static void mdt_fini(struct mdt_device *m)
{
struct lu_device *d = &m->mdt_md_dev.md_lu_dev;
if (d->ld_site != NULL) {
lu_site_fini(d->ld_site);
+ OBD_FREE_PTR(d->ld_site);
d->ld_site = NULL;
}
if (m->mdt_service != NULL) {
/* finish the stack */
if (m->mdt_child) {
struct lu_device *child = md2lu_dev(m->mdt_child);
-
child->ld_ops->ldo_device_fini(child);
}
static int mdt_init0(struct mdt_device *m,
struct lu_device_type *t, struct lustre_cfg *cfg)
{
+ int rc;
struct lu_site *s;
char ns_name[48];
struct obd_device * obd = NULL;
+ struct lu_device *mdt_child = NULL;
char *top = lustre_cfg_string(cfg, 0);
char *child = lustre_cfg_string(cfg, 1);
OBD_ALLOC_PTR(s);
if (s == NULL)
- return -ENOMEM;
+ RETURN(-ENOMEM);
md_device_init(&m->mdt_md_dev, t);
m->mdt_child = lu2md_dev(obd->obd_lu_dev);
} else {
CDEBUG(D_INFO, "Child device %s is not found\n", child);
- return -EINVAL;
+ GOTO(err_free_site, rc = -EINVAL);
}
+ if (m->mdt_child)
+ mdt_child = md2lu_dev(m->mdt_child);
+
+ spin_lock_init(&m->mdt_msq_lock);
+
m->mdt_service_conf.psc_nbufs = MDS_NBUFS;
m->mdt_service_conf.psc_bufsize = MDS_BUFSIZE;
m->mdt_service_conf.psc_max_req_size = MDS_MAXREQSIZE;
snprintf(ns_name, sizeof ns_name, LUSTRE_MDT0_NAME"-%p", m);
m->mdt_namespace = ldlm_namespace_new(ns_name, LDLM_NAMESPACE_SERVER);
if (m->mdt_namespace == NULL)
- return -ENOMEM;
+ GOTO(err_fini_site, rc = -ENOMEM);
+
ldlm_register_intent(m->mdt_namespace, mdt_intent_policy);
ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL,
m->mdt_md_dev.md_lu_dev.ld_proc_entry,
NULL);
if (m->mdt_service == NULL)
- return -ENOMEM;
+ GOTO(err_free_ns, rc = -ENOMEM);
/* init the stack */
- if (m->mdt_child) {
- struct lu_device *child = md2lu_dev(m->mdt_child);
- int err;
-
- if (child->ld_ops->ldo_device_init) {
- err = child->ld_ops->ldo_device_init(child, top);
- if (err)
- return err;
+ if (m->mdt_child && mdt_child) {
+ if (mdt_child->ld_ops->ldo_device_init) {
+ rc = mdt_child->ld_ops->ldo_device_init(mdt_child, top);
+ if (rc) {
+ CERROR("can't init device stack, rc %d\n", rc);
+ GOTO(err_free_svc, rc);
+ }
}
+ } else {
+ CERROR("something bad with child device\n");
+ LBUG();
}
- return ptlrpc_start_threads(NULL, m->mdt_service, LUSTRE_MDT0_NAME);
+
+ /* init meta-sequence info after device stack is initialized. */
+ rc = mdt_init_metaseq(m);
+ if (rc)
+ GOTO(err_fini_child, rc);
+
+ rc = ptlrpc_start_threads(NULL, m->mdt_service, LUSTRE_MDT0_NAME);
+ if (rc)
+ GOTO(err_fini_child, rc);
+
+ RETURN(0);
+
+err_fini_child:
+ mdt_child->ld_ops->ldo_device_fini(mdt_child);
+err_free_svc:
+ ptlrpc_unregister_service(m->mdt_service);
+ m->mdt_service = NULL;
+err_free_ns:
+ ldlm_namespace_free(m->mdt_namespace, 0);
+ m->mdt_namespace = NULL;
+err_fini_site:
+ lu_site_fini(s);
+err_free_site:
+ OBD_FREE_PTR(s);
+ return rc;
}
static struct lu_object *mdt_object_alloc(struct lu_device *d)
/* mds_connect copy */
static int mdt_obd_connect(struct lustre_handle *conn, struct obd_device *obd,
- struct obd_uuid *cluuid,
- struct obd_connect_data *data)
+ struct obd_uuid *cluuid, struct obd_connect_data *data)
{
struct obd_export *exp;
int rc, abort_recovery;
memcpy(mcd->mcd_uuid, cluuid, sizeof(mcd->mcd_uuid));
med->med_mcd = mcd;
-
+
+ rc = mdt_alloc_metaseq(mdt_dev(obd->obd_lu_dev),
+ &data->ocd_msq);
+ if (rc)
+ GOTO(out, rc);
out:
if (rc) {
if (mcd) {
* necessary.
*/
unsigned long mdt_flags;
+
+ /* Seq management related stuff */
+ spinlock_t mdt_msq_lock;
+ struct lu_msq mdt_msq;
};
static inline struct md_device_operations *mdt_child_ops(struct mdt_device * m)
};
+int mdt_alloc_metaseq(struct mdt_device *m, struct lu_msq *msq);
+
int fid_lock(struct ldlm_namespace *, const struct lu_fid *,
- struct lustre_handle *, ldlm_mode_t, ldlm_policy_data_t *);
+ struct lustre_handle *, ldlm_mode_t,
+ ldlm_policy_data_t *);
void fid_unlock(struct ldlm_namespace *, const struct lu_fid *,
struct lustre_handle *, ldlm_mode_t);
+struct mdt_object *mdt_object_find(struct mdt_device *,
+ struct lu_fid *);
+void mdt_object_put(struct mdt_object *);
+
+struct lu_fid *mdt_object_fid(struct mdt_object *);
+
+int mdt_object_lock(struct ldlm_namespace *, struct mdt_object *,
+ struct mdt_lock_handle *, __u64);
+
+void mdt_object_unlock(struct ldlm_namespace *, struct mdt_object *,
+ struct mdt_lock_handle *);
+
+struct mdt_object *mdt_object_find_lock(struct mdt_device *,
+ struct lu_fid *,
+ struct mdt_lock_handle *,
+ __u64);
#endif /* __KERNEL__ */
#endif /* _MDT_H */
.ptk_fini = osd_thread_fini
};
-static int osd_statfs(struct dt_device *d, struct kstatfs *sfs) {
+static int osd_config(struct dt_device *d, const char *name,
+ void *buf, int size, int mode)
+{
+ struct osd_device *osd = dt2osd_dev(d);
+ struct super_block *sb = osd->od_dt_dev.dd_lmi->lmi_sb;
+ int result = -EOPNOTSUPP;
+
+ ENTRY;
+
+ if (mode == LUSTRE_CONFIG_GET) {
+ /* to be continued */
+ } else {
+ /* to be continued */
+ }
+
+ RETURN (result);
+}
+
+static int osd_statfs(struct dt_device *d, struct kstatfs *sfs)
+{
struct osd_device *osd = dt2osd_dev(d);
struct super_block *sb = osd->od_dt_dev.dd_lmi->lmi_sb;
int result = -EOPNOTSUPP;
}
static struct dt_device_operations osd_dt_ops = {
- .dt_statfs = osd_statfs,
+ .dt_config = osd_config,
+ .dt_statfs = osd_statfs
};
/*
* lustre_idl.h implemented here.
*/
+void lustre_swab_msq(struct lu_msq *msq)
+{
+ __swab64s (&msq->m_ran);
+ __swab32s (&msq->m_seq);
+}
+
void lustre_swab_connect(struct obd_connect_data *ocd)
{
__swab64s (&ocd->ocd_connect_flags);
__swab32s (&ocd->ocd_index);
__swab32s (&ocd->ocd_unused);
__swab64s (&ocd->ocd_ibits_known);
+ lustre_swab_msq(&ocd->ocd_msq);
CLASSERT(offsetof(typeof(*ocd), padding2) != 0);
CLASSERT(offsetof(typeof(*ocd), padding3) != 0);
CLASSERT(offsetof(typeof(*ocd), padding4) != 0);
- CLASSERT(offsetof(typeof(*ocd), padding5) != 0);
- CLASSERT(offsetof(typeof(*ocd), padding6) != 0);
}
void lustre_swab_obdo (struct obdo *o)