Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0 2 : #include <linux/kernel.h> 3 : #include <linux/errno.h> 4 : #include <linux/fs.h> 5 : #include <linux/file.h> 6 : #include <linux/mm.h> 7 : #include <linux/slab.h> 8 : #include <linux/namei.h> 9 : #include <linux/io_uring.h> 10 : #include <linux/fsnotify.h> 11 : 12 : #include <uapi/linux/io_uring.h> 13 : 14 : #include "io_uring.h" 15 : #include "sync.h" 16 : 17 : struct io_sync { 18 : struct file *file; 19 : loff_t len; 20 : loff_t off; 21 : int flags; 22 : int mode; 23 : }; 24 : 25 0 : int io_sfr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) 26 : { 27 0 : struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync); 28 : 29 0 : if (unlikely(sqe->addr || sqe->buf_index || sqe->splice_fd_in)) 30 : return -EINVAL; 31 : 32 0 : sync->off = READ_ONCE(sqe->off); 33 0 : sync->len = READ_ONCE(sqe->len); 34 0 : sync->flags = READ_ONCE(sqe->sync_range_flags); 35 0 : req->flags |= REQ_F_FORCE_ASYNC; 36 : 37 0 : return 0; 38 : } 39 : 40 0 : int io_sync_file_range(struct io_kiocb *req, unsigned int issue_flags) 41 : { 42 0 : struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync); 43 : int ret; 44 : 45 : /* sync_file_range always requires a blocking context */ 46 0 : WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); 47 : 48 0 : ret = sync_file_range(req->file, sync->off, sync->len, sync->flags); 49 0 : io_req_set_res(req, ret, 0); 50 0 : return IOU_OK; 51 : } 52 : 53 0 : int io_fsync_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) 54 : { 55 0 : struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync); 56 : 57 0 : if (unlikely(sqe->addr || sqe->buf_index || sqe->splice_fd_in)) 58 : return -EINVAL; 59 : 60 0 : sync->flags = READ_ONCE(sqe->fsync_flags); 61 0 : if (unlikely(sync->flags & ~IORING_FSYNC_DATASYNC)) 62 : return -EINVAL; 63 : 64 0 : sync->off = READ_ONCE(sqe->off); 65 0 : sync->len = READ_ONCE(sqe->len); 66 0 : req->flags |= REQ_F_FORCE_ASYNC; 67 0 : return 0; 68 : } 69 : 70 0 : int io_fsync(struct io_kiocb *req, unsigned int issue_flags) 71 : { 72 0 : struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync); 73 0 : loff_t end = sync->off + sync->len; 74 : int ret; 75 : 76 : /* fsync always requires a blocking context */ 77 0 : WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); 78 : 79 0 : ret = vfs_fsync_range(req->file, sync->off, end > 0 ? end : LLONG_MAX, 80 0 : sync->flags & IORING_FSYNC_DATASYNC); 81 0 : io_req_set_res(req, ret, 0); 82 0 : return IOU_OK; 83 : } 84 : 85 0 : int io_fallocate_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) 86 : { 87 0 : struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync); 88 : 89 0 : if (sqe->buf_index || sqe->rw_flags || sqe->splice_fd_in) 90 : return -EINVAL; 91 : 92 0 : sync->off = READ_ONCE(sqe->off); 93 0 : sync->len = READ_ONCE(sqe->addr); 94 0 : sync->mode = READ_ONCE(sqe->len); 95 0 : req->flags |= REQ_F_FORCE_ASYNC; 96 0 : return 0; 97 : } 98 : 99 0 : int io_fallocate(struct io_kiocb *req, unsigned int issue_flags) 100 : { 101 0 : struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync); 102 : int ret; 103 : 104 : /* fallocate always requiring blocking context */ 105 0 : WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK); 106 : 107 0 : ret = vfs_fallocate(req->file, sync->mode, sync->off, sync->len); 108 0 : if (ret >= 0) 109 0 : fsnotify_modify(req->file); 110 0 : io_req_set_res(req, ret, 0); 111 0 : return IOU_OK; 112 : }