+
+ tmp1 = ost_req_buf1(r);
+ tmp2 = ost_req_buf2(r);
+ end2 = tmp2 + req->rq_req.ost->buflen2;
+ objcount = r->buflen1 / sizeof(*ioo);
+ niocount = r->buflen2 / sizeof(*nb);
+ cmd = r->cmd;
+
+ conn.oc_id = req->rq_req.ost->connid;
+ conn.oc_dev = req->rq_ost->ost_tgt;
+
+ rc = ost_pack_rep(NULL, niocount, NULL, 0,
+ &req->rq_rephdr, &req->rq_rep.ost,
+ &req->rq_replen, &req->rq_repbuf);
+ if (rc) {
+ printk("ost_create: cannot pack reply\n");
+ return rc;
+ }
+ res = ost_rep_buf1(req->rq_rep.ost);
+
+ for (i=0; i < objcount; i++) {
+ ost_unpack_ioo((void *)&tmp1, &ioo);
+ if (tmp2 + ioo->ioo_bufcnt > end2) {
+ rc = -EFAULT;
+ break;
+ }
+ for (j = 0 ; j < ioo->ioo_bufcnt ; j++) {
+ ost_unpack_niobuf((void *)&tmp2, &nb);
+ }
+ }
+
+ /* The unpackers move tmp1 and tmp2, so reset them before using */
+ tmp1 = ost_req_buf1(r);
+ tmp2 = ost_req_buf2(r);
+ req->rq_rep.ost->result =
+ req->rq_ost->ost_tgt->obd_type->typ_ops->o_preprw
+ (cmd, &conn, objcount, (struct obd_ioobj *)tmp1,
+ niocount, (struct niobuf *)tmp2, (struct niobuf *)res);
+
+ if (cmd == OBD_BRW_WRITE) {
+ for (i=0; i<niocount; i++) {
+ src = &((struct niobuf *)tmp2)[i];
+ dst = &((struct niobuf *)res)[i];
+ memcpy((void *)(unsigned long)dst->addr,
+ (void *)(unsigned long)src->addr,
+ src->len);
+ }
+ } else {
+ for (i=0; i<niocount; i++) {
+ dst = &((struct niobuf *)tmp2)[i];
+ src = &((struct niobuf *)res)[i];
+ memcpy((void *)(unsigned long)dst->addr,
+ (void *)(unsigned long)src->addr,
+ PAGE_SIZE);
+ }
+ }
+
+ req->rq_rep.ost->result =
+ req->rq_ost->ost_tgt->obd_type->typ_ops->o_commitrw
+ (cmd, &conn, objcount, (struct obd_ioobj *)tmp1,
+ niocount, (struct niobuf *)res);