History

Merge tag 'for-5.18/io_uring-statx-2022-03-18' of git://git.kernel.dk/linux-block

Pull io_uring statx fixes from Jens Axboe: "On top of the main io_uring branch, this is to ensure that the filename component of statx is stable after submit. That requires a few VFS related changes" * tag 'for-5.18/io_uring-statx-2022-03-18' of git://git.kernel.dk/linux-block: io-uring: Make statx API stable

Linus Torvalds committed 4 years ago

Commit b080cee2 parents af472a9 1b6fe6e3 files · +58 −17Browse files

Unified · Split

3 files
  1. fs/internal.h +3 −1
  2. fs/io_uring.c +20 −2
  3. fs/stat.c +35 −14
fs/internal.h+3−1
@@ -184,7 +184,9 @@ int sb_init_dio_done_wq(struct super_block *sb); · 183 unmodified lines
184184 /*
185185 * fs/stat.c:
186186 */
187−int do_statx(int dfd, const char __user *filename, unsigned flags,
187+
188+int getname_statx_lookup_flags(int flags);
189+int do_statx(int dfd, struct filename *filename, unsigned int flags,
188190 unsigned int mask, struct statx __user *buffer);
189191
190192 /*
fs/io_uring.c+20−2
@@ -675,7 +675,7 @@ struct io_statx { · 674 unmodified lines
675675 int dfd;
676676 unsigned int mask;
677677 unsigned int flags;
678− const char __user *filename;
678+ struct filename *filename;
679679 struct statx __user *buffer;
680680 };
681681
@@ -5000,6 +5000,8 @@ static int io_fadvise(struct io_kiocb *req, unsigned int issue_flags) · 4318 unmodified lines
50005000
50015001 static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
50025002 {
5003+ const char __user *path;
5004+
50035005 if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
50045006 return -EINVAL;
50055007 if (sqe->ioprio || sqe->buf_index || sqe->splice_fd_in)
@@ -5009,10 +5011,22 @@ static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe) · 3 unmodified lines
50095011
50105012 req->statx.dfd = READ_ONCE(sqe->fd);
50115013 req->statx.mask = READ_ONCE(sqe->len);
5012− req->statx.filename = u64_to_user_ptr(READ_ONCE(sqe->addr));
5014+ path = u64_to_user_ptr(READ_ONCE(sqe->addr));
50135015 req->statx.buffer = u64_to_user_ptr(READ_ONCE(sqe->addr2));
50145016 req->statx.flags = READ_ONCE(sqe->statx_flags);
50155017
5018+ req->statx.filename = getname_flags(path,
5019+ getname_statx_lookup_flags(req->statx.flags),
5020+ NULL);
5021+
5022+ if (IS_ERR(req->statx.filename)) {
5023+ int ret = PTR_ERR(req->statx.filename);
5024+
5025+ req->statx.filename = NULL;
5026+ return ret;
5027+ }
5028+
5029+ req->flags |= REQ_F_NEED_CLEANUP;
50165030 return 0;
50175031 }
50185032
@@ -7112,6 +7126,10 @@ static void io_clean_op(struct io_kiocb *req) · 2093 unmodified lines
71127126 putname(req->hardlink.oldpath);
71137127 putname(req->hardlink.newpath);
71147128 break;
7129+ case IORING_OP_STATX:
7130+ if (req->statx.filename)
7131+ putname(req->statx.filename);
7132+ break;
71157133 }
71167134 }
71177135 if ((req->flags & REQ_F_POLLED) && req->apoll) {
fs/stat.c+35−14
@@ -184,6 +184,20 @@ int vfs_fstat(int fd, struct kstat *stat) · 183 unmodified lines
184184 return error;
185185 }
186186
187+int getname_statx_lookup_flags(int flags)
188+{
189+ int lookup_flags = 0;
190+
191+ if (!(flags & AT_SYMLINK_NOFOLLOW))
192+ lookup_flags |= LOOKUP_FOLLOW;
193+ if (!(flags & AT_NO_AUTOMOUNT))
194+ lookup_flags |= LOOKUP_AUTOMOUNT;
195+ if (flags & AT_EMPTY_PATH)
196+ lookup_flags |= LOOKUP_EMPTY;
197+
198+ return lookup_flags;
199+}
200+
187201 /**
188202 * vfs_statx - Get basic and extra attributes by filename
189203 * @dfd: A file descriptor representing the base dir for a relative filename
@@ -199,26 +213,19 @@ int vfs_fstat(int fd, struct kstat *stat) · 9 unmodified lines
199213 *
200214 * 0 will be returned on success, and a -ve error code if unsuccessful.
201215 */
202−static int vfs_statx(int dfd, const char __user *filename, int flags,
216+static int vfs_statx(int dfd, struct filename *filename, int flags,
203217 struct kstat *stat, u32 request_mask)
204218 {
205219 struct path path;
206− unsigned lookup_flags = 0;
220+ unsigned int lookup_flags = getname_statx_lookup_flags(flags);
207221 int error;
208222
209223 if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH |
210224 AT_STATX_SYNC_TYPE))
211225 return -EINVAL;
212226
213− if (!(flags & AT_SYMLINK_NOFOLLOW))
214− lookup_flags |= LOOKUP_FOLLOW;
215− if (!(flags & AT_NO_AUTOMOUNT))
216− lookup_flags |= LOOKUP_AUTOMOUNT;
217− if (flags & AT_EMPTY_PATH)
218− lookup_flags |= LOOKUP_EMPTY;
219−
220227 retry:
221− error = user_path_at(dfd, filename, lookup_flags, &path);
228+ error = filename_lookup(dfd, filename, lookup_flags, &path, NULL);
222229 if (error)
223230 goto out;
224231
@@ -240,8 +247,15 @@ out: · 15 unmodified lines
240247 int vfs_fstatat(int dfd, const char __user *filename,
241248 struct kstat *stat, int flags)
242249 {
243− return vfs_statx(dfd, filename, flags | AT_NO_AUTOMOUNT,
244− stat, STATX_BASIC_STATS);
250+ int ret;
251+ int statx_flags = flags | AT_NO_AUTOMOUNT;
252+ struct filename *name;
253+
254+ name = getname_flags(filename, getname_statx_lookup_flags(statx_flags), NULL);
255+ ret = vfs_statx(dfd, name, statx_flags, stat, STATX_BASIC_STATS);
256+ putname(name);
257+
258+ return ret;
245259 }
246260
247261 #ifdef __ARCH_WANT_OLD_STAT
@@ -602,7 +616,7 @@ cp_statx(const struct kstat *stat, struct statx __user *buffer) · 354 unmodified lines
602616 return copy_to_user(buffer, &tmp, sizeof(tmp)) ? -EFAULT : 0;
603617 }
604618
605−int do_statx(int dfd, const char __user *filename, unsigned flags,
619+int do_statx(int dfd, struct filename *filename, unsigned int flags,
606620 unsigned int mask, struct statx __user *buffer)
607621 {
608622 struct kstat stat;
@@ -636,7 +650,14 @@ SYSCALL_DEFINE5(statx, · 27 unmodified lines
636650 unsigned int, mask,
637651 struct statx __user *, buffer)
638652 {
639− return do_statx(dfd, filename, flags, mask, buffer);
653+ int ret;
654+ struct filename *name;
655+
656+ name = getname_flags(filename, getname_statx_lookup_flags(flags), NULL);
657+ ret = do_statx(dfd, name, flags, mask, buffer);
658+ putname(name);
659+
660+ return ret;
640661 }
641662
642663 #ifdef CONFIG_COMPAT

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t