1 // SPDX-License-Identifier: GPL-2.0
2 #include <linux/kernel.h>
3 #include <linux/errno.h>
5 #include <linux/file.h>
7 #include <linux/slab.h>
8 #include <linux/namei.h>
9 #include <linux/io_uring.h>
11 #include <uapi/linux/io_uring.h>
13 #include "../fs/internal.h"
22 struct filename
*oldpath
;
23 struct filename
*newpath
;
31 struct filename
*filename
;
38 struct filename
*filename
;
45 struct filename
*oldpath
;
46 struct filename
*newpath
;
50 int io_renameat_prep(struct io_kiocb
*req
, const struct io_uring_sqe
*sqe
)
52 struct io_rename
*ren
= io_kiocb_to_cmd(req
, struct io_rename
);
53 const char __user
*oldf
, *newf
;
55 if (sqe
->buf_index
|| sqe
->splice_fd_in
)
57 if (unlikely(req
->flags
& REQ_F_FIXED_FILE
))
60 ren
->old_dfd
= READ_ONCE(sqe
->fd
);
61 oldf
= u64_to_user_ptr(READ_ONCE(sqe
->addr
));
62 newf
= u64_to_user_ptr(READ_ONCE(sqe
->addr2
));
63 ren
->new_dfd
= READ_ONCE(sqe
->len
);
64 ren
->flags
= READ_ONCE(sqe
->rename_flags
);
66 ren
->oldpath
= getname(oldf
);
67 if (IS_ERR(ren
->oldpath
))
68 return PTR_ERR(ren
->oldpath
);
70 ren
->newpath
= getname(newf
);
71 if (IS_ERR(ren
->newpath
)) {
72 putname(ren
->oldpath
);
73 return PTR_ERR(ren
->newpath
);
76 req
->flags
|= REQ_F_NEED_CLEANUP
;
77 req
->flags
|= REQ_F_FORCE_ASYNC
;
81 int io_renameat(struct io_kiocb
*req
, unsigned int issue_flags
)
83 struct io_rename
*ren
= io_kiocb_to_cmd(req
, struct io_rename
);
86 WARN_ON_ONCE(issue_flags
& IO_URING_F_NONBLOCK
);
88 ret
= do_renameat2(ren
->old_dfd
, ren
->oldpath
, ren
->new_dfd
,
89 ren
->newpath
, ren
->flags
);
91 req
->flags
&= ~REQ_F_NEED_CLEANUP
;
92 io_req_set_res(req
, ret
, 0);
96 void io_renameat_cleanup(struct io_kiocb
*req
)
98 struct io_rename
*ren
= io_kiocb_to_cmd(req
, struct io_rename
);
100 putname(ren
->oldpath
);
101 putname(ren
->newpath
);
104 int io_unlinkat_prep(struct io_kiocb
*req
, const struct io_uring_sqe
*sqe
)
106 struct io_unlink
*un
= io_kiocb_to_cmd(req
, struct io_unlink
);
107 const char __user
*fname
;
109 if (sqe
->off
|| sqe
->len
|| sqe
->buf_index
|| sqe
->splice_fd_in
)
111 if (unlikely(req
->flags
& REQ_F_FIXED_FILE
))
114 un
->dfd
= READ_ONCE(sqe
->fd
);
116 un
->flags
= READ_ONCE(sqe
->unlink_flags
);
117 if (un
->flags
& ~AT_REMOVEDIR
)
120 fname
= u64_to_user_ptr(READ_ONCE(sqe
->addr
));
121 un
->filename
= getname(fname
);
122 if (IS_ERR(un
->filename
))
123 return PTR_ERR(un
->filename
);
125 req
->flags
|= REQ_F_NEED_CLEANUP
;
126 req
->flags
|= REQ_F_FORCE_ASYNC
;
130 int io_unlinkat(struct io_kiocb
*req
, unsigned int issue_flags
)
132 struct io_unlink
*un
= io_kiocb_to_cmd(req
, struct io_unlink
);
135 WARN_ON_ONCE(issue_flags
& IO_URING_F_NONBLOCK
);
137 if (un
->flags
& AT_REMOVEDIR
)
138 ret
= do_rmdir(un
->dfd
, un
->filename
);
140 ret
= do_unlinkat(un
->dfd
, un
->filename
);
142 req
->flags
&= ~REQ_F_NEED_CLEANUP
;
143 io_req_set_res(req
, ret
, 0);
147 void io_unlinkat_cleanup(struct io_kiocb
*req
)
149 struct io_unlink
*ul
= io_kiocb_to_cmd(req
, struct io_unlink
);
151 putname(ul
->filename
);
154 int io_mkdirat_prep(struct io_kiocb
*req
, const struct io_uring_sqe
*sqe
)
156 struct io_mkdir
*mkd
= io_kiocb_to_cmd(req
, struct io_mkdir
);
157 const char __user
*fname
;
159 if (sqe
->off
|| sqe
->rw_flags
|| sqe
->buf_index
|| sqe
->splice_fd_in
)
161 if (unlikely(req
->flags
& REQ_F_FIXED_FILE
))
164 mkd
->dfd
= READ_ONCE(sqe
->fd
);
165 mkd
->mode
= READ_ONCE(sqe
->len
);
167 fname
= u64_to_user_ptr(READ_ONCE(sqe
->addr
));
168 mkd
->filename
= getname(fname
);
169 if (IS_ERR(mkd
->filename
))
170 return PTR_ERR(mkd
->filename
);
172 req
->flags
|= REQ_F_NEED_CLEANUP
;
173 req
->flags
|= REQ_F_FORCE_ASYNC
;
177 int io_mkdirat(struct io_kiocb
*req
, unsigned int issue_flags
)
179 struct io_mkdir
*mkd
= io_kiocb_to_cmd(req
, struct io_mkdir
);
182 WARN_ON_ONCE(issue_flags
& IO_URING_F_NONBLOCK
);
184 ret
= do_mkdirat(mkd
->dfd
, mkd
->filename
, mkd
->mode
);
186 req
->flags
&= ~REQ_F_NEED_CLEANUP
;
187 io_req_set_res(req
, ret
, 0);
191 void io_mkdirat_cleanup(struct io_kiocb
*req
)
193 struct io_mkdir
*md
= io_kiocb_to_cmd(req
, struct io_mkdir
);
195 putname(md
->filename
);
198 int io_symlinkat_prep(struct io_kiocb
*req
, const struct io_uring_sqe
*sqe
)
200 struct io_link
*sl
= io_kiocb_to_cmd(req
, struct io_link
);
201 const char __user
*oldpath
, *newpath
;
203 if (sqe
->len
|| sqe
->rw_flags
|| sqe
->buf_index
|| sqe
->splice_fd_in
)
205 if (unlikely(req
->flags
& REQ_F_FIXED_FILE
))
208 sl
->new_dfd
= READ_ONCE(sqe
->fd
);
209 oldpath
= u64_to_user_ptr(READ_ONCE(sqe
->addr
));
210 newpath
= u64_to_user_ptr(READ_ONCE(sqe
->addr2
));
212 sl
->oldpath
= getname(oldpath
);
213 if (IS_ERR(sl
->oldpath
))
214 return PTR_ERR(sl
->oldpath
);
216 sl
->newpath
= getname(newpath
);
217 if (IS_ERR(sl
->newpath
)) {
218 putname(sl
->oldpath
);
219 return PTR_ERR(sl
->newpath
);
222 req
->flags
|= REQ_F_NEED_CLEANUP
;
223 req
->flags
|= REQ_F_FORCE_ASYNC
;
227 int io_symlinkat(struct io_kiocb
*req
, unsigned int issue_flags
)
229 struct io_link
*sl
= io_kiocb_to_cmd(req
, struct io_link
);
232 WARN_ON_ONCE(issue_flags
& IO_URING_F_NONBLOCK
);
234 ret
= do_symlinkat(sl
->oldpath
, sl
->new_dfd
, sl
->newpath
);
236 req
->flags
&= ~REQ_F_NEED_CLEANUP
;
237 io_req_set_res(req
, ret
, 0);
241 int io_linkat_prep(struct io_kiocb
*req
, const struct io_uring_sqe
*sqe
)
243 struct io_link
*lnk
= io_kiocb_to_cmd(req
, struct io_link
);
244 const char __user
*oldf
, *newf
;
246 if (sqe
->buf_index
|| sqe
->splice_fd_in
)
248 if (unlikely(req
->flags
& REQ_F_FIXED_FILE
))
251 lnk
->old_dfd
= READ_ONCE(sqe
->fd
);
252 lnk
->new_dfd
= READ_ONCE(sqe
->len
);
253 oldf
= u64_to_user_ptr(READ_ONCE(sqe
->addr
));
254 newf
= u64_to_user_ptr(READ_ONCE(sqe
->addr2
));
255 lnk
->flags
= READ_ONCE(sqe
->hardlink_flags
);
257 lnk
->oldpath
= getname_uflags(oldf
, lnk
->flags
);
258 if (IS_ERR(lnk
->oldpath
))
259 return PTR_ERR(lnk
->oldpath
);
261 lnk
->newpath
= getname(newf
);
262 if (IS_ERR(lnk
->newpath
)) {
263 putname(lnk
->oldpath
);
264 return PTR_ERR(lnk
->newpath
);
267 req
->flags
|= REQ_F_NEED_CLEANUP
;
268 req
->flags
|= REQ_F_FORCE_ASYNC
;
272 int io_linkat(struct io_kiocb
*req
, unsigned int issue_flags
)
274 struct io_link
*lnk
= io_kiocb_to_cmd(req
, struct io_link
);
277 WARN_ON_ONCE(issue_flags
& IO_URING_F_NONBLOCK
);
279 ret
= do_linkat(lnk
->old_dfd
, lnk
->oldpath
, lnk
->new_dfd
,
280 lnk
->newpath
, lnk
->flags
);
282 req
->flags
&= ~REQ_F_NEED_CLEANUP
;
283 io_req_set_res(req
, ret
, 0);
287 void io_link_cleanup(struct io_kiocb
*req
)
289 struct io_link
*sl
= io_kiocb_to_cmd(req
, struct io_link
);
291 putname(sl
->oldpath
);
292 putname(sl
->newpath
);