Skip to content

Commit f4e8d80

Browse files
committed
Merge tag 'vfs-6.10.rw' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs rw iterator updates from Christian Brauner: "The core fs signalfd, userfaultfd, and timerfd subsystems did still use f_op->read() instead of f_op->read_iter(). Convert them over since we should aim to get rid of f_op->read() at some point. Aside from that io_uring and others want to mark files as FMODE_NOWAIT so it can make use of per-IO nonblocking hints to enable more efficient IO. Converting those users to f_op->read_iter() allows them to be marked with FMODE_NOWAIT" * tag 'vfs-6.10.rw' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: signalfd: convert to ->read_iter() userfaultfd: convert to ->read_iter() timerfd: convert to ->read_iter() new helper: copy_to_iter_full()
2 parents ef31ea6 + 3a93dae commit f4e8d80

File tree

5 files changed

+93
-50
lines changed

5 files changed

+93
-50
lines changed

fs/signalfd.c

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,7 @@ static __poll_t signalfd_poll(struct file *file, poll_table *wait)
6868
/*
6969
* Copied from copy_siginfo_to_user() in kernel/signal.c
7070
*/
71-
static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
72-
kernel_siginfo_t const *kinfo)
71+
static int signalfd_copyinfo(struct iov_iter *to, kernel_siginfo_t const *kinfo)
7372
{
7473
struct signalfd_siginfo new;
7574

@@ -146,10 +145,10 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
146145
break;
147146
}
148147

149-
if (copy_to_user(uinfo, &new, sizeof(struct signalfd_siginfo)))
148+
if (!copy_to_iter_full(&new, sizeof(struct signalfd_siginfo), to))
150149
return -EFAULT;
151150

152-
return sizeof(*uinfo);
151+
return sizeof(struct signalfd_siginfo);
153152
}
154153

155154
static ssize_t signalfd_dequeue(struct signalfd_ctx *ctx, kernel_siginfo_t *info,
@@ -199,28 +198,27 @@ static ssize_t signalfd_dequeue(struct signalfd_ctx *ctx, kernel_siginfo_t *info
199198
* error code. The "count" parameter must be at least the size of a
200199
* "struct signalfd_siginfo".
201200
*/
202-
static ssize_t signalfd_read(struct file *file, char __user *buf, size_t count,
203-
loff_t *ppos)
201+
static ssize_t signalfd_read_iter(struct kiocb *iocb, struct iov_iter *to)
204202
{
203+
struct file *file = iocb->ki_filp;
205204
struct signalfd_ctx *ctx = file->private_data;
206-
struct signalfd_siginfo __user *siginfo;
207-
int nonblock = file->f_flags & O_NONBLOCK;
205+
size_t count = iov_iter_count(to);
208206
ssize_t ret, total = 0;
209207
kernel_siginfo_t info;
208+
bool nonblock;
210209

211210
count /= sizeof(struct signalfd_siginfo);
212211
if (!count)
213212
return -EINVAL;
214213

215-
siginfo = (struct signalfd_siginfo __user *) buf;
214+
nonblock = file->f_flags & O_NONBLOCK || iocb->ki_flags & IOCB_NOWAIT;
216215
do {
217216
ret = signalfd_dequeue(ctx, &info, nonblock);
218217
if (unlikely(ret <= 0))
219218
break;
220-
ret = signalfd_copyinfo(siginfo, &info);
219+
ret = signalfd_copyinfo(to, &info);
221220
if (ret < 0)
222221
break;
223-
siginfo++;
224222
total += ret;
225223
nonblock = 1;
226224
} while (--count);
@@ -246,7 +244,7 @@ static const struct file_operations signalfd_fops = {
246244
#endif
247245
.release = signalfd_release,
248246
.poll = signalfd_poll,
249-
.read = signalfd_read,
247+
.read_iter = signalfd_read_iter,
250248
.llseek = noop_llseek,
251249
};
252250

@@ -265,20 +263,34 @@ static int do_signalfd4(int ufd, sigset_t *mask, int flags)
265263
signotset(mask);
266264

267265
if (ufd == -1) {
266+
struct file *file;
267+
268268
ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
269269
if (!ctx)
270270
return -ENOMEM;
271271

272272
ctx->sigmask = *mask;
273273

274+
ufd = get_unused_fd_flags(flags & O_CLOEXEC);
275+
if (ufd < 0) {
276+
kfree(ctx);
277+
return ufd;
278+
}
279+
280+
file = anon_inode_getfile("[signalfd]", &signalfd_fops, ctx,
281+
O_RDWR | (flags & O_NONBLOCK));
282+
if (IS_ERR(file)) {
283+
put_unused_fd(ufd);
284+
kfree(ctx);
285+
return ufd;
286+
}
287+
file->f_mode |= FMODE_NOWAIT;
288+
274289
/*
275290
* When we call this, the initialization must be complete, since
276291
* anon_inode_getfd() will install the fd.
277292
*/
278-
ufd = anon_inode_getfd("[signalfd]", &signalfd_fops, ctx,
279-
O_RDWR | (flags & (O_CLOEXEC | O_NONBLOCK)));
280-
if (ufd < 0)
281-
kfree(ctx);
293+
fd_install(ufd, file);
282294
} else {
283295
struct fd f = fdget(ufd);
284296
if (!f.file)

fs/timerfd.c

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -262,17 +262,18 @@ static __poll_t timerfd_poll(struct file *file, poll_table *wait)
262262
return events;
263263
}
264264

265-
static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count,
266-
loff_t *ppos)
265+
static ssize_t timerfd_read_iter(struct kiocb *iocb, struct iov_iter *to)
267266
{
267+
struct file *file = iocb->ki_filp;
268268
struct timerfd_ctx *ctx = file->private_data;
269269
ssize_t res;
270270
u64 ticks = 0;
271271

272-
if (count < sizeof(ticks))
272+
if (iov_iter_count(to) < sizeof(ticks))
273273
return -EINVAL;
274+
274275
spin_lock_irq(&ctx->wqh.lock);
275-
if (file->f_flags & O_NONBLOCK)
276+
if (file->f_flags & O_NONBLOCK || iocb->ki_flags & IOCB_NOWAIT)
276277
res = -EAGAIN;
277278
else
278279
res = wait_event_interruptible_locked_irq(ctx->wqh, ctx->ticks);
@@ -312,8 +313,11 @@ static ssize_t timerfd_read(struct file *file, char __user *buf, size_t count,
312313
ctx->ticks = 0;
313314
}
314315
spin_unlock_irq(&ctx->wqh.lock);
315-
if (ticks)
316-
res = put_user(ticks, (u64 __user *) buf) ? -EFAULT: sizeof(ticks);
316+
if (ticks) {
317+
res = copy_to_iter(&ticks, sizeof(ticks), to);
318+
if (!res)
319+
res = -EFAULT;
320+
}
317321
return res;
318322
}
319323

@@ -384,7 +388,7 @@ static long timerfd_ioctl(struct file *file, unsigned int cmd, unsigned long arg
384388
static const struct file_operations timerfd_fops = {
385389
.release = timerfd_release,
386390
.poll = timerfd_poll,
387-
.read = timerfd_read,
391+
.read_iter = timerfd_read_iter,
388392
.llseek = noop_llseek,
389393
.show_fdinfo = timerfd_show,
390394
.unlocked_ioctl = timerfd_ioctl,
@@ -407,6 +411,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
407411
{
408412
int ufd;
409413
struct timerfd_ctx *ctx;
414+
struct file *file;
410415

411416
/* Check the TFD_* constants for consistency. */
412417
BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC);
@@ -443,11 +448,22 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags)
443448

444449
ctx->moffs = ktime_mono_to_real(0);
445450

446-
ufd = anon_inode_getfd("[timerfd]", &timerfd_fops, ctx,
447-
O_RDWR | (flags & TFD_SHARED_FCNTL_FLAGS));
448-
if (ufd < 0)
451+
ufd = get_unused_fd_flags(flags & TFD_SHARED_FCNTL_FLAGS);
452+
if (ufd < 0) {
453+
kfree(ctx);
454+
return ufd;
455+
}
456+
457+
file = anon_inode_getfile("[timerfd]", &timerfd_fops, ctx,
458+
O_RDWR | (flags & TFD_SHARED_FCNTL_FLAGS));
459+
if (IS_ERR(file)) {
460+
put_unused_fd(ufd);
449461
kfree(ctx);
462+
return PTR_ERR(file);
463+
}
450464

465+
file->f_mode |= FMODE_NOWAIT;
466+
fd_install(ufd, file);
451467
return ufd;
452468
}
453469

fs/userfaultfd.c

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <linux/hugetlb.h>
3232
#include <linux/swapops.h>
3333
#include <linux/miscdevice.h>
34+
#include <linux/uio.h>
3435

3536
static int sysctl_unprivileged_userfaultfd __read_mostly;
3637

@@ -282,7 +283,7 @@ static inline bool userfaultfd_huge_must_wait(struct userfaultfd_ctx *ctx,
282283
/*
283284
* Verify the pagetables are still not ok after having reigstered into
284285
* the fault_pending_wqh to avoid userland having to UFFDIO_WAKE any
285-
* userfault that has already been resolved, if userfaultfd_read and
286+
* userfault that has already been resolved, if userfaultfd_read_iter and
286287
* UFFDIO_COPY|ZEROPAGE are being run simultaneously on two different
287288
* threads.
288289
*/
@@ -1181,34 +1182,34 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,
11811182
return ret;
11821183
}
11831184

1184-
static ssize_t userfaultfd_read(struct file *file, char __user *buf,
1185-
size_t count, loff_t *ppos)
1185+
static ssize_t userfaultfd_read_iter(struct kiocb *iocb, struct iov_iter *to)
11861186
{
1187+
struct file *file = iocb->ki_filp;
11871188
struct userfaultfd_ctx *ctx = file->private_data;
11881189
ssize_t _ret, ret = 0;
11891190
struct uffd_msg msg;
1190-
int no_wait = file->f_flags & O_NONBLOCK;
11911191
struct inode *inode = file_inode(file);
1192+
bool no_wait;
11921193

11931194
if (!userfaultfd_is_initialized(ctx))
11941195
return -EINVAL;
11951196

1197+
no_wait = file->f_flags & O_NONBLOCK || iocb->ki_flags & IOCB_NOWAIT;
11961198
for (;;) {
1197-
if (count < sizeof(msg))
1199+
if (iov_iter_count(to) < sizeof(msg))
11981200
return ret ? ret : -EINVAL;
11991201
_ret = userfaultfd_ctx_read(ctx, no_wait, &msg, inode);
12001202
if (_ret < 0)
12011203
return ret ? ret : _ret;
1202-
if (copy_to_user((__u64 __user *) buf, &msg, sizeof(msg)))
1204+
_ret = !copy_to_iter_full(&msg, sizeof(msg), to);
1205+
if (_ret)
12031206
return ret ? ret : -EFAULT;
12041207
ret += sizeof(msg);
1205-
buf += sizeof(msg);
1206-
count -= sizeof(msg);
12071208
/*
12081209
* Allow to read more than one fault at time but only
12091210
* block if waiting for the very first one.
12101211
*/
1211-
no_wait = O_NONBLOCK;
1212+
no_wait = true;
12121213
}
12131214
}
12141215

@@ -2176,7 +2177,7 @@ static const struct file_operations userfaultfd_fops = {
21762177
#endif
21772178
.release = userfaultfd_release,
21782179
.poll = userfaultfd_poll,
2179-
.read = userfaultfd_read,
2180+
.read_iter = userfaultfd_read_iter,
21802181
.unlocked_ioctl = userfaultfd_ioctl,
21812182
.compat_ioctl = compat_ptr_ioctl,
21822183
.llseek = noop_llseek,
@@ -2196,6 +2197,7 @@ static void init_once_userfaultfd_ctx(void *mem)
21962197
static int new_userfaultfd(int flags)
21972198
{
21982199
struct userfaultfd_ctx *ctx;
2200+
struct file *file;
21992201
int fd;
22002202

22012203
BUG_ON(!current->mm);
@@ -2219,16 +2221,26 @@ static int new_userfaultfd(int flags)
22192221
init_rwsem(&ctx->map_changing_lock);
22202222
atomic_set(&ctx->mmap_changing, 0);
22212223
ctx->mm = current->mm;
2222-
/* prevent the mm struct to be freed */
2223-
mmgrab(ctx->mm);
2224+
2225+
fd = get_unused_fd_flags(flags & UFFD_SHARED_FCNTL_FLAGS);
2226+
if (fd < 0)
2227+
goto err_out;
22242228

22252229
/* Create a new inode so that the LSM can block the creation. */
2226-
fd = anon_inode_create_getfd("[userfaultfd]", &userfaultfd_fops, ctx,
2230+
file = anon_inode_create_getfile("[userfaultfd]", &userfaultfd_fops, ctx,
22272231
O_RDONLY | (flags & UFFD_SHARED_FCNTL_FLAGS), NULL);
2228-
if (fd < 0) {
2229-
mmdrop(ctx->mm);
2230-
kmem_cache_free(userfaultfd_ctx_cachep, ctx);
2232+
if (IS_ERR(file)) {
2233+
put_unused_fd(fd);
2234+
fd = PTR_ERR(file);
2235+
goto err_out;
22312236
}
2237+
/* prevent the mm struct to be freed */
2238+
mmgrab(ctx->mm);
2239+
file->f_mode |= FMODE_NOWAIT;
2240+
fd_install(fd, file);
2241+
return fd;
2242+
err_out:
2243+
kmem_cache_free(userfaultfd_ctx_cachep, ctx);
22322244
return fd;
22332245
}
22342246

include/linux/uio.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,16 @@ size_t copy_from_iter(void *addr, size_t bytes, struct iov_iter *i)
205205
return 0;
206206
}
207207

208+
static __always_inline __must_check
209+
bool copy_to_iter_full(const void *addr, size_t bytes, struct iov_iter *i)
210+
{
211+
size_t copied = copy_to_iter(addr, bytes, i);
212+
if (likely(copied == bytes))
213+
return true;
214+
iov_iter_revert(i, copied);
215+
return false;
216+
}
217+
208218
static __always_inline __must_check
209219
bool copy_from_iter_full(void *addr, size_t bytes, struct iov_iter *i)
210220
{

include/net/udp.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -379,14 +379,7 @@ static inline bool udp_skb_is_linear(struct sk_buff *skb)
379379
static inline int copy_linear_skb(struct sk_buff *skb, int len, int off,
380380
struct iov_iter *to)
381381
{
382-
int n;
383-
384-
n = copy_to_iter(skb->data + off, len, to);
385-
if (n == len)
386-
return 0;
387-
388-
iov_iter_revert(to, n);
389-
return -EFAULT;
382+
return copy_to_iter_full(skb->data + off, len, to) ? 0 : -EFAULT;
390383
}
391384

392385
/*

0 commit comments

Comments
 (0)