Wrap calls to ldto_device_* methods with small wrapper functions.
This allows for default behavior to be defined when the ldto_device_*
methods are not defined.
Define a default allocator when ldto_device_alloc and ldto_device_free
are not provided. This will allow many of the simplier OBD devices
to be fully converted to LU devices without as much boilerplate.
Similarly, allow ldto_device_init/fini to be optional.
Signed-off-by: Timothy Day <timday@amazon.com>
Change-Id: Iac40138a31a0eef9a2100f958be8e00849301e46
Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/58783
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Reviewed-by: Arshad Hussain <arshad.hussain@aeoncomputing.com>
Reviewed-by: James Simmons <jsimmons@infradead.org>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
#include <stdarg.h>
#endif
#include <libcfs/libcfs.h>
+#include <obd_support.h>
#include <uapi/linux/lustre/lustre_idl.h>
#include <linux/percpu_counter.h>
#include <linux/rhashtable.h>
void (*ldto_stop)(struct lu_device_type *t);
};
+static inline struct lu_device *ldto_device_alloc(const struct lu_env *env,
+ struct lu_device_type *ldt,
+ struct lustre_cfg *lcfg)
+{
+ const struct lu_device_type_operations *ldto;
+ struct lu_device *lu;
+
+ LASSERT(ldt);
+ ldto = ldt->ldt_ops;
+ LASSERT(ldto);
+
+ if (ldto->ldto_device_alloc)
+ return ldto->ldto_device_alloc(env, ldt, lcfg);
+
+ OBD_ALLOC_PTR(lu);
+ if (!lu)
+ return ERR_PTR(-ENOMEM);
+
+ return lu;
+}
+
+static inline struct lu_device *ldto_device_free(const struct lu_env *env,
+ struct lu_device *lu)
+{
+ const struct lu_device_type_operations *ldto;
+
+ LASSERT(lu);
+ LASSERT(lu->ld_type);
+ ldto = lu->ld_type->ldt_ops;
+ LASSERT(ldto);
+
+ if (ldto->ldto_device_free)
+ return ldto->ldto_device_free(env, lu);
+
+ OBD_FREE_PTR(lu);
+ return NULL;
+}
+
+static inline int ldto_device_init(const struct lu_env *env,
+ struct lu_device *lu, const char *name,
+ struct lu_device *lu2)
+{
+ const struct lu_device_type_operations *ldto;
+
+ LASSERT(lu);
+ LASSERT(lu->ld_type);
+ ldto = lu->ld_type->ldt_ops;
+ LASSERT(ldto);
+
+ if (ldto->ldto_device_init)
+ return ldto->ldto_device_init(env, lu, name, lu2);
+
+ return 0;
+}
+
+static inline struct lu_device *ldto_device_fini(const struct lu_env *env,
+ struct lu_device *lu)
+{
+ const struct lu_device_type_operations *ldto;
+
+ LASSERT(lu);
+ LASSERT(lu->ld_type);
+ ldto = lu->ld_type->ldt_ops;
+ LASSERT(ldto);
+
+ if (ldto->ldto_device_fini)
+ return ldto->ldto_device_fini(env, lu);
+
+ return NULL;
+}
+
static inline int lu_device_is_md(const struct lu_device *d)
{
return ergo(d != NULL, d->ld_type->ldt_tags & LU_DEVICE_MD);
if (rc == 0) {
struct lu_device *dev;
env.le_ses = &session_ctx;
- dev = ldt->ldt_ops->ldto_device_alloc(&env, ldt, cfg);
+ dev = ldto_device_alloc(&env, ldt, cfg);
lu_env_fini(&env);
if (!IS_ERR(dev)) {
obd->obd_lu_dev = dev;
env = &_env;
rc = lu_env_add(env);
}
- ldt->ldt_ops->ldto_device_fini(env, d);
+ ldto_device_fini(env, d);
if (env == &_env) {
if (rc == 0)
lu_env_remove(env);
rc = lu_env_init(&env, ldt->ldt_ctx_tags);
if (rc == 0) {
- ldt->ldt_ops->ldto_device_free(&env, d);
+ ldto_device_free(&env, d);
lu_env_fini(&env);
obd->obd_lu_dev = NULL;
}
LASSERT(d->ld_site != NULL && next->ld_type != NULL);
next->ld_site = d->ld_site;
- rc = next->ld_type->ldt_ops->ldto_device_init(
- env, next, next->ld_type->ldt_name, NULL);
+ rc = ldto_device_init(env, next, next->ld_type->ldt_name, NULL);
if (rc == 0) {
lu_device_get(next);
}
next->ld_site = d->ld_site;
ldt = next->ld_type;
LASSERT(ldt != NULL);
- rc = ldt->ldt_ops->ldto_device_init(env, next, ldt->ldt_name, NULL);
+ rc = ldto_device_init(env, next, ldt->ldt_name, NULL);
if (rc) {
next->ld_site = NULL;
RETURN(rc);
*/
struct cl_device *cl_type_setup(const struct lu_env *env, struct lu_site *site,
- struct lu_device_type *ldt,
- struct lu_device *next)
+ struct lu_device_type *ldt,
+ struct lu_device *next)
{
- const char *typename;
- struct lu_device *d;
+ const char *typename;
+ struct lu_device *d;
- LASSERT(ldt != NULL);
+ LASSERT(ldt);
- typename = ldt->ldt_name;
- d = ldt->ldt_ops->ldto_device_alloc(env, ldt, NULL);
- if (!IS_ERR(d)) {
- int rc;
+ typename = ldt->ldt_name;
+ d = ldto_device_alloc(env, ldt, NULL);
+ if (!IS_ERR(d)) {
+ int rc;
- if (site != NULL)
- d->ld_site = site;
- rc = ldt->ldt_ops->ldto_device_init(env, d, typename, next);
- if (rc == 0) {
- lu_device_get(d);
- } else {
- ldt->ldt_ops->ldto_device_free(env, d);
- CERROR("can't init device '%s', %d\n", typename, rc);
- d = ERR_PTR(rc);
- }
- } else
- CERROR("Cannot allocate device: '%s'\n", typename);
- return lu2cl_dev(d);
+ if (site)
+ d->ld_site = site;
+
+ rc = ldto_device_init(env, d, typename, next);
+ if (rc == 0) {
+ lu_device_get(d);
+ } else {
+ ldto_device_free(env, d);
+ CERROR("can't init device '%s', %d\n", typename, rc);
+ d = ERR_PTR(rc);
+ }
+ } else {
+ CERROR("Cannot allocate device: '%s'\n", typename);
+ }
+
+ return lu2cl_dev(d);
}
EXPORT_SYMBOL(cl_type_setup);
lu_site_purge(env, site, ~0);
for (scan = top; scan != NULL; scan = next) {
- next = scan->ld_type->ldt_ops->ldto_device_fini(env, scan);
+ next = ldto_device_fini(env, scan);
lu_device_put(scan);
}
/* purge again. */
lu_site_purge(env, site, ~0);
- for (scan = top; scan != NULL; scan = next) {
- const struct lu_device_type *ldt = scan->ld_type;
-
- next = ldt->ldt_ops->ldto_device_free(env, scan);
- }
+ for (scan = top; scan != NULL; scan = next)
+ next = ldto_device_free(env, scan);
}
/**
GOTO(out, rc = -EBUSY);
next->ld_site = ed->ed_site;
- rc = next->ld_type->ldt_ops->ldto_device_init(env, next,
- next->ld_type->ldt_name,
- NULL);
+ rc = ldto_device_init(env, next, next->ld_type->ldt_name,
+ NULL);
if (rc)
GOTO(out, rc);
} else {
struct lu_device *next = ed->ed_next;
while (next && !ed->ed_next_ismd)
- next = next->ld_type->ldt_ops->ldto_device_fini(env, next);
+ next = ldto_device_fini(env, next);
return NULL;
}
echo_ed_los_fini(env, ed);
#endif
while (next && !ed->ed_next_ismd)
- next = next->ld_type->ldt_ops->ldto_device_free(env, next);
+ next = ldto_device_free(env, next);
LASSERT(ed->ed_site == d->ld_site);
echo_site_fini(env, ed);