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