aboutsummaryrefslogtreecommitdiffstats
path: root/fs/read_write.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/read_write.c')
-rw-r--r--fs/read_write.c176
1 files changed, 77 insertions, 99 deletions
diff --git a/fs/read_write.c b/fs/read_write.c
index 1adfb691e4f1..28b38279a219 100644
--- a/fs/read_write.c
+++ b/fs/read_write.c
@@ -232,23 +232,18 @@ EXPORT_SYMBOL(vfs_llseek);
232SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, origin) 232SYSCALL_DEFINE3(lseek, unsigned int, fd, off_t, offset, unsigned int, origin)
233{ 233{
234 off_t retval; 234 off_t retval;
235 struct file * file; 235 struct fd f = fdget(fd);
236 int fput_needed; 236 if (!f.file)
237 237 return -EBADF;
238 retval = -EBADF;
239 file = fget_light(fd, &fput_needed);
240 if (!file)
241 goto bad;
242 238
243 retval = -EINVAL; 239 retval = -EINVAL;
244 if (origin <= SEEK_MAX) { 240 if (origin <= SEEK_MAX) {
245 loff_t res = vfs_llseek(file, offset, origin); 241 loff_t res = vfs_llseek(f.file, offset, origin);
246 retval = res; 242 retval = res;
247 if (res != (loff_t)retval) 243 if (res != (loff_t)retval)
248 retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */ 244 retval = -EOVERFLOW; /* LFS: should only happen on 32 bit platforms */
249 } 245 }
250 fput_light(file, fput_needed); 246 fdput(f);
251bad:
252 return retval; 247 return retval;
253} 248}
254 249
@@ -258,20 +253,17 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
258 unsigned int, origin) 253 unsigned int, origin)
259{ 254{
260 int retval; 255 int retval;
261 struct file * file; 256 struct fd f = fdget(fd);
262 loff_t offset; 257 loff_t offset;
263 int fput_needed;
264 258
265 retval = -EBADF; 259 if (!f.file)
266 file = fget_light(fd, &fput_needed); 260 return -EBADF;
267 if (!file)
268 goto bad;
269 261
270 retval = -EINVAL; 262 retval = -EINVAL;
271 if (origin > SEEK_MAX) 263 if (origin > SEEK_MAX)
272 goto out_putf; 264 goto out_putf;
273 265
274 offset = vfs_llseek(file, ((loff_t) offset_high << 32) | offset_low, 266 offset = vfs_llseek(f.file, ((loff_t) offset_high << 32) | offset_low,
275 origin); 267 origin);
276 268
277 retval = (int)offset; 269 retval = (int)offset;
@@ -281,8 +273,7 @@ SYSCALL_DEFINE5(llseek, unsigned int, fd, unsigned long, offset_high,
281 retval = 0; 273 retval = 0;
282 } 274 }
283out_putf: 275out_putf:
284 fput_light(file, fput_needed); 276 fdput(f);
285bad:
286 return retval; 277 return retval;
287} 278}
288#endif 279#endif
@@ -461,34 +452,29 @@ static inline void file_pos_write(struct file *file, loff_t pos)
461 452
462SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count) 453SYSCALL_DEFINE3(read, unsigned int, fd, char __user *, buf, size_t, count)
463{ 454{
464 struct file *file; 455 struct fd f = fdget(fd);
465 ssize_t ret = -EBADF; 456 ssize_t ret = -EBADF;
466 int fput_needed;
467 457
468 file = fget_light(fd, &fput_needed); 458 if (f.file) {
469 if (file) { 459 loff_t pos = file_pos_read(f.file);
470 loff_t pos = file_pos_read(file); 460 ret = vfs_read(f.file, buf, count, &pos);
471 ret = vfs_read(file, buf, count, &pos); 461 file_pos_write(f.file, pos);
472 file_pos_write(file, pos); 462 fdput(f);
473 fput_light(file, fput_needed);
474 } 463 }
475
476 return ret; 464 return ret;
477} 465}
478 466
479SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf, 467SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
480 size_t, count) 468 size_t, count)
481{ 469{
482 struct file *file; 470 struct fd f = fdget(fd);
483 ssize_t ret = -EBADF; 471 ssize_t ret = -EBADF;
484 int fput_needed;
485 472
486 file = fget_light(fd, &fput_needed); 473 if (f.file) {
487 if (file) { 474 loff_t pos = file_pos_read(f.file);
488 loff_t pos = file_pos_read(file); 475 ret = vfs_write(f.file, buf, count, &pos);
489 ret = vfs_write(file, buf, count, &pos); 476 file_pos_write(f.file, pos);
490 file_pos_write(file, pos); 477 fdput(f);
491 fput_light(file, fput_needed);
492 } 478 }
493 479
494 return ret; 480 return ret;
@@ -497,19 +483,18 @@ SYSCALL_DEFINE3(write, unsigned int, fd, const char __user *, buf,
497SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf, 483SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf,
498 size_t count, loff_t pos) 484 size_t count, loff_t pos)
499{ 485{
500 struct file *file; 486 struct fd f;
501 ssize_t ret = -EBADF; 487 ssize_t ret = -EBADF;
502 int fput_needed;
503 488
504 if (pos < 0) 489 if (pos < 0)
505 return -EINVAL; 490 return -EINVAL;
506 491
507 file = fget_light(fd, &fput_needed); 492 f = fdget(fd);
508 if (file) { 493 if (f.file) {
509 ret = -ESPIPE; 494 ret = -ESPIPE;
510 if (file->f_mode & FMODE_PREAD) 495 if (f.file->f_mode & FMODE_PREAD)
511 ret = vfs_read(file, buf, count, &pos); 496 ret = vfs_read(f.file, buf, count, &pos);
512 fput_light(file, fput_needed); 497 fdput(f);
513 } 498 }
514 499
515 return ret; 500 return ret;
@@ -526,19 +511,18 @@ SYSCALL_ALIAS(sys_pread64, SyS_pread64);
526SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf, 511SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf,
527 size_t count, loff_t pos) 512 size_t count, loff_t pos)
528{ 513{
529 struct file *file; 514 struct fd f;
530 ssize_t ret = -EBADF; 515 ssize_t ret = -EBADF;
531 int fput_needed;
532 516
533 if (pos < 0) 517 if (pos < 0)
534 return -EINVAL; 518 return -EINVAL;
535 519
536 file = fget_light(fd, &fput_needed); 520 f = fdget(fd);
537 if (file) { 521 if (f.file) {
538 ret = -ESPIPE; 522 ret = -ESPIPE;
539 if (file->f_mode & FMODE_PWRITE) 523 if (f.file->f_mode & FMODE_PWRITE)
540 ret = vfs_write(file, buf, count, &pos); 524 ret = vfs_write(f.file, buf, count, &pos);
541 fput_light(file, fput_needed); 525 fdput(f);
542 } 526 }
543 527
544 return ret; 528 return ret;
@@ -789,16 +773,14 @@ EXPORT_SYMBOL(vfs_writev);
789SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec, 773SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
790 unsigned long, vlen) 774 unsigned long, vlen)
791{ 775{
792 struct file *file; 776 struct fd f = fdget(fd);
793 ssize_t ret = -EBADF; 777 ssize_t ret = -EBADF;
794 int fput_needed;
795 778
796 file = fget_light(fd, &fput_needed); 779 if (f.file) {
797 if (file) { 780 loff_t pos = file_pos_read(f.file);
798 loff_t pos = file_pos_read(file); 781 ret = vfs_readv(f.file, vec, vlen, &pos);
799 ret = vfs_readv(file, vec, vlen, &pos); 782 file_pos_write(f.file, pos);
800 file_pos_write(file, pos); 783 fdput(f);
801 fput_light(file, fput_needed);
802 } 784 }
803 785
804 if (ret > 0) 786 if (ret > 0)
@@ -810,16 +792,14 @@ SYSCALL_DEFINE3(readv, unsigned long, fd, const struct iovec __user *, vec,
810SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec, 792SYSCALL_DEFINE3(writev, unsigned long, fd, const struct iovec __user *, vec,
811 unsigned long, vlen) 793 unsigned long, vlen)
812{ 794{
813 struct file *file; 795 struct fd f = fdget(fd);
814 ssize_t ret = -EBADF; 796 ssize_t ret = -EBADF;
815 int fput_needed;
816 797
817 file = fget_light(fd, &fput_needed); 798 if (f.file) {
818 if (file) { 799 loff_t pos = file_pos_read(f.file);
819 loff_t pos = file_pos_read(file); 800 ret = vfs_writev(f.file, vec, vlen, &pos);
820 ret = vfs_writev(file, vec, vlen, &pos); 801 file_pos_write(f.file, pos);
821 file_pos_write(file, pos); 802 fdput(f);
822 fput_light(file, fput_needed);
823 } 803 }
824 804
825 if (ret > 0) 805 if (ret > 0)
@@ -838,19 +818,18 @@ SYSCALL_DEFINE5(preadv, unsigned long, fd, const struct iovec __user *, vec,
838 unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h) 818 unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
839{ 819{
840 loff_t pos = pos_from_hilo(pos_h, pos_l); 820 loff_t pos = pos_from_hilo(pos_h, pos_l);
841 struct file *file; 821 struct fd f;
842 ssize_t ret = -EBADF; 822 ssize_t ret = -EBADF;
843 int fput_needed;
844 823
845 if (pos < 0) 824 if (pos < 0)
846 return -EINVAL; 825 return -EINVAL;
847 826
848 file = fget_light(fd, &fput_needed); 827 f = fdget(fd);
849 if (file) { 828 if (f.file) {
850 ret = -ESPIPE; 829 ret = -ESPIPE;
851 if (file->f_mode & FMODE_PREAD) 830 if (f.file->f_mode & FMODE_PREAD)
852 ret = vfs_readv(file, vec, vlen, &pos); 831 ret = vfs_readv(f.file, vec, vlen, &pos);
853 fput_light(file, fput_needed); 832 fdput(f);
854 } 833 }
855 834
856 if (ret > 0) 835 if (ret > 0)
@@ -863,19 +842,18 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
863 unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h) 842 unsigned long, vlen, unsigned long, pos_l, unsigned long, pos_h)
864{ 843{
865 loff_t pos = pos_from_hilo(pos_h, pos_l); 844 loff_t pos = pos_from_hilo(pos_h, pos_l);
866 struct file *file; 845 struct fd f;
867 ssize_t ret = -EBADF; 846 ssize_t ret = -EBADF;
868 int fput_needed;
869 847
870 if (pos < 0) 848 if (pos < 0)
871 return -EINVAL; 849 return -EINVAL;
872 850
873 file = fget_light(fd, &fput_needed); 851 f = fdget(fd);
874 if (file) { 852 if (f.file) {
875 ret = -ESPIPE; 853 ret = -ESPIPE;
876 if (file->f_mode & FMODE_PWRITE) 854 if (f.file->f_mode & FMODE_PWRITE)
877 ret = vfs_writev(file, vec, vlen, &pos); 855 ret = vfs_writev(f.file, vec, vlen, &pos);
878 fput_light(file, fput_needed); 856 fdput(f);
879 } 857 }
880 858
881 if (ret > 0) 859 if (ret > 0)
@@ -887,28 +865,28 @@ SYSCALL_DEFINE5(pwritev, unsigned long, fd, const struct iovec __user *, vec,
887static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos, 865static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
888 size_t count, loff_t max) 866 size_t count, loff_t max)
889{ 867{
890 struct file * in_file, * out_file; 868 struct fd in, out;
891 struct inode * in_inode, * out_inode; 869 struct inode *in_inode, *out_inode;
892 loff_t pos; 870 loff_t pos;
893 ssize_t retval; 871 ssize_t retval;
894 int fput_needed_in, fput_needed_out, fl; 872 int fl;
895 873
896 /* 874 /*
897 * Get input file, and verify that it is ok.. 875 * Get input file, and verify that it is ok..
898 */ 876 */
899 retval = -EBADF; 877 retval = -EBADF;
900 in_file = fget_light(in_fd, &fput_needed_in); 878 in = fdget(in_fd);
901 if (!in_file) 879 if (!in.file)
902 goto out; 880 goto out;
903 if (!(in_file->f_mode & FMODE_READ)) 881 if (!(in.file->f_mode & FMODE_READ))
904 goto fput_in; 882 goto fput_in;
905 retval = -ESPIPE; 883 retval = -ESPIPE;
906 if (!ppos) 884 if (!ppos)
907 ppos = &in_file->f_pos; 885 ppos = &in.file->f_pos;
908 else 886 else
909 if (!(in_file->f_mode & FMODE_PREAD)) 887 if (!(in.file->f_mode & FMODE_PREAD))
910 goto fput_in; 888 goto fput_in;
911 retval = rw_verify_area(READ, in_file, ppos, count); 889 retval = rw_verify_area(READ, in.file, ppos, count);
912 if (retval < 0) 890 if (retval < 0)
913 goto fput_in; 891 goto fput_in;
914 count = retval; 892 count = retval;
@@ -917,15 +895,15 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
917 * Get output file, and verify that it is ok.. 895 * Get output file, and verify that it is ok..
918 */ 896 */
919 retval = -EBADF; 897 retval = -EBADF;
920 out_file = fget_light(out_fd, &fput_needed_out); 898 out = fdget(out_fd);
921 if (!out_file) 899 if (!out.file)
922 goto fput_in; 900 goto fput_in;
923 if (!(out_file->f_mode & FMODE_WRITE)) 901 if (!(out.file->f_mode & FMODE_WRITE))
924 goto fput_out; 902 goto fput_out;
925 retval = -EINVAL; 903 retval = -EINVAL;
926 in_inode = in_file->f_path.dentry->d_inode; 904 in_inode = in.file->f_path.dentry->d_inode;
927 out_inode = out_file->f_path.dentry->d_inode; 905 out_inode = out.file->f_path.dentry->d_inode;
928 retval = rw_verify_area(WRITE, out_file, &out_file->f_pos, count); 906 retval = rw_verify_area(WRITE, out.file, &out.file->f_pos, count);
929 if (retval < 0) 907 if (retval < 0)
930 goto fput_out; 908 goto fput_out;
931 count = retval; 909 count = retval;
@@ -949,10 +927,10 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
949 * and the application is arguably buggy if it doesn't expect 927 * and the application is arguably buggy if it doesn't expect
950 * EAGAIN on a non-blocking file descriptor. 928 * EAGAIN on a non-blocking file descriptor.
951 */ 929 */
952 if (in_file->f_flags & O_NONBLOCK) 930 if (in.file->f_flags & O_NONBLOCK)
953 fl = SPLICE_F_NONBLOCK; 931 fl = SPLICE_F_NONBLOCK;
954#endif 932#endif
955 retval = do_splice_direct(in_file, ppos, out_file, count, fl); 933 retval = do_splice_direct(in.file, ppos, out.file, count, fl);
956 934
957 if (retval > 0) { 935 if (retval > 0) {
958 add_rchar(current, retval); 936 add_rchar(current, retval);
@@ -965,9 +943,9 @@ static ssize_t do_sendfile(int out_fd, int in_fd, loff_t *ppos,
965 retval = -EOVERFLOW; 943 retval = -EOVERFLOW;
966 944
967fput_out: 945fput_out:
968 fput_light(out_file, fput_needed_out); 946 fdput(out);
969fput_in: 947fput_in:
970 fput_light(in_file, fput_needed_in); 948 fdput(in);
971out: 949out:
972 return retval; 950 return retval;
973} 951}