aboutsummaryrefslogtreecommitdiffstats
path: root/fs/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/compat.c')
-rw-r--r--fs/compat.c89
1 files changed, 75 insertions, 14 deletions
diff --git a/fs/compat.c b/fs/compat.c
index baabf203b847..1c859dae758f 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -1196,16 +1196,12 @@ out:
1196 return ret; 1196 return ret;
1197} 1197}
1198 1198
1199asmlinkage ssize_t 1199static size_t compat_readv(struct file *file,
1200compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, unsigned long vlen) 1200 const struct compat_iovec __user *vec,
1201 unsigned long vlen, loff_t *pos)
1201{ 1202{
1202 struct file *file;
1203 ssize_t ret = -EBADF; 1203 ssize_t ret = -EBADF;
1204 1204
1205 file = fget(fd);
1206 if (!file)
1207 return -EBADF;
1208
1209 if (!(file->f_mode & FMODE_READ)) 1205 if (!(file->f_mode & FMODE_READ))
1210 goto out; 1206 goto out;
1211 1207
@@ -1213,25 +1209,56 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, unsign
1213 if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read)) 1209 if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read))
1214 goto out; 1210 goto out;
1215 1211
1216 ret = compat_do_readv_writev(READ, file, vec, vlen, &file->f_pos); 1212 ret = compat_do_readv_writev(READ, file, vec, vlen, pos);
1217 1213
1218out: 1214out:
1219 if (ret > 0) 1215 if (ret > 0)
1220 add_rchar(current, ret); 1216 add_rchar(current, ret);
1221 inc_syscr(current); 1217 inc_syscr(current);
1222 fput(file);
1223 return ret; 1218 return ret;
1224} 1219}
1225 1220
1226asmlinkage ssize_t 1221asmlinkage ssize_t
1227compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, unsigned long vlen) 1222compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec,
1223 unsigned long vlen)
1228{ 1224{
1229 struct file *file; 1225 struct file *file;
1230 ssize_t ret = -EBADF; 1226 int fput_needed;
1227 ssize_t ret;
1231 1228
1232 file = fget(fd); 1229 file = fget_light(fd, &fput_needed);
1233 if (!file) 1230 if (!file)
1234 return -EBADF; 1231 return -EBADF;
1232 ret = compat_readv(file, vec, vlen, &file->f_pos);
1233 fput_light(file, fput_needed);
1234 return ret;
1235}
1236
1237asmlinkage ssize_t
1238compat_sys_preadv(unsigned long fd, const struct compat_iovec __user *vec,
1239 unsigned long vlen, u32 pos_high, u32 pos_low)
1240{
1241 loff_t pos = ((loff_t)pos_high << 32) | pos_low;
1242 struct file *file;
1243 int fput_needed;
1244 ssize_t ret;
1245
1246 if (pos < 0)
1247 return -EINVAL;
1248 file = fget_light(fd, &fput_needed);
1249 if (!file)
1250 return -EBADF;
1251 ret = compat_readv(file, vec, vlen, &pos);
1252 fput_light(file, fput_needed);
1253 return ret;
1254}
1255
1256static size_t compat_writev(struct file *file,
1257 const struct compat_iovec __user *vec,
1258 unsigned long vlen, loff_t *pos)
1259{
1260 ssize_t ret = -EBADF;
1261
1235 if (!(file->f_mode & FMODE_WRITE)) 1262 if (!(file->f_mode & FMODE_WRITE))
1236 goto out; 1263 goto out;
1237 1264
@@ -1239,13 +1266,47 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, unsig
1239 if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write)) 1266 if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write))
1240 goto out; 1267 goto out;
1241 1268
1242 ret = compat_do_readv_writev(WRITE, file, vec, vlen, &file->f_pos); 1269 ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos);
1243 1270
1244out: 1271out:
1245 if (ret > 0) 1272 if (ret > 0)
1246 add_wchar(current, ret); 1273 add_wchar(current, ret);
1247 inc_syscw(current); 1274 inc_syscw(current);
1248 fput(file); 1275 return ret;
1276}
1277
1278asmlinkage ssize_t
1279compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec,
1280 unsigned long vlen)
1281{
1282 struct file *file;
1283 int fput_needed;
1284 ssize_t ret;
1285
1286 file = fget_light(fd, &fput_needed);
1287 if (!file)
1288 return -EBADF;
1289 ret = compat_writev(file, vec, vlen, &file->f_pos);
1290 fput_light(file, fput_needed);
1291 return ret;
1292}
1293
1294asmlinkage ssize_t
1295compat_sys_pwritev(unsigned long fd, const struct compat_iovec __user *vec,
1296 unsigned long vlen, u32 pos_high, u32 pos_low)
1297{
1298 loff_t pos = ((loff_t)pos_high << 32) | pos_low;
1299 struct file *file;
1300 int fput_needed;
1301 ssize_t ret;
1302
1303 if (pos < 0)
1304 return -EINVAL;
1305 file = fget_light(fd, &fput_needed);
1306 if (!file)
1307 return -EBADF;
1308 ret = compat_writev(file, vec, vlen, &pos);
1309 fput_light(file, fput_needed);
1249 return ret; 1310 return ret;
1250} 1311}
1251 1312