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
184/*184/*
185 * fs/stat.c:185 * fs/stat.c:
186 */186 */
187int do_statx(int dfd, const char __user *filename, unsigned flags,187
188int getname_statx_lookup_flags(int flags);
189int do_statx(int dfd, struct filename *filename, unsigned int flags,
188 unsigned int mask, struct statx __user *buffer);190 unsigned int mask, struct statx __user *buffer);
189 191
190/*192/*
fs/io_uring.c+20−2
@@ -675,7 +675,7 @@ struct io_statx { · 674 unmodified lines
675 int dfd;675 int dfd;
676 unsigned int mask;676 unsigned int mask;
677 unsigned int flags;677 unsigned int flags;
678 const char __user *filename;678 struct filename *filename;
679 struct statx __user *buffer;679 struct statx __user *buffer;
680};680};
681 681
@@ -5000,6 +5000,8 @@ static int io_fadvise(struct io_kiocb *req, unsigned int issue_flags) · 4318 unmodified lines
5000 5000
5001static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)5001static int io_statx_prep(struct io_kiocb *req, const struct io_uring_sqe *sqe)
5002{5002{
5003 const char __user *path;
5004
5003 if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))5005 if (unlikely(req->ctx->flags & IORING_SETUP_IOPOLL))
5004 return -EINVAL;5006 return -EINVAL;
5005 if (sqe->ioprio || sqe->buf_index || sqe->splice_fd_in)5007 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
5009 5011
5010 req->statx.dfd = READ_ONCE(sqe->fd);5012 req->statx.dfd = READ_ONCE(sqe->fd);
5011 req->statx.mask = READ_ONCE(sqe->len);5013 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));
5013 req->statx.buffer = u64_to_user_ptr(READ_ONCE(sqe->addr2));5015 req->statx.buffer = u64_to_user_ptr(READ_ONCE(sqe->addr2));
5014 req->statx.flags = READ_ONCE(sqe->statx_flags);5016 req->statx.flags = READ_ONCE(sqe->statx_flags);
5015 5017
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;
5016 return 0;5030 return 0;
5017}5031}
5018 5032
@@ -7112,6 +7126,10 @@ static void io_clean_op(struct io_kiocb *req) · 2093 unmodified lines
7112 putname(req->hardlink.oldpath);7126 putname(req->hardlink.oldpath);
7113 putname(req->hardlink.newpath);7127 putname(req->hardlink.newpath);
7114 break;7128 break;
7129 case IORING_OP_STATX:
7130 if (req->statx.filename)
7131 putname(req->statx.filename);
7132 break;
7115 }7133 }
7116 }7134 }
7117 if ((req->flags & REQ_F_POLLED) && req->apoll) {7135 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
184 return error;184 return error;
185}185}
186 186
187int 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
187/**201/**
188 * vfs_statx - Get basic and extra attributes by filename202 * vfs_statx - Get basic and extra attributes by filename
189 * @dfd: A file descriptor representing the base dir for a relative filename203 * @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
199 *213 *
200 * 0 will be returned on success, and a -ve error code if unsuccessful.214 * 0 will be returned on success, and a -ve error code if unsuccessful.
201 */215 */
202static int vfs_statx(int dfd, const char __user *filename, int flags,216static int vfs_statx(int dfd, struct filename *filename, int flags,
203 struct kstat *stat, u32 request_mask)217 struct kstat *stat, u32 request_mask)
204{218{
205 struct path path;219 struct path path;
206 unsigned lookup_flags = 0;220 unsigned int lookup_flags = getname_statx_lookup_flags(flags);
207 int error;221 int error;
208 222
209 if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH |223 if (flags & ~(AT_SYMLINK_NOFOLLOW | AT_NO_AUTOMOUNT | AT_EMPTY_PATH |
210 AT_STATX_SYNC_TYPE))224 AT_STATX_SYNC_TYPE))
211 return -EINVAL;225 return -EINVAL;
212 226
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
220retry:227retry:
221 error = user_path_at(dfd, filename, lookup_flags, &path);228 error = filename_lookup(dfd, filename, lookup_flags, &path, NULL);
222 if (error)229 if (error)
223 goto out;230 goto out;
224 231
@@ -240,8 +247,15 @@ out: · 15 unmodified lines
240int vfs_fstatat(int dfd, const char __user *filename,247int vfs_fstatat(int dfd, const char __user *filename,
241 struct kstat *stat, int flags)248 struct kstat *stat, int flags)
242{249{
243 return vfs_statx(dfd, filename, flags | AT_NO_AUTOMOUNT,250 int ret;
244 stat, STATX_BASIC_STATS);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;
245}259}
246 260
247#ifdef __ARCH_WANT_OLD_STAT261#ifdef __ARCH_WANT_OLD_STAT
@@ -602,7 +616,7 @@ cp_statx(const struct kstat *stat, struct statx __user *buffer) · 354 unmodified lines
602 return copy_to_user(buffer, &tmp, sizeof(tmp)) ? -EFAULT : 0;616 return copy_to_user(buffer, &tmp, sizeof(tmp)) ? -EFAULT : 0;
603}617}
604 618
605int do_statx(int dfd, const char __user *filename, unsigned flags,619int do_statx(int dfd, struct filename *filename, unsigned int flags,
606 unsigned int mask, struct statx __user *buffer)620 unsigned int mask, struct statx __user *buffer)
607{621{
608 struct kstat stat;622 struct kstat stat;
@@ -636,7 +650,14 @@ SYSCALL_DEFINE5(statx, · 27 unmodified lines
636 unsigned int, mask,650 unsigned int, mask,
637 struct statx __user *, buffer)651 struct statx __user *, buffer)
638{652{
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;
640}661}
641 662
642#ifdef CONFIG_COMPAT663#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