xref: /openbmc/linux/io_uring/sync.c (revision aebb224f)
10d584727SJens Axboe // SPDX-License-Identifier: GPL-2.0
20d584727SJens Axboe #include <linux/kernel.h>
30d584727SJens Axboe #include <linux/errno.h>
40d584727SJens Axboe #include <linux/fs.h>
50d584727SJens Axboe #include <linux/file.h>
60d584727SJens Axboe #include <linux/mm.h>
70d584727SJens Axboe #include <linux/slab.h>
80d584727SJens Axboe #include <linux/namei.h>
90d584727SJens Axboe #include <linux/io_uring.h>
100d584727SJens Axboe #include <linux/fsnotify.h>
110d584727SJens Axboe 
120d584727SJens Axboe #include <uapi/linux/io_uring.h>
130d584727SJens Axboe 
140d584727SJens Axboe #include "io_uring.h"
150d584727SJens Axboe #include "sync.h"
160d584727SJens Axboe 
170d584727SJens Axboe struct io_sync {
180d584727SJens Axboe 	struct file			*file;
190d584727SJens Axboe 	loff_t				len;
200d584727SJens Axboe 	loff_t				off;
210d584727SJens Axboe 	int				flags;
220d584727SJens Axboe 	int				mode;
230d584727SJens Axboe };
240d584727SJens Axboe 
io_sfr_prep(struct io_kiocb * req,const struct io_uring_sqe * sqe)250d584727SJens Axboe int io_sfr_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
260d584727SJens Axboe {
27f2ccb5aeSStefan Metzmacher 	struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync);
280d584727SJens Axboe 
290d584727SJens Axboe 	if (unlikely(sqe->addr || sqe->buf_index || sqe->splice_fd_in))
300d584727SJens Axboe 		return -EINVAL;
310d584727SJens Axboe 
320d584727SJens Axboe 	sync->off = READ_ONCE(sqe->off);
330d584727SJens Axboe 	sync->len = READ_ONCE(sqe->len);
340d584727SJens Axboe 	sync->flags = READ_ONCE(sqe->sync_range_flags);
35*aebb224fSDylan Yudaken 	req->flags |= REQ_F_FORCE_ASYNC;
36*aebb224fSDylan Yudaken 
370d584727SJens Axboe 	return 0;
380d584727SJens Axboe }
390d584727SJens Axboe 
io_sync_file_range(struct io_kiocb * req,unsigned int issue_flags)400d584727SJens Axboe int io_sync_file_range(struct io_kiocb *req, unsigned int issue_flags)
410d584727SJens Axboe {
42f2ccb5aeSStefan Metzmacher 	struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync);
430d584727SJens Axboe 	int ret;
440d584727SJens Axboe 
450d584727SJens Axboe 	/* sync_file_range always requires a blocking context */
46*aebb224fSDylan Yudaken 	WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
470d584727SJens Axboe 
480d584727SJens Axboe 	ret = sync_file_range(req->file, sync->off, sync->len, sync->flags);
490d584727SJens Axboe 	io_req_set_res(req, ret, 0);
500d584727SJens Axboe 	return IOU_OK;
510d584727SJens Axboe }
520d584727SJens Axboe 
io_fsync_prep(struct io_kiocb * req,const struct io_uring_sqe * sqe)530d584727SJens Axboe int io_fsync_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
540d584727SJens Axboe {
55f2ccb5aeSStefan Metzmacher 	struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync);
560d584727SJens Axboe 
570d584727SJens Axboe 	if (unlikely(sqe->addr || sqe->buf_index || sqe->splice_fd_in))
580d584727SJens Axboe 		return -EINVAL;
590d584727SJens Axboe 
600d584727SJens Axboe 	sync->flags = READ_ONCE(sqe->fsync_flags);
610d584727SJens Axboe 	if (unlikely(sync->flags & ~IORING_FSYNC_DATASYNC))
620d584727SJens Axboe 		return -EINVAL;
630d584727SJens Axboe 
640d584727SJens Axboe 	sync->off = READ_ONCE(sqe->off);
650d584727SJens Axboe 	sync->len = READ_ONCE(sqe->len);
66*aebb224fSDylan Yudaken 	req->flags |= REQ_F_FORCE_ASYNC;
670d584727SJens Axboe 	return 0;
680d584727SJens Axboe }
690d584727SJens Axboe 
io_fsync(struct io_kiocb * req,unsigned int issue_flags)700d584727SJens Axboe int io_fsync(struct io_kiocb *req, unsigned int issue_flags)
710d584727SJens Axboe {
72f2ccb5aeSStefan Metzmacher 	struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync);
730d584727SJens Axboe 	loff_t end = sync->off + sync->len;
740d584727SJens Axboe 	int ret;
750d584727SJens Axboe 
760d584727SJens Axboe 	/* fsync always requires a blocking context */
77*aebb224fSDylan Yudaken 	WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
780d584727SJens Axboe 
790d584727SJens Axboe 	ret = vfs_fsync_range(req->file, sync->off, end > 0 ? end : LLONG_MAX,
800d584727SJens Axboe 				sync->flags & IORING_FSYNC_DATASYNC);
810d584727SJens Axboe 	io_req_set_res(req, ret, 0);
820d584727SJens Axboe 	return IOU_OK;
830d584727SJens Axboe }
840d584727SJens Axboe 
io_fallocate_prep(struct io_kiocb * req,const struct io_uring_sqe * sqe)850d584727SJens Axboe int io_fallocate_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
860d584727SJens Axboe {
87f2ccb5aeSStefan Metzmacher 	struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync);
880d584727SJens Axboe 
890d584727SJens Axboe 	if (sqe->buf_index || sqe->rw_flags || sqe->splice_fd_in)
900d584727SJens Axboe 		return -EINVAL;
910d584727SJens Axboe 
920d584727SJens Axboe 	sync->off = READ_ONCE(sqe->off);
930d584727SJens Axboe 	sync->len = READ_ONCE(sqe->addr);
940d584727SJens Axboe 	sync->mode = READ_ONCE(sqe->len);
95*aebb224fSDylan Yudaken 	req->flags |= REQ_F_FORCE_ASYNC;
960d584727SJens Axboe 	return 0;
970d584727SJens Axboe }
980d584727SJens Axboe 
io_fallocate(struct io_kiocb * req,unsigned int issue_flags)990d584727SJens Axboe int io_fallocate(struct io_kiocb *req, unsigned int issue_flags)
1000d584727SJens Axboe {
101f2ccb5aeSStefan Metzmacher 	struct io_sync *sync = io_kiocb_to_cmd(req, struct io_sync);
1020d584727SJens Axboe 	int ret;
1030d584727SJens Axboe 
1040d584727SJens Axboe 	/* fallocate always requiring blocking context */
105*aebb224fSDylan Yudaken 	WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
106*aebb224fSDylan Yudaken 
1070d584727SJens Axboe 	ret = vfs_fallocate(req->file, sync->mode, sync->off, sync->len);
1080d584727SJens Axboe 	if (ret >= 0)
1090d584727SJens Axboe 		fsnotify_modify(req->file);
1100d584727SJens Axboe 	io_req_set_res(req, ret, 0);
1110d584727SJens Axboe 	return IOU_OK;
1120d584727SJens Axboe }
113