Whamcloud - gitweb
LU-7623 Update obd iocontrol methods with __user attribute
[fs/lustre-release.git] / lustre / obdecho / echo_client.c
index 0ad6050..e435f5d 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2014, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
  */
 
 #define DEBUG_SUBSYSTEM S_ECHO
+
+#include <linux/user_namespace.h>
+#ifdef HAVE_UIDGID_HEADER
+# include <linux/uidgid.h>
+#endif
 #include <libcfs/libcfs.h>
 
 #include <obd.h>
  */
 
 struct echo_device {
-        struct cl_device        ed_cl;
-        struct echo_client_obd *ed_ec;
-
-        struct cl_site          ed_site_myself;
-        struct cl_site         *ed_site;
-        struct lu_device       *ed_next;
-        int                     ed_next_ismd;
-        struct lu_client_seq   *ed_cl_seq;
+       struct cl_device          ed_cl;
+       struct echo_client_obd   *ed_ec;
+
+       struct cl_site            ed_site_myself;
+       struct lu_site           *ed_site;
+       struct lu_device         *ed_next;
+       int                       ed_next_ismd;
+       struct lu_client_seq     *ed_cl_seq;
+#ifdef HAVE_SERVER_SUPPORT
+       struct local_oid_storage *ed_los;
+       struct lu_fid             ed_root_fid;
+#endif /* HAVE_SERVER_SUPPORT */
 };
 
 struct echo_object {
@@ -96,6 +105,23 @@ struct echo_lock {
        atomic_t                el_refcount;
 };
 
+#ifdef HAVE_SERVER_SUPPORT
+static const char echo_md_root_dir_name[] = "ROOT_ECHO";
+
+/**
+ * In order to use the values of members in struct mdd_device,
+ * we define an alias structure here.
+ */
+struct echo_md_device {
+       struct md_device                 emd_md_dev;
+       struct obd_export               *emd_child_exp;
+       struct dt_device                *emd_child;
+       struct dt_device                *emd_bottom;
+       struct lu_fid                    emd_root_fid;
+       struct lu_fid                    emd_local_root_fid;
+};
+#endif /* HAVE_SERVER_SUPPORT */
+
 static int echo_client_setup(const struct lu_env *env,
                              struct obd_device *obddev,
                              struct lustre_cfg *lcfg);
@@ -160,6 +186,28 @@ struct echo_object_conf *cl2echo_conf(const struct cl_object_conf *c)
         return container_of(c, struct echo_object_conf, eoc_cl);
 }
 
+#ifdef HAVE_SERVER_SUPPORT
+static inline struct echo_md_device *lu2emd_dev(struct lu_device *d)
+{
+       return container_of0(d, struct echo_md_device, emd_md_dev.md_lu_dev);
+}
+
+static inline struct lu_device *emd2lu_dev(struct echo_md_device *d)
+{
+       return &d->emd_md_dev.md_lu_dev;
+}
+
+static inline struct seq_server_site *echo_md_seq_site(struct echo_md_device *d)
+{
+       return emd2lu_dev(d)->ld_site->ld_seq_site;
+}
+
+static inline struct obd_device *emd2obd_dev(struct echo_md_device *d)
+{
+       return d->emd_md_dev.md_lu_dev.ld_obd;
+}
+#endif /* HAVE_SERVER_SUPPORT */
+
 /** @} echo_helpers */
 
 static int cl_echo_object_put(struct echo_object *eco);
@@ -182,7 +230,7 @@ struct echo_thread_info {
        struct md_attr          eti_ma;
        struct lu_name          eti_lname;
        /* per-thread values, can be re-used */
-       void                    *eti_big_lmm;
+       void                    *eti_big_lmm; /* may be vmalloc'd */
        int                     eti_big_lmmsize;
        char                    eti_name[20];
        struct lu_buf           eti_buf;
@@ -536,9 +584,6 @@ static struct lu_device_operations echo_device_lu_ops = {
 
 /** @} echo_lu_dev_ops */
 
-static struct cl_device_operations echo_device_cl_ops = {
-};
-
 /** \defgroup echo_init Setup and teardown
  *
  * Init and fini functions for echo client.
@@ -550,28 +595,30 @@ static int echo_site_init(const struct lu_env *env, struct echo_device *ed)
         struct cl_site *site = &ed->ed_site_myself;
         int rc;
 
-        /* initialize site */
+       /* initialize site */
         rc = cl_site_init(site, &ed->ed_cl);
         if (rc) {
-                CERROR("Cannot initilize site for echo client(%d)\n", rc);
+               CERROR("Cannot initialize site for echo client(%d)\n", rc);
                 return rc;
         }
 
-        rc = lu_site_init_finish(&site->cs_lu);
-        if (rc)
-                return rc;
+       rc = lu_site_init_finish(&site->cs_lu);
+       if (rc) {
+               cl_site_fini(site);
+               return rc;
+       }
 
-        ed->ed_site = site;
-        return 0;
+       ed->ed_site = &site->cs_lu;
+       return 0;
 }
 
 static void echo_site_fini(const struct lu_env *env, struct echo_device *ed)
 {
-        if (ed->ed_site) {
-                if (!ed->ed_next_ismd)
-                        cl_site_fini(ed->ed_site);
-                ed->ed_site = NULL;
-        }
+       if (ed->ed_site) {
+               if (!ed->ed_next_ismd)
+                       lu_site_fini(ed->ed_site);
+               ed->ed_site = NULL;
+       }
 }
 
 static void *echo_thread_key_init(const struct lu_context *ctx,
@@ -685,6 +732,87 @@ static int echo_fid_fini(struct obd_device *obddev)
 
         RETURN(0);
 }
+
+static void echo_ed_los_fini(const struct lu_env *env, struct echo_device *ed)
+{
+       ENTRY;
+
+       if (ed != NULL && ed->ed_next_ismd && ed->ed_los != NULL) {
+               local_oid_storage_fini(env, ed->ed_los);
+               ed->ed_los = NULL;
+       }
+}
+
+static int
+echo_md_local_file_create(const struct lu_env *env, struct echo_md_device *emd,
+                         struct local_oid_storage *los,
+                         const struct lu_fid *pfid, const char *name,
+                         __u32 mode, struct lu_fid *fid)
+{
+       struct dt_object        *parent = NULL;
+       struct dt_object        *dto = NULL;
+       int                      rc = 0;
+       ENTRY;
+
+       LASSERT(!fid_is_zero(pfid));
+       parent = dt_locate(env, emd->emd_bottom, pfid);
+       if (unlikely(IS_ERR(parent)))
+               RETURN(PTR_ERR(parent));
+
+       /* create local file with @fid */
+       dto = local_file_find_or_create_with_fid(env, emd->emd_bottom, fid,
+                                                parent, name, mode);
+       if (IS_ERR(dto))
+               GOTO(out_put, rc = PTR_ERR(dto));
+
+       *fid = *lu_object_fid(&dto->do_lu);
+       /* since stack is not fully set up the local_storage uses own stack
+        * and we should drop its object from cache */
+       lu_object_put_nocache(env, &dto->do_lu);
+
+       EXIT;
+out_put:
+       lu_object_put(env, &parent->do_lu);
+       RETURN(rc);
+}
+
+static int
+echo_md_root_get(const struct lu_env *env, struct echo_md_device *emd,
+                struct echo_device *ed)
+{
+       struct lu_fid                    fid;
+       int                              rc = 0;
+       ENTRY;
+
+       /* Setup local dirs */
+       fid.f_seq = FID_SEQ_LOCAL_NAME;
+       fid.f_oid = 1;
+       fid.f_ver = 0;
+       rc = local_oid_storage_init(env, emd->emd_bottom, &fid, &ed->ed_los);
+       if (rc != 0)
+               RETURN(rc);
+
+       lu_echo_root_fid(&fid);
+       if (echo_md_seq_site(emd)->ss_node_id == 0) {
+               rc = echo_md_local_file_create(env, emd, ed->ed_los,
+                                              &emd->emd_local_root_fid,
+                                              echo_md_root_dir_name, S_IFDIR |
+                                              S_IRUGO | S_IWUSR | S_IXUGO,
+                                              &fid);
+               if (rc != 0) {
+                       CERROR("%s: create md echo root fid failed: rc = %d\n",
+                              emd2obd_dev(emd)->obd_name, rc);
+                       GOTO(out_los, rc);
+               }
+       }
+       ed->ed_root_fid = fid;
+
+       RETURN(0);
+out_los:
+       echo_ed_los_fini(env, ed);
+
+       RETURN(rc);
+}
 #endif /* HAVE_SERVER_SUPPORT */
 
 static struct lu_device *echo_device_alloc(const struct lu_env *env,
@@ -712,7 +840,6 @@ static struct lu_device *echo_device_alloc(const struct lu_env *env,
                 GOTO(out, rc);
 
         cd->cd_lu_dev.ld_ops = &echo_device_lu_ops;
-        cd->cd_ops = &echo_device_cl_ops;
 
         cleanup = 2;
         obd = class_name2obd(lustre_cfg_string(cfg, 0));
@@ -751,10 +878,12 @@ static struct lu_device *echo_device_alloc(const struct lu_env *env,
 
         if (ed->ed_next_ismd) {
 #ifdef HAVE_SERVER_SUPPORT
-                /* Suppose to connect to some Metadata layer */
-                struct lu_site *ls;
-                struct lu_device *ld;
-                int    found = 0;
+               /* Suppose to connect to some Metadata layer */
+               struct lu_site          *ls = NULL;
+               struct lu_device        *ld = NULL;
+               struct md_device        *md = NULL;
+               struct echo_md_device   *emd = NULL;
+               int                      found = 0;
 
                 if (next == NULL) {
                         CERROR("%s is not lu device type!\n",
@@ -787,16 +916,24 @@ static struct lu_device *echo_device_alloc(const struct lu_env *env,
                         GOTO(out, rc = -EINVAL);
                 }
 
-                next = ld;
-                /* For MD echo client, it will use the site in MDS stack */
-                ed->ed_site_myself.cs_lu = *ls;
-                ed->ed_site = &ed->ed_site_myself;
-                ed->ed_cl.cd_lu_dev.ld_site = &ed->ed_site_myself.cs_lu;
+               next = ld;
+               /* For MD echo client, it will use the site in MDS stack */
+               ed->ed_site = ls;
+               ed->ed_cl.cd_lu_dev.ld_site = ls;
                rc = echo_fid_init(ed, obd->obd_name, lu_site2seq(ls));
                if (rc) {
                        CERROR("echo fid init error %d\n", rc);
                        GOTO(out, rc);
                }
+
+               md = lu2md_dev(next);
+               emd = lu2emd_dev(&md->md_lu_dev);
+               rc = echo_md_root_get(env, emd, ed);
+               if (rc != 0) {
+                       CERROR("%s: get root error: rc = %d\n",
+                               emd2obd_dev(emd)->obd_name, rc);
+                       GOTO(out, rc);
+               }
 #else /* !HAVE_SERVER_SUPPORT */
                CERROR("Local operations are NOT supported on client side. "
                       "Only remote operations are supported. Metadata client "
@@ -815,7 +952,7 @@ static struct lu_device *echo_device_alloc(const struct lu_env *env,
                         if (next->ld_site != NULL)
                                 GOTO(out, rc = -EBUSY);
 
-                        next->ld_site = &ed->ed_site->cs_lu;
+                        next->ld_site = ed->ed_site;
                         rc = next->ld_type->ldt_ops->ldto_device_init(env, next,
                                                      next->ld_type->ldt_name,
                                                      NULL);
@@ -888,7 +1025,7 @@ static struct lu_device *echo_device_free(const struct lu_env *env,
         CDEBUG(D_INFO, "echo device:%p is going to be freed, next = %p\n",
                ed, next);
 
-        lu_site_purge(env, &ed->ed_site->cs_lu, -1);
+       lu_site_purge(env, ed->ed_site, -1);
 
         /* check if there are objects still alive.
          * It shouldn't have any object because lu_site_purge would cleanup
@@ -901,7 +1038,7 @@ static struct lu_device *echo_device_free(const struct lu_env *env,
        spin_unlock(&ec->ec_lock);
 
        /* purge again */
-       lu_site_purge(env, &ed->ed_site->cs_lu, -1);
+       lu_site_purge(env, ed->ed_site, -1);
 
        CDEBUG(D_INFO,
               "Waiting for the reference of echo object to be dropped\n");
@@ -912,9 +1049,9 @@ static struct lu_device *echo_device_free(const struct lu_env *env,
                spin_unlock(&ec->ec_lock);
                CERROR("echo_client still has objects at cleanup time, "
                       "wait for 1 second\n");
-               schedule_timeout_and_set_state(TASK_UNINTERRUPTIBLE,
-                                                  cfs_time_seconds(1));
-               lu_site_purge(env, &ed->ed_site->cs_lu, -1);
+               set_current_state(TASK_UNINTERRUPTIBLE);
+               schedule_timeout(cfs_time_seconds(1));
+               lu_site_purge(env, ed->ed_site, -1);
                spin_lock(&ec->ec_lock);
        }
        spin_unlock(&ec->ec_lock);
@@ -926,11 +1063,12 @@ static struct lu_device *echo_device_free(const struct lu_env *env,
        echo_client_cleanup(d->ld_obd);
 #ifdef HAVE_SERVER_SUPPORT
        echo_fid_fini(d->ld_obd);
+       echo_ed_los_fini(env, ed);
 #endif
        while (next && !ed->ed_next_ismd)
                next = next->ld_type->ldt_ops->ldto_device_free(env, next);
 
-        LASSERT(ed->ed_site == lu2cl_site(d->ld_site));
+        LASSERT(ed->ed_site == d->ld_site);
         echo_site_fini(env, ed);
         cl_device_fini(&ed->ed_cl);
         OBD_FREE_PTR(ed);
@@ -977,7 +1115,7 @@ cl_echo_object_find(struct echo_device *d, const struct ost_id *oi)
        struct cl_object *obj;
        struct lov_oinfo *oinfo = NULL;
        struct lu_fid *fid;
-       int refcheck;
+       __u16  refcheck;
        int rc;
        ENTRY;
 
@@ -1037,7 +1175,7 @@ static int cl_echo_object_put(struct echo_object *eco)
 {
         struct lu_env *env;
         struct cl_object *obj = echo_obj2cl(eco);
-        int refcheck;
+       __u16  refcheck;
         ENTRY;
 
         env = cl_env_get(&refcheck);
@@ -1157,12 +1295,12 @@ static int cl_echo_object_brw(struct echo_object *eco, int rw, u64 offset,
         struct cl_page          *clp;
         struct lustre_handle    lh = { 0 };
         int page_size = cl_page_size(obj);
-        int refcheck;
         int rc;
         int i;
+       __u16 refcheck;
         ENTRY;
 
-        LASSERT((offset & ~CFS_PAGE_MASK) == 0);
+       LASSERT((offset & ~PAGE_MASK) == 0);
         LASSERT(ed->ed_next != NULL);
         env = cl_env_get(&refcheck);
         if (IS_ERR(env))
@@ -1820,22 +1958,16 @@ static struct lu_object *echo_resolve_path(const struct lu_env *env,
                                            struct echo_device *ed, char *path,
                                            int path_len)
 {
-        struct lu_device        *ld = ed->ed_next;
-        struct md_device        *md = lu2md_dev(ld);
-        struct echo_thread_info *info = echo_env_info(env);
-        struct lu_fid           *fid = &info->eti_fid;
-        struct lu_name          *lname = &info->eti_lname;
-        struct lu_object        *parent = NULL;
-        struct lu_object        *child = NULL;
-        int rc = 0;
-        ENTRY;
+       struct lu_device        *ld = ed->ed_next;
+       struct echo_thread_info *info = echo_env_info(env);
+       struct lu_fid           *fid = &info->eti_fid;
+       struct lu_name          *lname = &info->eti_lname;
+       struct lu_object        *parent = NULL;
+       struct lu_object        *child = NULL;
+       int                      rc = 0;
+       ENTRY;
 
-        /*Only support MDD layer right now*/
-        rc = md->md_ops->mdo_root_get(env, md, fid);
-        if (rc) {
-                CERROR("get root error: rc = %d\n", rc);
-                RETURN(ERR_PTR(rc));
-        }
+       *fid = ed->ed_root_fid;
 
        /* In the function below, .hs_keycmp resolves to
         * lu_obj_hop_keycmp() */
@@ -1928,7 +2060,7 @@ static int echo_md_handler(struct echo_device *ed, int command,
        struct echo_thread_info *info;
         struct lu_device      *ld = ed->ed_next;
         struct lu_env         *env;
-        int                    refcheck;
+       __u16                  refcheck;
         struct lu_object      *parent;
         char                  *name = NULL;
         int                    namelen = data->ioc_plen2;
@@ -2040,7 +2172,7 @@ out_env:
 #endif /* HAVE_SERVER_SUPPORT */
 
 static int echo_create_object(const struct lu_env *env, struct echo_device *ed,
-                             struct obdo *oa, struct obd_trans_info *oti)
+                             struct obdo *oa)
 {
        struct echo_object      *eco;
        struct echo_client_obd  *ec = ed->ed_ec;
@@ -2058,7 +2190,7 @@ static int echo_create_object(const struct lu_env *env, struct echo_device *ed,
        if (ostid_id(&oa->o_oi) == 0)
                ostid_set_id(&oa->o_oi, ++last_object_id);
 
-       rc = obd_create(env, ec->ec_exp, oa, oti);
+       rc = obd_create(env, ec->ec_exp, oa);
        if (rc != 0) {
                CERROR("Cannot create objects: rc = %d\n", rc);
                GOTO(failed, rc);
@@ -2078,7 +2210,7 @@ static int echo_create_object(const struct lu_env *env, struct echo_device *ed,
 
 failed:
        if (created && rc != 0)
-               obd_destroy(env, ec->ec_exp, oa, oti);
+               obd_destroy(env, ec->ec_exp, oa);
 
        if (rc != 0)
                CERROR("create object failed with: rc = %d\n", rc);
@@ -2182,8 +2314,7 @@ echo_client_page_debug_check(struct page *page, u64 id, u64 offset, u64 count)
 
 static int echo_client_kbrw(struct echo_device *ed, int rw, struct obdo *oa,
                            struct echo_object *eco, u64 offset,
-                           u64 count, int async,
-                           struct obd_trans_info *oti)
+                           u64 count, int async)
 {
        size_t                  npages;
         struct brw_page        *pga;
@@ -2205,7 +2336,7 @@ static int echo_client_kbrw(struct echo_device *ed, int rw, struct obdo *oa,
 
        LASSERT(rw == OBD_BRW_WRITE || rw == OBD_BRW_READ);
 
-       if ((count & (~CFS_PAGE_MASK)) != 0)
+       if ((count & (~PAGE_MASK)) != 0)
                RETURN(-EINVAL);
 
         /* XXX think again with misaligned I/O */
@@ -2224,27 +2355,27 @@ static int echo_client_kbrw(struct echo_device *ed, int rw, struct obdo *oa,
                 RETURN(-ENOMEM);
         }
 
-        for (i = 0, pgp = pga, off = offset;
-             i < npages;
+       for (i = 0, pgp = pga, off = offset;
+            i < npages;
             i++, pgp++, off += PAGE_CACHE_SIZE) {
 
-                LASSERT (pgp->pg == NULL);      /* for cleanup */
+               LASSERT(pgp->pg == NULL);       /* for cleanup */
 
-                rc = -ENOMEM;
-                OBD_PAGE_ALLOC(pgp->pg, gfp_mask);
-                if (pgp->pg == NULL)
-                        goto out;
+               rc = -ENOMEM;
+               pgp->pg = alloc_page(gfp_mask);
+               if (pgp->pg == NULL)
+                       goto out;
 
-                pages[i] = pgp->pg;
+               pages[i] = pgp->pg;
                pgp->count = PAGE_CACHE_SIZE;
-                pgp->off = off;
-                pgp->flag = brw_flags;
+               pgp->off = off;
+               pgp->flag = brw_flags;
 
                if (verify)
                        echo_client_page_debug_setup(pgp->pg, rw,
                                                     ostid_id(&oa->o_oi), off,
                                                     pgp->count);
-        }
+       }
 
         /* brw mode can only be used at client */
         LASSERT(ed->ed_next != NULL);
@@ -2266,7 +2397,7 @@ static int echo_client_kbrw(struct echo_device *ed, int rw, struct obdo *oa,
                        if (vrc != 0 && rc == 0)
                                rc = vrc;
                }
-               OBD_PAGE_FREE(pgp->pg);
+               __free_page(pgp->pg);
         }
         OBD_FREE(pga, npages * sizeof(*pga));
         OBD_FREE(pages, npages * sizeof(*pages));
@@ -2277,12 +2408,11 @@ static int echo_client_prep_commit(const struct lu_env *env,
                                   struct obd_export *exp, int rw,
                                   struct obdo *oa, struct echo_object *eco,
                                   u64 offset, u64 count,
-                                  u64 batch, struct obd_trans_info *oti,
-                                  int async)
+                                  u64 batch, int async)
 {
        struct obd_ioobj         ioo;
        struct niobuf_local     *lnb;
-       struct niobuf_remote    *rnb;
+       struct niobuf_remote     rnb;
        u64                      off;
        u64                      npages, tot_pages;
        int i, ret = 0, brw_flags = 0;
@@ -2295,41 +2425,35 @@ static int echo_client_prep_commit(const struct lu_env *env,
        npages = batch >> PAGE_CACHE_SHIFT;
        tot_pages = count >> PAGE_CACHE_SHIFT;
 
-        OBD_ALLOC(lnb, npages * sizeof(struct niobuf_local));
-        OBD_ALLOC(rnb, npages * sizeof(struct niobuf_remote));
-
-        if (lnb == NULL || rnb == NULL)
-                GOTO(out, ret = -ENOMEM);
+       OBD_ALLOC(lnb, npages * sizeof(struct niobuf_local));
+       if (lnb == NULL)
+               GOTO(out, ret = -ENOMEM);
 
        if (rw == OBD_BRW_WRITE && async)
                brw_flags |= OBD_BRW_ASYNC;
 
-        obdo_to_ioobj(oa, &ioo);
+       obdo_to_ioobj(oa, &ioo);
 
-        off = offset;
+       off = offset;
 
-        for(; tot_pages; tot_pages -= npages) {
-                int lpages;
+       for (; tot_pages > 0; tot_pages -= npages) {
+               int lpages;
 
-                if (tot_pages < npages)
-                        npages = tot_pages;
-
-               for (i = 0; i < npages; i++, off += PAGE_CACHE_SIZE) {
-                       rnb[i].rnb_offset = off;
-                       rnb[i].rnb_len = PAGE_CACHE_SIZE;
-                       rnb[i].rnb_flags = brw_flags;
-                }
+               if (tot_pages < npages)
+                       npages = tot_pages;
 
-                ioo.ioo_bufcnt = npages;
+               rnb.rnb_offset = off;
+               rnb.rnb_len = npages * PAGE_CACHE_SIZE;
+               rnb.rnb_flags = brw_flags;
+               ioo.ioo_bufcnt = 1;
+               off += npages * PAGE_CACHE_SIZE;
 
                 lpages = npages;
-               ret = obd_preprw(env, rw, exp, oa, 1, &ioo, rnb, &lpages,
-                                 lnb, oti, NULL);
+               ret = obd_preprw(env, rw, exp, oa, 1, &ioo, &rnb, &lpages, lnb);
                 if (ret != 0)
                         GOTO(out, ret);
-                LASSERT(lpages == npages);
 
-                for (i = 0; i < lpages; i++) {
+               for (i = 0; i < lpages; i++) {
                        struct page *page = lnb[i].lnb_page;
 
                        /* read past eof? */
@@ -2346,41 +2470,35 @@ static int echo_client_prep_commit(const struct lu_env *env,
 
                        if (rw == OBD_BRW_WRITE)
                                echo_client_page_debug_setup(page, rw,
-                                                           ostid_id(&oa->o_oi),
-                                                            rnb[i].rnb_offset,
-                                                            rnb[i].rnb_len);
+                                                       ostid_id(&oa->o_oi),
+                                                       lnb[i].lnb_file_offset,
+                                                       lnb[i].lnb_len);
                        else
                                echo_client_page_debug_check(page,
-                                                           ostid_id(&oa->o_oi),
-                                                            rnb[i].rnb_offset,
-                                                            rnb[i].rnb_len);
+                                                       ostid_id(&oa->o_oi),
+                                                       lnb[i].lnb_file_offset,
+                                                       lnb[i].lnb_len);
                }
 
-               ret = obd_commitrw(env, rw, exp, oa, 1, &ioo,
-                                  rnb, npages, lnb, oti, ret);
+               ret = obd_commitrw(env, rw, exp, oa, 1, &ioo, &rnb, npages, lnb,
+                                  ret);
                 if (ret != 0)
                         GOTO(out, ret);
 
-                /* Reset oti otherwise it would confuse ldiskfs. */
-                memset(oti, 0, sizeof(*oti));
-
                /* Reuse env context. */
                lu_context_exit((struct lu_context *)&env->le_ctx);
                lu_context_enter((struct lu_context *)&env->le_ctx);
-        }
+       }
 
 out:
-        if (lnb)
-                OBD_FREE(lnb, npages * sizeof(struct niobuf_local));
-        if (rnb)
-                OBD_FREE(rnb, npages * sizeof(struct niobuf_remote));
-        RETURN(ret);
+       if (lnb)
+               OBD_FREE(lnb, npages * sizeof(struct niobuf_local));
+       RETURN(ret);
 }
 
 static int echo_client_brw_ioctl(const struct lu_env *env, int rw,
                                 struct obd_export *exp,
-                                struct obd_ioctl_data *data,
-                                struct obd_trans_info *dummy_oti)
+                                struct obd_ioctl_data *data)
 {
         struct obd_device *obd = class_exp2obd(exp);
         struct echo_device *ed = obd2echo_dev(obd);
@@ -2418,26 +2536,26 @@ static int echo_client_brw_ioctl(const struct lu_env *env, int rw,
         case 1:
                 /* fall through */
         case 2:
-                rc = echo_client_kbrw(ed, rw, oa,
-                                      eco, data->ioc_offset,
-                                     data->ioc_count, async, dummy_oti);
-                break;
-        case 3:
-               rc = echo_client_prep_commit(env, ec->ec_exp, rw, oa,
-                                            eco, data->ioc_offset,
-                                            data->ioc_count, data->ioc_plen1,
-                                            dummy_oti, async);
-                break;
-        default:
-                rc = -EINVAL;
-        }
-        echo_put_object(eco);
-        RETURN(rc);
+               rc = echo_client_kbrw(ed, rw, oa, eco, data->ioc_offset,
+                                     data->ioc_count, async);
+               break;
+       case 3:
+               rc = echo_client_prep_commit(env, ec->ec_exp, rw, oa, eco,
+                                            data->ioc_offset, data->ioc_count,
+                                            data->ioc_plen1, async);
+               break;
+       default:
+               rc = -EINVAL;
+       }
+
+       echo_put_object(eco);
+
+       RETURN(rc);
 }
 
 static int
 echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
-                      void *karg, void *uarg)
+                     void *karg, void __user *uarg)
 {
 #ifdef HAVE_SERVER_SUPPORT
        struct tgt_session_info *tsi;
@@ -2447,21 +2565,16 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
         struct echo_client_obd *ec = ed->ed_ec;
         struct echo_object     *eco;
         struct obd_ioctl_data  *data = karg;
-        struct obd_trans_info   dummy_oti;
         struct lu_env          *env;
-        struct oti_req_ack_lock *ack_lock;
         struct obdo            *oa;
         struct lu_fid           fid;
         int                     rw = OBD_BRW_READ;
         int                     rc = 0;
-        int                     i;
 #ifdef HAVE_SERVER_SUPPORT
        struct lu_context        echo_session;
 #endif
         ENTRY;
 
-        memset(&dummy_oti, 0, sizeof(dummy_oti));
-
        oa = &data->ioc_obdo1;
        if (!(oa->o_valid & OBD_MD_FLGROUP)) {
                oa->o_valid |= OBD_MD_FLGROUP;
@@ -2497,7 +2610,7 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                 if (!cfs_capable(CFS_CAP_SYS_ADMIN))
                         GOTO (out, rc = -EPERM);
 
-               rc = echo_create_object(env, ed, oa, &dummy_oti);
+               rc = echo_create_object(env, ed, oa);
                 GOTO(out, rc);
 
 #ifdef HAVE_SERVER_SUPPORT
@@ -2531,7 +2644,7 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
        }
         case OBD_IOC_ECHO_ALLOC_SEQ: {
                 struct lu_env   *cl_env;
-                int              refcheck;
+               __u16            refcheck;
                 __u64            seq;
                 int              max_count;
 
@@ -2573,7 +2686,7 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
 
                 rc = echo_get_object(&eco, ed, oa);
                 if (rc == 0) {
-                       rc = obd_destroy(env, ec->ec_exp, oa, &dummy_oti);
+                       rc = obd_destroy(env, ec->ec_exp, oa);
                         if (rc == 0)
                                 eco->eo_deleted = 1;
                         echo_put_object(eco);
@@ -2583,11 +2696,7 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
         case OBD_IOC_GETATTR:
                 rc = echo_get_object(&eco, ed, oa);
                 if (rc == 0) {
-                       struct obd_info oinfo = {
-                               .oi_oa = oa,
-                       };
-
-                        rc = obd_getattr(env, ec->ec_exp, &oinfo);
+                       rc = obd_getattr(env, ec->ec_exp, oa);
                         echo_put_object(eco);
                 }
                 GOTO(out, rc);
@@ -2598,11 +2707,7 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
 
                 rc = echo_get_object(&eco, ed, oa);
                 if (rc == 0) {
-                       struct obd_info oinfo = {
-                               .oi_oa = oa,
-                       };
-
-                        rc = obd_setattr(env, ec->ec_exp, &oinfo, NULL);
+                       rc = obd_setattr(env, ec->ec_exp, oa);
                         echo_put_object(eco);
                 }
                 GOTO(out, rc);
@@ -2614,7 +2719,7 @@ echo_client_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
                 rw = OBD_BRW_WRITE;
                 /* fall through */
         case OBD_IOC_BRW_READ:
-               rc = echo_client_brw_ioctl(env, rw, exp, data, &dummy_oti);
+               rc = echo_client_brw_ioctl(env, rw, exp, data);
                 GOTO(out, rc);
 
         default:
@@ -2633,14 +2738,6 @@ out_env:
 out_alloc:
         OBD_FREE_PTR(env);
 
-        /* XXX this should be in a helper also called by target_send_reply */
-        for (ack_lock = dummy_oti.oti_ack_locks, i = 0; i < 4;
-             i++, ack_lock++) {
-                if (!ack_lock->mode)
-                        break;
-                ldlm_lock_decref(&ack_lock->lock, ack_lock->mode);
-        }
-
         return rc;
 }
 
@@ -2791,27 +2888,6 @@ static struct obd_ops echo_client_obd_ops = {
         .o_disconnect  = echo_client_disconnect
 };
 
-static int echo_client_init(void)
-{
-        int rc;
-
-       rc = lu_kmem_init(echo_caches);
-       if (rc == 0) {
-               rc = class_register_type(&echo_client_obd_ops, NULL, true, NULL,
-                                        LUSTRE_ECHO_CLIENT_NAME,
-                                        &echo_device_type);
-               if (rc)
-                       lu_kmem_fini(echo_caches);
-       }
-       return rc;
-}
-
-static void echo_client_exit(void)
-{
-        class_unregister_type(LUSTRE_ECHO_CLIENT_NAME);
-        lu_kmem_fini(echo_caches);
-}
-
 static int __init obdecho_init(void)
 {
         int rc;
@@ -2832,7 +2908,14 @@ static int __init obdecho_init(void)
                goto failed_1;
 # endif
 
-        rc = echo_client_init();
+       rc = lu_kmem_init(echo_caches);
+       if (rc == 0) {
+               rc = class_register_type(&echo_client_obd_ops, NULL, true, NULL,
+                                        LUSTRE_ECHO_CLIENT_NAME,
+                                        &echo_device_type);
+               if (rc)
+                       lu_kmem_fini(echo_caches);
+       }
 
 # ifdef HAVE_SERVER_SUPPORT
         if (rc == 0)
@@ -2846,20 +2929,23 @@ failed_0:
         RETURN(rc);
 }
 
-static void /*__exit*/ obdecho_exit(void)
+static void __exit obdecho_exit(void)
 {
-        echo_client_exit();
+       class_unregister_type(LUSTRE_ECHO_CLIENT_NAME);
+       lu_kmem_fini(echo_caches);
 
-# ifdef HAVE_SERVER_SUPPORT
-        class_unregister_type(LUSTRE_ECHO_NAME);
-        echo_persistent_pages_fini();
-# endif
+#ifdef HAVE_SERVER_SUPPORT
+       class_unregister_type(LUSTRE_ECHO_NAME);
+       echo_persistent_pages_fini();
+#endif
 }
 
-MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
-MODULE_DESCRIPTION("Lustre Testing Echo OBD driver");
+MODULE_AUTHOR("OpenSFS, Inc. <http://www.lustre.org/>");
+MODULE_DESCRIPTION("Lustre Echo Client test driver");
+MODULE_VERSION(LUSTRE_VERSION_STRING);
 MODULE_LICENSE("GPL");
 
-cfs_module(obdecho, LUSTRE_VERSION_STRING, obdecho_init, obdecho_exit);
+module_init(obdecho_init);
+module_exit(obdecho_exit);
 
 /** @} echo_client */