Pull final vfs updates from Al Viro: "Assorted cleanups and fixes all over the place" * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: sg_write()/bsg_write() is not fit to be called under KERNEL_DS ufs: fix function declaration for ufs_truncate_blocks fs: exec: apply CLOEXEC before changing dumpable task flags seq_file: reset iterator to first record for zero offset vfs: fix isize/pos/len checks for reflink & dedupe [iov_iter] fix iterate_all_kinds() on empty iterators move aio compat to fs/aio.c reorganize do_make_slave() clone_private_mount() doesn't need to touch namespace_sem remove a bogus claim about namespace_sem being held by callers of mnt_alloc_id()
Unified · Split
| @@ -655,6 +655,9 @@ bsg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) · 654 unmodified lines | ||
| 655 | 655 | |
| 656 | 656 | dprintk("%s: write %Zd bytes\n", bd->name, count); |
| 657 | 657 | |
| 658 | + if (unlikely(segment_eq(get_fs(), KERNEL_DS))) | |
| 659 | + return -EINVAL; | |
| 660 | + | |
| 658 | 661 | bsg_set_block(bd, file); |
| 659 | 662 | |
| 660 | 663 | bytes_written = 0; |
| @@ -581,6 +581,9 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) · 580 unmodified lines | ||
| 581 | 581 | sg_io_hdr_t *hp; |
| 582 | 582 | unsigned char cmnd[SG_MAX_CDB_SIZE]; |
| 583 | 583 | |
| 584 | + if (unlikely(segment_eq(get_fs(), KERNEL_DS))) | |
| 585 | + return -EINVAL; | |
| 586 | + | |
| 584 | 587 | if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) |
| 585 | 588 | return -ENXIO; |
| 586 | 589 | SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp, |
| @@ -1367,6 +1367,39 @@ out: · 1366 unmodified lines | ||
| 1367 | 1367 | return ret; |
| 1368 | 1368 | } |
| 1369 | 1369 | |
| 1370 | +#ifdef CONFIG_COMPAT | |
| 1371 | +COMPAT_SYSCALL_DEFINE2(io_setup, unsigned, nr_events, u32 __user *, ctx32p) | |
| 1372 | +{ | |
| 1373 | + struct kioctx *ioctx = NULL; | |
| 1374 | + unsigned long ctx; | |
| 1375 | + long ret; | |
| 1376 | + | |
| 1377 | + ret = get_user(ctx, ctx32p); | |
| 1378 | + if (unlikely(ret)) | |
| 1379 | + goto out; | |
| 1380 | + | |
| 1381 | + ret = -EINVAL; | |
| 1382 | + if (unlikely(ctx || nr_events == 0)) { | |
| 1383 | + pr_debug("EINVAL: ctx %lu nr_events %u\n", | |
| 1384 | + ctx, nr_events); | |
| 1385 | + goto out; | |
| 1386 | + } | |
| 1387 | + | |
| 1388 | + ioctx = ioctx_alloc(nr_events); | |
| 1389 | + ret = PTR_ERR(ioctx); | |
| 1390 | + if (!IS_ERR(ioctx)) { | |
| 1391 | + /* truncating is ok because it's a user address */ | |
| 1392 | + ret = put_user((u32)ioctx->user_id, ctx32p); | |
| 1393 | + if (ret) | |
| 1394 | + kill_ioctx(current->mm, ioctx, NULL); | |
| 1395 | + percpu_ref_put(&ioctx->users); | |
| 1396 | + } | |
| 1397 | + | |
| 1398 | +out: | |
| 1399 | + return ret; | |
| 1400 | +} | |
| 1401 | +#endif | |
| 1402 | + | |
| 1370 | 1403 | /* sys_io_destroy: |
| 1371 | 1404 | * Destroy the aio_context specified. May cancel any outstanding |
| 1372 | 1405 | * AIOs and block on completion. Will fail with -ENOSYS if not |
| @@ -1591,8 +1624,8 @@ out_put_req: · 218 unmodified lines | ||
| 1591 | 1624 | return ret; |
| 1592 | 1625 | } |
| 1593 | 1626 | |
| 1594 | −long do_io_submit(aio_context_t ctx_id, long nr, | |
| 1595 | − struct iocb __user *__user *iocbpp, bool compat) | |
| 1627 | +static long do_io_submit(aio_context_t ctx_id, long nr, | |
| 1628 | + struct iocb __user *__user *iocbpp, bool compat) | |
| 1596 | 1629 | { |
| 1597 | 1630 | struct kioctx *ctx; |
| 1598 | 1631 | long ret = 0; |
| @@ -1662,6 +1695,44 @@ SYSCALL_DEFINE3(io_submit, aio_context_t, ctx_id, long, nr, · 63 unmodified lines | ||
| 1662 | 1695 | return do_io_submit(ctx_id, nr, iocbpp, 0); |
| 1663 | 1696 | } |
| 1664 | 1697 | |
| 1698 | +#ifdef CONFIG_COMPAT | |
| 1699 | +static inline long | |
| 1700 | +copy_iocb(long nr, u32 __user *ptr32, struct iocb __user * __user *ptr64) | |
| 1701 | +{ | |
| 1702 | + compat_uptr_t uptr; | |
| 1703 | + int i; | |
| 1704 | + | |
| 1705 | + for (i = 0; i < nr; ++i) { | |
| 1706 | + if (get_user(uptr, ptr32 + i)) | |
| 1707 | + return -EFAULT; | |
| 1708 | + if (put_user(compat_ptr(uptr), ptr64 + i)) | |
| 1709 | + return -EFAULT; | |
| 1710 | + } | |
| 1711 | + return 0; | |
| 1712 | +} | |
| 1713 | + | |
| 1714 | +#define MAX_AIO_SUBMITS (PAGE_SIZE/sizeof(struct iocb *)) | |
| 1715 | + | |
| 1716 | +COMPAT_SYSCALL_DEFINE3(io_submit, compat_aio_context_t, ctx_id, | |
| 1717 | + int, nr, u32 __user *, iocb) | |
| 1718 | +{ | |
| 1719 | + struct iocb __user * __user *iocb64; | |
| 1720 | + long ret; | |
| 1721 | + | |
| 1722 | + if (unlikely(nr < 0)) | |
| 1723 | + return -EINVAL; | |
| 1724 | + | |
| 1725 | + if (nr > MAX_AIO_SUBMITS) | |
| 1726 | + nr = MAX_AIO_SUBMITS; | |
| 1727 | + | |
| 1728 | + iocb64 = compat_alloc_user_space(nr * sizeof(*iocb64)); | |
| 1729 | + ret = copy_iocb(nr, iocb, iocb64); | |
| 1730 | + if (!ret) | |
| 1731 | + ret = do_io_submit(ctx_id, nr, iocb64, 1); | |
| 1732 | + return ret; | |
| 1733 | +} | |
| 1734 | +#endif | |
| 1735 | + | |
| 1665 | 1736 | /* lookup_kiocb |
| 1666 | 1737 | * Finds a given iocb for cancellation. |
| 1667 | 1738 | */ |
| @@ -1761,3 +1832,25 @@ SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id, · 93 unmodified lines | ||
| 1761 | 1832 | } |
| 1762 | 1833 | return ret; |
| 1763 | 1834 | } |
| 1835 | + | |
| 1836 | +#ifdef CONFIG_COMPAT | |
| 1837 | +COMPAT_SYSCALL_DEFINE5(io_getevents, compat_aio_context_t, ctx_id, | |
| 1838 | + compat_long_t, min_nr, | |
| 1839 | + compat_long_t, nr, | |
| 1840 | + struct io_event __user *, events, | |
| 1841 | + struct compat_timespec __user *, timeout) | |
| 1842 | +{ | |
| 1843 | + struct timespec t; | |
| 1844 | + struct timespec __user *ut = NULL; | |
| 1845 | + | |
| 1846 | + if (timeout) { | |
| 1847 | + if (compat_get_timespec(&t, timeout)) | |
| 1848 | + return -EFAULT; | |
| 1849 | + | |
| 1850 | + ut = compat_alloc_user_space(sizeof(*ut)); | |
| 1851 | + if (copy_to_user(ut, &t, sizeof(t))) | |
| 1852 | + return -EFAULT; | |
| 1853 | + } | |
| 1854 | + return sys_io_getevents(ctx_id, min_nr, nr, events, ut); | |
| 1855 | +} | |
| 1856 | +#endif | |
| @@ -487,45 +487,6 @@ COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, · 486 unmodified lines | ||
| 487 | 487 | return compat_sys_fcntl64(fd, cmd, arg); |
| 488 | 488 | } |
| 489 | 489 | |
| 490 | −COMPAT_SYSCALL_DEFINE2(io_setup, unsigned, nr_reqs, u32 __user *, ctx32p) | |
| 491 | −{ | |
| 492 | − long ret; | |
| 493 | − aio_context_t ctx64; | |
| 494 | − | |
| 495 | − mm_segment_t oldfs = get_fs(); | |
| 496 | − if (unlikely(get_user(ctx64, ctx32p))) | |
| 497 | − return -EFAULT; | |
| 498 | − | |
| 499 | − set_fs(KERNEL_DS); | |
| 500 | − /* The __user pointer cast is valid because of the set_fs() */ | |
| 501 | − ret = sys_io_setup(nr_reqs, (aio_context_t __user *) &ctx64); | |
| 502 | − set_fs(oldfs); | |
| 503 | − /* truncating is ok because it's a user address */ | |
| 504 | − if (!ret) | |
| 505 | − ret = put_user((u32) ctx64, ctx32p); | |
| 506 | − return ret; | |
| 507 | −} | |
| 508 | − | |
| 509 | −COMPAT_SYSCALL_DEFINE5(io_getevents, compat_aio_context_t, ctx_id, | |
| 510 | − compat_long_t, min_nr, | |
| 511 | − compat_long_t, nr, | |
| 512 | − struct io_event __user *, events, | |
| 513 | − struct compat_timespec __user *, timeout) | |
| 514 | −{ | |
| 515 | − struct timespec t; | |
| 516 | − struct timespec __user *ut = NULL; | |
| 517 | − | |
| 518 | − if (timeout) { | |
| 519 | − if (compat_get_timespec(&t, timeout)) | |
| 520 | − return -EFAULT; | |
| 521 | − | |
| 522 | − ut = compat_alloc_user_space(sizeof(*ut)); | |
| 523 | − if (copy_to_user(ut, &t, sizeof(t)) ) | |
| 524 | − return -EFAULT; | |
| 525 | − } | |
| 526 | − return sys_io_getevents(ctx_id, min_nr, nr, events, ut); | |
| 527 | −} | |
| 528 | − | |
| 529 | 490 | /* A write operation does a read from user space and vice versa */ |
| 530 | 491 | #define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ) |
| 531 | 492 | |
| @@ -602,42 +563,6 @@ out: · 70 unmodified lines | ||
| 602 | 563 | return ret; |
| 603 | 564 | } |
| 604 | 565 | |
| 605 | −static inline long | |
| 606 | −copy_iocb(long nr, u32 __user *ptr32, struct iocb __user * __user *ptr64) | |
| 607 | −{ | |
| 608 | − compat_uptr_t uptr; | |
| 609 | − int i; | |
| 610 | − | |
| 611 | − for (i = 0; i < nr; ++i) { | |
| 612 | − if (get_user(uptr, ptr32 + i)) | |
| 613 | − return -EFAULT; | |
| 614 | − if (put_user(compat_ptr(uptr), ptr64 + i)) | |
| 615 | − return -EFAULT; | |
| 616 | − } | |
| 617 | − return 0; | |
| 618 | −} | |
| 619 | − | |
| 620 | −#define MAX_AIO_SUBMITS (PAGE_SIZE/sizeof(struct iocb *)) | |
| 621 | − | |
| 622 | −COMPAT_SYSCALL_DEFINE3(io_submit, compat_aio_context_t, ctx_id, | |
| 623 | − int, nr, u32 __user *, iocb) | |
| 624 | −{ | |
| 625 | − struct iocb __user * __user *iocb64; | |
| 626 | − long ret; | |
| 627 | − | |
| 628 | − if (unlikely(nr < 0)) | |
| 629 | − return -EINVAL; | |
| 630 | − | |
| 631 | − if (nr > MAX_AIO_SUBMITS) | |
| 632 | − nr = MAX_AIO_SUBMITS; | |
| 633 | − | |
| 634 | − iocb64 = compat_alloc_user_space(nr * sizeof(*iocb64)); | |
| 635 | − ret = copy_iocb(nr, iocb, iocb64); | |
| 636 | − if (!ret) | |
| 637 | − ret = do_io_submit(ctx_id, nr, iocb64, 1); | |
| 638 | − return ret; | |
| 639 | −} | |
| 640 | − | |
| 641 | 566 | struct compat_ncp_mount_data { |
| 642 | 567 | compat_int_t version; |
| 643 | 568 | compat_uint_t ncp_fd; |
| @@ -19,7 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | * current->executable is only used by the procfs. This allows a dispatch |
| 20 | 20 | * table to check for several different types of binary formats. We keep |
| 21 | 21 | * trying until we recognize the file or we run out of supported binary |
| 22 | − * formats. | |
| 22 | + * formats. | |
| 23 | 23 | */ |
| 24 | 24 | |
| 25 | 25 | #include <linux/slab.h> |
| @@ -1268,6 +1268,13 @@ int flush_old_exec(struct linux_binprm * bprm) · 1242 unmodified lines | ||
| 1268 | 1268 | flush_thread(); |
| 1269 | 1269 | current->personality &= ~bprm->per_clear; |
| 1270 | 1270 | |
| 1271 | + /* | |
| 1272 | + * We have to apply CLOEXEC before we change whether the process is | |
| 1273 | + * dumpable (in setup_new_exec) to avoid a race with a process in userspace | |
| 1274 | + * trying to access the should-be-closed file descriptors of a process | |
| 1275 | + * undergoing exec(2). | |
| 1276 | + */ | |
| 1277 | + do_close_on_exec(current->files); | |
| 1271 | 1278 | return 0; |
| 1272 | 1279 | |
| 1273 | 1280 | out: |
| @@ -1330,7 +1337,6 @@ void setup_new_exec(struct linux_binprm * bprm) · 56 unmodified lines | ||
| 1330 | 1337 | group */ |
| 1331 | 1338 | current->self_exec_id++; |
| 1332 | 1339 | flush_signal_handlers(current, 0); |
| 1333 | − do_close_on_exec(current->files); | |
| 1334 | 1340 | } |
| 1335 | 1341 | EXPORT_SYMBOL(setup_new_exec); |
| 1336 | 1342 | |
| @@ -96,10 +96,6 @@ static inline struct hlist_head *mp_hash(struct dentry *dentry) · 95 unmodified lines | ||
| 96 | 96 | return &mountpoint_hashtable[tmp & mp_hash_mask]; |
| 97 | 97 | } |
| 98 | 98 | |
| 99 | −/* | |
| 100 | − * allocation is serialized by namespace_sem, but we need the spinlock to | |
| 101 | − * serialize with freeing. | |
| 102 | − */ | |
| 103 | 99 | static int mnt_alloc_id(struct mount *mnt) |
| 104 | 100 | { |
| 105 | 101 | int res; |
| @@ -1034,6 +1030,8 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, · 928 unmodified lines | ||
| 1034 | 1030 | if (IS_MNT_SLAVE(old)) |
| 1035 | 1031 | list_add(&mnt->mnt_slave, &old->mnt_slave); |
| 1036 | 1032 | mnt->mnt_master = old->mnt_master; |
| 1033 | + } else { | |
| 1034 | + CLEAR_MNT_SHARED(mnt); | |
| 1037 | 1035 | } |
| 1038 | 1036 | if (flag & CL_MAKE_SHARED) |
| 1039 | 1037 | set_mnt_shared(mnt); |
| @@ -1828,9 +1826,7 @@ struct vfsmount *clone_private_mount(const struct path *path) · 788 unmodified lines | ||
| 1828 | 1826 | if (IS_MNT_UNBINDABLE(old_mnt)) |
| 1829 | 1827 | return ERR_PTR(-EINVAL); |
| 1830 | 1828 | |
| 1831 | − down_read(&namespace_sem); | |
| 1832 | 1829 | new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE); |
| 1833 | − up_read(&namespace_sem); | |
| 1834 | 1830 | if (IS_ERR(new_mnt)) |
| 1835 | 1831 | return ERR_CAST(new_mnt); |
| 1836 | 1832 | |
| @@ -4834,7 +4834,7 @@ int ocfs2_reflink_remap_range(struct file *file_in, · 4833 unmodified lines | ||
| 4834 | 4834 | |
| 4835 | 4835 | ret = vfs_clone_file_prep_inodes(inode_in, pos_in, inode_out, pos_out, |
| 4836 | 4836 | &len, is_dedupe); |
| 4837 | − if (ret || len == 0) | |
| 4837 | + if (ret <= 0) | |
| 4838 | 4838 | goto out_unlock; |
| 4839 | 4839 | |
| 4840 | 4840 | /* Lock out changes to the allocation maps and remap. */ |
| @@ -67,49 +67,47 @@ int get_dominating_id(struct mount *mnt, const struct path *root) · 66 unmodified lines | ||
| 67 | 67 | |
| 68 | 68 | static int do_make_slave(struct mount *mnt) |
| 69 | 69 | { |
| 70 | − struct mount *peer_mnt = mnt, *master = mnt->mnt_master; | |
| 71 | − struct mount *slave_mnt; | |
| 70 | + struct mount *master, *slave_mnt; | |
| 72 | 71 | |
| 73 | − /* | |
| 74 | − * slave 'mnt' to a peer mount that has the | |
| 75 | − * same root dentry. If none is available then | |
| 76 | − * slave it to anything that is available. | |
| 77 | − */ | |
| 78 | − while ((peer_mnt = next_peer(peer_mnt)) != mnt && | |
| 79 | − peer_mnt->mnt.mnt_root != mnt->mnt.mnt_root) ; | |
| 80 | − | |
| 81 | − if (peer_mnt == mnt) { | |
| 82 | − peer_mnt = next_peer(mnt); | |
| 83 | − if (peer_mnt == mnt) | |
| 84 | − peer_mnt = NULL; | |
| 85 | − } | |
| 86 | − if (mnt->mnt_group_id && IS_MNT_SHARED(mnt) && | |
| 87 | − list_empty(&mnt->mnt_share)) | |
| 88 | − mnt_release_group_id(mnt); | |
| 89 | − | |
| 90 | − list_del_init(&mnt->mnt_share); | |
| 91 | − mnt->mnt_group_id = 0; | |
| 92 | − | |
| 93 | − if (peer_mnt) | |
| 94 | − master = peer_mnt; | |
| 95 | − | |
| 96 | − if (master) { | |
| 97 | − list_for_each_entry(slave_mnt, &mnt->mnt_slave_list, mnt_slave) | |
| 98 | − slave_mnt->mnt_master = master; | |
| 99 | − list_move(&mnt->mnt_slave, &master->mnt_slave_list); | |
| 100 | − list_splice(&mnt->mnt_slave_list, master->mnt_slave_list.prev); | |
| 101 | − INIT_LIST_HEAD(&mnt->mnt_slave_list); | |
| 72 | + if (list_empty(&mnt->mnt_share)) { | |
| 73 | + if (IS_MNT_SHARED(mnt)) { | |
| 74 | + mnt_release_group_id(mnt); | |
| 75 | + CLEAR_MNT_SHARED(mnt); | |
| 76 | + } | |
| 77 | + master = mnt->mnt_master; | |
| 78 | + if (!master) { | |
| 79 | + struct list_head *p = &mnt->mnt_slave_list; | |
| 80 | + while (!list_empty(p)) { | |
| 81 | + slave_mnt = list_first_entry(p, | |
| 82 | + struct mount, mnt_slave); | |
| 83 | + list_del_init(&slave_mnt->mnt_slave); | |
| 84 | + slave_mnt->mnt_master = NULL; | |
| 85 | + } | |
| 86 | + return 0; | |
| 87 | + } | |
| 102 | 88 | } else { |
| 103 | − struct list_head *p = &mnt->mnt_slave_list; | |
| 104 | − while (!list_empty(p)) { | |
| 105 | − slave_mnt = list_first_entry(p, | |
| 106 | − struct mount, mnt_slave); | |
| 107 | − list_del_init(&slave_mnt->mnt_slave); | |
| 108 | − slave_mnt->mnt_master = NULL; | |
| 89 | + struct mount *m; | |
| 90 | + /* | |
| 91 | + * slave 'mnt' to a peer mount that has the | |
| 92 | + * same root dentry. If none is available then | |
| 93 | + * slave it to anything that is available. | |
| 94 | + */ | |
| 95 | + for (m = master = next_peer(mnt); m != mnt; m = next_peer(m)) { | |
| 96 | + if (m->mnt.mnt_root == mnt->mnt.mnt_root) { | |
| 97 | + master = m; | |
| 98 | + break; | |
| 99 | + } | |
| 109 | 100 | } |
| 101 | + list_del_init(&mnt->mnt_share); | |
| 102 | + mnt->mnt_group_id = 0; | |
| 103 | + CLEAR_MNT_SHARED(mnt); | |
| 110 | 104 | } |
| 105 | + list_for_each_entry(slave_mnt, &mnt->mnt_slave_list, mnt_slave) | |
| 106 | + slave_mnt->mnt_master = master; | |
| 107 | + list_move(&mnt->mnt_slave, &master->mnt_slave_list); | |
| 108 | + list_splice(&mnt->mnt_slave_list, master->mnt_slave_list.prev); | |
| 109 | + INIT_LIST_HEAD(&mnt->mnt_slave_list); | |
| 111 | 110 | mnt->mnt_master = master; |
| 112 | − CLEAR_MNT_SHARED(mnt); | |
| 113 | 111 | return 0; |
| 114 | 112 | } |
| 115 | 113 | |
| @@ -1669,6 +1669,9 @@ static int clone_verify_area(struct file *file, loff_t pos, u64 len, bool write) · 1668 unmodified lines | ||
| 1669 | 1669 | * Check that the two inodes are eligible for cloning, the ranges make |
| 1670 | 1670 | * sense, and then flush all dirty data. Caller must ensure that the |
| 1671 | 1671 | * inodes have been locked against any other modifications. |
| 1672 | + * | |
| 1673 | + * Returns: 0 for "nothing to clone", 1 for "something to clone", or | |
| 1674 | + * the usual negative error code. | |
| 1672 | 1675 | */ |
| 1673 | 1676 | int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, |
| 1674 | 1677 | struct inode *inode_out, loff_t pos_out, |
| @@ -1695,17 +1698,15 @@ int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, · 20 unmodified lines | ||
| 1695 | 1698 | |
| 1696 | 1699 | /* Are we going all the way to the end? */ |
| 1697 | 1700 | isize = i_size_read(inode_in); |
| 1698 | − if (isize == 0) { | |
| 1699 | − *len = 0; | |
| 1701 | + if (isize == 0) | |
| 1700 | 1702 | return 0; |
| 1701 | − } | |
| 1702 | 1703 | |
| 1703 | 1704 | /* Zero length dedupe exits immediately; reflink goes to EOF. */ |
| 1704 | 1705 | if (*len == 0) { |
| 1705 | − if (is_dedupe) { | |
| 1706 | − *len = 0; | |
| 1706 | + if (is_dedupe || pos_in == isize) | |
| 1707 | 1707 | return 0; |
| 1708 | − } | |
| 1708 | + if (pos_in > isize) | |
| 1709 | + return -EINVAL; | |
| 1709 | 1710 | *len = isize - pos_in; |
| 1710 | 1711 | } |
| 1711 | 1712 | |
| @@ -1769,7 +1770,7 @@ int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, · 57 unmodified lines | ||
| 1769 | 1770 | return -EBADE; |
| 1770 | 1771 | } |
| 1771 | 1772 | |
| 1772 | − return 0; | |
| 1773 | + return 1; | |
| 1773 | 1774 | } |
| 1774 | 1775 | EXPORT_SYMBOL(vfs_clone_file_prep_inodes); |
| 1775 | 1776 | |
| @@ -1955,6 +1956,9 @@ int vfs_dedupe_file_range(struct file *file, struct file_dedupe_range *same) · 179 unmodified lines | ||
| 1955 | 1956 | goto out; |
| 1956 | 1957 | ret = 0; |
| 1957 | 1958 | |
| 1959 | + if (off + len > i_size_read(src)) | |
| 1960 | + return -EINVAL; | |
| 1961 | + | |
| 1958 | 1962 | /* pre-format output fields to sane values */ |
| 1959 | 1963 | for (i = 0; i < count; i++) { |
| 1960 | 1964 | same->info[i].bytes_deduped = 0ULL; |
| @@ -190,6 +190,13 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) · 189 unmodified lines | ||
| 190 | 190 | */ |
| 191 | 191 | m->version = file->f_version; |
| 192 | 192 | |
| 193 | + /* | |
| 194 | + * if request is to read from zero offset, reset iterator to first | |
| 195 | + * record as it might have been already advanced by previous requests | |
| 196 | + */ | |
| 197 | + if (*ppos == 0) | |
| 198 | + m->index = 0; | |
| 199 | + | |
| 193 | 200 | /* Don't assume *ppos is where we left it */ |
| 194 | 201 | if (unlikely(*ppos != m->read_pos)) { |
| 195 | 202 | while ((err = traverse(m, *ppos)) == -EAGAIN) |
| @@ -1191,7 +1191,7 @@ out: · 1190 unmodified lines | ||
| 1191 | 1191 | return err; |
| 1192 | 1192 | } |
| 1193 | 1193 | |
| 1194 | −void ufs_truncate_blocks(struct inode *inode) | |
| 1194 | +static void ufs_truncate_blocks(struct inode *inode) | |
| 1195 | 1195 | { |
| 1196 | 1196 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || |
| 1197 | 1197 | S_ISLNK(inode->i_mode))) |
| @@ -1161,7 +1161,7 @@ xfs_reflink_remap_range( · 1160 unmodified lines | ||
| 1161 | 1161 | |
| 1162 | 1162 | ret = vfs_clone_file_prep_inodes(inode_in, pos_in, inode_out, pos_out, |
| 1163 | 1163 | &len, is_dedupe); |
| 1164 | − if (ret || len == 0) | |
| 1164 | + if (ret <= 0) | |
| 1165 | 1165 | goto out_unlock; |
| 1166 | 1166 | |
| 1167 | 1167 | trace_xfs_reflink_remap_range(src, pos_in, len, dest, pos_out); |
| @@ -14,14 +14,9 @@ typedef int (kiocb_cancel_fn)(struct kiocb *); · 13 unmodified lines | ||
| 14 | 14 | /* prototypes */ |
| 15 | 15 | #ifdef CONFIG_AIO |
| 16 | 16 | extern void exit_aio(struct mm_struct *mm); |
| 17 | −extern long do_io_submit(aio_context_t ctx_id, long nr, | |
| 18 | − struct iocb __user *__user *iocbpp, bool compat); | |
| 19 | 17 | void kiocb_set_cancel_fn(struct kiocb *req, kiocb_cancel_fn *cancel); |
| 20 | 18 | #else |
| 21 | 19 | static inline void exit_aio(struct mm_struct *mm) { } |
| 22 | −static inline long do_io_submit(aio_context_t ctx_id, long nr, | |
| 23 | − struct iocb __user * __user *iocbpp, | |
| 24 | − bool compat) { return 0; } | |
| 25 | 20 | static inline void kiocb_set_cancel_fn(struct kiocb *req, |
| 26 | 21 | kiocb_cancel_fn *cancel) { } |
| 27 | 22 | #endif /* CONFIG_AIO */ |
| @@ -150,6 +150,9 @@ cond_syscall(sys_io_destroy); · 149 unmodified lines | ||
| 150 | 150 | cond_syscall(sys_io_submit); |
| 151 | 151 | cond_syscall(sys_io_cancel); |
| 152 | 152 | cond_syscall(sys_io_getevents); |
| 153 | +cond_syscall(compat_sys_io_setup); | |
| 154 | +cond_syscall(compat_sys_io_submit); | |
| 155 | +cond_syscall(compat_sys_io_getevents); | |
| 153 | 156 | cond_syscall(sys_sysfs); |
| 154 | 157 | cond_syscall(sys_syslog); |
| 155 | 158 | cond_syscall(sys_process_vm_readv); |
| @@ -73,19 +73,21 @@ · 72 unmodified lines | ||
| 73 | 73 | } |
| 74 | 74 | |
| 75 | 75 | #define iterate_all_kinds(i, n, v, I, B, K) { \ |
| 76 | − size_t skip = i->iov_offset; \ | |
| 77 | − if (unlikely(i->type & ITER_BVEC)) { \ | |
| 78 | − struct bio_vec v; \ | |
| 79 | − struct bvec_iter __bi; \ | |
| 80 | − iterate_bvec(i, n, v, __bi, skip, (B)) \ | |
| 81 | − } else if (unlikely(i->type & ITER_KVEC)) { \ | |
| 82 | − const struct kvec *kvec; \ | |
| 83 | − struct kvec v; \ | |
| 84 | − iterate_kvec(i, n, v, kvec, skip, (K)) \ | |
| 85 | − } else { \ | |
| 86 | − const struct iovec *iov; \ | |
| 87 | − struct iovec v; \ | |
| 88 | − iterate_iovec(i, n, v, iov, skip, (I)) \ | |
| 76 | + if (likely(n)) { \ | |
| 77 | + size_t skip = i->iov_offset; \ | |
| 78 | + if (unlikely(i->type & ITER_BVEC)) { \ | |
| 79 | + struct bio_vec v; \ | |
| 80 | + struct bvec_iter __bi; \ | |
| 81 | + iterate_bvec(i, n, v, __bi, skip, (B)) \ | |
| 82 | + } else if (unlikely(i->type & ITER_KVEC)) { \ | |
| 83 | + const struct kvec *kvec; \ | |
| 84 | + struct kvec v; \ | |
| 85 | + iterate_kvec(i, n, v, kvec, skip, (K)) \ | |
| 86 | + } else { \ | |
| 87 | + const struct iovec *iov; \ | |
| 88 | + struct iovec v; \ | |
| 89 | + iterate_iovec(i, n, v, iov, skip, (I)) \ | |
| 90 | + } \ | |
| 89 | 91 | } \ |
| 90 | 92 | } |
| 91 | 93 | |
| @@ -576,7 +578,7 @@ bool copy_from_iter_full(void *addr, size_t bytes, struct iov_iter *i) · 484 unmodified lines | ||
| 576 | 578 | WARN_ON(1); |
| 577 | 579 | return false; |
| 578 | 580 | } |
| 579 | − if (unlikely(i->count < bytes)) \ | |
| 581 | + if (unlikely(i->count < bytes)) | |
| 580 | 582 | return false; |
| 581 | 583 | |
| 582 | 584 | iterate_all_kinds(i, bytes, v, ({ |
| @@ -620,7 +622,7 @@ bool copy_from_iter_full_nocache(void *addr, size_t bytes, struct iov_iter *i) · 37 unmodified lines | ||
| 620 | 622 | WARN_ON(1); |
| 621 | 623 | return false; |
| 622 | 624 | } |
| 623 | − if (unlikely(i->count < bytes)) \ | |
| 625 | + if (unlikely(i->count < bytes)) | |
| 624 | 626 | return false; |
| 625 | 627 | iterate_all_kinds(i, bytes, v, ({ |
| 626 | 628 | if (__copy_from_user_nocache((to += v.iov_len) - v.iov_len, |
| @@ -837,11 +839,8 @@ unsigned long iov_iter_alignment(const struct iov_iter *i) · 210 unmodified lines | ||
| 837 | 839 | unsigned long res = 0; |
| 838 | 840 | size_t size = i->count; |
| 839 | 841 | |
| 840 | − if (!size) | |
| 841 | − return 0; | |
| 842 | − | |
| 843 | 842 | if (unlikely(i->type & ITER_PIPE)) { |
| 844 | − if (i->iov_offset && allocated(&i->pipe->bufs[i->idx])) | |
| 843 | + if (size && i->iov_offset && allocated(&i->pipe->bufs[i->idx])) | |
| 845 | 844 | return size | i->iov_offset; |
| 846 | 845 | return size; |
| 847 | 846 | } |
| @@ -856,10 +855,8 @@ EXPORT_SYMBOL(iov_iter_alignment); · 8 unmodified lines | ||
| 856 | 855 | |
| 857 | 856 | unsigned long iov_iter_gap_alignment(const struct iov_iter *i) |
| 858 | 857 | { |
| 859 | − unsigned long res = 0; | |
| 858 | + unsigned long res = 0; | |
| 860 | 859 | size_t size = i->count; |
| 861 | − if (!size) | |
| 862 | − return 0; | |
| 863 | 860 | |
| 864 | 861 | if (unlikely(i->type & ITER_PIPE)) { |
| 865 | 862 | WARN_ON(1); |
| @@ -874,7 +871,7 @@ unsigned long iov_iter_gap_alignment(const struct iov_iter *i) · 8 unmodified lines | ||
| 874 | 871 | (res |= (!res ? 0 : (unsigned long)v.iov_base) | |
| 875 | 872 | (size != v.iov_len ? size : 0)) |
| 876 | 873 | ); |
| 877 | − return res; | |
| 874 | + return res; | |
| 878 | 875 | } |
| 879 | 876 | EXPORT_SYMBOL(iov_iter_gap_alignment); |
| 880 | 877 | |
| @@ -908,6 +905,9 @@ static ssize_t pipe_get_pages(struct iov_iter *i, · 27 unmodified lines | ||
| 908 | 905 | size_t capacity; |
| 909 | 906 | int idx; |
| 910 | 907 | |
| 908 | + if (!maxsize) | |
| 909 | + return 0; | |
| 910 | + | |
| 911 | 911 | if (!sanity(i)) |
| 912 | 912 | return -EFAULT; |
| 913 | 913 | |
| @@ -926,9 +926,6 @@ ssize_t iov_iter_get_pages(struct iov_iter *i, · 12 unmodified lines | ||
| 926 | 926 | if (maxsize > i->count) |
| 927 | 927 | maxsize = i->count; |
| 928 | 928 | |
| 929 | − if (!maxsize) | |
| 930 | − return 0; | |
| 931 | − | |
| 932 | 929 | if (unlikely(i->type & ITER_PIPE)) |
| 933 | 930 | return pipe_get_pages(i, pages, maxsize, maxpages, start); |
| 934 | 931 | iterate_all_kinds(i, maxsize, v, ({ |
| @@ -975,6 +972,9 @@ static ssize_t pipe_get_pages_alloc(struct iov_iter *i, · 40 unmodified lines | ||
| 975 | 972 | int idx; |
| 976 | 973 | int npages; |
| 977 | 974 | |
| 975 | + if (!maxsize) | |
| 976 | + return 0; | |
| 977 | + | |
| 978 | 978 | if (!sanity(i)) |
| 979 | 979 | return -EFAULT; |
| 980 | 980 | |
| @@ -1006,9 +1006,6 @@ ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, · 25 unmodified lines | ||
| 1006 | 1006 | if (maxsize > i->count) |
| 1007 | 1007 | maxsize = i->count; |
| 1008 | 1008 | |
| 1009 | − if (!maxsize) | |
| 1010 | − return 0; | |
| 1011 | − | |
| 1012 | 1009 | if (unlikely(i->type & ITER_PIPE)) |
| 1013 | 1010 | return pipe_get_pages_alloc(i, pages, maxsize, start); |
| 1014 | 1011 | iterate_all_kinds(i, maxsize, v, ({ |