@@ -68,8 +68,7 @@ static __poll_t signalfd_poll(struct file *file, poll_table *wait)
68
68
/*
69
69
* Copied from copy_siginfo_to_user() in kernel/signal.c
70
70
*/
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 )
73
72
{
74
73
struct signalfd_siginfo new ;
75
74
@@ -146,10 +145,10 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
146
145
break ;
147
146
}
148
147
149
- if (copy_to_user ( uinfo , & new , sizeof (struct signalfd_siginfo )))
148
+ if (! copy_to_iter_full ( & new , sizeof (struct signalfd_siginfo ), to ))
150
149
return - EFAULT ;
151
150
152
- return sizeof (* uinfo );
151
+ return sizeof (struct signalfd_siginfo );
153
152
}
154
153
155
154
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
199
198
* error code. The "count" parameter must be at least the size of a
200
199
* "struct signalfd_siginfo".
201
200
*/
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 )
204
202
{
203
+ struct file * file = iocb -> ki_filp ;
205
204
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 );
208
206
ssize_t ret , total = 0 ;
209
207
kernel_siginfo_t info ;
208
+ bool nonblock ;
210
209
211
210
count /= sizeof (struct signalfd_siginfo );
212
211
if (!count )
213
212
return - EINVAL ;
214
213
215
- siginfo = ( struct signalfd_siginfo __user * ) buf ;
214
+ nonblock = file -> f_flags & O_NONBLOCK || iocb -> ki_flags & IOCB_NOWAIT ;
216
215
do {
217
216
ret = signalfd_dequeue (ctx , & info , nonblock );
218
217
if (unlikely (ret <= 0 ))
219
218
break ;
220
- ret = signalfd_copyinfo (siginfo , & info );
219
+ ret = signalfd_copyinfo (to , & info );
221
220
if (ret < 0 )
222
221
break ;
223
- siginfo ++ ;
224
222
total += ret ;
225
223
nonblock = 1 ;
226
224
} while (-- count );
@@ -246,7 +244,7 @@ static const struct file_operations signalfd_fops = {
246
244
#endif
247
245
.release = signalfd_release ,
248
246
.poll = signalfd_poll ,
249
- .read = signalfd_read ,
247
+ .read_iter = signalfd_read_iter ,
250
248
.llseek = noop_llseek ,
251
249
};
252
250
@@ -265,20 +263,34 @@ static int do_signalfd4(int ufd, sigset_t *mask, int flags)
265
263
signotset (mask );
266
264
267
265
if (ufd == -1 ) {
266
+ struct file * file ;
267
+
268
268
ctx = kmalloc (sizeof (* ctx ), GFP_KERNEL );
269
269
if (!ctx )
270
270
return - ENOMEM ;
271
271
272
272
ctx -> sigmask = * mask ;
273
273
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
+
274
289
/*
275
290
* When we call this, the initialization must be complete, since
276
291
* anon_inode_getfd() will install the fd.
277
292
*/
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 );
282
294
} else {
283
295
struct fd f = fdget (ufd );
284
296
if (!f .file )
0 commit comments