P9_DPRINTK(P9_DEBUG_VFS, "\n");
        fid = filp->private_data;
-       ret = p9_client_uread(fid, data, *offset, count);
+       ret = p9_client_read(fid, NULL, data, *offset, count);
        if (ret > 0)
                *offset += ret;
 
                (int)count, (int)*offset);
 
        fid = filp->private_data;
-       ret = p9_client_uwrite(fid, data, *offset, count);
+       ret = p9_client_write(fid, NULL, data, *offset, count);
        if (ret > 0) {
                invalidate_inode_pages2_range(inode->i_mapping, *offset,
                                                                *offset+ret);
 
                                                        char *extension);
 int p9_client_clunk(struct p9_fid *fid);
 int p9_client_remove(struct p9_fid *fid);
-int p9_client_read(struct p9_fid *fid, char *data, u64 offset, u32 count);
+int p9_client_read(struct p9_fid *fid, char *data, char __user *udata,
+                                                       u64 offset, u32 count);
 int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count);
-int p9_client_write(struct p9_fid *fid, char *data, u64 offset, u32 count);
-int p9_client_uread(struct p9_fid *fid, char __user *data, u64 offset,
-                                                               u32 count);
-int p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset,
-                                                               u32 count);
+int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
+                                                       u64 offset, u32 count);
 struct p9_stat *p9_client_stat(struct p9_fid *fid);
 int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst);
 struct p9_stat *p9_client_dirread(struct p9_fid *fid, u64 offset);
 
 }
 EXPORT_SYMBOL(p9_client_remove);
 
-int p9_client_read(struct p9_fid *fid, char *data, u64 offset, u32 count)
+int
+p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
+                                                               u32 count)
 {
        int err, n, rsize, total;
        struct p9_fcall *tc, *rc;
                if (n > count)
                        n = count;
 
-               memmove(data, rc->params.rread.data, n);
-               count -= n;
-               data += n;
-               offset += n;
-               total += n;
-               kfree(tc);
-               tc = NULL;
-               kfree(rc);
-               rc = NULL;
-       } while (count > 0 && n == rsize);
-
-       return total;
-
-error:
-       kfree(tc);
-       kfree(rc);
-       return err;
-}
-EXPORT_SYMBOL(p9_client_read);
-
-int p9_client_write(struct p9_fid *fid, char *data, u64 offset, u32 count)
-{
-       int err, n, rsize, total;
-       struct p9_fcall *tc, *rc;
-       struct p9_client *clnt;
-
-       P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid,
-                                       (long long unsigned) offset, count);
-       err = 0;
-       tc = NULL;
-       rc = NULL;
-       clnt = fid->clnt;
-       total = 0;
-
-       rsize = fid->iounit;
-       if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
-               rsize = clnt->msize - P9_IOHDRSZ;
-
-       do {
-               if (count < rsize)
-                       rsize = count;
-
-               tc = p9_create_twrite(fid->fid, offset, rsize, data);
-               if (IS_ERR(tc)) {
-                       err = PTR_ERR(tc);
-                       tc = NULL;
-                       goto error;
+               if (data) {
+                       memmove(data, rc->params.rread.data, n);
+                       data += n;
                }
 
-               err = p9_client_rpc(clnt, tc, &rc);
-               if (err)
-                       goto error;
-
-               n = rc->params.rread.count;
-               count -= n;
-               data += n;
-               offset += n;
-               total += n;
-               kfree(tc);
-               tc = NULL;
-               kfree(rc);
-               rc = NULL;
-       } while (count > 0);
-
-       return total;
-
-error:
-       kfree(tc);
-       kfree(rc);
-       return err;
-}
-EXPORT_SYMBOL(p9_client_write);
-
-int
-p9_client_uread(struct p9_fid *fid, char __user *data, u64 offset, u32 count)
-{
-       int err, n, rsize, total;
-       struct p9_fcall *tc, *rc;
-       struct p9_client *clnt;
-
-       P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid,
-                                       (long long unsigned) offset, count);
-       err = 0;
-       tc = NULL;
-       rc = NULL;
-       clnt = fid->clnt;
-       total = 0;
-
-       rsize = fid->iounit;
-       if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
-               rsize = clnt->msize - P9_IOHDRSZ;
-
-       do {
-               if (count < rsize)
-                       rsize = count;
-
-               tc = p9_create_tread(fid->fid, offset, rsize);
-               if (IS_ERR(tc)) {
-                       err = PTR_ERR(tc);
-                       tc = NULL;
-                       goto error;
-               }
-
-               err = p9_client_rpc(clnt, tc, &rc);
-               if (err)
-                       goto error;
-
-               n = rc->params.rread.count;
-               if (n > count)
-                       n = count;
-
-               err = copy_to_user(data, rc->params.rread.data, n);
-               if (err) {
-                       err = -EFAULT;
-                       goto error;
+               if (udata) {
+                       err = copy_to_user(udata, rc->params.rread.data, n);
+                       if (err) {
+                               err = -EFAULT;
+                               goto error;
+                       }
+                       udata += n;
                }
 
                count -= n;
-               data += n;
                offset += n;
                total += n;
                kfree(tc);
        kfree(rc);
        return err;
 }
-EXPORT_SYMBOL(p9_client_uread);
+EXPORT_SYMBOL(p9_client_read);
 
 int
-p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset,
-                                                                  u32 count)
+p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
+                                                       u64 offset, u32 count)
 {
        int err, n, rsize, total;
        struct p9_fcall *tc, *rc;
                if (count < rsize)
                        rsize = count;
 
-               tc = p9_create_twrite_u(fid->fid, offset, rsize, data);
+               if (data)
+                       tc = p9_create_twrite(fid->fid, offset, rsize, data);
+               else
+                       tc = p9_create_twrite_u(fid->fid, offset, rsize, udata);
                if (IS_ERR(tc)) {
                        err = PTR_ERR(tc);
                        tc = NULL;
 
                n = rc->params.rread.count;
                count -= n;
-               data += n;
+
+               if (data)
+                       data += n;
+               else
+                       udata += n;
+
                offset += n;
                total += n;
                kfree(tc);
        kfree(rc);
        return err;
 }
-EXPORT_SYMBOL(p9_client_uwrite);
+EXPORT_SYMBOL(p9_client_write);
 
 int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count)
 {
        n = 0;
        total = 0;
        while (count) {
-               n = p9_client_read(fid, data, offset, count);
+               n = p9_client_read(fid, data, NULL, offset, count);
                if (n <= 0)
                        break;