Commit 0fc9655ec67ec5d4dfd08e469e0e9f0a494bf5bc

Authored by Eric Van Hensbergen
1 parent 95820a3651

9p: consolidate read/write functions

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>

Showing 3 changed files with 34 additions and 130 deletions Side-by-side Diff

... ... @@ -136,7 +136,7 @@
136 136  
137 137 P9_DPRINTK(P9_DEBUG_VFS, "\n");
138 138 fid = filp->private_data;
139   - ret = p9_client_uread(fid, data, *offset, count);
  139 + ret = p9_client_read(fid, NULL, data, *offset, count);
140 140 if (ret > 0)
141 141 *offset += ret;
142 142  
... ... @@ -164,7 +164,7 @@
164 164 (int)count, (int)*offset);
165 165  
166 166 fid = filp->private_data;
167   - ret = p9_client_uwrite(fid, data, *offset, count);
  167 + ret = p9_client_write(fid, NULL, data, *offset, count);
168 168 if (ret > 0) {
169 169 invalidate_inode_pages2_range(inode->i_mapping, *offset,
170 170 *offset+ret);
include/net/9p/client.h
... ... @@ -201,13 +201,11 @@
201 201 char *extension);
202 202 int p9_client_clunk(struct p9_fid *fid);
203 203 int p9_client_remove(struct p9_fid *fid);
204   -int p9_client_read(struct p9_fid *fid, char *data, u64 offset, u32 count);
  204 +int p9_client_read(struct p9_fid *fid, char *data, char __user *udata,
  205 + u64 offset, u32 count);
205 206 int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count);
206   -int p9_client_write(struct p9_fid *fid, char *data, u64 offset, u32 count);
207   -int p9_client_uread(struct p9_fid *fid, char __user *data, u64 offset,
208   - u32 count);
209   -int p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset,
210   - u32 count);
  207 +int p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
  208 + u64 offset, u32 count);
211 209 struct p9_stat *p9_client_stat(struct p9_fid *fid);
212 210 int p9_client_wstat(struct p9_fid *fid, struct p9_wstat *wst);
213 211 struct p9_stat *p9_client_dirread(struct p9_fid *fid, u64 offset);
... ... @@ -1016,7 +1016,9 @@
1016 1016 }
1017 1017 EXPORT_SYMBOL(p9_client_remove);
1018 1018  
1019   -int p9_client_read(struct p9_fid *fid, char *data, u64 offset, u32 count)
  1019 +int
  1020 +p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
  1021 + u32 count)
1020 1022 {
1021 1023 int err, n, rsize, total;
1022 1024 struct p9_fcall *tc, *rc;
1023 1025  
1024 1026  
1025 1027  
... ... @@ -1053,125 +1055,21 @@
1053 1055 if (n > count)
1054 1056 n = count;
1055 1057  
1056   - memmove(data, rc->params.rread.data, n);
1057   - count -= n;
1058   - data += n;
1059   - offset += n;
1060   - total += n;
1061   - kfree(tc);
1062   - tc = NULL;
1063   - kfree(rc);
1064   - rc = NULL;
1065   - } while (count > 0 && n == rsize);
1066   -
1067   - return total;
1068   -
1069   -error:
1070   - kfree(tc);
1071   - kfree(rc);
1072   - return err;
1073   -}
1074   -EXPORT_SYMBOL(p9_client_read);
1075   -
1076   -int p9_client_write(struct p9_fid *fid, char *data, u64 offset, u32 count)
1077   -{
1078   - int err, n, rsize, total;
1079   - struct p9_fcall *tc, *rc;
1080   - struct p9_client *clnt;
1081   -
1082   - P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid,
1083   - (long long unsigned) offset, count);
1084   - err = 0;
1085   - tc = NULL;
1086   - rc = NULL;
1087   - clnt = fid->clnt;
1088   - total = 0;
1089   -
1090   - rsize = fid->iounit;
1091   - if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
1092   - rsize = clnt->msize - P9_IOHDRSZ;
1093   -
1094   - do {
1095   - if (count < rsize)
1096   - rsize = count;
1097   -
1098   - tc = p9_create_twrite(fid->fid, offset, rsize, data);
1099   - if (IS_ERR(tc)) {
1100   - err = PTR_ERR(tc);
1101   - tc = NULL;
1102   - goto error;
  1058 + if (data) {
  1059 + memmove(data, rc->params.rread.data, n);
  1060 + data += n;
1103 1061 }
1104 1062  
1105   - err = p9_client_rpc(clnt, tc, &rc);
1106   - if (err)
1107   - goto error;
1108   -
1109   - n = rc->params.rread.count;
1110   - count -= n;
1111   - data += n;
1112   - offset += n;
1113   - total += n;
1114   - kfree(tc);
1115   - tc = NULL;
1116   - kfree(rc);
1117   - rc = NULL;
1118   - } while (count > 0);
1119   -
1120   - return total;
1121   -
1122   -error:
1123   - kfree(tc);
1124   - kfree(rc);
1125   - return err;
1126   -}
1127   -EXPORT_SYMBOL(p9_client_write);
1128   -
1129   -int
1130   -p9_client_uread(struct p9_fid *fid, char __user *data, u64 offset, u32 count)
1131   -{
1132   - int err, n, rsize, total;
1133   - struct p9_fcall *tc, *rc;
1134   - struct p9_client *clnt;
1135   -
1136   - P9_DPRINTK(P9_DEBUG_9P, "fid %d offset %llu count %d\n", fid->fid,
1137   - (long long unsigned) offset, count);
1138   - err = 0;
1139   - tc = NULL;
1140   - rc = NULL;
1141   - clnt = fid->clnt;
1142   - total = 0;
1143   -
1144   - rsize = fid->iounit;
1145   - if (!rsize || rsize > clnt->msize-P9_IOHDRSZ)
1146   - rsize = clnt->msize - P9_IOHDRSZ;
1147   -
1148   - do {
1149   - if (count < rsize)
1150   - rsize = count;
1151   -
1152   - tc = p9_create_tread(fid->fid, offset, rsize);
1153   - if (IS_ERR(tc)) {
1154   - err = PTR_ERR(tc);
1155   - tc = NULL;
1156   - goto error;
  1063 + if (udata) {
  1064 + err = copy_to_user(udata, rc->params.rread.data, n);
  1065 + if (err) {
  1066 + err = -EFAULT;
  1067 + goto error;
  1068 + }
  1069 + udata += n;
1157 1070 }
1158 1071  
1159   - err = p9_client_rpc(clnt, tc, &rc);
1160   - if (err)
1161   - goto error;
1162   -
1163   - n = rc->params.rread.count;
1164   - if (n > count)
1165   - n = count;
1166   -
1167   - err = copy_to_user(data, rc->params.rread.data, n);
1168   - if (err) {
1169   - err = -EFAULT;
1170   - goto error;
1171   - }
1172   -
1173 1072 count -= n;
1174   - data += n;
1175 1073 offset += n;
1176 1074 total += n;
1177 1075 kfree(tc);
1178 1076  
... ... @@ -1187,11 +1085,11 @@
1187 1085 kfree(rc);
1188 1086 return err;
1189 1087 }
1190   -EXPORT_SYMBOL(p9_client_uread);
  1088 +EXPORT_SYMBOL(p9_client_read);
1191 1089  
1192 1090 int
1193   -p9_client_uwrite(struct p9_fid *fid, const char __user *data, u64 offset,
1194   - u32 count)
  1091 +p9_client_write(struct p9_fid *fid, char *data, const char __user *udata,
  1092 + u64 offset, u32 count)
1195 1093 {
1196 1094 int err, n, rsize, total;
1197 1095 struct p9_fcall *tc, *rc;
... ... @@ -1213,7 +1111,10 @@
1213 1111 if (count < rsize)
1214 1112 rsize = count;
1215 1113  
1216   - tc = p9_create_twrite_u(fid->fid, offset, rsize, data);
  1114 + if (data)
  1115 + tc = p9_create_twrite(fid->fid, offset, rsize, data);
  1116 + else
  1117 + tc = p9_create_twrite_u(fid->fid, offset, rsize, udata);
1217 1118 if (IS_ERR(tc)) {
1218 1119 err = PTR_ERR(tc);
1219 1120 tc = NULL;
... ... @@ -1226,7 +1127,12 @@
1226 1127  
1227 1128 n = rc->params.rread.count;
1228 1129 count -= n;
1229   - data += n;
  1130 +
  1131 + if (data)
  1132 + data += n;
  1133 + else
  1134 + udata += n;
  1135 +
1230 1136 offset += n;
1231 1137 total += n;
1232 1138 kfree(tc);
... ... @@ -1242,7 +1148,7 @@
1242 1148 kfree(rc);
1243 1149 return err;
1244 1150 }
1245   -EXPORT_SYMBOL(p9_client_uwrite);
  1151 +EXPORT_SYMBOL(p9_client_write);
1246 1152  
1247 1153 int p9_client_readn(struct p9_fid *fid, char *data, u64 offset, u32 count)
1248 1154 {
... ... @@ -1253,7 +1159,7 @@
1253 1159 n = 0;
1254 1160 total = 0;
1255 1161 while (count) {
1256   - n = p9_client_read(fid, data, offset, count);
  1162 + n = p9_client_read(fid, data, NULL, offset, count);
1257 1163 if (n <= 0)
1258 1164 break;
1259 1165