X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Fobdecho%2Fecho_client.c;h=41e6214005965e300701e8c9d56eaa8597ed097b;hp=504196aa5cd6d506831b055ad74767fae4301e1c;hb=a08b190a278e952e1c303eb49233b542189656e6;hpb=e41b9977627f6082d060091f7eabcd55ce45e9ec diff --git a/lustre/obdecho/echo_client.c b/lustre/obdecho/echo_client.c index 504196a..41e6214 100644 --- a/lustre/obdecho/echo_client.c +++ b/lustre/obdecho/echo_client.c @@ -26,8 +26,11 @@ * GPL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2011 Whamcloud, Inc. + * */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -69,9 +72,9 @@ struct echo_object { struct cl_object_header eo_hdr; struct echo_device *eo_dev; - struct list_head eo_obj_chain; + cfs_list_t eo_obj_chain; struct lov_stripe_md *eo_lsm; - atomic_t eo_npages; + cfs_atomic_t eo_npages; int eo_deleted; }; @@ -82,15 +85,16 @@ struct echo_object_conf { struct echo_page { struct cl_page_slice ep_cl; + cfs_mutex_t ep_lock; cfs_page_t *ep_vmpage; }; struct echo_lock { struct cl_lock_slice el_cl; - struct list_head el_chain; + cfs_list_t el_chain; struct echo_object *el_object; __u64 el_cookie; - atomic_t el_refcount; + cfs_atomic_t el_refcount; }; struct echo_io { @@ -169,8 +173,10 @@ struct echo_object_conf *cl2echo_conf(const struct cl_object_conf *c) static inline void lsm2fid(struct lov_stripe_md *lsm, struct lu_fid *fid) { fid_zero(fid); - fid->f_seq = lsm->lsm_object_gr << 16 | lsm->lsm_object_id >> 32; + fid->f_seq = FID_SEQ_ECHO; + /* truncated to 32 bits by assignment */ fid->f_oid = lsm->lsm_object_id; + fid->f_ver = lsm->lsm_object_id >> 32; } /** @} echo_helpers */ @@ -257,6 +263,29 @@ cfs_page_t *echo_page_vmpage(const struct lu_env *env, return cl2echo_page(slice)->ep_vmpage; } +static int echo_page_own(const struct lu_env *env, + const struct cl_page_slice *slice, + struct cl_io *io, int nonblock) +{ + struct echo_page *ep = cl2echo_page(slice); + + if (!nonblock) + cfs_mutex_lock(&ep->ep_lock); + else if (!cfs_mutex_trylock(&ep->ep_lock)) + return -EAGAIN; + return 0; +} + +static void echo_page_disown(const struct lu_env *env, + const struct cl_page_slice *slice, + struct cl_io *io) +{ + struct echo_page *ep = cl2echo_page(slice); + + LASSERT(cfs_mutex_is_locked(&ep->ep_lock)); + cfs_mutex_unlock(&ep->ep_lock); +} + static void echo_page_discard(const struct lu_env *env, const struct cl_page_slice *slice, struct cl_io *unused) @@ -267,7 +296,7 @@ static void echo_page_discard(const struct lu_env *env, static int echo_page_is_vmlocked(const struct lu_env *env, const struct cl_page_slice *slice) { - return 1; + return cfs_mutex_is_locked(&cl2echo_page(slice)->ep_lock); } static void echo_page_completion(const struct lu_env *env, @@ -285,7 +314,7 @@ static void echo_page_fini(const struct lu_env *env, cfs_page_t *vmpage = ep->ep_vmpage; ENTRY; - atomic_dec(&eco->eo_npages); + cfs_atomic_dec(&eco->eo_npages); page_cache_release(vmpage); OBD_SLAB_FREE_PTR(ep, echo_page_kmem); EXIT; @@ -304,12 +333,14 @@ static int echo_page_print(const struct lu_env *env, { struct echo_page *ep = cl2echo_page(slice); - (*printer)(env, cookie, LUSTRE_ECHO_CLIENT_NAME"-page@%p vm@%p\n", - ep, ep->ep_vmpage); + (*printer)(env, cookie, LUSTRE_ECHO_CLIENT_NAME"-page@%p %d vm@%p\n", + ep, cfs_mutex_is_locked(&ep->ep_lock), ep->ep_vmpage); return 0; } static const struct cl_page_operations echo_page_ops = { + .cpo_own = echo_page_own, + .cpo_disown = echo_page_disown, .cpo_discard = echo_page_discard, .cpo_vmpage = echo_page_vmpage, .cpo_fini = echo_page_fini, @@ -339,7 +370,7 @@ static void echo_lock_fini(const struct lu_env *env, { struct echo_lock *ecl = cl2echo_lock(slice); - LASSERT(list_empty(&ecl->el_chain)); + LASSERT(cfs_list_empty(&ecl->el_chain)); OBD_SLAB_FREE_PTR(ecl, echo_lock_kmem); } @@ -348,7 +379,7 @@ static void echo_lock_delete(const struct lu_env *env, { struct echo_lock *ecl = cl2echo_lock(slice); - LASSERT(list_empty(&ecl->el_chain)); + LASSERT(cfs_list_empty(&ecl->el_chain)); } static int echo_lock_fits_into(const struct lu_env *env, @@ -385,8 +416,9 @@ static struct cl_page *echo_page_init(const struct lu_env *env, struct echo_object *eco = cl2echo_obj(obj); ep->ep_vmpage = vmpage; page_cache_get(vmpage); + cfs_mutex_init(&ep->ep_lock); cl_page_slice_add(page, &ep->ep_cl, obj, &echo_page_ops); - atomic_inc(&eco->eo_npages); + cfs_atomic_inc(&eco->eo_npages); } RETURN(ERR_PTR(ep ? 0 : -ENOMEM)); } @@ -409,7 +441,7 @@ static int echo_lock_init(const struct lu_env *env, cl_lock_slice_add(lock, &el->el_cl, obj, &echo_lock_ops); el->el_object = cl2echo_obj(obj); CFS_INIT_LIST_HEAD(&el->el_chain); - atomic_set(&el->el_refcount, 0); + cfs_atomic_set(&el->el_refcount, 0); } RETURN(el == NULL ? -ENOMEM : 0); } @@ -459,14 +491,14 @@ static int echo_object_init(const struct lu_env *env, struct lu_object *obj, LASSERT(econf->eoc_md); eco->eo_lsm = *econf->eoc_md; eco->eo_dev = ed; - atomic_set(&eco->eo_npages, 0); + cfs_atomic_set(&eco->eo_npages, 0); /* clear the lsm pointer so that it won't get freed. */ *econf->eoc_md = NULL; - spin_lock(&ec->ec_lock); - list_add_tail(&eco->eo_obj_chain, &ec->ec_objects); - spin_unlock(&ec->ec_lock); + cfs_spin_lock(&ec->ec_lock); + cfs_list_add_tail(&eco->eo_obj_chain, &ec->ec_objects); + cfs_spin_unlock(&ec->ec_lock); RETURN(0); } @@ -478,11 +510,11 @@ static void echo_object_free(const struct lu_env *env, struct lu_object *obj) struct lov_stripe_md *lsm = eco->eo_lsm; ENTRY; - LASSERT(atomic_read(&eco->eo_npages) == 0); + LASSERT(cfs_atomic_read(&eco->eo_npages) == 0); - spin_lock(&ec->ec_lock); - list_del_init(&eco->eo_obj_chain); - spin_unlock(&ec->ec_lock); + cfs_spin_lock(&ec->ec_lock); + cfs_list_del_init(&eco->eo_obj_chain); + cfs_spin_unlock(&ec->ec_lock); lu_object_fini(obj); lu_object_header_fini(obj->lo_header); @@ -791,28 +823,8 @@ static struct lu_device *echo_device_free(const struct lu_env *env, struct echo_object *eco; struct lu_device *next = ed->ed_next; - CDEBUG(D_INFO, "echo device:%p is going to be freed, next = %p\n", ed, next); - - /* destroy locks */ - spin_lock(&ec->ec_lock); - while (!list_empty(&ec->ec_locks)) { - struct echo_lock *ecl = list_entry(ec->ec_locks.next, - struct echo_lock, el_chain); - int still_used = 0; - - if (atomic_dec_and_test(&ecl->el_refcount)) - list_del_init(&ecl->el_chain); - else - still_used = 1; - spin_unlock(&ec->ec_lock); - - CERROR("echo client: pending lock %p refs %d\n", - ecl, atomic_read(&ecl->el_refcount)); - - echo_lock_release(env, ecl, still_used); - spin_lock(&ec->ec_lock); - } - spin_unlock(&ec->ec_lock); + CDEBUG(D_INFO, "echo device:%p is going to be freed, next = %p\n", + ed, next); LASSERT(ed->ed_site); lu_site_purge(env, &ed->ed_site->cs_lu, -1); @@ -822,26 +834,30 @@ static struct lu_device *echo_device_free(const struct lu_env *env, * all of cached objects. Anyway, probably the echo device is being * parallelly accessed. */ - spin_lock(&ec->ec_lock); - list_for_each_entry(eco, &ec->ec_objects, eo_obj_chain) + cfs_spin_lock(&ec->ec_lock); + cfs_list_for_each_entry(eco, &ec->ec_objects, eo_obj_chain) eco->eo_deleted = 1; - spin_unlock(&ec->ec_lock); + cfs_spin_unlock(&ec->ec_lock); /* purge again */ lu_site_purge(env, &ed->ed_site->cs_lu, -1); - CDEBUG(D_INFO, "Waiting for the reference of echo object to be dropped\n"); + CDEBUG(D_INFO, + "Waiting for the reference of echo object to be dropped\n"); /* Wait for the last reference to be dropped. */ - spin_lock(&ec->ec_lock); - while (!list_empty(&ec->ec_objects)) { - spin_unlock(&ec->ec_lock); + cfs_spin_lock(&ec->ec_lock); + while (!cfs_list_empty(&ec->ec_objects)) { + cfs_spin_unlock(&ec->ec_lock); CERROR("echo_client still has objects at cleanup time, " "wait for 1 second\n"); - cfs_schedule_timeout(CFS_TASK_UNINT, cfs_time_seconds(1)); - spin_lock(&ec->ec_lock); + cfs_schedule_timeout_and_set_state(CFS_TASK_UNINT, + cfs_time_seconds(1)); + cfs_spin_lock(&ec->ec_lock); } - spin_unlock(&ec->ec_lock); + cfs_spin_unlock(&ec->ec_lock); + + LASSERT(cfs_list_empty(&ec->ec_locks)); CDEBUG(D_INFO, "No object exists, exiting...\n"); @@ -920,7 +936,7 @@ static struct echo_object *cl_echo_object_find(struct echo_device *d, struct lov_oinfo *oinfo = lsm->lsm_oinfo[0]; LASSERT(oinfo != NULL); oinfo->loi_id = lsm->lsm_object_id; - oinfo->loi_gr = lsm->lsm_object_gr; + oinfo->loi_seq = lsm->lsm_object_seq; conf->eoc_cl.u.coc_oinfo = oinfo; } else { struct lustre_md *md; @@ -965,8 +981,7 @@ static int cl_echo_object_put(struct echo_object *eco) if (eco->eo_deleted) { struct lu_object_header *loh = obj->co_lu.lo_header; LASSERT(&eco->eo_hdr == luh2coh(loh)); - set_bit(LU_OBJECT_HEARD_BANSHEE, &loh->loh_flags); - cl_object_prune(env, obj); + cfs_set_bit(LU_OBJECT_HEARD_BANSHEE, &loh->loh_flags); } cl_object_put(env, obj); @@ -995,10 +1010,10 @@ static int cl_echo_enqueue0(struct lu_env *env, struct echo_object *eco, descr->cld_start = cl_index(obj, start); descr->cld_end = cl_index(obj, end); descr->cld_mode = mode == LCK_PW ? CLM_WRITE : CLM_READ; + descr->cld_enq_flags = enqflags; io->ci_obj = obj; - lck = cl_lock_request(env, io, descr, CEF_ASYNC | enqflags, - "ec enqueue", eco); + lck = cl_lock_request(env, io, descr, "ec enqueue", eco); if (lck) { struct echo_client_obd *ec = eco->eo_dev->ed_ec; struct echo_lock *el; @@ -1006,14 +1021,14 @@ static int cl_echo_enqueue0(struct lu_env *env, struct echo_object *eco, rc = cl_wait(env, lck); if (rc == 0) { el = cl2echo_lock(cl_lock_at(lck, &echo_device_type)); - spin_lock(&ec->ec_lock); - if (list_empty(&el->el_chain)) { - list_add(&el->el_chain, &ec->ec_locks); + cfs_spin_lock(&ec->ec_lock); + if (cfs_list_empty(&el->el_chain)) { + cfs_list_add(&el->el_chain, &ec->ec_locks); el->el_cookie = ++ec->ec_unique; } - atomic_inc(&el->el_refcount); + cfs_atomic_inc(&el->el_refcount); *cookie = el->el_cookie; - spin_unlock(&ec->ec_lock); + cfs_spin_unlock(&ec->ec_lock); } else cl_lock_release(env, lck, "ec enqueue", cfs_current()); } @@ -1056,25 +1071,25 @@ static int cl_echo_cancel0(struct lu_env *env, struct echo_device *ed, { struct echo_client_obd *ec = ed->ed_ec; struct echo_lock *ecl = NULL; - struct list_head *el; + cfs_list_t *el; int found = 0, still_used = 0; ENTRY; LASSERT(ec != NULL); - spin_lock (&ec->ec_lock); - list_for_each (el, &ec->ec_locks) { - ecl = list_entry (el, struct echo_lock, el_chain); - CDEBUG(D_INFO, "ecl: %p, cookie: %llx\n", ecl, ecl->el_cookie); + cfs_spin_lock (&ec->ec_lock); + cfs_list_for_each (el, &ec->ec_locks) { + ecl = cfs_list_entry (el, struct echo_lock, el_chain); + CDEBUG(D_INFO, "ecl: %p, cookie: "LPX64"\n", ecl, ecl->el_cookie); found = (ecl->el_cookie == cookie); if (found) { - if (atomic_dec_and_test(&ecl->el_refcount)) - list_del_init(&ecl->el_chain); + if (cfs_atomic_dec_and_test(&ecl->el_refcount)) + cfs_list_del_init(&ecl->el_chain); else still_used = 1; break; } } - spin_unlock (&ec->ec_lock); + cfs_spin_unlock (&ec->ec_lock); if (!found) RETURN(-ENOENT); @@ -1154,8 +1169,8 @@ static int cl_echo_object_brw(struct echo_object *eco, int rw, obd_off offset, rc = cl_echo_enqueue0(env, eco, offset, offset + npages * CFS_PAGE_SIZE - 1, - rw == READ ? LCK_PW : LCK_PW, &lh.cookie, - CILR_NEVER); + rw == READ ? LCK_PR : LCK_PW, &lh.cookie, + CEF_NEVER); if (rc < 0) GOTO(error_lock, rc); @@ -1225,12 +1240,12 @@ echo_copyout_lsm (struct lov_stripe_md *lsm, void *_ulsm, int ulsm_nob) if (nob > ulsm_nob) return (-EINVAL); - if (copy_to_user (ulsm, lsm, sizeof(ulsm))) + if (cfs_copy_to_user (ulsm, lsm, sizeof(ulsm))) return (-EFAULT); for (i = 0; i < lsm->lsm_stripe_count; i++) { - if (copy_to_user (ulsm->lsm_oinfo[i], lsm->lsm_oinfo[i], - sizeof(lsm->lsm_oinfo[0]))) + if (cfs_copy_to_user (ulsm->lsm_oinfo[i], lsm->lsm_oinfo[i], + sizeof(lsm->lsm_oinfo[0]))) return (-EFAULT); } return 0; @@ -1246,7 +1261,7 @@ echo_copyin_lsm (struct echo_device *ed, struct lov_stripe_md *lsm, if (ulsm_nob < sizeof (*lsm)) return (-EINVAL); - if (copy_from_user (lsm, ulsm, sizeof (*lsm))) + if (cfs_copy_from_user (lsm, ulsm, sizeof (*lsm))) return (-EFAULT); if (lsm->lsm_stripe_count > ec->ec_nstripes || @@ -1257,9 +1272,10 @@ echo_copyin_lsm (struct echo_device *ed, struct lov_stripe_md *lsm, for (i = 0; i < lsm->lsm_stripe_count; i++) { - if (copy_from_user(lsm->lsm_oinfo[i], - ((struct lov_stripe_md *)ulsm)->lsm_oinfo[i], - sizeof(lsm->lsm_oinfo[0]))) + if (cfs_copy_from_user(lsm->lsm_oinfo[i], + ((struct lov_stripe_md *)ulsm)-> \ + lsm_oinfo[i], + sizeof(lsm->lsm_oinfo[0]))) return (-EFAULT); } return (0); @@ -1302,7 +1318,7 @@ static int echo_create_object(struct echo_device *ed, int on_target, if (lsm->lsm_stripe_size == 0) lsm->lsm_stripe_size = CFS_PAGE_SIZE; - idx = ll_rand(); + idx = cfs_rand(); /* setup stripes: indices + default ids if required */ for (i = 0; i < lsm->lsm_stripe_count; i++) { @@ -1325,7 +1341,7 @@ static int echo_create_object(struct echo_device *ed, int on_target, if (on_target) { /* Only echo objects are allowed to be created */ LASSERT((oa->o_valid & OBD_MD_FLGROUP) && - (oa->o_gr == FILTER_GROUP_ECHO)); + (oa->o_seq == FID_SEQ_ECHO)); rc = obd_create(ec->ec_exp, oa, &lsm, oti); if (rc != 0) { CERROR("Cannot create objects, rc = %d\n", rc); @@ -1378,9 +1394,9 @@ static int echo_get_object(struct echo_object **ecop, struct echo_device *ed, lsm->lsm_object_id = oa->o_id; if (oa->o_valid & OBD_MD_FLGROUP) - lsm->lsm_object_gr = oa->o_gr; + lsm->lsm_object_seq = oa->o_seq; else - lsm->lsm_object_gr = FILTER_GROUP_ECHO; + lsm->lsm_object_seq = FID_SEQ_ECHO; rc = 0; eco = cl_echo_object_find(ed, &lsm); @@ -1509,6 +1525,7 @@ static int echo_client_kbrw(struct echo_device *ed, int rw, struct obdo *oa, int rc; int verify; int gfp_mask; + int brw_flags = 0; ENTRY; verify = ((oa->o_id) != ECHO_PERSISTENT_OBJID && @@ -1528,6 +1545,9 @@ static int echo_client_kbrw(struct echo_device *ed, int rw, struct obdo *oa, /* XXX think again with misaligned I/O */ npages = count >> CFS_PAGE_SHIFT; + if (rw == OBD_BRW_WRITE) + brw_flags = OBD_BRW_ASYNC; + OBD_ALLOC(pga, npages * sizeof(*pga)); if (pga == NULL) RETURN(-ENOMEM); @@ -1552,7 +1572,7 @@ static int echo_client_kbrw(struct echo_device *ed, int rw, struct obdo *oa, pages[i] = pgp->pg; pgp->count = CFS_PAGE_SIZE; pgp->off = off; - pgp->flag = 0; + pgp->flag = brw_flags; if (verify) echo_client_page_debug_setup(lsm, pgp->pg, rw, @@ -1687,7 +1707,7 @@ static int echo_client_brw_ioctl(int rw, struct obd_export *exp, struct obd_device *obd = class_exp2obd(exp); struct echo_device *ed = obd2echo_dev(obd); struct echo_client_obd *ec = ed->ed_ec; - struct obd_trans_info dummy_oti = { .oti_thread = NULL }; + struct obd_trans_info dummy_oti = { 0 }; struct obdo *oa = &data->ioc_obdo1; struct echo_object *eco; int rc; @@ -1753,7 +1773,7 @@ echo_client_enqueue(struct obd_export *exp, struct obdo *oa, rc = cl_echo_enqueue(eco, offset, end, mode, &ulh->cookie); if (rc == 0) { oa->o_valid |= OBD_MD_FLHANDLE; - CDEBUG(D_INFO, "Cookie is %llx\n", ulh->cookie); + CDEBUG(D_INFO, "Cookie is "LPX64"\n", ulh->cookie); } echo_put_object(eco); RETURN(rc); @@ -1768,7 +1788,7 @@ echo_client_cancel(struct obd_export *exp, struct obdo *oa) if ((oa->o_valid & OBD_MD_FLHANDLE) == 0) return -EINVAL; - CDEBUG(D_INFO, "Cookie is %llx\n", cookie); + CDEBUG(D_INFO, "Cookie is "LPX64"\n", cookie); return cl_echo_cancel(ed, cookie); } @@ -1784,22 +1804,28 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, struct obd_trans_info dummy_oti; struct oti_req_ack_lock *ack_lock; struct obdo *oa; + struct lu_fid fid; int rw = OBD_BRW_READ; int rc = 0; int i; ENTRY; - unlock_kernel(); +#ifndef HAVE_UNLOCKED_IOCTL + cfs_unlock_kernel(); +#endif memset(&dummy_oti, 0, sizeof(dummy_oti)); oa = &data->ioc_obdo1; if (!(oa->o_valid & OBD_MD_FLGROUP)) { oa->o_valid |= OBD_MD_FLGROUP; - oa->o_gr = FILTER_GROUP_ECHO; + oa->o_seq = FID_SEQ_ECHO; } - /* assume we can touch filter native objects with echo device. */ - /* LASSERT(oa->o_gr == FILTER_GROUP_ECHO); */ + + /* This FID is unpacked just for validation at this point */ + rc = fid_ostid_unpack(&fid, &oa->o_oi, 0); + if (rc < 0) + RETURN(rc); switch (cmd) { case OBD_IOC_CREATE: /* may create echo object */ @@ -1917,7 +1943,9 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, ldlm_lock_decref(&ack_lock->lock, ack_lock->mode); } - lock_kernel(); +#ifndef HAVE_UNLOCKED_IOCTL + cfs_lock_kernel(); +#endif return rc; } @@ -1943,7 +1971,7 @@ static int echo_client_setup(struct obd_device *obddev, struct lustre_cfg *lcfg) RETURN(-EINVAL); } - spin_lock_init (&ec->ec_lock); + cfs_spin_lock_init (&ec->ec_lock); CFS_INIT_LIST_HEAD (&ec->ec_objects); CFS_INIT_LIST_HEAD (&ec->ec_locks); ec->ec_unique = 0; @@ -1957,16 +1985,17 @@ static int echo_client_setup(struct obd_device *obddev, struct lustre_cfg *lcfg) } ocd->ocd_connect_flags = OBD_CONNECT_VERSION | OBD_CONNECT_REQPORTAL | - OBD_CONNECT_GRANT; + OBD_CONNECT_GRANT | OBD_CONNECT_FULL20 | + OBD_CONNECT_64BITHASH; ocd->ocd_version = LUSTRE_VERSION_CODE; - ocd->ocd_group = FILTER_GROUP_ECHO; + ocd->ocd_group = FID_SEQ_ECHO; rc = obd_connect(NULL, &ec->ec_exp, tgt, &echo_uuid, ocd, NULL); if (rc == 0) { /* Turn off pinger because it connects to tgt obd directly. */ - spin_lock(&tgt->obd_dev_lock); - list_del_init(&ec->ec_exp->exp_obd_chain_timed); - spin_unlock(&tgt->obd_dev_lock); + cfs_spin_lock(&tgt->obd_dev_lock); + cfs_list_del_init(&ec->ec_exp->exp_obd_chain_timed); + cfs_spin_unlock(&tgt->obd_dev_lock); } OBD_FREE(ocd, sizeof(*ocd)); @@ -1986,12 +2015,12 @@ static int echo_client_cleanup(struct obd_device *obddev) int rc; ENTRY; - if (!list_empty(&obddev->obd_exports)) { + if (!cfs_list_empty(&obddev->obd_exports)) { CERROR("still has clients!\n"); RETURN(-EBUSY); } - LASSERT(atomic_read(&ec->ec_exp->exp_refcount) > 0); + LASSERT(cfs_atomic_read(&ec->ec_exp->exp_refcount) > 0); rc = obd_disconnect(ec->ec_exp); if (rc != 0) CERROR("fail to disconnect device: %d\n", rc); @@ -2034,10 +2063,10 @@ static int echo_client_disconnect(struct obd_export *exp) ec = &obd->u.echo_client; /* no more contention on export's lock list */ - while (!list_empty (&exp->exp_ec_data.eced_locks)) { - ecl = list_entry (exp->exp_ec_data.eced_locks.next, - struct ec_lock, ecl_exp_chain); - list_del (&ecl->ecl_exp_chain); + while (!cfs_list_empty (&exp->exp_ec_data.eced_locks)) { + ecl = cfs_list_entry (exp->exp_ec_data.eced_locks.next, + struct ec_lock, ecl_exp_chain); + cfs_list_del (&ecl->ecl_exp_chain); rc = obd_cancel(ec->ec_exp, ecl->ecl_object->eco_lsm, ecl->ecl_mode, &ecl->ecl_lock_handle); @@ -2075,10 +2104,16 @@ int echo_client_init(void) int rc; lprocfs_echo_init_vars(&lvars); - rc = class_register_type(&echo_obd_ops, NULL, lvars.module_vars, - LUSTRE_ECHO_CLIENT_NAME, &echo_device_type); + + rc = lu_kmem_init(echo_caches); if (rc == 0) - lu_kmem_init(echo_caches); + rc = class_register_type(&echo_obd_ops, NULL, + lvars.module_vars, + LUSTRE_ECHO_CLIENT_NAME, + &echo_device_type); + if (rc) + lu_kmem_fini(echo_caches); + return rc; }