fs.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  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 <uapi/linux/io_uring.h>
  11. #include "../fs/internal.h"
  12. #include "io_uring.h"
  13. #include "fs.h"
  14. struct io_rename {
  15. struct file *file;
  16. int old_dfd;
  17. int new_dfd;
  18. struct filename *oldpath;
  19. struct filename *newpath;
  20. int flags;
  21. };
  22. struct io_unlink {
  23. struct file *file;
  24. int dfd;
  25. int flags;
  26. struct filename *filename;
  27. };
  28. struct io_mkdir {
  29. struct file *file;
  30. int dfd;
  31. umode_t mode;
  32. struct filename *filename;
  33. };
  34. struct io_link {
  35. struct file *file;
  36. int old_dfd;
  37. int new_dfd;
  38. struct filename *oldpath;
  39. struct filename *newpath;
  40. int flags;
  41. };
  42. int io_renameat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
  43. {
  44. struct io_rename *ren = io_kiocb_to_cmd(req, struct io_rename);
  45. const char __user *oldf, *newf;
  46. if (sqe->buf_index || sqe->splice_fd_in)
  47. return -EINVAL;
  48. if (unlikely(req->flags & REQ_F_FIXED_FILE))
  49. return -EBADF;
  50. ren->old_dfd = READ_ONCE(sqe->fd);
  51. oldf = u64_to_user_ptr(READ_ONCE(sqe->addr));
  52. newf = u64_to_user_ptr(READ_ONCE(sqe->addr2));
  53. ren->new_dfd = READ_ONCE(sqe->len);
  54. ren->flags = READ_ONCE(sqe->rename_flags);
  55. ren->oldpath = getname(oldf);
  56. if (IS_ERR(ren->oldpath))
  57. return PTR_ERR(ren->oldpath);
  58. ren->newpath = getname(newf);
  59. if (IS_ERR(ren->newpath)) {
  60. putname(ren->oldpath);
  61. return PTR_ERR(ren->newpath);
  62. }
  63. req->flags |= REQ_F_NEED_CLEANUP;
  64. req->flags |= REQ_F_FORCE_ASYNC;
  65. return 0;
  66. }
  67. int io_renameat(struct io_kiocb *req, unsigned int issue_flags)
  68. {
  69. struct io_rename *ren = io_kiocb_to_cmd(req, struct io_rename);
  70. int ret;
  71. WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
  72. ret = do_renameat2(ren->old_dfd, ren->oldpath, ren->new_dfd,
  73. ren->newpath, ren->flags);
  74. req->flags &= ~REQ_F_NEED_CLEANUP;
  75. io_req_set_res(req, ret, 0);
  76. return IOU_OK;
  77. }
  78. void io_renameat_cleanup(struct io_kiocb *req)
  79. {
  80. struct io_rename *ren = io_kiocb_to_cmd(req, struct io_rename);
  81. putname(ren->oldpath);
  82. putname(ren->newpath);
  83. }
  84. int io_unlinkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
  85. {
  86. struct io_unlink *un = io_kiocb_to_cmd(req, struct io_unlink);
  87. const char __user *fname;
  88. if (sqe->off || sqe->len || sqe->buf_index || sqe->splice_fd_in)
  89. return -EINVAL;
  90. if (unlikely(req->flags & REQ_F_FIXED_FILE))
  91. return -EBADF;
  92. un->dfd = READ_ONCE(sqe->fd);
  93. un->flags = READ_ONCE(sqe->unlink_flags);
  94. if (un->flags & ~AT_REMOVEDIR)
  95. return -EINVAL;
  96. fname = u64_to_user_ptr(READ_ONCE(sqe->addr));
  97. un->filename = getname(fname);
  98. if (IS_ERR(un->filename))
  99. return PTR_ERR(un->filename);
  100. req->flags |= REQ_F_NEED_CLEANUP;
  101. req->flags |= REQ_F_FORCE_ASYNC;
  102. return 0;
  103. }
  104. int io_unlinkat(struct io_kiocb *req, unsigned int issue_flags)
  105. {
  106. struct io_unlink *un = io_kiocb_to_cmd(req, struct io_unlink);
  107. int ret;
  108. WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
  109. if (un->flags & AT_REMOVEDIR)
  110. ret = do_rmdir(un->dfd, un->filename);
  111. else
  112. ret = do_unlinkat(un->dfd, un->filename);
  113. req->flags &= ~REQ_F_NEED_CLEANUP;
  114. io_req_set_res(req, ret, 0);
  115. return IOU_OK;
  116. }
  117. void io_unlinkat_cleanup(struct io_kiocb *req)
  118. {
  119. struct io_unlink *ul = io_kiocb_to_cmd(req, struct io_unlink);
  120. putname(ul->filename);
  121. }
  122. int io_mkdirat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
  123. {
  124. struct io_mkdir *mkd = io_kiocb_to_cmd(req, struct io_mkdir);
  125. const char __user *fname;
  126. if (sqe->off || sqe->rw_flags || sqe->buf_index || sqe->splice_fd_in)
  127. return -EINVAL;
  128. if (unlikely(req->flags & REQ_F_FIXED_FILE))
  129. return -EBADF;
  130. mkd->dfd = READ_ONCE(sqe->fd);
  131. mkd->mode = READ_ONCE(sqe->len);
  132. fname = u64_to_user_ptr(READ_ONCE(sqe->addr));
  133. mkd->filename = getname(fname);
  134. if (IS_ERR(mkd->filename))
  135. return PTR_ERR(mkd->filename);
  136. req->flags |= REQ_F_NEED_CLEANUP;
  137. req->flags |= REQ_F_FORCE_ASYNC;
  138. return 0;
  139. }
  140. int io_mkdirat(struct io_kiocb *req, unsigned int issue_flags)
  141. {
  142. struct io_mkdir *mkd = io_kiocb_to_cmd(req, struct io_mkdir);
  143. int ret;
  144. WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
  145. ret = do_mkdirat(mkd->dfd, mkd->filename, mkd->mode);
  146. req->flags &= ~REQ_F_NEED_CLEANUP;
  147. io_req_set_res(req, ret, 0);
  148. return IOU_OK;
  149. }
  150. void io_mkdirat_cleanup(struct io_kiocb *req)
  151. {
  152. struct io_mkdir *md = io_kiocb_to_cmd(req, struct io_mkdir);
  153. putname(md->filename);
  154. }
  155. int io_symlinkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
  156. {
  157. struct io_link *sl = io_kiocb_to_cmd(req, struct io_link);
  158. const char __user *oldpath, *newpath;
  159. if (sqe->len || sqe->rw_flags || sqe->buf_index || sqe->splice_fd_in)
  160. return -EINVAL;
  161. if (unlikely(req->flags & REQ_F_FIXED_FILE))
  162. return -EBADF;
  163. sl->new_dfd = READ_ONCE(sqe->fd);
  164. oldpath = u64_to_user_ptr(READ_ONCE(sqe->addr));
  165. newpath = u64_to_user_ptr(READ_ONCE(sqe->addr2));
  166. sl->oldpath = getname(oldpath);
  167. if (IS_ERR(sl->oldpath))
  168. return PTR_ERR(sl->oldpath);
  169. sl->newpath = getname(newpath);
  170. if (IS_ERR(sl->newpath)) {
  171. putname(sl->oldpath);
  172. return PTR_ERR(sl->newpath);
  173. }
  174. req->flags |= REQ_F_NEED_CLEANUP;
  175. req->flags |= REQ_F_FORCE_ASYNC;
  176. return 0;
  177. }
  178. int io_symlinkat(struct io_kiocb *req, unsigned int issue_flags)
  179. {
  180. struct io_link *sl = io_kiocb_to_cmd(req, struct io_link);
  181. int ret;
  182. WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
  183. ret = do_symlinkat(sl->oldpath, sl->new_dfd, sl->newpath);
  184. req->flags &= ~REQ_F_NEED_CLEANUP;
  185. io_req_set_res(req, ret, 0);
  186. return IOU_OK;
  187. }
  188. int io_linkat_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
  189. {
  190. struct io_link *lnk = io_kiocb_to_cmd(req, struct io_link);
  191. const char __user *oldf, *newf;
  192. if (sqe->buf_index || sqe->splice_fd_in)
  193. return -EINVAL;
  194. if (unlikely(req->flags & REQ_F_FIXED_FILE))
  195. return -EBADF;
  196. lnk->old_dfd = READ_ONCE(sqe->fd);
  197. lnk->new_dfd = READ_ONCE(sqe->len);
  198. oldf = u64_to_user_ptr(READ_ONCE(sqe->addr));
  199. newf = u64_to_user_ptr(READ_ONCE(sqe->addr2));
  200. lnk->flags = READ_ONCE(sqe->hardlink_flags);
  201. lnk->oldpath = getname_uflags(oldf, lnk->flags);
  202. if (IS_ERR(lnk->oldpath))
  203. return PTR_ERR(lnk->oldpath);
  204. lnk->newpath = getname(newf);
  205. if (IS_ERR(lnk->newpath)) {
  206. putname(lnk->oldpath);
  207. return PTR_ERR(lnk->newpath);
  208. }
  209. req->flags |= REQ_F_NEED_CLEANUP;
  210. req->flags |= REQ_F_FORCE_ASYNC;
  211. return 0;
  212. }
  213. int io_linkat(struct io_kiocb *req, unsigned int issue_flags)
  214. {
  215. struct io_link *lnk = io_kiocb_to_cmd(req, struct io_link);
  216. int ret;
  217. WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
  218. ret = do_linkat(lnk->old_dfd, lnk->oldpath, lnk->new_dfd,
  219. lnk->newpath, lnk->flags);
  220. req->flags &= ~REQ_F_NEED_CLEANUP;
  221. io_req_set_res(req, ret, 0);
  222. return IOU_OK;
  223. }
  224. void io_link_cleanup(struct io_kiocb *req)
  225. {
  226. struct io_link *sl = io_kiocb_to_cmd(req, struct io_link);
  227. putname(sl->oldpath);
  228. putname(sl->newpath);
  229. }