9p: consolidate read/write functions
authorEric Van Hensbergen <ericvh@gmail.com>
Tue, 14 Oct 2008 01:36:17 +0000 (20:36 -0500)
committerEric Van Hensbergen <ericvh@gmail.com>
Fri, 17 Oct 2008 16:04:42 +0000 (11:04 -0500)
Currently there are two separate versions of read and write.  One for
dealing with user buffers and the other for dealing with kernel buffers.
There is a tremendous amount of code duplication in the otherwise
identical versions of these functions.  This patch adds an additional
user buffer parameter to read and write and conditionalizes handling of
the buffer on whether the kernel buffer or the user buffer is populated.

Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
fs/9p/vfs_file.c
include/net/9p/client.h
net/9p/client.c

index 52944d2249a49a1e05c7fdc05d63919180dc3a29..3819a195de8f027745880b2866d465e62444a910 100644 (file)
@@ -136,7 +136,7 @@ v9fs_file_read(struct file *filp, char __user * data, size_t count,
 
        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;
 
@@ -164,7 +164,7 @@ v9fs_file_write(struct file *filp, const char __user * data,
                (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);
index 6a71d906781810361e1d98a4f7b37a7d24e01f17..c70a0f0b448d1477bba1a1996c4ceb9e14495a9a 100644 (file)
@@ -201,13 +201,11 @@ int p9_client_fcreate(struct p9_fid *fid, char *name, u32 perm, int mode,
                                                        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);
index 29934febecdbe31cafe4c091193a59cc5a03c2c2..5fc3aa1eb39b3eeeed0d2f676c610c4c61c0b66e 100644 (file)
@@ -1016,7 +1016,9 @@ done:
 }
 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;
@@ -1053,125 +1055,21 @@ int p9_client_read(struct p9_fid *fid, char *data, u64 offset, u32 count)
                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);
@@ -1187,11 +1085,11 @@ error:
        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;
@@ -1213,7 +1111,10 @@ p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset,
                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;
@@ -1226,7 +1127,12 @@ p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset,
 
                n = rc->params.rread.count;
                count -= n;
-               data += n;
+
+               if (data)
+                       data += n;
+               else
+                       udata += n;
+
                offset += n;
                total += n;
                kfree(tc);
@@ -1242,7 +1148,7 @@ error:
        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)
 {
@@ -1253,7 +1159,7 @@ 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;