Merge branch 'viafb-next' of git://github.com/schandinat/linux-2.6
[pandora-kernel.git] / 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/smp_lock.h>
13 #include <linux/fsnotify.h>
14 #include <linux/security.h>
15 #include <linux/module.h>
16 #include <linux/syscalls.h>
17 #include <linux/pagemap.h>
18 #include <linux/splice.h>
19 #include "read_write.h"
20
21 #include <asm/uaccess.h>
22 #include <asm/unistd.h>
23
24 const struct file_operations generic_ro_fops = {
25         .llseek         = generic_file_llseek,
26         .read           = do_sync_read,
27         .aio_read       = generic_file_aio_read,
28         .mmap           = generic_file_readonly_mmap,
29         .splice_read    = generic_file_splice_read,
30 };
31
32 EXPORT_SYMBOL(generic_ro_fops);
33
34 static int
35 __negative_fpos_check(struct file *file, loff_t pos, size_t count)
36 {
37         /*
38          * pos or pos+count is negative here, check overflow.
39          * too big "count" will be caught in rw_verify_area().
40          */
41         if ((pos < 0) && (pos + count < pos))
42                 return -EOVERFLOW;
43         if (file->f_mode & FMODE_UNSIGNED_OFFSET)
44                 return 0;
45         return -EINVAL;
46 }
47
48 /**
49  * generic_file_llseek_unlocked - lockless generic llseek implementation
50  * @file:       file structure to seek on
51  * @offset:     file offset to seek to
52  * @origin:     type of seek
53  *
54  * Updates the file offset to the value specified by @offset and @origin.
55  * Locking must be provided by the caller.
56  */
57 loff_t
58 generic_file_llseek_unlocked(struct file *file, loff_t offset, int origin)
59 {
60         struct inode *inode = file->f_mapping->host;
61
62         switch (origin) {
63         case SEEK_END:
64                 offset += inode->i_size;
65                 break;
66         case SEEK_CUR:
67                 /*
68                  * Here we special-case the lseek(fd, 0, SEEK_CUR)
69                  * position-querying operation.  Avoid rewriting the "same"
70                  * f_pos value back to the file because a concurrent read(),
71                  * write() or lseek() might have altered it
72                  */
73                 if (offset == 0)
74                         return file->f_pos;
75                 offset += file->f_pos;
76                 break;
77         }
78
79         if (offset < 0 && __negative_fpos_check(file, offset, 0))
80                 return -EINVAL;
81         if (offset > inode->i_sb->s_maxbytes)
82                 return -EINVAL;
83
84         /* Special lock needed here? */
85         if (offset != file->f_pos) {
86                 file->f_pos = offset;
87                 file->f_version = 0;
88         }
89
90         return offset;
91 }
92 EXPORT_SYMBOL(generic_file_llseek_unlocked);
93
94 /**
95  * generic_file_llseek - generic llseek implementation for regular files
96  * @file:       file structure to seek on
97  * @offset:     file offset to seek to
98  * @origin:     type of seek
99  *
100  * This is a generic implemenation of ->llseek useable for all normal local
101  * filesystems.  It just updates the file offset to the value specified by
102  * @offset and @origin under i_mutex.
103  */
104 loff_t generic_file_llseek(struct file *file, loff_t offset, int origin)
105 {
106         loff_t rval;
107
108         mutex_lock(&file->f_dentry->d_inode->i_mutex);
109         rval = generic_file_llseek_unlocked(file, offset, origin);
110         mutex_unlock(&file->f_dentry->d_inode->i_mutex);
111
112         return rval;
113 }
114 EXPORT_SYMBOL(generic_file_llseek);
115
116 /**
117  * noop_llseek - No Operation Performed llseek implementation
118  * @file:       file structure to seek on
119  * @offset:     file offset to seek to
120  * @origin:     type of seek
121  *
122  * This is an implementation of ->llseek useable for the rare special case when
123  * userspace expects the seek to succeed but the (device) file is actually not
124  * able to perform the seek. In this case you use noop_llseek() instead of
125  * falling back to the default implementation of ->llseek.
126  */
127 loff_t noop_llseek(struct file *file, loff_t offset, int origin)
128 {
129         return file->f_pos;
130 }
131 EXPORT_SYMBOL(noop_llseek);
132
133 loff_t no_llseek(struct file *file, loff_t offset, int origin)
134 {
135         return -ESPIPE;
136 }
137 EXPORT_SYMBOL(no_llseek);
138
139 loff_t default_llseek(struct file *file, loff_t offset, int origin)
140 {
141         loff_t retval;
142
143         mutex_lock(&file->f_dentry->d_inode->i_mutex);
144         switch (origin) {
145                 case SEEK_END:
146                         offset += i_size_read(file->f_path.dentry->d_inode);
147                         break;
148                 case SEEK_CUR:
149                         if (offset == 0) {
150                                 retval = file->f_pos;
151                                 goto out;
152                         }
153                         offset += file->f_pos;
154         }
155         retval = -EINVAL;
156         if (offset >= 0 || !__negative_fpos_check(file, offset, 0)) {
157                 if (offset != file->f_pos) {
158                         file->f_pos = offset;
159                         file->f_version = 0;
160                 }
161                 retval = offset;
162         }
163 out:
164         mutex_unlock(&file->f_dentry->d_inode->i_mutex);
165         return retval;
166 }
167 EXPORT_SYMBOL(default_llseek);
168
169 loff_t vfs_llseek(struct file *file, loff_t offset, int origin)
170 {
171         loff_t (*fn)(struct file *, loff_t, int);
172
173         fn = no_llseek;
174         if (file->f_mode & FMODE_LSEEK) {
175                 if (file->f_op && file->f_op->llseek)
176                         fn = file->f_op->llseek;
177         }
178         return fn(file, offset, origin);
179 }
180 EXPORT_SYMBOL(vfs_llseek);
181
182 SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, origin)
183 {
184         off_t retval;
185         struct file * file;
186         int fput_needed;
187
188         retval = -EBADF;
189         file = fget_light(fd, &fput_needed);
190         if (!file)
191                 goto bad;
192
193         retval = -EINVAL;
194         if (origin <= SEEK_MAX) {
195                 loff_t res = vfs_llseek(file, offset, origin);
196                 retval = res;
197                 if (res != (loff_t)retval)
198                         retval = -EOVERFLOW;    /* LFS: should only happen on 32 bit platforms */
199         }
200         fput_light(file, fput_needed);
201 bad:
202         return retval;
203 }
204
205 #ifdef __ARCH_WANT_SYS_LLSEEK
206 SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
207                 unsigned long, offset_low, loff_t __user *, result,
208                 unsigned int, origin)
209 {
210         int retval;
211         struct file * file;
212         loff_t offset;
213         int fput_needed;
214
215         retval = -EBADF;
216         file = fget_light(fd, &fput_needed);
217         if (!file)
218                 goto bad;
219
220         retval = -EINVAL;
221         if (origin > SEEK_MAX)
222                 goto out_putf;
223
224         offset = vfs_llseek(file, ((loff_t) offset_high << 32) | offset_low,
225                         origin);
226
227         retval = (int)offset;
228         if (offset >= 0) {
229                 retval = -EFAULT;
230                 if (!copy_to_user(result, &offset, sizeof(offset)))
231                         retval = 0;
232         }
233 out_putf:
234         fput_light(file, fput_needed);
235 bad:
236         return retval;
237 }
238 #endif
239
240
241 /*
242  * rw_verify_area doesn't like huge counts. We limit
243  * them to something that fits in "int" so that others
244  * won't have to do range checks all the time.
245  */
246 #define MAX_RW_COUNT (INT_MAX & PAGE_CACHE_MASK)
247
248 int rw_verify_area(int read_write, struct file *file, loff_t *ppos, size_t count)
249 {
250         struct inode *inode;
251         loff_t pos;
252         int retval = -EINVAL;
253
254         inode = file->f_path.dentry->d_inode;
255         if (unlikely((ssize_t) count < 0))
256                 return retval;
257         pos = *ppos;
258         if (unlikely((pos < 0) || (loff_t) (pos + count) < 0)) {
259                 retval = __negative_fpos_check(file, pos, count);
260                 if (retval)
261                         return retval;
262         }
263
264         if (unlikely(inode->i_flock && mandatory_lock(inode))) {
265                 retval = locks_mandatory_area(
266                         read_write == READ ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE,
267                         inode, file, pos, count);
268                 if (retval < 0)
269                         return retval;
270         }
271         retval = security_file_permission(file,
272                                 read_write == READ ? MAY_READ : MAY_WRITE);
273         if (retval)
274                 return retval;
275         return count > MAX_RW_COUNT ? MAX_RW_COUNT : count;
276 }
277
278 static void wait_on_retry_sync_kiocb(struct kiocb *iocb)
279 {
280         set_current_state(TASK_UNINTERRUPTIBLE);
281         if (!kiocbIsKicked(iocb))
282                 schedule();
283         else
284                 kiocbClearKicked(iocb);
285         __set_current_state(TASK_RUNNING);
286 }
287
288 ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
289 {
290         struct iovec iov = { .iov_base = buf, .iov_len = len };
291         struct kiocb kiocb;
292         ssize_t ret;
293
294         init_sync_kiocb(&kiocb, filp);
295         kiocb.ki_pos = *ppos;
296         kiocb.ki_left = len;
297         kiocb.ki_nbytes = len;
298
299         for (;;) {
300                 ret = filp->f_op->aio_read(&kiocb, &iov, 1, kiocb.ki_pos);
301                 if (ret != -EIOCBRETRY)
302                         break;
303                 wait_on_retry_sync_kiocb(&kiocb);
304         }
305
306         if (-EIOCBQUEUED == ret)
307                 ret = wait_on_sync_kiocb(&kiocb);
308         *ppos = kiocb.ki_pos;
309         return ret;
310 }
311
312 EXPORT_SYMBOL(do_sync_read);
313
314 ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos)
315 {
316         ssize_t ret;
317
318         if (!(file->f_mode & FMODE_READ))
319                 return -EBADF;
320         if (!file->f_op || (!file->f_op->read && !file->f_op->aio_read))
321                 return -EINVAL;
322         if (unlikely(!access_ok(VERIFY_WRITE, buf, count)))
323                 return -EFAULT;
324
325         ret = rw_verify_area(READ, file, pos, count);
326         if (ret >= 0) {
327                 count = ret;
328                 if (file->f_op->read)
329                         ret = file->f_op->read(file, buf, count, pos);
330                 else
331                         ret = do_sync_read(file, buf, count, pos);
332                 if (ret > 0) {
333                         fsnotify_access(file);
334                         add_rchar(current, ret);
335                 }
336                 inc_syscr(current);
337         }
338
339         return ret;
340 }
341
342 EXPORT_SYMBOL(vfs_read);
343
344 ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
345 {
346         struct iovec iov = { .iov_base = (void __user *)buf, .iov_len = len };
347         struct kiocb kiocb;
348         ssize_t ret;
349
350         init_sync_kiocb(&kiocb, filp);
351         kiocb.ki_pos = *ppos;
352         kiocb.ki_left = len;
353         kiocb.ki_nbytes = len;
354
355         for (;;) {
356                 ret = filp->f_op->aio_write(&kiocb, &iov, 1, kiocb.ki_pos);
357                 if (ret != -EIOCBRETRY)
358                         break;
359                 wait_on_retry_sync_kiocb(&kiocb);
360         }
361
362         if (-EIOCBQUEUED == ret)
363                 ret = wait_on_sync_kiocb(&kiocb);
364         *ppos = kiocb.ki_pos;
365         return ret;
366 }
367
368 EXPORT_SYMBOL(do_sync_write);
369
370 ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
371 {
372         ssize_t ret;
373
374         if (!(file->f_mode & FMODE_WRITE))
375                 return -EBADF;
376         if (!file->f_op || (!file->f_op->write && !file->f_op->aio_write))
377                 return -EINVAL;
378         if (unlikely(!access_ok(VERIFY_READ, buf, count)))
379                 return -EFAULT;
380
381         ret = rw_verify_area(WRITE, file, pos, count);
382         if (ret >= 0) {
383                 count = ret;
384                 if (file->f_op->write)
385                         ret = file->f_op->write(file, buf, count, pos);
386                 else
387                         ret = do_sync_write(file, buf, count, pos);
388                 if (ret > 0) {
389                         fsnotify_modify(file);
390                         add_wchar(current, ret);
391                 }
392                 inc_syscw(current);
393         }
394
395         return ret;
396 }
397
398 EXPORT_SYMBOL(vfs_write);
399
400 static inline loff_t file_pos_read(struct file *file)
401 {
402         return file->f_pos;
403 }
404
405 static inline void file_pos_write(struct file *file, loff_t pos)
406 {
407         file->f_pos = pos;
408 }
409
410 SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
411 {
412         struct file *file;
413         ssize_t ret = -EBADF;
414         int fput_needed;
415
416         file = fget_light(fd, &fput_needed);
417         if (file) {
418                 loff_t pos = file_pos_read(file);
419                 ret = vfs_read(file, buf, count, &pos);
420                 file_pos_write(file, pos);
421                 fput_light(file, fput_needed);
422         }
423
424         return ret;
425 }
426
427 SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
428                 size_t, count)
429 {
430         struct file *file;
431         ssize_t ret = -EBADF;
432         int fput_needed;
433
434         file = fget_light(fd, &fput_needed);
435         if (file) {
436                 loff_t pos = file_pos_read(file);
437                 ret = vfs_write(file, buf, count, &pos);
438                 file_pos_write(file, pos);
439                 fput_light(file, fput_needed);
440         }
441
442         return ret;
443 }
444
445 SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf,
446                         size_t count, loff_t pos)
447 {
448         struct file *file;
449         ssize_t ret = -EBADF;
450         int fput_needed;
451
452         if (pos < 0)
453                 return -EINVAL;
454
455         file = fget_light(fd, &fput_needed);
456         if (file) {
457                 ret = -ESPIPE;
458                 if (file->f_mode & FMODE_PREAD)
459                         ret = vfs_read(file, buf, count, &pos);
460                 fput_light(file, fput_needed);
461         }
462
463         return ret;
464 }
465 #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
466 asmlinkage long SyS_pread64(long fd, long buf, long count, loff_t pos)
467 {
468         return SYSC_pread64((unsigned int) fd, (char __user *) buf,
469                             (size_t) count, pos);
470 }
471 SYSCALL_ALIAS(sys_pread64, SyS_pread64);
472 #endif
473
474 SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf,
475                          size_t count, loff_t pos)
476 {
477         struct file *file;
478         ssize_t ret = -EBADF;
479         int fput_needed;
480
481         if (pos < 0)
482                 return -EINVAL;
483
484         file = fget_light(fd, &fput_needed);
485         if (file) {
486                 ret = -ESPIPE;
487                 if (file->f_mode & FMODE_PWRITE)  
488                         ret = vfs_write(file, buf, count, &pos);
489                 fput_light(file, fput_needed);
490         }
491
492         return ret;
493 }
494 #ifdef CONFIG_HAVE_SYSCALL_WRAPPERS
495 asmlinkage long SyS_pwrite64(long fd, long buf, long count, loff_t pos)
496 {
497         return SYSC_pwrite64((unsigned int) fd, (const char __user *) buf,
498                              (size_t) count, pos);
499 }
500 SYSCALL_ALIAS(sys_pwrite64, SyS_pwrite64);
501 #endif
502
503 /*
504  * Reduce an iovec's length in-place.  Return the resulting number of segments
505  */
506 unsigned long iov_shorten(struct iovec *iov, unsigned long nr_segs, size_t to)
507 {
508         unsigned long seg = 0;
509         size_t len = 0;
510
511         while (seg < nr_segs) {
512                 seg++;
513                 if (len + iov->iov_len >= to) {
514                         iov->iov_len = to - len;
515                         break;
516                 }
517                 len += iov->iov_len;
518                 iov++;
519         }
520         return seg;
521 }
522 EXPORT_SYMBOL(iov_shorten);
523
524 ssize_t do_sync_readv_writev(struct file *filp, const struct iovec *iov,
525                 unsigned long nr_segs, size_t len, loff_t *ppos, iov_fn_t fn)
526 {
527         struct kiocb kiocb;
528         ssize_t ret;
529
530         init_sync_kiocb(&kiocb, filp);
531         kiocb.ki_pos = *ppos;
532         kiocb.ki_left = len;
533         kiocb.ki_nbytes = len;
534
535         for (;;) {
536                 ret = fn(&kiocb, iov, nr_segs, kiocb.ki_pos);
537                 if (ret != -EIOCBRETRY)
538                         break;
539                 wait_on_retry_sync_kiocb(&kiocb);
540         }
541
542         if (ret == -EIOCBQUEUED)
543                 ret = wait_on_sync_kiocb(&kiocb);
544         *ppos = kiocb.ki_pos;
545         return ret;
546 }
547
548 /* Do it by hand, with file-ops */
549 ssize_t do_loop_readv_writev(struct file *filp, struct iovec *iov,
550                 unsigned long nr_segs, loff_t *ppos, io_fn_t fn)
551 {
552         struct iovec *vector = iov;
553         ssize_t ret = 0;
554
555         while (nr_segs > 0) {
556                 void __user *base;
557                 size_t len;
558                 ssize_t nr;
559
560                 base = vector->iov_base;
561                 len = vector->iov_len;
562                 vector++;
563                 nr_segs--;
564
565                 nr = fn(filp, base, len, ppos);
566
567                 if (nr < 0) {
568                         if (!ret)
569                                 ret = nr;
570                         break;
571                 }
572                 ret += nr;
573                 if (nr != len)
574                         break;
575         }
576
577         return ret;
578 }
579
580 /* A write operation does a read from user space and vice versa */
581 #define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ)
582
583 ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector,
584                               unsigned long nr_segs, unsigned long fast_segs,
585                               struct iovec *fast_pointer,
586                               struct iovec **ret_pointer)
587   {
588         unsigned long seg;
589         ssize_t ret;
590         struct iovec *iov = fast_pointer;
591
592         /*
593          * SuS says "The readv() function *may* fail if the iovcnt argument
594          * was less than or equal to 0, or greater than {IOV_MAX}.  Linux has
595          * traditionally returned zero for zero segments, so...
596          */
597         if (nr_segs == 0) {
598                 ret = 0;
599                 goto out;
600         }
601
602         /*
603          * First get the "struct iovec" from user memory and
604          * verify all the pointers
605          */
606         if (nr_segs > UIO_MAXIOV) {
607                 ret = -EINVAL;
608                 goto out;
609         }
610         if (nr_segs > fast_segs) {
611                 iov = kmalloc(nr_segs*sizeof(struct iovec), GFP_KERNEL);
612                 if (iov == NULL) {
613                         ret = -ENOMEM;
614                         goto out;
615                 }
616         }
617         if (copy_from_user(iov, uvector, nr_segs*sizeof(*uvector))) {
618                 ret = -EFAULT;
619                 goto out;
620         }
621
622         /*
623          * According to the Single Unix Specification we should return EINVAL
624          * if an element length is < 0 when cast to ssize_t or if the
625          * total length would overflow the ssize_t return value of the
626          * system call.
627          */
628         ret = 0;
629         for (seg = 0; seg < nr_segs; seg++) {
630                 void __user *buf = iov[seg].iov_base;
631                 ssize_t len = (ssize_t)iov[seg].iov_len;
632
633                 /* see if we we're about to use an invalid len or if
634                  * it's about to overflow ssize_t */
635                 if (len < 0 || (ret + len < ret)) {
636                         ret = -EINVAL;
637                         goto out;
638                 }
639                 if (unlikely(!access_ok(vrfy_dir(type), buf, len))) {
640                         ret = -EFAULT;
641                         goto out;
642                 }
643
644                 ret += len;
645         }
646 out:
647         *ret_pointer = iov;
648         return ret;
649 }
650
651 static ssize_t do_readv_writev(int type, struct file *file,
652                                const struct iovec __user * uvector,
653                                unsigned long nr_segs, loff_t *pos)
654 {
655         size_t tot_len;
656         struct iovec iovstack[UIO_FASTIOV];
657         struct iovec *iov = iovstack;
658         ssize_t ret;
659         io_fn_t fn;
660         iov_fn_t fnv;
661
662         if (!file->f_op) {
663                 ret = -EINVAL;
664                 goto out;
665         }
666
667         ret = rw_copy_check_uvector(type, uvector, nr_segs,
668                         ARRAY_SIZE(iovstack), iovstack, &iov);
669         if (ret <= 0)
670                 goto out;
671
672         tot_len = ret;
673         ret = rw_verify_area(type, file, pos, tot_len);
674         if (ret < 0)
675                 goto out;
676
677         fnv = NULL;
678         if (type == READ) {
679                 fn = file->f_op->read;
680                 fnv = file->f_op->aio_read;
681         } else {
682                 fn = (io_fn_t)file->f_op->write;
683                 fnv = file->f_op->aio_write;
684         }
685
686         if (fnv)
687                 ret = do_sync_readv_writev(file, iov, nr_segs, tot_len,
688                                                 pos, fnv);
689         else
690                 ret = do_loop_readv_writev(file, iov, nr_segs, pos, fn);
691
692 out:
693         if (iov != iovstack)
694                 kfree(iov);
695         if ((ret + (type == READ)) > 0) {
696                 if (type == READ)
697                         fsnotify_access(file);
698                 else
699                         fsnotify_modify(file);
700         }
701         return ret;
702 }
703
704 ssize_t vfs_readv(struct file *file, const struct iovec __user *vec,
705                   unsigned long vlen, loff_t *pos)
706 {
707         if (!(file->f_mode & FMODE_READ))
708                 return -EBADF;
709         if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read))
710                 return -EINVAL;
711
712         return do_readv_writev(READ, file, vec, vlen, pos);
713 }
714
715 EXPORT_SYMBOL(vfs_readv);
716
717 ssize_t vfs_writev(struct file *file, const struct iovec __user *vec,
718                    unsigned long vlen, loff_t *pos)
719 {
720         if (!(file->f_mode & FMODE_WRITE))
721                 return -EBADF;
722         if (!file->f_op || (!file->f_op->aio_write && !file->f_op->write))
723                 return -EINVAL;
724
725         return do_readv_writev(WRITE, file, vec, vlen, pos);
726 }
727
728 EXPORT_SYMBOL(vfs_writev);
729
730 SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
731                 unsigned long, vlen)
732 {
733         struct file *file;
734         ssize_t ret = -EBADF;
735         int fput_needed;
736
737         file = fget_light(fd, &fput_needed);
738         if (file) {
739                 loff_t pos = file_pos_read(file);
740                 ret = vfs_readv(file, vec, vlen, &pos);
741                 file_pos_write(file, pos);
742                 fput_light(file, fput_needed);
743         }
744
745         if (ret > 0)
746                 add_rchar(current, ret);
747         inc_syscr(current);
748         return ret;
749 }
750
751 SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec,
752                 unsigned long, vlen)
753 {
754         struct file *file;
755         ssize_t ret = -EBADF;
756         int fput_needed;
757
758         file = fget_light(fd, &fput_needed);
759         if (file) {
760                 loff_t pos = file_pos_read(file);
761                 ret = vfs_writev(file, vec, vlen, &pos);
762                 file_pos_write(file, pos);
763                 fput_light(file, fput_needed);
764         }
765
766         if (ret > 0)
767                 add_wchar(current, ret);
768         inc_syscw(current);
769         return ret;
770 }
771
772 static inline loff_t pos_from_hilo(unsigned long high, unsigned long low)
773 {
774 #define HALF_LONG_BITS (BITS_PER_LONG / 2)
775         return (((loff_t)high << HALF_LONG_BITS) << HALF_LONG_BITS) | low;
776 }
777
778 SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
779                 unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
780 {
781         loff_t pos = pos_from_hilo(pos_h, pos_l);
782         struct file *file;
783         ssize_t ret = -EBADF;
784         int fput_needed;
785
786         if (pos < 0)
787                 return -EINVAL;
788
789         file = fget_light(fd, &fput_needed);
790         if (file) {
791                 ret = -ESPIPE;
792                 if (file->f_mode & FMODE_PREAD)
793                         ret = vfs_readv(file, vec, vlen, &pos);
794                 fput_light(file, fput_needed);
795         }
796
797         if (ret > 0)
798                 add_rchar(current, ret);
799         inc_syscr(current);
800         return ret;
801 }
802
803 SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
804                 unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
805 {
806         loff_t pos = pos_from_hilo(pos_h, pos_l);
807         struct file *file;
808         ssize_t ret = -EBADF;
809         int fput_needed;
810
811         if (pos < 0)
812                 return -EINVAL;
813
814         file = fget_light(fd, &fput_needed);
815         if (file) {
816                 ret = -ESPIPE;
817                 if (file->f_mode & FMODE_PWRITE)
818                         ret = vfs_writev(file, vec, vlen, &pos);
819                 fput_light(file, fput_needed);
820         }
821
822         if (ret > 0)
823                 add_wchar(current, ret);
824         inc_syscw(current);
825         return ret;
826 }
827
828 static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
829                            size_t count, loff_t max)
830 {
831         struct file * in_file, * out_file;
832         struct inode * in_inode, * out_inode;
833         loff_t pos;
834         ssize_t retval;
835         int fput_needed_in, fput_needed_out, fl;
836
837         /*
838          * Get input file, and verify that it is ok..
839          */
840         retval = -EBADF;
841         in_file = fget_light(in_fd, &fput_needed_in);
842         if (!in_file)
843                 goto out;
844         if (!(in_file->f_mode & FMODE_READ))
845                 goto fput_in;
846         retval = -ESPIPE;
847         if (!ppos)
848                 ppos = &in_file->f_pos;
849         else
850                 if (!(in_file->f_mode & FMODE_PREAD))
851                         goto fput_in;
852         retval = rw_verify_area(READ, in_file, ppos, count);
853         if (retval < 0)
854                 goto fput_in;
855         count = retval;
856
857         /*
858          * Get output file, and verify that it is ok..
859          */
860         retval = -EBADF;
861         out_file = fget_light(out_fd, &fput_needed_out);
862         if (!out_file)
863                 goto fput_in;
864         if (!(out_file->f_mode & FMODE_WRITE))
865                 goto fput_out;
866         retval = -EINVAL;
867         in_inode = in_file->f_path.dentry->d_inode;
868         out_inode = out_file->f_path.dentry->d_inode;
869         retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count);
870         if (retval < 0)
871                 goto fput_out;
872         count = retval;
873
874         if (!max)
875                 max = min(in_inode->i_sb->s_maxbytes, out_inode->i_sb->s_maxbytes);
876
877         pos = *ppos;
878         if (unlikely(pos + count > max)) {
879                 retval = -EOVERFLOW;
880                 if (pos >= max)
881                         goto fput_out;
882                 count = max - pos;
883         }
884
885         fl = 0;
886 #if 0
887         /*
888          * We need to debate whether we can enable this or not. The
889          * man page documents EAGAIN return for the output at least,
890          * and the application is arguably buggy if it doesn't expect
891          * EAGAIN on a non-blocking file descriptor.
892          */
893         if (in_file->f_flags & O_NONBLOCK)
894                 fl = SPLICE_F_NONBLOCK;
895 #endif
896         retval = do_splice_direct(in_file, ppos, out_file, count, fl);
897
898         if (retval > 0) {
899                 add_rchar(current, retval);
900                 add_wchar(current, retval);
901         }
902
903         inc_syscr(current);
904         inc_syscw(current);
905         if (*ppos > max)
906                 retval = -EOVERFLOW;
907
908 fput_out:
909         fput_light(out_file, fput_needed_out);
910 fput_in:
911         fput_light(in_file, fput_needed_in);
912 out:
913         return retval;
914 }
915
916 SYSCALL_DEFINE4(sendfile, int, out_fd, int, in_fd, off_t __user *, offset, size_t, count)
917 {
918         loff_t pos;
919         off_t off;
920         ssize_t ret;
921
922         if (offset) {
923                 if (unlikely(get_user(off, offset)))
924                         return -EFAULT;
925                 pos = off;
926                 ret = do_sendfile(out_fd, in_fd, &pos, count, MAX_NON_LFS);
927                 if (unlikely(put_user(pos, offset)))
928                         return -EFAULT;
929                 return ret;
930         }
931
932         return do_sendfile(out_fd, in_fd, NULL, count, 0);
933 }
934
935 SYSCALL_DEFINE4(sendfile64, int, out_fd, int, in_fd, loff_t __user *, offset, size_t, count)
936 {
937         loff_t pos;
938         ssize_t ret;
939
940         if (offset) {
941                 if (unlikely(copy_from_user(&pos, offset, sizeof(loff_t))))
942                         return -EFAULT;
943                 ret = do_sendfile(out_fd, in_fd, &pos, count, 0);
944                 if (unlikely(put_user(pos, offset)))
945                         return -EFAULT;
946                 return ret;
947         }
948
949         return do_sendfile(out_fd, in_fd, NULL, count, 0);
950 }