0001
0002 #include <linux/kernel.h>
0003 #include <linux/errno.h>
0004 #include <linux/fs.h>
0005 #include <linux/file.h>
0006 #include <linux/mm.h>
0007 #include <linux/slab.h>
0008 #include <linux/namei.h>
0009 #include <linux/io_uring.h>
0010 #include <linux/fsnotify.h>
0011
0012 #include <uapi/linux/io_uring.h>
0013
0014 #include "io_uring.h"
0015 #include "sync.h"
0016
0017 struct io_sync {
0018 struct file *file;
0019 loff_t len;
0020 loff_t off;
0021 int flags;
0022 int mode;
0023 };
0024
0025 int io_sfr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
0026 {
0027 struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync);
0028
0029 if (unlikely(sqe->addr || sqe->buf_index || sqe->splice_fd_in))
0030 return -EINVAL;
0031
0032 sync->off = READ_ONCE(sqe->off);
0033 sync->len = READ_ONCE(sqe->len);
0034 sync->flags = READ_ONCE(sqe->sync_range_flags);
0035 return 0;
0036 }
0037
0038 int io_sync_file_range(struct io_kiocb *req, unsigned int issue_flags)
0039 {
0040 struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync);
0041 int ret;
0042
0043
0044 if (issue_flags & IO_URING_F_NONBLOCK)
0045 return -EAGAIN;
0046
0047 ret = sync_file_range(req->file, sync->off, sync->len, sync->flags);
0048 io_req_set_res(req, ret, 0);
0049 return IOU_OK;
0050 }
0051
0052 int io_fsync_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
0053 {
0054 struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync);
0055
0056 if (unlikely(sqe->addr || sqe->buf_index || sqe->splice_fd_in))
0057 return -EINVAL;
0058
0059 sync->flags = READ_ONCE(sqe->fsync_flags);
0060 if (unlikely(sync->flags & ~IORING_FSYNC_DATASYNC))
0061 return -EINVAL;
0062
0063 sync->off = READ_ONCE(sqe->off);
0064 sync->len = READ_ONCE(sqe->len);
0065 return 0;
0066 }
0067
0068 int io_fsync(struct io_kiocb *req, unsigned int issue_flags)
0069 {
0070 struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync);
0071 loff_t end = sync->off + sync->len;
0072 int ret;
0073
0074
0075 if (issue_flags & IO_URING_F_NONBLOCK)
0076 return -EAGAIN;
0077
0078 ret = vfs_fsync_range(req->file, sync->off, end > 0 ? end : LLONG_MAX,
0079 sync->flags & IORING_FSYNC_DATASYNC);
0080 io_req_set_res(req, ret, 0);
0081 return IOU_OK;
0082 }
0083
0084 int io_fallocate_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
0085 {
0086 struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync);
0087
0088 if (sqe->buf_index || sqe->rw_flags || sqe->splice_fd_in)
0089 return -EINVAL;
0090
0091 sync->off = READ_ONCE(sqe->off);
0092 sync->len = READ_ONCE(sqe->addr);
0093 sync->mode = READ_ONCE(sqe->len);
0094 return 0;
0095 }
0096
0097 int io_fallocate(struct io_kiocb *req, unsigned int issue_flags)
0098 {
0099 struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync);
0100 int ret;
0101
0102
0103 if (issue_flags & IO_URING_F_NONBLOCK)
0104 return -EAGAIN;
0105 ret = vfs_fallocate(req->file, sync->mode, sync->off, sync->len);
0106 if (ret >= 0)
0107 fsnotify_modify(req->file);
0108 io_req_set_res(req, ret, 0);
0109 return IOU_OK;
0110 }