Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
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     /* sync_file_range always requires a blocking context */
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     /* fsync always requires a blocking context */
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     /* fallocate always requiring blocking context */
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 }