statx.c 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  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 delayed_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. int ret;
  23. if (sqe->buf_index || sqe->splice_fd_in)
  24. return -EINVAL;
  25. if (req->flags & REQ_F_FIXED_FILE)
  26. return -EBADF;
  27. sx->dfd = READ_ONCE(sqe->fd);
  28. sx->mask = READ_ONCE(sqe->len);
  29. path = u64_to_user_ptr(READ_ONCE(sqe->addr));
  30. sx->buffer = u64_to_user_ptr(READ_ONCE(sqe->addr2));
  31. sx->flags = READ_ONCE(sqe->statx_flags);
  32. ret = delayed_getname_uflags(&sx->filename, path, sx->flags);
  33. if (unlikely(ret))
  34. return ret;
  35. req->flags |= REQ_F_NEED_CLEANUP;
  36. req->flags |= REQ_F_FORCE_ASYNC;
  37. return 0;
  38. }
  39. int io_statx(struct io_kiocb *req, unsigned int issue_flags)
  40. {
  41. struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx);
  42. CLASS(filename_complete_delayed, name)(&sx->filename);
  43. int ret;
  44. WARN_ON_ONCE(issue_flags & IO_URING_F_NONBLOCK);
  45. ret = do_statx(sx->dfd, name, sx->flags, sx->mask, sx->buffer);
  46. io_req_set_res(req, ret, 0);
  47. return IOU_COMPLETE;
  48. }
  49. void io_statx_cleanup(struct io_kiocb *req)
  50. {
  51. struct io_statx *sx = io_kiocb_to_cmd(req, struct io_statx);
  52. dismiss_delayed_filename(&sx->filename);
  53. }