aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/compat.c')
-rw-r--r--fs/compat.c44
1 files changed, 11 insertions, 33 deletions
diff --git a/fs/compat.c b/fs/compat.c
index 122b4e3992b5..6b90bf35f61d 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -70,6 +70,8 @@ int compat_printk(const char *fmt, ...)
70 return ret; 70 return ret;
71} 71}
72 72
73#include "read_write.h"
74
73/* 75/*
74 * Not all architectures have sys_utime, so implement this in terms 76 * Not all architectures have sys_utime, so implement this in terms
75 * of sys_utimes. 77 * of sys_utimes.
@@ -1149,9 +1151,6 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
1149 const struct compat_iovec __user *uvector, 1151 const struct compat_iovec __user *uvector,
1150 unsigned long nr_segs, loff_t *pos) 1152 unsigned long nr_segs, loff_t *pos)
1151{ 1153{
1152 typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *);
1153 typedef ssize_t (*iov_fn_t)(struct file *, const struct iovec *, unsigned long, loff_t *);
1154
1155 compat_ssize_t tot_len; 1154 compat_ssize_t tot_len;
1156 struct iovec iovstack[UIO_FASTIOV]; 1155 struct iovec iovstack[UIO_FASTIOV];
1157 struct iovec *iov=iovstack, *vector; 1156 struct iovec *iov=iovstack, *vector;
@@ -1234,39 +1233,18 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
1234 fnv = NULL; 1233 fnv = NULL;
1235 if (type == READ) { 1234 if (type == READ) {
1236 fn = file->f_op->read; 1235 fn = file->f_op->read;
1237 fnv = file->f_op->readv; 1236 fnv = file->f_op->aio_read;
1238 } else { 1237 } else {
1239 fn = (io_fn_t)file->f_op->write; 1238 fn = (io_fn_t)file->f_op->write;
1240 fnv = file->f_op->writev; 1239 fnv = file->f_op->aio_write;
1241 }
1242 if (fnv) {
1243 ret = fnv(file, iov, nr_segs, pos);
1244 goto out;
1245 } 1240 }
1246 1241
1247 /* Do it by hand, with file-ops */ 1242 if (fnv)
1248 ret = 0; 1243 ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
1249 vector = iov; 1244 pos, fnv);
1250 while (nr_segs > 0) { 1245 else
1251 void __user * base; 1246 ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);
1252 size_t len;
1253 ssize_t nr;
1254
1255 base = vector->iov_base;
1256 len = vector->iov_len;
1257 vector++;
1258 nr_segs--;
1259
1260 nr = fn(file, base, len, pos);
1261 1247
1262 if (nr < 0) {
1263 if (!ret) ret = nr;
1264 break;
1265 }
1266 ret += nr;
1267 if (nr != len)
1268 break;
1269 }
1270out: 1248out:
1271 if (iov != iovstack) 1249 if (iov != iovstack)
1272 kfree(iov); 1250 kfree(iov);
@@ -1294,7 +1272,7 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, unsign
1294 goto out; 1272 goto out;
1295 1273
1296 ret = -EINVAL; 1274 ret = -EINVAL;
1297 if (!file->f_op || (!file->f_op->readv && !file->f_op->read)) 1275 if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read))
1298 goto out; 1276 goto out;
1299 1277
1300 ret = compat_do_readv_writev(READ, file, vec, vlen, &file->f_pos); 1278 ret = compat_do_readv_writev(READ, file, vec, vlen, &file->f_pos);
@@ -1317,7 +1295,7 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, unsig
1317 goto out; 1295 goto out;
1318 1296
1319 ret = -EINVAL; 1297 ret = -EINVAL;
1320 if (!file->f_op || (!file->f_op->writev && !file->f_op->write)) 1298 if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write))
1321 goto out; 1299 goto out;
1322 1300
1323 ret = compat_do_readv_writev(WRITE, file, vec, vlen, &file->f_pos); 1301 ret = compat_do_readv_writev(WRITE, file, vec, vlen, &file->f_pos);