@@ -489,6 +489,29 @@ void osc_io_unplug(const struct lu_env *env, struct client_obd *cli,
int osc_lock_is_lockless(const struct osc_lock *olck);
+/* osc_dev.c */
+int osc_device_init(const struct lu_env *env, struct lu_device *d,
+ const char *name, struct lu_device *next);
+struct lu_device *osc_device_fini(const struct lu_env *env,
+ struct lu_device *d);
+struct lu_device *osc_device_free(const struct lu_env *env,
+ struct lu_device *d);
+
+/* osc_object.c */
+int osc_object_init(const struct lu_env *env, struct lu_object *obj,
+ const struct lu_object_conf *conf);
+void osc_object_free(const struct lu_env *env, struct lu_object *obj);
+int osc_lvb_print(const struct lu_env *env, void *cookie,
+ lu_printer_t p, const struct ost_lvb *lvb);
+int osc_object_print(const struct lu_env *env, void *cookie,
+ lu_printer_t p, const struct lu_object *obj);
+int osc_attr_get(const struct lu_env *env, struct cl_object *obj,
+ struct cl_attr *attr);
+int osc_attr_update(const struct lu_env *env, struct cl_object *obj,
+ const struct cl_attr *attr, unsigned int valid);
+int osc_object_glimpse(const struct lu_env *env, const struct cl_object *obj,
+ struct ost_lvb *lvb);
+
/****************************************************************************
*
* Accessors and type conversions.
@@ -2,3 +2,4 @@ ccflags-y += -I$(srctree)/$(src)/../include
obj-$(CONFIG_LUSTRE_FS) += mdc.o
mdc-y := mdc_changelog.o mdc_request.o mdc_reint.o mdc_lib.o mdc_locks.o lproc_mdc.o
+mdc-y += mdc_dev.o
new file mode 100644
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2017 Intel Corporation.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ *
+ * Implementation of cl_device, cl_req for MDC layer.
+ *
+ * Author: Mikhail Pershin <mpershin@whamcloud.com>
+ */
+
+#define DEBUG_SUBSYSTEM S_MDC
+
+#include <obd_class.h>
+#include <lustre_osc.h>
+
+#include "mdc_internal.h"
+
+int mdc_page_init(const struct lu_env *env, struct cl_object *obj,
+ struct cl_page *page, pgoff_t index)
+{
+ return -ENOTSUPP;
+}
+
+int mdc_lock_init(const struct lu_env *env,
+ struct cl_object *obj, struct cl_lock *lock,
+ const struct cl_io *unused)
+{
+ return -ENOTSUPP;
+}
+
+int mdc_io_init(const struct lu_env *env,
+ struct cl_object *obj, struct cl_io *io)
+{
+ return -ENOTSUPP;
+}
+
+/**
+ * Implementation of struct cl_req_operations::cro_attr_set() for MDC
+ * layer. MDC is responsible for struct obdo::o_id and struct obdo::o_seq
+ * fields.
+ */
+static void mdc_req_attr_set(const struct lu_env *env, struct cl_object *obj,
+ struct cl_req_attr *attr)
+{
+ u64 flags = attr->cra_flags;
+
+ /* Copy object FID to cl_attr */
+ attr->cra_oa->o_oi.oi_fid = *lu_object_fid(&obj->co_lu);
+
+ if (flags & OBD_MD_FLGROUP)
+ attr->cra_oa->o_valid |= OBD_MD_FLGROUP;
+
+ if (flags & OBD_MD_FLID)
+ attr->cra_oa->o_valid |= OBD_MD_FLID;
+}
+
+static const struct cl_object_operations mdc_ops = {
+ .coo_page_init = mdc_page_init,
+ .coo_lock_init = mdc_lock_init,
+ .coo_io_init = mdc_io_init,
+ .coo_attr_get = osc_attr_get,
+ .coo_attr_update = osc_attr_update,
+ .coo_glimpse = osc_object_glimpse,
+ .coo_req_attr_set = mdc_req_attr_set,
+};
+
+static int mdc_object_init(const struct lu_env *env, struct lu_object *obj,
+ const struct lu_object_conf *conf)
+{
+ struct osc_object *osc = lu2osc(obj);
+
+ if (osc->oo_initialized)
+ return 0;
+
+ osc->oo_initialized = true;
+
+ return osc_object_init(env, obj, conf);
+}
+
+static void mdc_object_free(const struct lu_env *env, struct lu_object *obj)
+{
+ osc_object_free(env, obj);
+}
+
+static const struct lu_object_operations mdc_lu_obj_ops = {
+ .loo_object_init = mdc_object_init,
+ .loo_object_delete = NULL,
+ .loo_object_release = NULL,
+ .loo_object_free = mdc_object_free,
+ .loo_object_print = osc_object_print,
+ .loo_object_invariant = NULL
+};
+
+struct lu_object *mdc_object_alloc(const struct lu_env *env,
+ const struct lu_object_header *unused,
+ struct lu_device *dev)
+{
+ struct osc_object *osc;
+ struct lu_object *obj;
+
+ osc = kmem_cache_zalloc(osc_object_kmem, GFP_NOFS);
+ if (osc) {
+ obj = osc2lu(osc);
+ lu_object_init(obj, NULL, dev);
+ osc->oo_cl.co_ops = &mdc_ops;
+ obj->lo_ops = &mdc_lu_obj_ops;
+ osc->oo_initialized = false;
+ } else {
+ obj = NULL;
+ }
+ return obj;
+}
+
+static int mdc_cl_process_config(const struct lu_env *env,
+ struct lu_device *d, struct lustre_cfg *cfg)
+{
+ return mdc_process_config(d->ld_obd, 0, cfg);
+}
+
+const struct lu_device_operations mdc_lu_ops = {
+ .ldo_object_alloc = mdc_object_alloc,
+ .ldo_process_config = mdc_cl_process_config,
+ .ldo_recovery_complete = NULL,
+};
+
+static struct lu_device *mdc_device_alloc(const struct lu_env *env,
+ struct lu_device_type *t,
+ struct lustre_cfg *cfg)
+{
+ struct lu_device *d;
+ struct osc_device *od;
+ struct obd_device *obd;
+ int rc;
+
+ od = kzalloc(sizeof(*od), GFP_NOFS);
+ if (!od)
+ return ERR_PTR(-ENOMEM);
+
+ cl_device_init(&od->od_cl, t);
+ d = osc2lu_dev(od);
+ d->ld_ops = &mdc_lu_ops;
+
+ /* Setup MDC OBD */
+ obd = class_name2obd(lustre_cfg_string(cfg, 0));
+ if (!obd)
+ return ERR_PTR(-ENODEV);
+
+ rc = mdc_setup(obd, cfg);
+ if (rc < 0) {
+ osc_device_free(env, d);
+ return ERR_PTR(rc);
+ }
+ od->od_exp = obd->obd_self_export;
+ return d;
+}
+
+static const struct lu_device_type_operations mdc_device_type_ops = {
+ .ldto_device_alloc = mdc_device_alloc,
+ .ldto_device_free = osc_device_free,
+ .ldto_device_init = osc_device_init,
+ .ldto_device_fini = osc_device_fini
+};
+
+struct lu_device_type mdc_device_type = {
+ .ldt_tags = LU_DEVICE_CL,
+ .ldt_name = LUSTRE_MDC_NAME,
+ .ldt_ops = &mdc_device_type_ops,
+ .ldt_ctx_tags = LCT_CL_THREAD
+};
@@ -90,6 +90,9 @@ int mdc_resource_get_unused(struct obd_export *exp, const struct lu_fid *fid,
/* mdc/mdc_request.c */
int mdc_fid_alloc(const struct lu_env *env, struct obd_export *exp,
struct lu_fid *fid, struct md_op_data *op_data);
+int mdc_setup(struct obd_device *obd, struct lustre_cfg *cfg);
+int mdc_process_config(struct obd_device *obd, u32 len, void *buf);
+
struct obd_client_handle;
int mdc_set_open_replay_data(struct obd_export *exp,
@@ -149,4 +152,7 @@ static inline unsigned long hash_x_index(u64 hash, int hash64)
return ~0UL - (hash + !hash);
}
+/* mdc_dev.c */
+extern struct lu_device_type mdc_device_type;
+
#endif
@@ -2473,7 +2473,7 @@ static void mdc_llog_finish(struct obd_device *obd)
llog_cleanup(NULL, ctxt);
}
-static int mdc_setup(struct obd_device *obd, struct lustre_cfg *cfg)
+int mdc_setup(struct obd_device *obd, struct lustre_cfg *cfg)
{
int rc;
@@ -2566,7 +2566,7 @@ static int mdc_cleanup(struct obd_device *obd)
return client_obd_cleanup(obd);
}
-static int mdc_process_config(struct obd_device *obd, u32 len, void *buf)
+int mdc_process_config(struct obd_device *obd, u32 len, void *buf)
{
struct lustre_cfg *lcfg = buf;
size_t count = class_modify_config(lcfg, PARAM_MDC,
@@ -2635,7 +2635,7 @@ static int __init mdc_init(void)
return rc;
return class_register_type(&mdc_obd_ops, &mdc_md_ops,
- LUSTRE_MDC_NAME, NULL);
+ LUSTRE_MDC_NAME, &mdc_device_type);
}
static void /*__exit*/ mdc_exit(void)
@@ -48,11 +48,16 @@
*/
struct kmem_cache *osc_lock_kmem;
+EXPORT_SYMBOL(osc_lock_kmem);
struct kmem_cache *osc_object_kmem;
+EXPORT_SYMBOL(osc_object_kmem);
+
struct kmem_cache *osc_thread_kmem;
struct kmem_cache *osc_session_kmem;
struct kmem_cache *osc_extent_kmem;
+EXPORT_SYMBOL(osc_extent_kmem);
struct kmem_cache *osc_quota_kmem;
+EXPORT_SYMBOL(osc_quota_kmem);
struct lu_kmem_descr osc_caches[] = {
{
@@ -162,20 +167,20 @@ static int osc_cl_process_config(const struct lu_env *env,
.ldo_recovery_complete = NULL
};
-static int osc_device_init(const struct lu_env *env, struct lu_device *d,
- const char *name, struct lu_device *next)
+int osc_device_init(const struct lu_env *env, struct lu_device *d,
+ const char *name, struct lu_device *next)
{
return 0;
}
-
-static struct lu_device *osc_device_fini(const struct lu_env *env,
- struct lu_device *d)
+EXPORT_SYMBOL(osc_device_init);
+struct lu_device *osc_device_fini(const struct lu_env *env,
+ struct lu_device *d)
{
return NULL;
}
-
-static struct lu_device *osc_device_free(const struct lu_env *env,
- struct lu_device *d)
+EXPORT_SYMBOL(osc_device_fini);
+struct lu_device *osc_device_free(const struct lu_env *env,
+ struct lu_device *d)
{
struct osc_device *od = lu2osc_dev(d);
@@ -183,6 +188,7 @@ static struct lu_device *osc_device_free(const struct lu_env *env,
kfree(od);
return NULL;
}
+EXPORT_SYMBOL(osc_device_free);
static struct lu_device *osc_device_alloc(const struct lu_env *env,
struct lu_device_type *t,
@@ -51,8 +51,8 @@
*
*/
-static int osc_object_init(const struct lu_env *env, struct lu_object *obj,
- const struct lu_object_conf *conf)
+int osc_object_init(const struct lu_env *env, struct lu_object *obj,
+ const struct lu_object_conf *conf)
{
struct osc_object *osc = lu2osc(obj);
const struct cl_object_conf *cconf = lu2cl_conf(conf);
@@ -82,8 +82,9 @@ static int osc_object_init(const struct lu_env *env, struct lu_object *obj,
return 0;
}
+EXPORT_SYMBOL(osc_object_init);
-static void osc_object_free(const struct lu_env *env, struct lu_object *obj)
+void osc_object_free(const struct lu_env *env, struct lu_object *obj)
{
struct osc_object *osc = lu2osc(obj);
@@ -105,6 +106,7 @@ static void osc_object_free(const struct lu_env *env, struct lu_object *obj)
lu_object_fini(obj);
kmem_cache_free(osc_object_kmem, osc);
}
+EXPORT_SYMBOL(osc_object_free);
int osc_lvb_print(const struct lu_env *env, void *cookie,
lu_printer_t p, const struct ost_lvb *lvb)
@@ -114,9 +116,10 @@ int osc_lvb_print(const struct lu_env *env, void *cookie,
lvb->lvb_size, lvb->lvb_mtime, lvb->lvb_atime,
lvb->lvb_ctime, lvb->lvb_blocks);
}
+EXPORT_SYMBOL(osc_lvb_print);
-static int osc_object_print(const struct lu_env *env, void *cookie,
- lu_printer_t p, const struct lu_object *obj)
+int osc_object_print(const struct lu_env *env, void *cookie,
+ lu_printer_t p, const struct lu_object *obj)
{
struct osc_object *osc = lu2osc(obj);
struct lov_oinfo *oinfo = osc->oo_oinfo;
@@ -130,9 +133,10 @@ static int osc_object_print(const struct lu_env *env, void *cookie,
osc_lvb_print(env, cookie, p, &oinfo->loi_lvb);
return 0;
}
+EXPORT_SYMBOL(osc_object_print);
-static int osc_attr_get(const struct lu_env *env, struct cl_object *obj,
- struct cl_attr *attr)
+int osc_attr_get(const struct lu_env *env, struct cl_object *obj,
+ struct cl_attr *attr)
{
struct lov_oinfo *oinfo = cl2osc(obj)->oo_oinfo;
@@ -140,9 +144,10 @@ static int osc_attr_get(const struct lu_env *env, struct cl_object *obj,
attr->cat_kms = oinfo->loi_kms_valid ? oinfo->loi_kms : 0;
return 0;
}
+EXPORT_SYMBOL(osc_attr_get);
-static int osc_attr_update(const struct lu_env *env, struct cl_object *obj,
- const struct cl_attr *attr, unsigned int valid)
+int osc_attr_update(const struct lu_env *env, struct cl_object *obj,
+ const struct cl_attr *attr, unsigned int valid)
{
struct lov_oinfo *oinfo = cl2osc(obj)->oo_oinfo;
struct ost_lvb *lvb = &oinfo->loi_lvb;
@@ -164,9 +169,10 @@ static int osc_attr_update(const struct lu_env *env, struct cl_object *obj,
}
return 0;
}
+EXPORT_SYMBOL(osc_attr_update);
-static int osc_object_glimpse(const struct lu_env *env,
- const struct cl_object *obj, struct ost_lvb *lvb)
+int osc_object_glimpse(const struct lu_env *env,
+ const struct cl_object *obj, struct ost_lvb *lvb)
{
struct lov_oinfo *oinfo = cl2osc(obj)->oo_oinfo;
@@ -174,6 +180,7 @@ static int osc_object_glimpse(const struct lu_env *env,
lvb->lvb_blocks = oinfo->loi_lvb.lvb_blocks;
return 0;
}
+EXPORT_SYMBOL(osc_object_glimpse);
static int osc_object_ast_clear(struct ldlm_lock *lock, void *data)
{