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