diff options
| -rw-r--r-- | block/bsg.c | 3 | ||||
| -rw-r--r-- | drivers/scsi/sg.c | 3 | ||||
| -rw-r--r-- | fs/aio.c | 97 | ||||
| -rw-r--r-- | fs/compat.c | 75 | ||||
| -rw-r--r-- | fs/exec.c | 10 | ||||
| -rw-r--r-- | fs/namespace.c | 8 | ||||
| -rw-r--r-- | fs/ocfs2/refcounttree.c | 2 | ||||
| -rw-r--r-- | fs/pnode.c | 74 | ||||
| -rw-r--r-- | fs/read_write.c | 18 | ||||
| -rw-r--r-- | fs/seq_file.c | 7 | ||||
| -rw-r--r-- | fs/ufs/inode.c | 2 | ||||
| -rw-r--r-- | fs/xfs/xfs_reflink.c | 2 | ||||
| -rw-r--r-- | include/linux/aio.h | 5 | ||||
| -rw-r--r-- | kernel/sys_ni.c | 3 | ||||
| -rw-r--r-- | lib/iov_iter.c | 55 |
15 files changed, 197 insertions, 167 deletions
diff --git a/block/bsg.c b/block/bsg.c index 8a05a404ae70..a57046de2f07 100644 --- a/block/bsg.c +++ b/block/bsg.c | |||
| @@ -655,6 +655,9 @@ bsg_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
| 655 | 655 | ||
| 656 | dprintk("%s: write %Zd bytes\n", bd->name, count); | 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 | bsg_set_block(bd, file); | 661 | bsg_set_block(bd, file); |
| 659 | 662 | ||
| 660 | bytes_written = 0; | 663 | bytes_written = 0; |
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 070332eb41f3..dbe5b4b95df0 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
| @@ -581,6 +581,9 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos) | |||
| 581 | sg_io_hdr_t *hp; | 581 | sg_io_hdr_t *hp; |
| 582 | unsigned char cmnd[SG_MAX_CDB_SIZE]; | 582 | unsigned char cmnd[SG_MAX_CDB_SIZE]; |
| 583 | 583 | ||
| 584 | if (unlikely(segment_eq(get_fs(), KERNEL_DS))) | ||
| 585 | return -EINVAL; | ||
| 586 | |||
| 584 | if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) | 587 | if ((!(sfp = (Sg_fd *) filp->private_data)) || (!(sdp = sfp->parentdp))) |
| 585 | return -ENXIO; | 588 | return -ENXIO; |
| 586 | SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp, | 589 | SCSI_LOG_TIMEOUT(3, sg_printk(KERN_INFO, sdp, |
| @@ -1367,6 +1367,39 @@ out: | |||
| 1367 | return ret; | 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 | /* sys_io_destroy: | 1403 | /* sys_io_destroy: |
| 1371 | * Destroy the aio_context specified. May cancel any outstanding | 1404 | * Destroy the aio_context specified. May cancel any outstanding |
| 1372 | * AIOs and block on completion. Will fail with -ENOSYS if not | 1405 | * AIOs and block on completion. Will fail with -ENOSYS if not |
| @@ -1591,8 +1624,8 @@ out_put_req: | |||
| 1591 | return ret; | 1624 | return ret; |
| 1592 | } | 1625 | } |
| 1593 | 1626 | ||
| 1594 | long do_io_submit(aio_context_t ctx_id, long nr, | 1627 | static long do_io_submit(aio_context_t ctx_id, long nr, |
| 1595 | struct iocb __user *__user *iocbpp, bool compat) | 1628 | struct iocb __user *__user *iocbpp, bool compat) |
| 1596 | { | 1629 | { |
| 1597 | struct kioctx *ctx; | 1630 | struct kioctx *ctx; |
| 1598 | long ret = 0; | 1631 | long ret = 0; |
| @@ -1662,6 +1695,44 @@ SYSCALL_DEFINE3(io_submit, aio_context_t, ctx_id, long, nr, | |||
| 1662 | return do_io_submit(ctx_id, nr, iocbpp, 0); | 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 | /* lookup_kiocb | 1736 | /* lookup_kiocb |
| 1666 | * Finds a given iocb for cancellation. | 1737 | * Finds a given iocb for cancellation. |
| 1667 | */ | 1738 | */ |
| @@ -1761,3 +1832,25 @@ SYSCALL_DEFINE5(io_getevents, aio_context_t, ctx_id, | |||
| 1761 | } | 1832 | } |
| 1762 | return ret; | 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 | ||
diff --git a/fs/compat.c b/fs/compat.c index 543b48c29ac3..3f4908c28698 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
| @@ -487,45 +487,6 @@ COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, | |||
| 487 | return compat_sys_fcntl64(fd, cmd, arg); | 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 | /* A write operation does a read from user space and vice versa */ | 490 | /* A write operation does a read from user space and vice versa */ |
| 530 | #define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ) | 491 | #define vrfy_dir(type) ((type) == READ ? VERIFY_WRITE : VERIFY_READ) |
| 531 | 492 | ||
| @@ -602,42 +563,6 @@ out: | |||
| 602 | return ret; | 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 | struct compat_ncp_mount_data { | 566 | struct compat_ncp_mount_data { |
| 642 | compat_int_t version; | 567 | compat_int_t version; |
| 643 | compat_uint_t ncp_fd; | 568 | compat_uint_t ncp_fd; |
| @@ -19,7 +19,7 @@ | |||
| 19 | * current->executable is only used by the procfs. This allows a dispatch | 19 | * current->executable is only used by the procfs. This allows a dispatch |
| 20 | * table to check for several different types of binary formats. We keep | 20 | * table to check for several different types of binary formats. We keep |
| 21 | * trying until we recognize the file or we run out of supported binary | 21 | * trying until we recognize the file or we run out of supported binary |
| 22 | * formats. | 22 | * formats. |
| 23 | */ | 23 | */ |
| 24 | 24 | ||
| 25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
| @@ -1268,6 +1268,13 @@ int flush_old_exec(struct linux_binprm * bprm) | |||
| 1268 | flush_thread(); | 1268 | flush_thread(); |
| 1269 | current->personality &= ~bprm->per_clear; | 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 | return 0; | 1278 | return 0; |
| 1272 | 1279 | ||
| 1273 | out: | 1280 | out: |
| @@ -1330,7 +1337,6 @@ void setup_new_exec(struct linux_binprm * bprm) | |||
| 1330 | group */ | 1337 | group */ |
| 1331 | current->self_exec_id++; | 1338 | current->self_exec_id++; |
| 1332 | flush_signal_handlers(current, 0); | 1339 | flush_signal_handlers(current, 0); |
| 1333 | do_close_on_exec(current->files); | ||
| 1334 | } | 1340 | } |
| 1335 | EXPORT_SYMBOL(setup_new_exec); | 1341 | EXPORT_SYMBOL(setup_new_exec); |
| 1336 | 1342 | ||
diff --git a/fs/namespace.c b/fs/namespace.c index f7e28f8ea04d..b5b1259e064f 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
| @@ -96,10 +96,6 @@ static inline struct hlist_head *mp_hash(struct dentry *dentry) | |||
| 96 | return &mountpoint_hashtable[tmp & mp_hash_mask]; | 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 | static int mnt_alloc_id(struct mount *mnt) | 99 | static int mnt_alloc_id(struct mount *mnt) |
| 104 | { | 100 | { |
| 105 | int res; | 101 | int res; |
| @@ -1034,6 +1030,8 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, | |||
| 1034 | if (IS_MNT_SLAVE(old)) | 1030 | if (IS_MNT_SLAVE(old)) |
| 1035 | list_add(&mnt->mnt_slave, &old->mnt_slave); | 1031 | list_add(&mnt->mnt_slave, &old->mnt_slave); |
| 1036 | mnt->mnt_master = old->mnt_master; | 1032 | mnt->mnt_master = old->mnt_master; |
| 1033 | } else { | ||
| 1034 | CLEAR_MNT_SHARED(mnt); | ||
| 1037 | } | 1035 | } |
| 1038 | if (flag & CL_MAKE_SHARED) | 1036 | if (flag & CL_MAKE_SHARED) |
| 1039 | set_mnt_shared(mnt); | 1037 | set_mnt_shared(mnt); |
| @@ -1828,9 +1826,7 @@ struct vfsmount *clone_private_mount(const struct path *path) | |||
| 1828 | if (IS_MNT_UNBINDABLE(old_mnt)) | 1826 | if (IS_MNT_UNBINDABLE(old_mnt)) |
| 1829 | return ERR_PTR(-EINVAL); | 1827 | return ERR_PTR(-EINVAL); |
| 1830 | 1828 | ||
| 1831 | down_read(&namespace_sem); | ||
| 1832 | new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE); | 1829 | new_mnt = clone_mnt(old_mnt, path->dentry, CL_PRIVATE); |
| 1833 | up_read(&namespace_sem); | ||
| 1834 | if (IS_ERR(new_mnt)) | 1830 | if (IS_ERR(new_mnt)) |
| 1835 | return ERR_CAST(new_mnt); | 1831 | return ERR_CAST(new_mnt); |
| 1836 | 1832 | ||
diff --git a/fs/ocfs2/refcounttree.c b/fs/ocfs2/refcounttree.c index d171d2c53f7f..f8933cb53d68 100644 --- a/fs/ocfs2/refcounttree.c +++ b/fs/ocfs2/refcounttree.c | |||
| @@ -4834,7 +4834,7 @@ int ocfs2_reflink_remap_range(struct file *file_in, | |||
| 4834 | 4834 | ||
| 4835 | ret = vfs_clone_file_prep_inodes(inode_in, pos_in, inode_out, pos_out, | 4835 | ret = vfs_clone_file_prep_inodes(inode_in, pos_in, inode_out, pos_out, |
| 4836 | &len, is_dedupe); | 4836 | &len, is_dedupe); |
| 4837 | if (ret || len == 0) | 4837 | if (ret <= 0) |
| 4838 | goto out_unlock; | 4838 | goto out_unlock; |
| 4839 | 4839 | ||
| 4840 | /* Lock out changes to the allocation maps and remap. */ | 4840 | /* Lock out changes to the allocation maps and remap. */ |
diff --git a/fs/pnode.c b/fs/pnode.c index 234a9ac49958..06a793f4ae38 100644 --- a/fs/pnode.c +++ b/fs/pnode.c | |||
| @@ -67,49 +67,47 @@ int get_dominating_id(struct mount *mnt, const struct path *root) | |||
| 67 | 67 | ||
| 68 | static int do_make_slave(struct mount *mnt) | 68 | static int do_make_slave(struct mount *mnt) |
| 69 | { | 69 | { |
| 70 | struct mount *peer_mnt = mnt, *master = mnt->mnt_master; | 70 | struct mount *master, *slave_mnt; |
| 71 | struct mount *slave_mnt; | ||
| 72 | 71 | ||
| 73 | /* | 72 | if (list_empty(&mnt->mnt_share)) { |
| 74 | * slave 'mnt' to a peer mount that has the | 73 | if (IS_MNT_SHARED(mnt)) { |
| 75 | * same root dentry. If none is available then | 74 | mnt_release_group_id(mnt); |
| 76 | * slave it to anything that is available. | 75 | CLEAR_MNT_SHARED(mnt); |
| 77 | */ | 76 | } |
| 78 | while ((peer_mnt = next_peer(peer_mnt)) != mnt && | 77 | master = mnt->mnt_master; |
| 79 | peer_mnt->mnt.mnt_root != mnt->mnt.mnt_root) ; | 78 | if (!master) { |
| 80 | 79 | struct list_head *p = &mnt->mnt_slave_list; | |
| 81 | if (peer_mnt == mnt) { | 80 | while (!list_empty(p)) { |
| 82 | peer_mnt = next_peer(mnt); | 81 | slave_mnt = list_first_entry(p, |
| 83 | if (peer_mnt == mnt) | 82 | struct mount, mnt_slave); |
| 84 | peer_mnt = NULL; | 83 | list_del_init(&slave_mnt->mnt_slave); |
| 85 | } | 84 | slave_mnt->mnt_master = NULL; |
| 86 | if (mnt->mnt_group_id && IS_MNT_SHARED(mnt) && | 85 | } |
| 87 | list_empty(&mnt->mnt_share)) | 86 | return 0; |
| 88 | mnt_release_group_id(mnt); | 87 | } |
| 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); | ||
| 102 | } else { | 88 | } else { |
| 103 | struct list_head *p = &mnt->mnt_slave_list; | 89 | struct mount *m; |
| 104 | while (!list_empty(p)) { | 90 | /* |
| 105 | slave_mnt = list_first_entry(p, | 91 | * slave 'mnt' to a peer mount that has the |
| 106 | struct mount, mnt_slave); | 92 | * same root dentry. If none is available then |
| 107 | list_del_init(&slave_mnt->mnt_slave); | 93 | * slave it to anything that is available. |
| 108 | slave_mnt->mnt_master = NULL; | 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 | mnt->mnt_master = master; | 110 | mnt->mnt_master = master; |
| 112 | CLEAR_MNT_SHARED(mnt); | ||
| 113 | return 0; | 111 | return 0; |
| 114 | } | 112 | } |
| 115 | 113 | ||
diff --git a/fs/read_write.c b/fs/read_write.c index da6de12b5c46..7537b6b6b5a2 100644 --- a/fs/read_write.c +++ b/fs/read_write.c | |||
| @@ -1669,6 +1669,9 @@ static int clone_verify_area(struct file *file, loff_t pos, u64 len, bool write) | |||
| 1669 | * Check that the two inodes are eligible for cloning, the ranges make | 1669 | * Check that the two inodes are eligible for cloning, the ranges make |
| 1670 | * sense, and then flush all dirty data. Caller must ensure that the | 1670 | * sense, and then flush all dirty data. Caller must ensure that the |
| 1671 | * inodes have been locked against any other modifications. | 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 | int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, | 1676 | int vfs_clone_file_prep_inodes(struct inode *inode_in, loff_t pos_in, |
| 1674 | struct inode *inode_out, loff_t pos_out, | 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, | |||
| 1695 | 1698 | ||
| 1696 | /* Are we going all the way to the end? */ | 1699 | /* Are we going all the way to the end? */ |
| 1697 | isize = i_size_read(inode_in); | 1700 | isize = i_size_read(inode_in); |
| 1698 | if (isize == 0) { | 1701 | if (isize == 0) |
| 1699 | *len = 0; | ||
| 1700 | return 0; | 1702 | return 0; |
| 1701 | } | ||
| 1702 | 1703 | ||
| 1703 | /* Zero length dedupe exits immediately; reflink goes to EOF. */ | 1704 | /* Zero length dedupe exits immediately; reflink goes to EOF. */ |
| 1704 | if (*len == 0) { | 1705 | if (*len == 0) { |
| 1705 | if (is_dedupe) { | 1706 | if (is_dedupe || pos_in == isize) |
| 1706 | *len = 0; | ||
| 1707 | return 0; | 1707 | return 0; |
| 1708 | } | 1708 | if (pos_in > isize) |
| 1709 | return -EINVAL; | ||
| 1709 | *len = isize - pos_in; | 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, | |||
| 1769 | return -EBADE; | 1770 | return -EBADE; |
| 1770 | } | 1771 | } |
| 1771 | 1772 | ||
| 1772 | return 0; | 1773 | return 1; |
| 1773 | } | 1774 | } |
| 1774 | EXPORT_SYMBOL(vfs_clone_file_prep_inodes); | 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) | |||
| 1955 | goto out; | 1956 | goto out; |
| 1956 | ret = 0; | 1957 | ret = 0; |
| 1957 | 1958 | ||
| 1959 | if (off + len > i_size_read(src)) | ||
| 1960 | return -EINVAL; | ||
| 1961 | |||
| 1958 | /* pre-format output fields to sane values */ | 1962 | /* pre-format output fields to sane values */ |
| 1959 | for (i = 0; i < count; i++) { | 1963 | for (i = 0; i < count; i++) { |
| 1960 | same->info[i].bytes_deduped = 0ULL; | 1964 | same->info[i].bytes_deduped = 0ULL; |
diff --git a/fs/seq_file.c b/fs/seq_file.c index 368bfb92b115..a11f271800ef 100644 --- a/fs/seq_file.c +++ b/fs/seq_file.c | |||
| @@ -190,6 +190,13 @@ ssize_t seq_read(struct file *file, char __user *buf, size_t size, loff_t *ppos) | |||
| 190 | */ | 190 | */ |
| 191 | m->version = file->f_version; | 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 | /* Don't assume *ppos is where we left it */ | 200 | /* Don't assume *ppos is where we left it */ |
| 194 | if (unlikely(*ppos != m->read_pos)) { | 201 | if (unlikely(*ppos != m->read_pos)) { |
| 195 | while ((err = traverse(m, *ppos)) == -EAGAIN) | 202 | while ((err = traverse(m, *ppos)) == -EAGAIN) |
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c index 45ceb94e89e4..1bc0bd6a9848 100644 --- a/fs/ufs/inode.c +++ b/fs/ufs/inode.c | |||
| @@ -1191,7 +1191,7 @@ out: | |||
| 1191 | return err; | 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 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || | 1196 | if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || |
| 1197 | S_ISLNK(inode->i_mode))) | 1197 | S_ISLNK(inode->i_mode))) |
diff --git a/fs/xfs/xfs_reflink.c b/fs/xfs/xfs_reflink.c index aca2d4bd4303..07593a362cd0 100644 --- a/fs/xfs/xfs_reflink.c +++ b/fs/xfs/xfs_reflink.c | |||
| @@ -1161,7 +1161,7 @@ xfs_reflink_remap_range( | |||
| 1161 | 1161 | ||
| 1162 | ret = vfs_clone_file_prep_inodes(inode_in, pos_in, inode_out, pos_out, | 1162 | ret = vfs_clone_file_prep_inodes(inode_in, pos_in, inode_out, pos_out, |
| 1163 | &len, is_dedupe); | 1163 | &len, is_dedupe); |
| 1164 | if (ret || len == 0) | 1164 | if (ret <= 0) |
| 1165 | goto out_unlock; | 1165 | goto out_unlock; |
| 1166 | 1166 | ||
| 1167 | trace_xfs_reflink_remap_range(src, pos_in, len, dest, pos_out); | 1167 | trace_xfs_reflink_remap_range(src, pos_in, len, dest, pos_out); |
diff --git a/include/linux/aio.h b/include/linux/aio.h index 9eb42dbc5582..fdd0a343f455 100644 --- a/include/linux/aio.h +++ b/include/linux/aio.h | |||
| @@ -14,14 +14,9 @@ typedef int (kiocb_cancel_fn)(struct kiocb *); | |||
| 14 | /* prototypes */ | 14 | /* prototypes */ |
| 15 | #ifdef CONFIG_AIO | 15 | #ifdef CONFIG_AIO |
| 16 | extern void exit_aio(struct mm_struct *mm); | 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 | void kiocb_set_cancel_fn(struct kiocb *req, kiocb_cancel_fn *cancel); | 17 | void kiocb_set_cancel_fn(struct kiocb *req, kiocb_cancel_fn *cancel); |
| 20 | #else | 18 | #else |
| 21 | static inline void exit_aio(struct mm_struct *mm) { } | 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 | static inline void kiocb_set_cancel_fn(struct kiocb *req, | 20 | static inline void kiocb_set_cancel_fn(struct kiocb *req, |
| 26 | kiocb_cancel_fn *cancel) { } | 21 | kiocb_cancel_fn *cancel) { } |
| 27 | #endif /* CONFIG_AIO */ | 22 | #endif /* CONFIG_AIO */ |
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c index 635482e60ca3..8acef8576ce9 100644 --- a/kernel/sys_ni.c +++ b/kernel/sys_ni.c | |||
| @@ -150,6 +150,9 @@ cond_syscall(sys_io_destroy); | |||
| 150 | cond_syscall(sys_io_submit); | 150 | cond_syscall(sys_io_submit); |
| 151 | cond_syscall(sys_io_cancel); | 151 | cond_syscall(sys_io_cancel); |
| 152 | cond_syscall(sys_io_getevents); | 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 | cond_syscall(sys_sysfs); | 156 | cond_syscall(sys_sysfs); |
| 154 | cond_syscall(sys_syslog); | 157 | cond_syscall(sys_syslog); |
| 155 | cond_syscall(sys_process_vm_readv); | 158 | cond_syscall(sys_process_vm_readv); |
diff --git a/lib/iov_iter.c b/lib/iov_iter.c index 228892dabba6..25f572303801 100644 --- a/lib/iov_iter.c +++ b/lib/iov_iter.c | |||
| @@ -73,19 +73,21 @@ | |||
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | #define iterate_all_kinds(i, n, v, I, B, K) { \ | 75 | #define iterate_all_kinds(i, n, v, I, B, K) { \ |
| 76 | size_t skip = i->iov_offset; \ | 76 | if (likely(n)) { \ |
| 77 | if (unlikely(i->type & ITER_BVEC)) { \ | 77 | size_t skip = i->iov_offset; \ |
| 78 | struct bio_vec v; \ | 78 | if (unlikely(i->type & ITER_BVEC)) { \ |
| 79 | struct bvec_iter __bi; \ | 79 | struct bio_vec v; \ |
| 80 | iterate_bvec(i, n, v, __bi, skip, (B)) \ | 80 | struct bvec_iter __bi; \ |
| 81 | } else if (unlikely(i->type & ITER_KVEC)) { \ | 81 | iterate_bvec(i, n, v, __bi, skip, (B)) \ |
| 82 | const struct kvec *kvec; \ | 82 | } else if (unlikely(i->type & ITER_KVEC)) { \ |
| 83 | struct kvec v; \ | 83 | const struct kvec *kvec; \ |
| 84 | iterate_kvec(i, n, v, kvec, skip, (K)) \ | 84 | struct kvec v; \ |
| 85 | } else { \ | 85 | iterate_kvec(i, n, v, kvec, skip, (K)) \ |
| 86 | const struct iovec *iov; \ | 86 | } else { \ |
| 87 | struct iovec v; \ | 87 | const struct iovec *iov; \ |
| 88 | iterate_iovec(i, n, v, iov, skip, (I)) \ | 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) | |||
| 576 | WARN_ON(1); | 578 | WARN_ON(1); |
| 577 | return false; | 579 | return false; |
| 578 | } | 580 | } |
| 579 | if (unlikely(i->count < bytes)) \ | 581 | if (unlikely(i->count < bytes)) |
| 580 | return false; | 582 | return false; |
| 581 | 583 | ||
| 582 | iterate_all_kinds(i, bytes, v, ({ | 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) | |||
| 620 | WARN_ON(1); | 622 | WARN_ON(1); |
| 621 | return false; | 623 | return false; |
| 622 | } | 624 | } |
| 623 | if (unlikely(i->count < bytes)) \ | 625 | if (unlikely(i->count < bytes)) |
| 624 | return false; | 626 | return false; |
| 625 | iterate_all_kinds(i, bytes, v, ({ | 627 | iterate_all_kinds(i, bytes, v, ({ |
| 626 | if (__copy_from_user_nocache((to += v.iov_len) - v.iov_len, | 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) | |||
| 837 | unsigned long res = 0; | 839 | unsigned long res = 0; |
| 838 | size_t size = i->count; | 840 | size_t size = i->count; |
| 839 | 841 | ||
| 840 | if (!size) | ||
| 841 | return 0; | ||
| 842 | |||
| 843 | if (unlikely(i->type & ITER_PIPE)) { | 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 | return size | i->iov_offset; | 844 | return size | i->iov_offset; |
| 846 | return size; | 845 | return size; |
| 847 | } | 846 | } |
| @@ -856,10 +855,8 @@ EXPORT_SYMBOL(iov_iter_alignment); | |||
| 856 | 855 | ||
| 857 | unsigned long iov_iter_gap_alignment(const struct iov_iter *i) | 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 | size_t size = i->count; | 859 | size_t size = i->count; |
| 861 | if (!size) | ||
| 862 | return 0; | ||
| 863 | 860 | ||
| 864 | if (unlikely(i->type & ITER_PIPE)) { | 861 | if (unlikely(i->type & ITER_PIPE)) { |
| 865 | WARN_ON(1); | 862 | WARN_ON(1); |
| @@ -874,7 +871,7 @@ unsigned long iov_iter_gap_alignment(const struct iov_iter *i) | |||
| 874 | (res |= (!res ? 0 : (unsigned long)v.iov_base) | | 871 | (res |= (!res ? 0 : (unsigned long)v.iov_base) | |
| 875 | (size != v.iov_len ? size : 0)) | 872 | (size != v.iov_len ? size : 0)) |
| 876 | ); | 873 | ); |
| 877 | return res; | 874 | return res; |
| 878 | } | 875 | } |
| 879 | EXPORT_SYMBOL(iov_iter_gap_alignment); | 876 | EXPORT_SYMBOL(iov_iter_gap_alignment); |
| 880 | 877 | ||
| @@ -908,6 +905,9 @@ static ssize_t pipe_get_pages(struct iov_iter *i, | |||
| 908 | size_t capacity; | 905 | size_t capacity; |
| 909 | int idx; | 906 | int idx; |
| 910 | 907 | ||
| 908 | if (!maxsize) | ||
| 909 | return 0; | ||
| 910 | |||
| 911 | if (!sanity(i)) | 911 | if (!sanity(i)) |
| 912 | return -EFAULT; | 912 | return -EFAULT; |
| 913 | 913 | ||
| @@ -926,9 +926,6 @@ ssize_t iov_iter_get_pages(struct iov_iter *i, | |||
| 926 | if (maxsize > i->count) | 926 | if (maxsize > i->count) |
| 927 | maxsize = i->count; | 927 | maxsize = i->count; |
| 928 | 928 | ||
| 929 | if (!maxsize) | ||
| 930 | return 0; | ||
| 931 | |||
| 932 | if (unlikely(i->type & ITER_PIPE)) | 929 | if (unlikely(i->type & ITER_PIPE)) |
| 933 | return pipe_get_pages(i, pages, maxsize, maxpages, start); | 930 | return pipe_get_pages(i, pages, maxsize, maxpages, start); |
| 934 | iterate_all_kinds(i, maxsize, v, ({ | 931 | iterate_all_kinds(i, maxsize, v, ({ |
| @@ -975,6 +972,9 @@ static ssize_t pipe_get_pages_alloc(struct iov_iter *i, | |||
| 975 | int idx; | 972 | int idx; |
| 976 | int npages; | 973 | int npages; |
| 977 | 974 | ||
| 975 | if (!maxsize) | ||
| 976 | return 0; | ||
| 977 | |||
| 978 | if (!sanity(i)) | 978 | if (!sanity(i)) |
| 979 | return -EFAULT; | 979 | return -EFAULT; |
| 980 | 980 | ||
| @@ -1006,9 +1006,6 @@ ssize_t iov_iter_get_pages_alloc(struct iov_iter *i, | |||
| 1006 | if (maxsize > i->count) | 1006 | if (maxsize > i->count) |
| 1007 | maxsize = i->count; | 1007 | maxsize = i->count; |
| 1008 | 1008 | ||
| 1009 | if (!maxsize) | ||
| 1010 | return 0; | ||
| 1011 | |||
| 1012 | if (unlikely(i->type & ITER_PIPE)) | 1009 | if (unlikely(i->type & ITER_PIPE)) |
| 1013 | return pipe_get_pages_alloc(i, pages, maxsize, start); | 1010 | return pipe_get_pages_alloc(i, pages, maxsize, start); |
| 1014 | iterate_all_kinds(i, maxsize, v, ({ | 1011 | iterate_all_kinds(i, maxsize, v, ({ |
