]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/aio.c
f2fs: add a condition to detect overflow in f2fs_ioc_gc_range()
[linux.git] / fs / aio.c
index 3490d1fa0e16f4f1f189727661e18696ab3a7a08..01e0fb9ae45aed3b1e10b3bfe25b878f393e0ab6 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -42,6 +42,7 @@
 #include <linux/ramfs.h>
 #include <linux/percpu-refcount.h>
 #include <linux/mount.h>
+#include <linux/pseudo_fs.h>
 
 #include <asm/kmap_types.h>
 #include <linux/uaccess.h>
@@ -249,15 +250,12 @@ static struct file *aio_private_file(struct kioctx *ctx, loff_t nr_pages)
        return file;
 }
 
-static struct dentry *aio_mount(struct file_system_type *fs_type,
-                               int flags, const char *dev_name, void *data)
+static int aio_init_fs_context(struct fs_context *fc)
 {
-       struct dentry *root = mount_pseudo(fs_type, "aio:", NULL, NULL,
-                                          AIO_RING_MAGIC);
-
-       if (!IS_ERR(root))
-               root->d_sb->s_iflags |= SB_I_NOEXEC;
-       return root;
+       if (!init_pseudo(fc, AIO_RING_MAGIC))
+               return -ENOMEM;
+       fc->s_iflags |= SB_I_NOEXEC;
+       return 0;
 }
 
 /* aio_setup
@@ -268,7 +266,7 @@ static int __init aio_setup(void)
 {
        static struct file_system_type aio_fs = {
                .name           = "aio",
-               .mount          = aio_mount,
+               .init_fs_context = aio_init_fs_context,
                .kill_sb        = kill_anon_super,
        };
        aio_mnt = kern_mount(&aio_fs);
@@ -425,7 +423,7 @@ static int aio_migratepage(struct address_space *mapping, struct page *new,
        BUG_ON(PageWriteback(old));
        get_page(new);
 
-       rc = migrate_page_move_mapping(mapping, new, old, mode, 1);
+       rc = migrate_page_move_mapping(mapping, new, old, 1);
        if (rc != MIGRATEPAGE_SUCCESS) {
                put_page(new);
                goto out_unlock;
@@ -1479,8 +1477,9 @@ static int aio_prep_rw(struct kiocb *req, const struct iocb *iocb)
        return 0;
 }
 
-static int aio_setup_rw(int rw, const struct iocb *iocb, struct iovec **iovec,
-               bool vectored, bool compat, struct iov_iter *iter)
+static ssize_t aio_setup_rw(int rw, const struct iocb *iocb,
+               struct iovec **iovec, bool vectored, bool compat,
+               struct iov_iter *iter)
 {
        void __user *buf = (void __user *)(uintptr_t)iocb->aio_buf;
        size_t len = iocb->aio_nbytes;
@@ -1537,7 +1536,7 @@ static int aio_read(struct kiocb *req, const struct iocb *iocb,
                return -EINVAL;
 
        ret = aio_setup_rw(READ, iocb, &iovec, vectored, compat, &iter);
-       if (ret)
+       if (ret < 0)
                return ret;
        ret = rw_verify_area(READ, file, &req->ki_pos, iov_iter_count(&iter));
        if (!ret)
@@ -1565,7 +1564,7 @@ static int aio_write(struct kiocb *req, const struct iocb *iocb,
                return -EINVAL;
 
        ret = aio_setup_rw(WRITE, iocb, &iovec, vectored, compat, &iter);
-       if (ret)
+       if (ret < 0)
                return ret;
        ret = rw_verify_area(WRITE, file, &req->ki_pos, iov_iter_count(&iter));
        if (!ret) {
@@ -2093,8 +2092,8 @@ SYSCALL_DEFINE6(io_pgetevents,
                const struct __aio_sigset __user *, usig)
 {
        struct __aio_sigset     ksig = { NULL, };
-       sigset_t                ksigmask, sigsaved;
        struct timespec64       ts;
+       bool interrupted;
        int ret;
 
        if (timeout && unlikely(get_timespec64(&ts, timeout)))
@@ -2103,13 +2102,15 @@ SYSCALL_DEFINE6(io_pgetevents,
        if (usig && copy_from_user(&ksig, usig, sizeof(ksig)))
                return -EFAULT;
 
-       ret = set_user_sigmask(ksig.sigmask, &ksigmask, &sigsaved, ksig.sigsetsize);
+       ret = set_user_sigmask(ksig.sigmask, ksig.sigsetsize);
        if (ret)
                return ret;
 
        ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
-       restore_user_sigmask(ksig.sigmask, &sigsaved);
-       if (signal_pending(current) && !ret)
+
+       interrupted = signal_pending(current);
+       restore_saved_sigmask_unless(interrupted);
+       if (interrupted && !ret)
                ret = -ERESTARTNOHAND;
 
        return ret;
@@ -2126,8 +2127,8 @@ SYSCALL_DEFINE6(io_pgetevents_time32,
                const struct __aio_sigset __user *, usig)
 {
        struct __aio_sigset     ksig = { NULL, };
-       sigset_t                ksigmask, sigsaved;
        struct timespec64       ts;
+       bool interrupted;
        int ret;
 
        if (timeout && unlikely(get_old_timespec32(&ts, timeout)))
@@ -2137,13 +2138,15 @@ SYSCALL_DEFINE6(io_pgetevents_time32,
                return -EFAULT;
 
 
-       ret = set_user_sigmask(ksig.sigmask, &ksigmask, &sigsaved, ksig.sigsetsize);
+       ret = set_user_sigmask(ksig.sigmask, ksig.sigsetsize);
        if (ret)
                return ret;
 
        ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &ts : NULL);
-       restore_user_sigmask(ksig.sigmask, &sigsaved);
-       if (signal_pending(current) && !ret)
+
+       interrupted = signal_pending(current);
+       restore_saved_sigmask_unless(interrupted);
+       if (interrupted && !ret)
                ret = -ERESTARTNOHAND;
 
        return ret;
@@ -2191,8 +2194,8 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents,
                const struct __compat_aio_sigset __user *, usig)
 {
        struct __compat_aio_sigset ksig = { NULL, };
-       sigset_t ksigmask, sigsaved;
        struct timespec64 t;
+       bool interrupted;
        int ret;
 
        if (timeout && get_old_timespec32(&t, timeout))
@@ -2201,13 +2204,15 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents,
        if (usig && copy_from_user(&ksig, usig, sizeof(ksig)))
                return -EFAULT;
 
-       ret = set_compat_user_sigmask(ksig.sigmask, &ksigmask, &sigsaved, ksig.sigsetsize);
+       ret = set_compat_user_sigmask(ksig.sigmask, ksig.sigsetsize);
        if (ret)
                return ret;
 
        ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
-       restore_user_sigmask(ksig.sigmask, &sigsaved);
-       if (signal_pending(current) && !ret)
+
+       interrupted = signal_pending(current);
+       restore_saved_sigmask_unless(interrupted);
+       if (interrupted && !ret)
                ret = -ERESTARTNOHAND;
 
        return ret;
@@ -2224,8 +2229,8 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64,
                const struct __compat_aio_sigset __user *, usig)
 {
        struct __compat_aio_sigset ksig = { NULL, };
-       sigset_t ksigmask, sigsaved;
        struct timespec64 t;
+       bool interrupted;
        int ret;
 
        if (timeout && get_timespec64(&t, timeout))
@@ -2234,13 +2239,15 @@ COMPAT_SYSCALL_DEFINE6(io_pgetevents_time64,
        if (usig && copy_from_user(&ksig, usig, sizeof(ksig)))
                return -EFAULT;
 
-       ret = set_compat_user_sigmask(ksig.sigmask, &ksigmask, &sigsaved, ksig.sigsetsize);
+       ret = set_compat_user_sigmask(ksig.sigmask, ksig.sigsetsize);
        if (ret)
                return ret;
 
        ret = do_io_getevents(ctx_id, min_nr, nr, events, timeout ? &t : NULL);
-       restore_user_sigmask(ksig.sigmask, &sigsaved);
-       if (signal_pending(current) && !ret)
+
+       interrupted = signal_pending(current);
+       restore_saved_sigmask_unless(interrupted);
+       if (interrupted && !ret)
                ret = -ERESTARTNOHAND;
 
        return ret;