int                             dfd;
        unsigned int                    mask;
        unsigned int                    flags;
-       const char __user               *filename;
+       struct filename                 *filename;
        struct statx __user             *buffer;
 };
 
 
 static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
 {
+       const char __user *path;
+
        if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
                return -EINVAL;
        if (sqe->ioprio || sqe->buf_index || sqe->splice_fd_in)
 
        req->statx.dfd = READ_ONCE(sqe->fd);
        req->statx.mask = READ_ONCE(sqe->len);
-       req->statx.filename = u64_to_user_ptr(READ_ONCE(sqe->addr));
+       path = u64_to_user_ptr(READ_ONCE(sqe->addr));
        req->statx.buffer = u64_to_user_ptr(READ_ONCE(sqe->addr2));
        req->statx.flags = READ_ONCE(sqe->statx_flags);
 
+       req->statx.filename = getname_flags(path,
+                                       getname_statx_lookup_flags(req->statx.flags),
+                                       NULL);
+
+       if (IS_ERR(req->statx.filename)) {
+               int ret = PTR_ERR(req->statx.filename);
+
+               req->statx.filename = NULL;
+               return ret;
+       }
+
+       req->flags |= REQ_F_NEED_CLEANUP;
        return 0;
 }
 
                        putname(req->hardlink.oldpath);
                        putname(req->hardlink.newpath);
                        break;
+               case IORING_OP_STATX:
+                       if (req->statx.filename)
+                               putname(req->statx.filename);
+                       break;
                }
        }
        if ((req->flags & REQ_F_POLLED) && req->apoll) {
 
        return error;
 }
 
+int getname_statx_lookup_flags(int flags)
+{
+       int lookup_flags = 0;
+
+       if (!(flags & AT_SYMLINK_NOFOLLOW))
+               lookup_flags |= LOOKUP_FOLLOW;
+       if (!(flags & AT_NO_AUTOMOUNT))
+               lookup_flags |= LOOKUP_AUTOMOUNT;
+       if (flags & AT_EMPTY_PATH)
+               lookup_flags |= LOOKUP_EMPTY;
+
+       return lookup_flags;
+}
+
 /**
  * vfs_statx - Get basic and extra attributes by filename
  * @dfd: A file descriptor representing the base dir for a relative filename
  *
  * 0 will be returned on success, and a -ve error code if unsuccessful.
  */
-static int vfs_statx(int dfd, const char __user *filename, int flags,
+static int vfs_statx(int dfd, struct filename *filename, int flags,
              struct kstat *stat, u32 request_mask)
 {
        struct path path;
-       unsigned lookup_flags = 0;
+       unsigned int lookup_flags = getname_statx_lookup_flags(flags);
        int error;
 
        if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH |
                      AT_STATX_SYNC_TYPE))
                return -EINVAL;
 
-       if (!(flags & AT_SYMLINK_NOFOLLOW))
-               lookup_flags |= LOOKUP_FOLLOW;
-       if (!(flags & AT_NO_AUTOMOUNT))
-               lookup_flags |= LOOKUP_AUTOMOUNT;
-       if (flags & AT_EMPTY_PATH)
-               lookup_flags |= LOOKUP_EMPTY;
-
 retry:
-       error = user_path_at(dfd, filename, lookup_flags, &path);
+       error = filename_lookup(dfd, filename, lookup_flags, &path, NULL);
        if (error)
                goto out;
 
 int vfs_fstatat(int dfd, const char __user *filename,
                              struct kstat *stat, int flags)
 {
-       return vfs_statx(dfd, filename, flags | AT_NO_AUTOMOUNT,
-                        stat, STATX_BASIC_STATS);
+       int ret;
+       int statx_flags = flags | AT_NO_AUTOMOUNT;
+       struct filename *name;
+
+       name = getname_flags(filename, getname_statx_lookup_flags(statx_flags), NULL);
+       ret = vfs_statx(dfd, name, statx_flags, stat, STATX_BASIC_STATS);
+       putname(name);
+
+       return ret;
 }
 
 #ifdef __ARCH_WANT_OLD_STAT
        return copy_to_user(buffer, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 }
 
-int do_statx(int dfd, const char __user *filename, unsigned flags,
+int do_statx(int dfd, struct filename *filename, unsigned int flags,
             unsigned int mask, struct statx __user *buffer)
 {
        struct kstat stat;
                unsigned int, mask,
                struct statx __user *, buffer)
 {
-       return do_statx(dfd, filename, flags, mask, buffer);
+       int ret;
+       struct filename *name;
+
+       name = getname_flags(filename, getname_statx_lookup_flags(flags), NULL);
+       ret = do_statx(dfd, name, flags, mask, buffer);
+       putname(name);
+
+       return ret;
 }
 
 #ifdef CONFIG_COMPAT