io_uring: deduplicate io_openat{,2}_prep()
authorPavel Begunkov <asml.silence@gmail.com>
Wed, 3 Jun 2020 15:03:24 +0000 (18:03 +0300)
committerJens Axboe <axboe@kernel.dk>
Thu, 4 Jun 2020 17:14:19 +0000 (11:14 -0600)
io_openat_prep() and io_openat2_prep() are identical except for how
struct open_how is built. Deduplicate it with a helper.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/io_uring.c

index 0c5b484..4823a11 100644 (file)
@@ -2990,26 +2990,21 @@ static int io_fallocate(struct io_kiocb *req, bool force_nonblock)
        return 0;
 }
 
-static int io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+static int __io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 {
        const char __user *fname;
-       u64 flags, mode;
        int ret;
 
        if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL|IORING_SETUP_SQPOLL)))
                return -EINVAL;
-       if (sqe->ioprio || sqe->buf_index)
+       if (unlikely(sqe->ioprio || sqe->buf_index))
                return -EINVAL;
-       if (req->flags & REQ_F_FIXED_FILE)
+       if (unlikely(req->flags & REQ_F_FIXED_FILE))
                return -EBADF;
-       if (req->flags & REQ_F_NEED_CLEANUP)
-               return 0;
 
-       mode = READ_ONCE(sqe->len);
-       flags = READ_ONCE(sqe->open_flags);
-       if (force_o_largefile())
-               flags |= O_LARGEFILE;
-       req->open.how = build_open_how(flags, mode);
+       /* open.how should be already initialised */
+       if (!(req->open.how.flags & O_PATH) && force_o_largefile())
+               req->open.how.flags |= O_LARGEFILE;
 
        req->open.dfd = READ_ONCE(sqe->fd);
        fname = u64_to_user_ptr(READ_ONCE(sqe->addr));
@@ -3019,33 +3014,33 @@ static int io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
                req->open.filename = NULL;
                return ret;
        }
-
        req->open.nofile = rlimit(RLIMIT_NOFILE);
        req->flags |= REQ_F_NEED_CLEANUP;
        return 0;
 }
 
+static int io_openat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
+{
+       u64 flags, mode;
+
+       if (req->flags & REQ_F_NEED_CLEANUP)
+               return 0;
+       mode = READ_ONCE(sqe->len);
+       flags = READ_ONCE(sqe->open_flags);
+       req->open.how = build_open_how(flags, mode);
+       return __io_openat_prep(req, sqe);
+}
+
 static int io_openat2_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 {
        struct open_how __user *how;
-       const char __user *fname;
        size_t len;
        int ret;
 
-       if (unlikely(req->ctx->flags & (IORING_SETUP_IOPOLL|IORING_SETUP_SQPOLL)))
-               return -EINVAL;
-       if (sqe->ioprio || sqe->buf_index)
-               return -EINVAL;
-       if (req->flags & REQ_F_FIXED_FILE)
-               return -EBADF;
        if (req->flags & REQ_F_NEED_CLEANUP)
                return 0;
-
-       req->open.dfd = READ_ONCE(sqe->fd);
-       fname = u64_to_user_ptr(READ_ONCE(sqe->addr));
        how = u64_to_user_ptr(READ_ONCE(sqe->addr2));
        len = READ_ONCE(sqe->len);
-
        if (len < OPEN_HOW_SIZE_VER0)
                return -EINVAL;
 
@@ -3054,19 +3049,7 @@ static int io_openat2_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
        if (ret)
                return ret;
 
-       if (!(req->open.how.flags & O_PATH) && force_o_largefile())
-               req->open.how.flags |= O_LARGEFILE;
-
-       req->open.filename = getname(fname);
-       if (IS_ERR(req->open.filename)) {
-               ret = PTR_ERR(req->open.filename);
-               req->open.filename = NULL;
-               return ret;
-       }
-
-       req->open.nofile = rlimit(RLIMIT_NOFILE);
-       req->flags |= REQ_F_NEED_CLEANUP;
-       return 0;
+       return __io_openat_prep(req, sqe);
 }
 
 static int io_openat2(struct io_kiocb *req, bool force_nonblock)