]> Pileus Git - ~andy/linux/blob - fs/read_write.c
vfs: atomic f_pos accesses as per POSIX
[~andy/linux] / fs / read_write.c
1 /*
2  *  linux/fs/read_write.c
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  */
6
7 #include <linux/slab.h> 
8 #include <linux/stat.h>
9 #include <linux/fcntl.h>
10 #include <linux/file.h>
11 #include <linux/uio.h>
12 #include <linux/aio.h>
13 #include <linux/fsnotify.h>
14 #include <linux/security.h>
15 #include <linux/export.h>
16 #include <linux/syscalls.h>
17 #include <linux/pagemap.h>
18 #include <linux/splice.h>
19 #include <linux/compat.h>
20 #include "internal.h"
21
22 #include <asm/uaccess.h>
23 #include <asm/unistd.h>
24
25 typedef ssize_t (*io_fn_t)(struct file *, char __user *, size_t, loff_t *);
26 typedef ssize_t (*iov_fn_t)(struct kiocb *, const struct iovec *,
27                 unsigned long, loff_t);
28
29 const struct file_operations generic_ro_fops = {
30         .llseek         = generic_file_llseek,
31         .read           = do_sync_read,
32         .aio_read       = generic_file_aio_read,
33         .mmap           = generic_file_readonly_mmap,
34         .splice_read    = generic_file_splice_read,
35 };
36
37 EXPORT_SYMBOL(generic_ro_fops);
38
39 static inline int unsigned_offsets(struct file *file)
40 {
41         return file->f_mode & FMODE_UNSIGNED_OFFSET;
42 }
43
44 /**
45  * vfs_setpos - update the file offset for lseek
46  * @file:       file structure in question
47  * @offset:     file offset to seek to
48  * @maxsize:    maximum file size
49  *
50  * This is a low-level filesystem helper for updating the file offset to
51  * the value specified by @offset if the given offset is valid and it is
52  * not equal to the current file offset.
53  *
54  * Return the specified offset on success and -EINVAL on invalid offset.
55  */
56 loff_t vfs_setpos(struct file *file, loff_t offset, loff_t maxsize)
57 {
58         if (offset < 0 && !unsigned_offsets(file))
59                 return -EINVAL;
60         if (offset > maxsize)
61                 return -EINVAL;
62
63         if (offset != file->f_pos) {
64                 file->f_pos = offset;
65                 file->f_version = 0;
66         }
67         return offset;
68 }
69 EXPORT_SYMBOL(vfs_setpos);
70
71 /**
72  * generic_file_llseek_size - generic llseek implementation for regular files
73  * @file:       file structure to seek on
74  * @offset:     file offset to seek to
75  * @whence:     type of seek
76  * @size:       max size of this file in file system
77  * @eof:        offset used for SEEK_END position
78  *
79  * This is a variant of generic_file_llseek that allows passing in a custom
80  * maximum file size and a custom EOF position, for e.g. hashed directories
81  *
82  * Synchronization:
83  * SEEK_SET and SEEK_END are unsynchronized (but atomic on 64bit platforms)
84  * SEEK_CUR is synchronized against other SEEK_CURs, but not read/writes.
85  * read/writes behave like SEEK_SET against seeks.
86  */
87 loff_t
88 generic_file_llseek_size(struct file *file, loff_t offset, int whence,
89                 loff_t maxsize, loff_t eof)
90 {
91         switch (whence) {
92         case SEEK_END:
93                 offset += eof;
94                 break;
95         case SEEK_CUR:
96                 /*
97                  * Here we special-case the lseek(fd, 0, SEEK_CUR)
98                  * position-querying operation.  Avoid rewriting the "same"
99                  * f_pos value back to the file because a concurrent read(),
100                  * write() or lseek() might have altered it
101                  */
102                 if (offset == 0)
103                         return file->f_pos;
104                 /*
105                  * f_lock protects against read/modify/write race with other
106                  * SEEK_CURs. Note that parallel writes and reads behave
107                  * like SEEK_SET.
108                  */
109                 spin_lock(&file->f_lock);
110                 offset = vfs_setpos(file, file->f_pos + offset, maxsize);
111                 spin_unlock(&file->f_lock);
112                 return offset;
113         case SEEK_DATA:
114                 /*
115                  * In the generic case the entire file is data, so as long as
116                  * offset isn't at the end of the file then the offset is data.
117                  */
118                 if (offset >= eof)
119                         return -ENXIO;
120                 break;
121         case SEEK_HOLE:
122                 /*
123                  * There is a virtual hole at the end of the file, so as long as
124                  * offset isn't i_size or larger, return i_size.
125                  */
126                 if (offset >= eof)
127                         return -ENXIO;
128                 offset = eof;
129                 break;
130         }
131
132         return vfs_setpos(file, offset, maxsize);
133 }
134 EXPORT_SYMBOL(generic_file_llseek_size);
135
136 /**
137  * generic_file_llseek - generic llseek implementation for regular files
138  * @file:       file structure to seek on
139  * @offset:     file offset to seek to
140  * @whence:     type of seek
141  *
142  * This is a generic implemenation of ->llseek useable for all normal local
143  * filesystems.  It just updates the file offset to the value specified by
144  * @offset and @whence.
145  */
146 loff_t generic_file_llseek(struct file *file, loff_t offset, int whence)
147 {
148         struct inode *inode = file->f_mapping->host;
149
150         return generic_file_llseek_size(file, offset, whence,
151                                         inode->i_sb->s_maxbytes,
152                                         i_size_read(inode));
153 }
154 EXPORT_SYMBOL(generic_file_llseek);
155
156 /**
157  * fixed_size_llseek - llseek implementation for fixed-sized devices
158  * @file:       file structure to seek on
159  * @offset:     file offset to seek to
160  * @whence:     type of seek
161  * @size:       size of the file
162  *
163  */
164 loff_t fixed_size_llseek(struct file *file, loff_t offset, int whence, loff_t size)
165 {
166         switch (whence) {
167         case SEEK_SET: case SEEK_CUR: case SEEK_END:
168                 return generic_file_llseek_size(file, offset, whence,
169                                                 size, size);
170         default:
171                 return -EINVAL;
172         }
173 }
174 EXPORT_SYMBOL(fixed_size_llseek);
175
176 /**
177  * noop_llseek - No Operation Performed llseek implementation
178  * @file:       file structure to seek on
179  * @offset:     file offset to seek to
180  * @whence:     type of seek
181  *
182  * This is an implementation of ->llseek useable for the rare special case when
183  * userspace expects the seek to succeed but the (device) file is actually not
184  * able to perform the seek. In this case you use noop_llseek() instead of
185  * falling back to the default implementation of ->llseek.
186  */
187 loff_t noop_llseek(struct file *file, loff_t offset, int whence)
188 {
189         return file->f_pos;
190 }
191 EXPORT_SYMBOL(noop_llseek);
192
193 loff_t no_llseek(struct file *file, loff_t offset, int whence)
194 {
195         return -ESPIPE;
196 }
197 EXPORT_SYMBOL(no_llseek);
198
199 loff_t default_llseek(struct file *file, loff_t offset, int whence)
200 {
201         struct inode *inode = file_inode(file);
202         loff_t retval;
203
204         mutex_lock(&inode->i_mutex);
205         switch (whence) {
206                 case SEEK_END:
207                         offset += i_size_read(inode);
208                         break;
209                 case SEEK_CUR:
210                         if (offset == 0) {
211                                 retval = file->f_pos;
212                                 goto out;
213                         }
214                         offset += file->f_pos;
215                         break;
216                 case SEEK_DATA:
217                         /*
218                          * In the generic case the entire file is data, so as
219                          * long as offset isn't at the end of the file then the
220                          * offset is data.
221                          */
222                         if (offset >= inode->i_size) {
223                                 retval = -ENXIO;
224                                 goto out;
225                         }
226                         break;
227                 case SEEK_HOLE:
228                         /*
229                          * There is a virtual hole at the end of the file, so
230                          * as long as offset isn't i_size or larger, return
231                          * i_size.
232                          */
233                         if (offset >= inode->i_size) {
234                                 retval = -ENXIO;
235                                 goto out;
236                         }
237                         offset = inode->i_size;
238                         break;
239         }
240         retval = -EINVAL;
241         if (offset >= 0 || unsigned_offsets(file)) {
242                 if (offset != file->f_pos) {
243                         file->f_pos = offset;
244                         file->f_version = 0;
245                 }
246                 retval = offset;
247         }
248 out:
249         mutex_unlock(&inode->i_mutex);
250         return retval;
251 }
252 EXPORT_SYMBOL(default_llseek);
253
254 loff_t vfs_llseek(struct file *file, loff_t offset, int whence)
255 {
256         loff_t (*fn)(struct file *, loff_t, int);
257
258         fn = no_llseek;
259         if (file->f_mode & FMODE_LSEEK) {
260                 if (file->f_op->llseek)
261                         fn = file->f_op->llseek;
262         }
263         return fn(file, offset, whence);
264 }
265 EXPORT_SYMBOL(vfs_llseek);
266
267 /*
268  * We only lock f_pos if we have threads or if the file might be
269  * shared with another process. In both cases we'll have an elevated
270  * file count (done either by fdget() or by fork()).
271  */
272 static inline struct fd fdget_pos(int fd)
273 {
274         struct fd f = fdget(fd);
275         struct file *file = f.file;
276
277         if (file && (file->f_mode & FMODE_ATOMIC_POS)) {
278                 if (file_count(file) > 1) {
279                         f.flags |= FDPUT_POS_UNLOCK;
280                         mutex_lock(&file->f_pos_lock);
281                 }
282         }
283         return f;
284 }
285
286 static inline void fdput_pos(struct fd f)
287 {
288         if (f.flags & FDPUT_POS_UNLOCK)
289                 mutex_unlock(&f.file->f_pos_lock);
290         fdput(f);
291 }
292
293 SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, whence)
294 {
295         off_t retval;
296         struct fd f = fdget_pos(fd);
297         if (!f.file)
298                 return -EBADF;
299
300         retval = -EINVAL;
301         if (whence <= SEEK_MAX) {
302                 loff_t res = vfs_llseek(f.file, offset, whence);
303                 retval = res;
304                 if (res != (loff_t)retval)
305                         retval = -EOVERFLOW;    /* LFS: should only happen on 32 bit platforms */
306         }
307         fdput_pos(f);
308         return retval;
309 }
310
311 #ifdef CONFIG_COMPAT
312 COMPAT_SYSCALL_DEFINE3(lseek, unsigned int, fd, compat_off_t, offset, unsigned int, whence)
313 {
314         return sys_lseek(fd, offset, whence);
315 }
316 #endif
317
318 #ifdef __ARCH_WANT_SYS_LLSEEK
319 SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
320                 unsigned long, offset_low, loff_t __user *, result,
321                 unsigned int, whence)
322 {
323         int retval;
324         struct fd f = fdget(fd);
325         loff_t offset;
326
327         if (!f.file)
328                 return -EBADF;
329
330         retval = -EINVAL;
331         if (whence > SEEK_MAX)
332                 goto out_putf;
333
334         offset = vfs_llseek(f.file, ((loff_t) offset_high << 32) | offset_low,
335                         whence);
336
337         retval = (int)offset;
338         if (offset >= 0) {
339                 retval = -EFAULT;
340                 if (!copy_to_user(result, &offset, sizeof(offset)))
341                         retval = 0;
342         }
343 out_putf:
344         fdput(f);
345         return retval;
346 }
347 #endif
348
349 /*
350  * rw_verify_area doesn't like huge counts. We limit
351  * them to something that fits in "int" so that others
352  * won't have to do range checks all the time.
353  */
354 int rw_verify_area(int read_write, struct file *file, const loff_t *ppos, size_t count)
355 {
356         struct inode *inode;
357         loff_t pos;
358         int retval = -EINVAL;
359
360         inode = file_inode(file);
361         if (unlikely((ssize_t) count < 0))
362                 return retval;
363         pos = *ppos;
364         if (unlikely(pos < 0)) {
365                 if (!unsigned_offsets(file))
366                         return retval;
367                 if (count >= -pos) /* both values are in 0..LLONG_MAX */
368                         return -EOVERFLOW;
369         } else if (unlikely((loff_t) (pos + count) < 0)) {
370                 if (!unsigned_offsets(file))
371                         return retval;
372         }
373
374         if (unlikely(inode->i_flock && mandatory_lock(inode))) {
375                 retval = locks_mandatory_area(
376                         read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE,
377                         inode, file, pos, count);
378                 if (retval < 0)
379                         return retval;
380         }
381         retval = security_file_permission(file,
382                                 read_write == READ ? MAY_READ : MAY_WRITE);
383         if (retval)
384                 return retval;
385         return count > MAX_RW_COUNT ? MAX_RW_COUNT : count;
386 }
387
388 ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
389 {
390         struct iovec iov = { .iov_base = buf, .iov_len = len };
391         struct kiocb kiocb;
392         ssize_t ret;
393
394         init_sync_kiocb(&kiocb, filp);
395         kiocb.ki_pos = *ppos;
396         kiocb.ki_nbytes = len;
397
398         ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
399         if (-EIOCBQUEUED == ret)
400                 ret = wait_on_sync_kiocb(&kiocb);
401         *ppos = kiocb.ki_pos;
402         return ret;
403 }
404
405 EXPORT_SYMBOL(do_sync_read);
406
407 ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
408 {
409         ssize_t ret;
410
411         if (!(file->f_mode & FMODE_READ))
412                 return -EBADF;
413         if (!file->f_op->read && !file->f_op->aio_read)
414                 return -EINVAL;
415         if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
416                 return -EFAULT;
417
418         ret = rw_verify_area(READ, file, pos, count);
419         if (ret >= 0) {
420                 count = ret;
421                 if (file->f_op->read)
422                         ret = file->f_op->read(file, buf, count, pos);
423                 else
424                         ret = do_sync_read(file, buf, count, pos);
425                 if (ret > 0) {
426                         fsnotify_access(file);
427                         add_rchar(current, ret);
428                 }
429                 inc_syscr(current);
430         }
431
432         return ret;
433 }
434
435 EXPORT_SYMBOL(vfs_read);
436
437 ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
438 {
439         struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
440         struct kiocb kiocb;
441         ssize_t ret;
442
443         init_sync_kiocb(&kiocb, filp);
444         kiocb.ki_pos = *ppos;
445         kiocb.ki_nbytes = len;
446
447         ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
448         if (-EIOCBQUEUED == ret)
449                 ret = wait_on_sync_kiocb(&kiocb);
450         *ppos = kiocb.ki_pos;
451         return ret;
452 }
453
454 EXPORT_SYMBOL(do_sync_write);
455
456 ssize_t __kernel_write(struct file *file, const char *buf, size_t count, loff_t *pos)
457 {
458         mm_segment_t old_fs;
459         const char __user *p;
460         ssize_t ret;
461
462         if (!file->f_op->write && !file->f_op->aio_write)
463                 return -EINVAL;
464
465         old_fs = get_fs();
466         set_fs(get_ds());
467         p = (__force const char __user *)buf;
468         if (count > MAX_RW_COUNT)
469                 count =  MAX_RW_COUNT;
470         if (file->f_op->write)
471                 ret = file->f_op->write(file, p, count, pos);
472         else
473                 ret = do_sync_write(file, p, count, pos);
474         set_fs(old_fs);
475         if (ret > 0) {
476                 fsnotify_modify(file);
477                 add_wchar(current, ret);
478         }
479         inc_syscw(current);
480         return ret;
481 }
482
483 ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
484 {
485         ssize_t ret;
486
487         if (!(file->f_mode & FMODE_WRITE))
488                 return -EBADF;
489         if (!file->f_op->write && !file->f_op->aio_write)
490                 return -EINVAL;
491         if (unlikely(!access_ok(VERIFY_READ, buf, count)))
492                 return -EFAULT;
493
494         ret = rw_verify_area(WRITE, file, pos, count);
495         if (ret >= 0) {
496                 count = ret;
497                 file_start_write(file);
498                 if (file->f_op->write)
499                         ret = file->f_op->write(file, buf, count, pos);
500                 else
501                         ret = do_sync_write(file, buf, count, pos);
502                 if (ret > 0) {
503                         fsnotify_modify(file);
504                         add_wchar(current, ret);
505                 }
506                 inc_syscw(current);
507                 file_end_write(file);
508         }
509
510         return ret;
511 }
512
513 EXPORT_SYMBOL(vfs_write);
514
515 static inline loff_t file_pos_read(struct file *file)
516 {
517         return file->f_pos;
518 }
519
520 static inline void file_pos_write(struct file *file, loff_t pos)
521 {
522         file->f_pos = pos;
523 }
524
525 SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
526 {
527         struct fd f = fdget_pos(fd);
528         ssize_t ret = -EBADF;
529
530         if (f.file) {
531                 loff_t pos = file_pos_read(f.file);
532                 ret = vfs_read(f.file, buf, count, &pos);
533                 if (ret >= 0)
534                         file_pos_write(f.file, pos);
535                 fdput_pos(f);
536         }
537         return ret;
538 }
539
540 SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
541                 size_t, count)
542 {
543         struct fd f = fdget_pos(fd);
544         ssize_t ret = -EBADF;
545
546         if (f.file) {
547                 loff_t pos = file_pos_read(f.file);
548                 ret = vfs_write(f.file, buf, count, &pos);
549                 if (ret >= 0)
550                         file_pos_write(f.file, pos);
551                 fdput_pos(f);
552         }
553
554         return ret;
555 }
556
557 SYSCALL_DEFINE4(pread64, unsigned int, fd, char __user *, buf,
558                         size_t, count, loff_t, pos)
559 {
560         struct fd f;
561         ssize_t ret = -EBADF;
562
563         if (pos < 0)
564                 return -EINVAL;
565
566         f = fdget(fd);
567         if (f.file) {
568                 ret = -ESPIPE;
569                 if (f.file->f_mode & FMODE_PREAD)
570                         ret = vfs_read(f.file, buf, count, &pos);
571                 fdput(f);
572         }
573
574         return ret;
575 }
576
577 SYSCALL_DEFINE4(pwrite64, unsigned int, fd, const char __user *, buf,
578                          size_t, count, loff_t, pos)
579 {
580         struct fd f;
581         ssize_t ret = -EBADF;
582
583         if (pos < 0)
584                 return -EINVAL;
585
586         f = fdget(fd);
587         if (f.file) {
588                 ret = -ESPIPE;
589                 if (f.file->f_mode & FMODE_PWRITE)  
590                         ret = vfs_write(f.file, buf, count, &pos);
591                 fdput(f);
592         }
593
594         return ret;
595 }
596
597 /*
598  * Reduce an iovec's length in-place.  Return the resulting number of segments
599  */
600 unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to)
601 {
602         unsigned long seg = 0;
603         size_t len = 0;
604
605         while (seg < nr_segs) {
606                 seg++;
607                 if (len + iov->iov_len >= to) {
608                         iov->iov_len = to - len;
609                         break;
610                 }
611                 len += iov->iov_len;
612                 iov++;
613         }
614         return seg;
615 }
616 EXPORT_SYMBOL(iov_shorten);
617
618 static ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
619                 unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn)
620 {
621         struct kiocb kiocb;
622         ssize_t ret;
623
624         init_sync_kiocb(&kiocb, filp);
625         kiocb.ki_pos = *ppos;
626         kiocb.ki_nbytes = len;
627
628         ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
629         if (ret == -EIOCBQUEUED)
630                 ret = wait_on_sync_kiocb(&kiocb);
631         *ppos = kiocb.ki_pos;
632         return ret;
633 }
634
635 /* Do it by hand, with file-ops */
636 static ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov,
637                 unsigned long nr_segs, loff_t *ppos, io_fn_t fn)
638 {
639         struct iovec *vector = iov;
640         ssize_t ret = 0;
641
642         while (nr_segs > 0) {
643                 void __user *base;
644                 size_t len;
645                 ssize_t nr;
646
647                 base = vector->iov_base;
648                 len = vector->iov_len;
649                 vector++;
650                 nr_segs--;
651
652                 nr = fn(filp, base, len, ppos);
653
654                 if (nr < 0) {
655                         if (!ret)
656                                 ret = nr;
657                         break;
658                 }
659                 ret += nr;
660                 if (nr != len)
661                         break;
662         }
663
664         return ret;
665 }
666
667 /* A write operation does a read from user space and vice versa */
668 #define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ)
669
670 ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
671                               unsigned long nr_segs, unsigned long fast_segs,
672                               struct iovec *fast_pointer,
673                               struct iovec **ret_pointer)
674 {
675         unsigned long seg;
676         ssize_t ret;
677         struct iovec *iov = fast_pointer;
678
679         /*
680          * SuS says "The readv() function *may* fail if the iovcnt argument
681          * was less than or equal to 0, or greater than {IOV_MAX}.  Linux has
682          * traditionally returned zero for zero segments, so...
683          */
684         if (nr_segs == 0) {
685                 ret = 0;
686                 goto out;
687         }
688
689         /*
690          * First get the "struct iovec" from user memory and
691          * verify all the pointers
692          */
693         if (nr_segs > UIO_MAXIOV) {
694                 ret = -EINVAL;
695                 goto out;
696         }
697         if (nr_segs > fast_segs) {
698                 iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL);
699                 if (iov == NULL) {
700                         ret = -ENOMEM;
701                         goto out;
702                 }
703         }
704         if (copy_from_user(iov, uvector, nr_segs*sizeof(*uvector))) {
705                 ret = -EFAULT;
706                 goto out;
707         }
708
709         /*
710          * According to the Single Unix Specification we should return EINVAL
711          * if an element length is < 0 when cast to ssize_t or if the
712          * total length would overflow the ssize_t return value of the
713          * system call.
714          *
715          * Linux caps all read/write calls to MAX_RW_COUNT, and avoids the
716          * overflow case.
717          */
718         ret = 0;
719         for (seg = 0; seg < nr_segs; seg++) {
720                 void __user *buf = iov[seg].iov_base;
721                 ssize_t len = (ssize_t)iov[seg].iov_len;
722
723                 /* see if we we're about to use an invalid len or if
724                  * it's about to overflow ssize_t */
725                 if (len < 0) {
726                         ret = -EINVAL;
727                         goto out;
728                 }
729                 if (type >= 0
730                     && unlikely(!access_ok(vrfy_dir(type), buf, len))) {
731                         ret = -EFAULT;
732                         goto out;
733                 }
734                 if (len > MAX_RW_COUNT - ret) {
735                         len = MAX_RW_COUNT - ret;
736                         iov[seg].iov_len = len;
737                 }
738                 ret += len;
739         }
740 out:
741         *ret_pointer = iov;
742         return ret;
743 }
744
745 static ssize_t do_readv_writev(int type, struct file *file,
746                                const struct iovec __user * uvector,
747                                unsigned long nr_segs, loff_t *pos)
748 {
749         size_t tot_len;
750         struct iovec iovstack[UIO_FASTIOV];
751         struct iovec *iov = iovstack;
752         ssize_t ret;
753         io_fn_t fn;
754         iov_fn_t fnv;
755
756         ret = rw_copy_check_uvector(type, uvector, nr_segs,
757                                     ARRAY_SIZE(iovstack), iovstack, &iov);
758         if (ret <= 0)
759                 goto out;
760
761         tot_len = ret;
762         ret = rw_verify_area(type, file, pos, tot_len);
763         if (ret < 0)
764                 goto out;
765
766         fnv = NULL;
767         if (type == READ) {
768                 fn = file->f_op->read;
769                 fnv = file->f_op->aio_read;
770         } else {
771                 fn = (io_fn_t)file->f_op->write;
772                 fnv = file->f_op->aio_write;
773                 file_start_write(file);
774         }
775
776         if (fnv)
777                 ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
778                                                 pos, fnv);
779         else
780                 ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);
781
782         if (type != READ)
783                 file_end_write(file);
784
785 out:
786         if (iov != iovstack)
787                 kfree(iov);
788         if ((ret + (type == READ)) > 0) {
789                 if (type == READ)
790                         fsnotify_access(file);
791                 else
792                         fsnotify_modify(file);
793         }
794         return ret;
795 }
796
797 ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
798                   unsigned long vlen, loff_t *pos)
799 {
800         if (!(file->f_mode & FMODE_READ))
801                 return -EBADF;
802         if (!file->f_op->aio_read && !file->f_op->read)
803                 return -EINVAL;
804
805         return do_readv_writev(READ, file, vec, vlen, pos);
806 }
807
808 EXPORT_SYMBOL(vfs_readv);
809
810 ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
811                    unsigned long vlen, loff_t *pos)
812 {
813         if (!(file->f_mode & FMODE_WRITE))
814                 return -EBADF;
815         if (!file->f_op->aio_write && !file->f_op->write)
816                 return -EINVAL;
817
818         return do_readv_writev(WRITE, file, vec, vlen, pos);
819 }
820
821 EXPORT_SYMBOL(vfs_writev);
822
823 SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
824                 unsigned long, vlen)
825 {
826         struct fd f = fdget_pos(fd);
827         ssize_t ret = -EBADF;
828
829         if (f.file) {
830                 loff_t pos = file_pos_read(f.file);
831                 ret = vfs_readv(f.file, vec, vlen, &pos);
832                 if (ret >= 0)
833                         file_pos_write(f.file, pos);
834                 fdput_pos(f);
835         }
836
837         if (ret > 0)
838                 add_rchar(current, ret);
839         inc_syscr(current);
840         return ret;
841 }
842
843 SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec,
844                 unsigned long, vlen)
845 {
846         struct fd f = fdget_pos(fd);
847         ssize_t ret = -EBADF;
848
849         if (f.file) {
850                 loff_t pos = file_pos_read(f.file);
851                 ret = vfs_writev(f.file, vec, vlen, &pos);
852                 if (ret >= 0)
853                         file_pos_write(f.file, pos);
854                 fdput_pos(f);
855         }
856
857         if (ret > 0)
858                 add_wchar(current, ret);
859         inc_syscw(current);
860         return ret;
861 }
862
863 static inline loff_t pos_from_hilo(unsigned long high, unsigned long low)
864 {
865 #define HALF_LONG_BITS (BITS_PER_LONG / 2)
866         return (((loff_t)high << HALF_LONG_BITS) << HALF_LONG_BITS) | low;
867 }
868
869 SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
870                 unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
871 {
872         loff_t pos = pos_from_hilo(pos_h, pos_l);
873         struct fd f;
874         ssize_t ret = -EBADF;
875
876         if (pos < 0)
877                 return -EINVAL;
878
879         f = fdget(fd);
880         if (f.file) {
881                 ret = -ESPIPE;
882                 if (f.file->f_mode & FMODE_PREAD)
883                         ret = vfs_readv(f.file, vec, vlen, &pos);
884                 fdput(f);
885         }
886
887         if (ret > 0)
888                 add_rchar(current, ret);
889         inc_syscr(current);
890         return ret;
891 }
892
893 SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
894                 unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
895 {
896         loff_t pos = pos_from_hilo(pos_h, pos_l);
897         struct fd f;
898         ssize_t ret = -EBADF;
899
900         if (pos < 0)
901                 return -EINVAL;
902
903         f = fdget(fd);
904         if (f.file) {
905                 ret = -ESPIPE;
906                 if (f.file->f_mode & FMODE_PWRITE)
907                         ret = vfs_writev(f.file, vec, vlen, &pos);
908                 fdput(f);
909         }
910
911         if (ret > 0)
912                 add_wchar(current, ret);
913         inc_syscw(current);
914         return ret;
915 }
916
917 #ifdef CONFIG_COMPAT
918
919 static ssize_t compat_do_readv_writev(int type, struct file *file,
920                                const struct compat_iovec __user *uvector,
921                                unsigned long nr_segs, loff_t *pos)
922 {
923         compat_ssize_t tot_len;
924         struct iovec iovstack[UIO_FASTIOV];
925         struct iovec *iov = iovstack;
926         ssize_t ret;
927         io_fn_t fn;
928         iov_fn_t fnv;
929
930         ret = compat_rw_copy_check_uvector(type, uvector, nr_segs,
931                                                UIO_FASTIOV, iovstack, &iov);
932         if (ret <= 0)
933                 goto out;
934
935         tot_len = ret;
936         ret = rw_verify_area(type, file, pos, tot_len);
937         if (ret < 0)
938                 goto out;
939
940         fnv = NULL;
941         if (type == READ) {
942                 fn = file->f_op->read;
943                 fnv = file->f_op->aio_read;
944         } else {
945                 fn = (io_fn_t)file->f_op->write;
946                 fnv = file->f_op->aio_write;
947                 file_start_write(file);
948         }
949
950         if (fnv)
951                 ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
952                                                 pos, fnv);
953         else
954                 ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);
955
956         if (type != READ)
957                 file_end_write(file);
958
959 out:
960         if (iov != iovstack)
961                 kfree(iov);
962         if ((ret + (type == READ)) > 0) {
963                 if (type == READ)
964                         fsnotify_access(file);
965                 else
966                         fsnotify_modify(file);
967         }
968         return ret;
969 }
970
971 static size_t compat_readv(struct file *file,
972                            const struct compat_iovec __user *vec,
973                            unsigned long vlen, loff_t *pos)
974 {
975         ssize_t ret = -EBADF;
976
977         if (!(file->f_mode & FMODE_READ))
978                 goto out;
979
980         ret = -EINVAL;
981         if (!file->f_op->aio_read && !file->f_op->read)
982                 goto out;
983
984         ret = compat_do_readv_writev(READ, file, vec, vlen, pos);
985
986 out:
987         if (ret > 0)
988                 add_rchar(current, ret);
989         inc_syscr(current);
990         return ret;
991 }
992
993 COMPAT_SYSCALL_DEFINE3(readv, compat_ulong_t, fd,
994                 const struct compat_iovec __user *,vec,
995                 compat_ulong_t, vlen)
996 {
997         struct fd f = fdget_pos(fd);
998         ssize_t ret;
999         loff_t pos;
1000
1001         if (!f.file)
1002                 return -EBADF;
1003         pos = f.file->f_pos;
1004         ret = compat_readv(f.file, vec, vlen, &pos);
1005         if (ret >= 0)
1006                 f.file->f_pos = pos;
1007         fdput_pos(f);
1008         return ret;
1009 }
1010
1011 COMPAT_SYSCALL_DEFINE4(preadv64, unsigned long, fd,
1012                 const struct compat_iovec __user *,vec,
1013                 unsigned long, vlen, loff_t, pos)
1014 {
1015         struct fd f;
1016         ssize_t ret;
1017
1018         if (pos < 0)
1019                 return -EINVAL;
1020         f = fdget(fd);
1021         if (!f.file)
1022                 return -EBADF;
1023         ret = -ESPIPE;
1024         if (f.file->f_mode & FMODE_PREAD)
1025                 ret = compat_readv(f.file, vec, vlen, &pos);
1026         fdput(f);
1027         return ret;
1028 }
1029
1030 COMPAT_SYSCALL_DEFINE5(preadv, compat_ulong_t, fd,
1031                 const struct compat_iovec __user *,vec,
1032                 compat_ulong_t, vlen, u32, pos_low, u32, pos_high)
1033 {
1034         loff_t pos = ((loff_t)pos_high << 32) | pos_low;
1035         return compat_sys_preadv64(fd, vec, vlen, pos);
1036 }
1037
1038 static size_t compat_writev(struct file *file,
1039                             const struct compat_iovec __user *vec,
1040                             unsigned long vlen, loff_t *pos)
1041 {
1042         ssize_t ret = -EBADF;
1043
1044         if (!(file->f_mode & FMODE_WRITE))
1045                 goto out;
1046
1047         ret = -EINVAL;
1048         if (!file->f_op->aio_write && !file->f_op->write)
1049                 goto out;
1050
1051         ret = compat_do_readv_writev(WRITE, file, vec, vlen, pos);
1052
1053 out:
1054         if (ret > 0)
1055                 add_wchar(current, ret);
1056         inc_syscw(current);
1057         return ret;
1058 }
1059
1060 COMPAT_SYSCALL_DEFINE3(writev, compat_ulong_t, fd,
1061                 const struct compat_iovec __user *, vec,
1062                 compat_ulong_t, vlen)
1063 {
1064         struct fd f = fdget_pos(fd);
1065         ssize_t ret;
1066         loff_t pos;
1067
1068         if (!f.file)
1069                 return -EBADF;
1070         pos = f.file->f_pos;
1071         ret = compat_writev(f.file, vec, vlen, &pos);
1072         if (ret >= 0)
1073                 f.file->f_pos = pos;
1074         fdput_pos(f);
1075         return ret;
1076 }
1077
1078 COMPAT_SYSCALL_DEFINE4(pwritev64, unsigned long, fd,
1079                 const struct compat_iovec __user *,vec,
1080                 unsigned long, vlen, loff_t, pos)
1081 {
1082         struct fd f;
1083         ssize_t ret;
1084
1085         if (pos < 0)
1086                 return -EINVAL;
1087         f = fdget(fd);
1088         if (!f.file)
1089                 return -EBADF;
1090         ret = -ESPIPE;
1091         if (f.file->f_mode & FMODE_PWRITE)
1092                 ret = compat_writev(f.file, vec, vlen, &pos);
1093         fdput(f);
1094         return ret;
1095 }
1096
1097 COMPAT_SYSCALL_DEFINE5(pwritev, compat_ulong_t, fd,
1098                 const struct compat_iovec __user *,vec,
1099                 compat_ulong_t, vlen, u32, pos_low, u32, pos_high)
1100 {
1101         loff_t pos = ((loff_t)pos_high << 32) | pos_low;
1102         return compat_sys_pwritev64(fd, vec, vlen, pos);
1103 }
1104 #endif
1105
1106 static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
1107                            size_t count, loff_t max)
1108 {
1109         struct fd in, out;
1110         struct inode *in_inode, *out_inode;
1111         loff_t pos;
1112         loff_t out_pos;
1113         ssize_t retval;
1114         int fl;
1115
1116         /*
1117          * Get input file, and verify that it is ok..
1118          */
1119         retval = -EBADF;
1120         in = fdget(in_fd);
1121         if (!in.file)
1122                 goto out;
1123         if (!(in.file->f_mode & FMODE_READ))
1124                 goto fput_in;
1125         retval = -ESPIPE;
1126         if (!ppos) {
1127                 pos = in.file->f_pos;
1128         } else {
1129                 pos = *ppos;
1130                 if (!(in.file->f_mode & FMODE_PREAD))
1131                         goto fput_in;
1132         }
1133         retval = rw_verify_area(READ, in.file, &pos, count);
1134         if (retval < 0)
1135                 goto fput_in;
1136         count = retval;
1137
1138         /*
1139          * Get output file, and verify that it is ok..
1140          */
1141         retval = -EBADF;
1142         out = fdget(out_fd);
1143         if (!out.file)
1144                 goto fput_in;
1145         if (!(out.file->f_mode & FMODE_WRITE))
1146                 goto fput_out;
1147         retval = -EINVAL;
1148         in_inode = file_inode(in.file);
1149         out_inode = file_inode(out.file);
1150         out_pos = out.file->f_pos;
1151         retval = rw_verify_area(WRITE, out.file, &out_pos, count);
1152         if (retval < 0)
1153                 goto fput_out;
1154         count = retval;
1155
1156         if (!max)
1157                 max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
1158
1159         if (unlikely(pos + count > max)) {
1160                 retval = -EOVERFLOW;
1161                 if (pos >= max)
1162                         goto fput_out;
1163                 count = max - pos;
1164         }
1165
1166         fl = 0;
1167 #if 0
1168         /*
1169          * We need to debate whether we can enable this or not. The
1170          * man page documents EAGAIN return for the output at least,
1171          * and the application is arguably buggy if it doesn't expect
1172          * EAGAIN on a non-blocking file descriptor.
1173          */
1174         if (in.file->f_flags & O_NONBLOCK)
1175                 fl = SPLICE_F_NONBLOCK;
1176 #endif
1177         file_start_write(out.file);
1178         retval = do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl);
1179         file_end_write(out.file);
1180
1181         if (retval > 0) {
1182                 add_rchar(current, retval);
1183                 add_wchar(current, retval);
1184                 fsnotify_access(in.file);
1185                 fsnotify_modify(out.file);
1186                 out.file->f_pos = out_pos;
1187                 if (ppos)
1188                         *ppos = pos;
1189                 else
1190                         in.file->f_pos = pos;
1191         }
1192
1193         inc_syscr(current);
1194         inc_syscw(current);
1195         if (pos > max)
1196                 retval = -EOVERFLOW;
1197
1198 fput_out:
1199         fdput(out);
1200 fput_in:
1201         fdput(in);
1202 out:
1203         return retval;
1204 }
1205
1206 SYSCALL_DEFINE4(sendfile, int, out_fd, int, in_fd, off_t __user *, offset, size_t, count)
1207 {
1208         loff_t pos;
1209         off_t off;
1210         ssize_t ret;
1211
1212         if (offset) {
1213                 if (unlikely(get_user(off, offset)))
1214                         return -EFAULT;
1215                 pos = off;
1216                 ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
1217                 if (unlikely(put_user(pos, offset)))
1218                         return -EFAULT;
1219                 return ret;
1220         }
1221
1222         return do_sendfile(out_fd, in_fd, NULL, count, 0);
1223 }
1224
1225 SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, loff_t __user *, offset, size_t, count)
1226 {
1227         loff_t pos;
1228         ssize_t ret;
1229
1230         if (offset) {
1231                 if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
1232                         return -EFAULT;
1233                 ret = do_sendfile(out_fd, in_fd, &pos, count, 0);
1234                 if (unlikely(put_user(pos, offset)))
1235                         return -EFAULT;
1236                 return ret;
1237         }
1238
1239         return do_sendfile(out_fd, in_fd, NULL, count, 0);
1240 }
1241
1242 #ifdef CONFIG_COMPAT
1243 COMPAT_SYSCALL_DEFINE4(sendfile, int, out_fd, int, in_fd,
1244                 compat_off_t __user *, offset, compat_size_t, count)
1245 {
1246         loff_t pos;
1247         off_t off;
1248         ssize_t ret;
1249
1250         if (offset) {
1251                 if (unlikely(get_user(off, offset)))
1252                         return -EFAULT;
1253                 pos = off;
1254                 ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
1255                 if (unlikely(put_user(pos, offset)))
1256                         return -EFAULT;
1257                 return ret;
1258         }
1259
1260         return do_sendfile(out_fd, in_fd, NULL, count, 0);
1261 }
1262
1263 COMPAT_SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd,
1264                 compat_loff_t __user *, offset, compat_size_t, count)
1265 {
1266         loff_t pos;
1267         ssize_t ret;
1268
1269         if (offset) {
1270                 if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
1271                         return -EFAULT;
1272                 ret = do_sendfile(out_fd, in_fd, &pos, count, 0);
1273                 if (unlikely(put_user(pos, offset)))
1274                         return -EFAULT;
1275                 return ret;
1276         }
1277
1278         return do_sendfile(out_fd, in_fd, NULL, count, 0);
1279 }
1280 #endif