Whamcloud - gitweb
b=6332
[fs/lustre-release.git] / lustre / obdecho / echo_client.c
index fa591b2..3d5e145 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/iobuf.h>
 #endif
 #include <asm/div64.h>
+#include <linux/smp_lock.h>
 #else
 #include <liblustre.h>
 #endif
@@ -65,7 +66,7 @@ echo_printk_object (char *msg, struct ec_object *eco)
 static struct ec_object *
 echo_find_object_locked (struct obd_device *obd, obd_id id)
 {
-        struct echo_client_obd *ec = &obd->u.echo_client;
+        struct echo_client_obd *ec = &obd->u.echocli;
         struct ec_object       *eco = NULL;
         struct list_head       *el;
 
@@ -97,7 +98,7 @@ static int
 echo_copyin_lsm (struct obd_device *obd, struct lov_stripe_md *lsm,
                  void *ulsm, int ulsm_nob)
 {
-        struct echo_client_obd *ec = &obd->u.echo_client;
+        struct echo_client_obd *ec = &obd->u.echocli;
         int                     nob;
 
         if (ulsm_nob < sizeof (*lsm))
@@ -125,7 +126,7 @@ echo_copyin_lsm (struct obd_device *obd, struct lov_stripe_md *lsm,
 static struct ec_object *
 echo_allocate_object (struct obd_device *obd)
 {
-        struct echo_client_obd *ec = &obd->u.echo_client;
+        struct echo_client_obd *ec = &obd->u.echocli;
         struct ec_object       *eco;
         int rc;
 
@@ -152,7 +153,7 @@ static void
 echo_free_object (struct ec_object *eco)
 {
         struct obd_device      *obd = eco->eco_device;
-        struct echo_client_obd *ec = &obd->u.echo_client;
+        struct echo_client_obd *ec = &obd->u.echocli;
 
         LASSERT (eco->eco_refcount == 0);
         obd_free_memmd(ec->ec_exp, &eco->eco_lsm);
@@ -163,7 +164,7 @@ static int echo_create_object(struct obd_device *obd, int on_target,
                               struct obdo *oa, void *ulsm, int ulsm_nob,
                               struct obd_trans_info *oti)
 {
-        struct echo_client_obd *ec = &obd->u.echo_client;
+        struct echo_client_obd *ec = &obd->u.echocli;
         struct ec_object       *eco2;
         struct ec_object       *eco;
         struct lov_stripe_md   *lsm;
@@ -218,10 +219,9 @@ static int echo_create_object(struct obd_device *obd, int on_target,
                 oa->o_id = ++last_object_id;
 
         if (on_target) {
-                /* XXX get some filter group constants */
-                oa->o_gr = 2;
+                oa->o_gr = FILTER_GROUP_ECHO;
                 oa->o_valid |= OBD_MD_FLGROUP;
-                rc = obd_create(ec->ec_exp, oa, &lsm, oti);
+                rc = obd_create(ec->ec_exp, oa, NULL, 0, &lsm, oti);
                 if (rc != 0)
                         goto failed;
 
@@ -269,12 +269,13 @@ static int
 echo_get_object (struct ec_object **ecop, struct obd_device *obd,
                  struct obdo *oa)
 {
-        struct echo_client_obd *ec = &obd->u.echo_client;
+        struct echo_client_obd *ec = &obd->u.echocli;
         struct ec_object       *eco;
         struct ec_object       *eco2;
         int                     rc;
 
-        if ((oa->o_valid & OBD_MD_FLID) == 0)
+        if ((oa->o_valid & OBD_MD_FLID) == 0 ||
+            oa->o_id == 0)                      /* disallow use of object id 0 */
         {
                 CERROR ("No valid oid\n");
                 return (-EINVAL);
@@ -353,7 +354,7 @@ static void
 echo_put_object (struct ec_object *eco)
 {
         struct obd_device      *obd = eco->eco_device;
-        struct echo_client_obd *ec = &obd->u.echo_client;
+        struct echo_client_obd *ec = &obd->u.echocli;
 
         /* Release caller's ref on the object.
          * delete => mark for deletion when last ref goes
@@ -423,25 +424,91 @@ echo_get_stripe_off_id (struct lov_stripe_md *lsm, obd_off *offp, obd_id *idp)
         *offp = offset * stripe_size + woffset % stripe_size;
 }
 
+static void 
+echo_client_page_debug_setup(struct lov_stripe_md *lsm, 
+                             struct page *page, int rw, obd_id id, 
+                             obd_off offset, obd_off count)
+{
+        char    *addr;
+        obd_off  stripe_off;
+        obd_id   stripe_id;
+        int      delta;
+
+        /* no partial pages on the client */
+        LASSERT(count == PAGE_SIZE);
+
+        addr = kmap(page);
+
+        for (delta = 0; delta < PAGE_SIZE; delta += OBD_ECHO_BLOCK_SIZE) {
+                if (rw == OBD_BRW_WRITE) {
+                        stripe_off = offset + delta;
+                        stripe_id = id;
+                        echo_get_stripe_off_id(lsm, &stripe_off, &stripe_id);
+                } else {
+                        stripe_off = 0xdeadbeef00c0ffeeULL;
+                        stripe_id = 0xdeadbeef00c0ffeeULL;
+                }
+                block_debug_setup(addr + delta, OBD_ECHO_BLOCK_SIZE, 
+                                  stripe_off, stripe_id);
+        }
+
+        kunmap(page);
+}
+
+static int
+echo_client_page_debug_check(struct lov_stripe_md *lsm, 
+                             struct page *page, obd_id id, 
+                             obd_off offset, obd_off count)
+{
+        obd_off stripe_off;
+        obd_id  stripe_id;
+        char   *addr;
+        int     delta;
+        int     rc;
+        int     rc2;
+
+        /* no partial pages on the client */
+        LASSERT(count == PAGE_SIZE);
+
+        addr = kmap(page);
+
+        for (rc = delta = 0; delta < PAGE_SIZE; delta += OBD_ECHO_BLOCK_SIZE) {
+                stripe_off = offset + delta;
+                stripe_id = id;
+                echo_get_stripe_off_id (lsm, &stripe_off, &stripe_id);
+
+                rc2 = block_debug_check("test_brw", 
+                                        addr + delta, OBD_ECHO_BLOCK_SIZE, 
+                                        stripe_off, stripe_id);
+                if (rc2 != 0) {
+                        CERROR ("Error in echo object "LPX64"\n", id);
+                        rc = rc2;
+                }
+        }
+
+        kunmap(page);
+        return rc;
+}
+
 static int echo_client_kbrw(struct obd_device *obd, int rw, struct obdo *oa,
                             struct lov_stripe_md *lsm, obd_off offset,
                             obd_size count, struct obd_trans_info *oti)
 {
-        struct echo_client_obd *ec = &obd->u.echo_client;
+        struct echo_client_obd *ec = &obd->u.echocli;
         obd_count               npages;
         struct brw_page        *pga;
         struct brw_page        *pgp;
         obd_off                 off;
         int                     i;
         int                     rc;
-        int                     verify;
+        int                     verify = 0;
         int                     gfp_mask;
 
-        /* oa_id  == 0    => speed test (no verification) else...
-         * oa & 1         => use HIGHMEM
-         */
-        verify = (oa->o_id != 0);
-        gfp_mask = ((oa->o_id & 1) == 0) ? GFP_KERNEL : GFP_HIGHUSER;
+        verify = ((oa->o_id) != ECHO_PERSISTENT_OBJID &&
+                  (oa->o_valid & OBD_MD_FLFLAGS) != 0 &&
+                  (oa->o_flags & OBD_FL_DEBUG_CHECK) != 0);
+
+        gfp_mask = ((oa->o_id & 2) == 0) ? GFP_KERNEL : GFP_HIGHUSER;
 
         LASSERT(rw == OBD_BRW_WRITE || rw == OBD_BRW_READ);
 
@@ -470,32 +537,18 @@ static int echo_client_kbrw(struct obd_device *obd, int rw, struct obdo *oa,
                         goto out;
 
                 pgp->count = PAGE_SIZE;
-                pgp->off = off;
+                pgp->disk_offset = pgp->page_offset = off;
                 pgp->flag = 0;
 
-                if (verify) {
-                        void *addr = kmap(pgp->pg);
-                        obd_off      stripe_off = off;
-                        obd_id       stripe_id = oa->o_id;
-
-                        if (rw == OBD_BRW_WRITE) {
-                                echo_get_stripe_off_id(lsm, &stripe_off,
-                                                       &stripe_id);
-                                page_debug_setup(addr, pgp->count,
-                                                 stripe_off, stripe_id);
-                        } else {
-                                page_debug_setup(addr, pgp->count,
-                                                 0xdeadbeef00c0ffeeULL,
-                                                 0xdeadbeef00c0ffeeULL);
-                        }
-                        kunmap(pgp->pg);
-                }
+                if (verify)
+                        echo_client_page_debug_setup(lsm, pgp->pg, rw, 
+                                                     oa->o_id, off, pgp->count);
         }
 
         rc = obd_brw(rw, ec->ec_exp, oa, lsm, npages, pga, oti);
 
  out:
-        if (rc != 0)
+        if (rc != 0 || rw != OBD_BRW_READ)
                 verify = 0;
 
         for (i = 0, pgp = pga; i < npages; i++, pgp++) {
@@ -503,18 +556,12 @@ static int echo_client_kbrw(struct obd_device *obd, int rw, struct obdo *oa,
                         continue;
 
                 if (verify) {
-                        void    *addr = kmap(pgp->pg);
-                        obd_off  stripe_off = pgp->off;
-                        obd_id   stripe_id  = oa->o_id;
-                        int      vrc;
-
-                        echo_get_stripe_off_id (lsm, &stripe_off, &stripe_id);
-                        vrc = page_debug_check("test_brw", addr, pgp->count,
-                                               stripe_off, stripe_id);
+                        int vrc;
+                        vrc = echo_client_page_debug_check(lsm, pgp->pg, oa->o_id,
+                                                           pgp->page_offset, 
+                                                           pgp->count);
                         if (vrc != 0 && rc == 0)
                                 rc = vrc;
-
-                        kunmap(pgp->pg);
                 }
                 __free_pages(pgp->pg, 0);
         }
@@ -529,7 +576,7 @@ static int echo_client_ubrw(struct obd_device *obd, int rw,
                             obd_off offset, obd_size count, char *buffer,
                             struct obd_trans_info *oti)
 {
-        struct echo_client_obd *ec = &obd->u.echo_client;
+        struct echo_client_obd *ec = &obd->u.echocli;
         obd_count               npages;
         struct brw_page        *pga;
         struct brw_page        *pgp;
@@ -571,7 +618,7 @@ static int echo_client_ubrw(struct obd_device *obd, int rw,
         for (i = 0, off = offset, pgp = pga;
              i < npages;
              i++, off += PAGE_SIZE, pgp++) {
-                pgp->off = off;
+                pgp->disk_offset = pgp->page_offset = off;
                 pgp->pg = kiobuf->maplist[i];
                 pgp->count = PAGE_SIZE;
                 pgp->flag = 0;
@@ -614,6 +661,10 @@ struct echo_async_page {
         struct list_head        eap_item;
 };
 
+#define EAP_FROM_COOKIE(c)                                                      \
+        (LASSERT(((struct echo_async_page *)(c))->eap_magic == EAP_MAGIC),      \
+         (struct echo_async_page *)(c))
+
 struct echo_async_state {
         spinlock_t              eas_lock;
         obd_off                 eas_next_offset;
@@ -623,6 +674,7 @@ struct echo_async_state {
         wait_queue_head_t       eas_waitq;
         struct list_head        eas_avail;
         struct obdo             eas_oa;
+        struct lov_stripe_md    *eas_lsm;
 };
 
 static int eas_should_wake(struct echo_async_state *eas)
@@ -636,14 +688,6 @@ static int eas_should_wake(struct echo_async_state *eas)
         return rc;
 };
 
-struct echo_async_page *eap_from_cookie(void *cookie)
-{
-        struct echo_async_page *eap = cookie;
-        if (eap->eap_magic != EAP_MAGIC)
-                return ERR_PTR(-EINVAL);
-        return eap;
-};
-
 static int ec_ap_make_ready(void *data, int cmd)
 {
         /* our pages are issued ready */
@@ -658,23 +702,27 @@ static int ec_ap_refresh_count(void *data, int cmd)
 }
 static void ec_ap_fill_obdo(void *data, int cmd, struct obdo *oa)
 {
-        struct echo_async_page *eap;
-        eap = eap_from_cookie(data);
-        if (IS_ERR(eap))
-                return;
+        struct echo_async_page *eap = EAP_FROM_COOKIE(data);
 
         memcpy(oa, &eap->eap_eas->eas_oa, sizeof(*oa));
 }
-static void ec_ap_completion(void *data, int cmd, int rc)
+
+static void ec_ap_completion(void *data, int cmd, struct obdo *oa, int rc)
 {
-        struct echo_async_page *eap = eap_from_cookie(data);
+        struct echo_async_page *eap = EAP_FROM_COOKIE(data);
         struct echo_async_state *eas;
         unsigned long flags;
 
-        if (IS_ERR(eap))
-                return;
         eas = eap->eap_eas;
 
+        if (cmd == OBD_BRW_READ &&
+            eas->eas_oa.o_id != ECHO_PERSISTENT_OBJID &&
+            (eas->eas_oa.o_valid & OBD_MD_FLFLAGS) != 0 &&
+            (eas->eas_oa.o_flags & OBD_FL_DEBUG_CHECK) != 0)
+                echo_client_page_debug_check(eas->eas_lsm, eap->eap_page, 
+                                             eas->eas_oa.o_id, eap->eap_off,
+                                             PAGE_SIZE);
+
         spin_lock_irqsave(&eas->eas_lock, flags);
         if (rc && !eas->eas_rc)
                 eas->eas_rc = rc;
@@ -731,6 +779,7 @@ static int echo_client_async_page(struct obd_export *exp, int rw,
         init_waitqueue_head(&eas.eas_waitq);
         eas.eas_in_flight = 0;
         eas.eas_rc = 0;
+        eas.eas_lsm = lsm;
         INIT_LIST_HEAD(&eas.eas_avail);
 
         /* prepare the group of pages that we're going to be keeping
@@ -740,7 +789,8 @@ static int echo_client_async_page(struct obd_export *exp, int rw,
                 if (page == NULL)
                         GOTO(out, rc = -ENOMEM);
 
-                list_add_tail(&page->list, &pages);
+                page->private = 0;
+                list_add_tail(&PAGE_LIST(page), &pages);
 
                 OBD_ALLOC(eap, sizeof(*eap));
                 if (eap == NULL)
@@ -749,7 +799,7 @@ static int echo_client_async_page(struct obd_export *exp, int rw,
                 eap->eap_magic = EAP_MAGIC;
                 eap->eap_page = page;
                 eap->eap_eas = &eas;
-                eap->eap_cookie = ERR_PTR(-ENOENT);
+                page->private = (unsigned long)eap;
                 list_add_tail(&eap->eap_item, &eas.eas_avail);
         }
 
@@ -775,17 +825,17 @@ static int echo_client_async_page(struct obd_export *exp, int rw,
                 spin_unlock_irqrestore(&eas.eas_lock, flags);
 
                 /* unbind the eap from its old page offset */
-                if (!IS_ERR(eap->eap_cookie)) {
+                if (eap->eap_cookie != NULL) {
                         obd_teardown_async_page(exp, lsm, NULL, 
                                                 eap->eap_cookie);
-                        eap->eap_cookie = ERR_PTR(-ENOENT);
+                        eap->eap_cookie = NULL;
                 }
 
                 eas.eas_next_offset += PAGE_SIZE;
                 eap->eap_off = eas.eas_next_offset;
 
-                rc = obd_prep_async_page(exp, lsm, NULL, eap->eap_page, 
-                                         eap->eap_off, &ec_async_page_ops, 
+                rc = obd_prep_async_page(exp, lsm, NULL, eap->eap_page,
+                                         eap->eap_off, &ec_async_page_ops,
                                          eap, &eap->eap_cookie);
                 if (rc) {
                         spin_lock_irqsave(&eas.eas_lock, flags);
@@ -793,9 +843,16 @@ static int echo_client_async_page(struct obd_export *exp, int rw,
                         break;
                 }
 
+                if (oa->o_id != ECHO_PERSISTENT_OBJID &&
+                    (oa->o_valid & OBD_MD_FLFLAGS) != 0 &&
+                    (oa->o_flags & OBD_FL_DEBUG_CHECK) != 0)
+                        echo_client_page_debug_setup(lsm, eap->eap_page, rw, 
+                                                     oa->o_id, 
+                                                     eap->eap_off, PAGE_SIZE);
+
                 /* always asserts urgent, which isn't quite right */
-                rc = obd_queue_async_io(exp, lsm, NULL, eap->eap_cookie, 
-                                        rw, 0, PAGE_SIZE, 0, 
+                rc = obd_queue_async_io(exp, lsm, NULL, eap->eap_cookie,
+                                        rw, 0, PAGE_SIZE, 0,
                                         ASYNC_READY | ASYNC_URGENT |
                                         ASYNC_COUNT_STABLE);
                 spin_lock_irqsave(&eas.eas_lock, flags);
@@ -821,12 +878,13 @@ static int echo_client_async_page(struct obd_export *exp, int rw,
 
 out:
         list_for_each_safe(pos, n, &pages) {
-                struct page *page = list_entry(pos, struct page, list);
+                struct page *page = list_entry(pos, struct page, 
+                                               PAGE_LIST_ENTRY);
 
-                list_del(&page->list);
-                if (page->private) {
+                list_del(&PAGE_LIST(page));
+                if (page->private != 0) {
                         eap = (struct echo_async_page *)page->private;
-                        if (!IS_ERR(eap->eap_cookie))
+                        if (eap->eap_cookie != NULL)
                                 obd_teardown_async_page(exp, lsm, NULL, 
                                                         eap->eap_cookie);
                         OBD_FREE(eap, sizeof(*eap));
@@ -847,7 +905,7 @@ static int echo_client_prep_commit(struct obd_export *exp, int rw,
         struct niobuf_remote *rnb;
         obd_off off;
         obd_size npages, tot_pages;
-        int i, ret = 0, err = 0;
+        int i, ret = 0;
         ENTRY;
 
         if (count <= 0 || (count & (PAGE_SIZE - 1)) != 0 ||
@@ -886,30 +944,32 @@ static int echo_client_prep_commit(struct obd_export *exp, int rw,
 
                 for (i = 0; i < npages; i++) {
                         struct page *page = lnb[i].page;
-                        void *addr;
 
                         /* read past eof? */
-                        if (page == NULL && lnb[i].rc == 0) 
+                        if (page == NULL && lnb[i].rc == 0)
                                 continue;
 
-                        addr = kmap(lnb[i].page);
+                        if (oa->o_id == ECHO_PERSISTENT_OBJID ||
+                            (oa->o_valid & OBD_MD_FLFLAGS) == 0 ||
+                            (oa->o_flags & OBD_FL_DEBUG_CHECK) == 0)
+                                continue;
 
-                        if (rw == OBD_BRW_WRITE) 
-                                page_debug_setup(addr, PAGE_SIZE,
-                                                 rnb[i].offset, oa->o_id);
-                        else 
-                                err = page_debug_check("prep_commit", addr, 
-                                                 PAGE_SIZE, rnb[i].offset,
-                                                 oa->o_id);
 
-                        kunmap(lnb[i].page);
+                        if (rw == OBD_BRW_WRITE)
+                                echo_client_page_debug_setup(lsm, page, rw,
+                                                             oa->o_id,
+                                                             rnb[i].offset,
+                                                             rnb[i].len);
+                        else
+                                echo_client_page_debug_check(lsm, page,
+                                                             oa->o_id,
+                                                             rnb[i].offset,
+                                                             rnb[i].len);
                 }
 
-                ret = obd_commitrw(rw, exp, oa, 1, &ioo, npages, lnb, oti);
+                ret = obd_commitrw(rw, exp, oa, 1, &ioo, npages, lnb, oti, ret);
                 if (ret != 0)
                         GOTO(out, ret);
-                if (err)
-                        GOTO(out, ret = err);
         }
 
 out:
@@ -920,11 +980,11 @@ out:
         RETURN(ret);
 }
 
-int echo_client_brw_ioctl(int rw, struct obd_export *exp, 
+int echo_client_brw_ioctl(int rw, struct obd_export *exp,
                           struct obd_ioctl_data *data)
 {
         struct obd_device *obd = class_exp2obd(exp);
-        struct echo_client_obd *ec = &obd->u.echo_client;
+        struct echo_client_obd *ec = &obd->u.echocli;
         struct obd_trans_info dummy_oti;
         struct ec_object *eco;
         int rc;
@@ -938,7 +998,7 @@ int echo_client_brw_ioctl(int rw, struct obd_export *exp,
 
         data->ioc_obdo1.o_valid &= ~OBD_MD_FLHANDLE;
         data->ioc_obdo1.o_valid |= OBD_MD_FLGROUP;
-        data->ioc_obdo1.o_gr = 2;
+        data->ioc_obdo1.o_gr = FILTER_GROUP_ECHO;
 
         switch((long)data->ioc_pbuf1) {
         case 1:
@@ -978,7 +1038,7 @@ echo_ldlm_callback (struct ldlm_lock *lock, struct ldlm_lock_desc *new,
                     void *data, int flag)
 {
         struct ec_object       *eco = (struct ec_object *)data;
-        struct echo_client_obd *ec = &(eco->eco_device->u.echo_client);
+        struct echo_client_obd *ec = &(eco->eco_device->u.echocli);
         struct lustre_handle    lockh;
         struct list_head       *el;
         int                     found = 0;
@@ -1023,7 +1083,7 @@ echo_client_enqueue(struct obd_export *exp, struct obdo *oa,
                     int mode, obd_off offset, obd_size nob)
 {
         struct obd_device      *obd = exp->exp_obd;
-        struct echo_client_obd *ec = &obd->u.echo_client;
+        struct echo_client_obd *ec = &obd->u.echocli;
         struct lustre_handle   *ulh = obdo_handle (oa);
         struct ec_object       *eco;
         struct ec_lock         *ecl;
@@ -1048,14 +1108,15 @@ echo_client_enqueue(struct obd_export *exp, struct obdo *oa,
 
         ecl->ecl_mode = mode;
         ecl->ecl_object = eco;
-        ecl->ecl_extent.start = offset;
-        ecl->ecl_extent.end = (nob == 0) ? ((obd_off) -1) : (offset + nob - 1);
+        ecl->ecl_policy.l_extent.start = offset;
+        ecl->ecl_policy.l_extent.end =
+                (nob == 0) ? ((obd_off) -1) : (offset + nob - 1);
 
         flags = 0;
-        rc = obd_enqueue(ec->ec_exp, eco->eco_lsm, NULL, LDLM_EXTENT,
-                         &ecl->ecl_extent,sizeof(ecl->ecl_extent), mode,
-                         &flags, echo_ldlm_callback, eco,
-                         &ecl->ecl_lock_handle);
+        rc = obd_enqueue(ec->ec_exp, eco->eco_lsm, LDLM_EXTENT,
+                         &ecl->ecl_policy, mode, &flags, echo_ldlm_callback,
+                         ldlm_completion_ast, NULL, eco, sizeof(struct ost_lvb),
+                         lustre_swab_ost_lvb, &ecl->ecl_lock_handle);
         if (rc != 0)
                 goto failed_1;
 
@@ -1083,7 +1144,7 @@ static int
 echo_client_cancel(struct obd_export *exp, struct obdo *oa)
 {
         struct obd_device      *obd = exp->exp_obd;
-        struct echo_client_obd *ec = &obd->u.echo_client;
+        struct echo_client_obd *ec = &obd->u.echocli;
         struct lustre_handle   *ulh = obdo_handle (oa);
         struct ec_lock         *ecl = NULL;
         int                     found = 0;
@@ -1134,10 +1195,12 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp,
         int                     i;
         ENTRY;
 
+        unlock_kernel();
+
         memset(&dummy_oti, 0, sizeof(dummy_oti));
 
         obd = exp->exp_obd;
-        ec = &obd->u.echo_client;
+        ec = &obd->u.echocli;
 
         switch (cmd) {
         case OBD_IOC_CREATE:                    /* may create echo object */
@@ -1156,7 +1219,7 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp,
                 rc = echo_get_object (&eco, obd, &data->ioc_obdo1);
                 if (rc == 0) {
                         oa = &data->ioc_obdo1;
-                        oa->o_gr = 2;
+                        oa->o_gr = FILTER_GROUP_ECHO;
                         oa->o_valid |= OBD_MD_FLGROUP;
                         rc = obd_destroy(ec->ec_exp, oa, eco->eco_lsm, 
                                          &dummy_oti);
@@ -1252,6 +1315,8 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp,
                 ldlm_lock_decref(&ack_lock->lock, ack_lock->mode);
         }
 
+        lock_kernel();
+
         return rc;
 }
 
@@ -1259,7 +1324,7 @@ static int
 echo_client_setup(struct obd_device *obddev, obd_count len, void *buf)
 {
         struct lustre_cfg* lcfg = buf;
-        struct echo_client_obd *ec = &obddev->u.echo_client;
+        struct echo_client_obd *ec = &obddev->u.echocli;
         struct obd_device *tgt;
         struct lustre_handle conn = {0, };
         struct obd_uuid echo_uuid = { "ECHO_UUID" };
@@ -1282,7 +1347,7 @@ echo_client_setup(struct obd_device *obddev, obd_count len, void *buf)
         INIT_LIST_HEAD (&ec->ec_objects);
         ec->ec_unique = 0;
 
-        rc = obd_connect(&conn, tgt, &echo_uuid);
+        rc = obd_connect(&conn, tgt, &echo_uuid, NULL, FILTER_GROUP_ECHO);
         if (rc) {
                 CERROR("fail to connect to device %s\n", lcfg->lcfg_inlbuf1);
                 return (rc);
@@ -1296,7 +1361,7 @@ static int echo_client_cleanup(struct obd_device *obddev, int flags)
 {
         struct list_head       *el;
         struct ec_object       *eco;
-        struct echo_client_obd *ec = &obddev->u.echo_client;
+        struct echo_client_obd *ec = &obddev->u.echocli;
         int rc;
         ENTRY;
 
@@ -1324,7 +1389,10 @@ static int echo_client_cleanup(struct obd_device *obddev, int flags)
 }
 
 static int echo_client_connect(struct lustre_handle *conn,
-                               struct obd_device *src, struct obd_uuid *cluuid)
+                               struct obd_device *src, 
+                              struct obd_uuid *cluuid,
+                               struct obd_connect_data *data,
+                               unsigned long flags)
 {
         struct obd_export *exp;
         int                rc;
@@ -1339,7 +1407,8 @@ static int echo_client_connect(struct lustre_handle *conn,
         RETURN (rc);
 }
 
-static int echo_client_disconnect(struct obd_export *exp, int flags)
+static int echo_client_disconnect(struct obd_export *exp, 
+                                 unsigned long flags)
 {
         struct obd_device      *obd;
         struct echo_client_obd *ec;
@@ -1351,7 +1420,7 @@ static int echo_client_disconnect(struct obd_export *exp, int flags)
                 GOTO(out, rc = -EINVAL);
 
         obd = exp->exp_obd;
-        ec = &obd->u.echo_client;
+        ec = &obd->u.echocli;
 
         /* no more contention on export's lock list */
         while (!list_empty (&exp->exp_ec_data.eced_locks)) {
@@ -1376,12 +1445,12 @@ static int echo_client_disconnect(struct obd_export *exp, int flags)
 }
 
 static struct obd_ops echo_obd_ops = {
-        o_owner:       THIS_MODULE,
-        o_setup:       echo_client_setup,
-        o_cleanup:     echo_client_cleanup,
-        o_iocontrol:   echo_client_iocontrol,
-        o_connect:     echo_client_connect,
-        o_disconnect:  echo_client_disconnect
+        .o_owner       = THIS_MODULE,
+        .o_setup       = echo_client_setup,
+        .o_cleanup     = echo_client_cleanup,
+        .o_iocontrol   = echo_client_iocontrol,
+        .o_connect     = echo_client_connect,
+        .o_disconnect  = echo_client_disconnect
 };
 
 int echo_client_init(void)
@@ -1389,7 +1458,7 @@ int echo_client_init(void)
         struct lprocfs_static_vars lvars;
 
         lprocfs_init_vars(echo, &lvars);
-        return class_register_type(&echo_obd_ops, lvars.module_vars,
+        return class_register_type(&echo_obd_ops, NULL, lvars.module_vars,
                                    OBD_ECHO_CLIENT_DEVICENAME);
 }