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