statx.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. // SPDX-License-Identifier: GPL-2.0
  2. #include <linux/kernel.h>
  3. #include <linux/errno.h>
  4. #include <linux/file.h>
  5. #include <linux/io_uring.h>
  6. #include <uapi/linux/io_uring.h>
  7. #include "../fs/internal.h"
  8. #include "io_uring.h"
  9. #include "statx.h"
  10. struct io_statx {
  11. struct file *file;
  12. int dfd;
  13. unsigned int mask;
  14. unsigned int flags;
  15. struct filename *filename;
  16. struct statx __user *buffer;
  17. };
  18. int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
  19. {
  20. struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx);
  21. const char __user *path;
  22. if (sqe->buf_index || sqe->splice_fd_in)
  23. return -EINVAL;
  24. if (req->flags & REQ_F_FIXED_FILE)
  25. return -EBADF;
  26. sx->dfd = READ_ONCE(sqe->fd);
  27. sx->mask = READ_ONCE(sqe->len);
  28. path = u64_to_user_ptr(READ_ONCE(sqe->addr));
  29. sx->buffer = u64_to_user_ptr(READ_ONCE(sqe->addr2));
  30. sx->flags = READ_ONCE(sqe->statx_flags);
  31. sx->filename = getname_flags(path,
  32. getname_statx_lookup_flags(sx->flags));
  33. if (IS_ERR(sx->filename)) {
  34. int ret = PTR_ERR(sx->filename);
  35. sx->filename = NULL;
  36. return ret;
  37. }
  38. req->flags |= REQ_F_NEED_CLEANUP;
  39. req->flags |= REQ_F_FORCE_ASYNC;
  40. return 0;
  41. }
  42. int io_statx(struct io_kiocb *req, unsigned int issue_flags)
  43. {
  44. struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx);
  45. int ret;
  46. WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
  47. ret = do_statx(sx->dfd, sx->filename, sx->flags, sx->mask, sx->buffer);
  48. io_req_set_res(req, ret, 0);
  49. return IOU_OK;
  50. }
  51. void io_statx_cleanup(struct io_kiocb *req)
  52. {
  53. struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx);
  54. if (sx->filename)
  55. putname(sx->filename);
  56. }