23
23
#include <linux/proc_fs.h>
24
24
#include <linux/seq_file.h>
25
25
#include <linux/idr.h>
26
+ #include <linux/uio.h>
26
27
27
28
DEFINE_PER_CPU (int , eventfd_wake_count );
28
29
@@ -216,32 +217,32 @@ int eventfd_ctx_remove_wait_queue(struct eventfd_ctx *ctx, wait_queue_entry_t *w
216
217
}
217
218
EXPORT_SYMBOL_GPL (eventfd_ctx_remove_wait_queue );
218
219
219
- static ssize_t eventfd_read (struct file * file , char __user * buf , size_t count ,
220
- loff_t * ppos )
220
+ static ssize_t eventfd_read (struct kiocb * iocb , struct iov_iter * to )
221
221
{
222
+ struct file * file = iocb -> ki_filp ;
222
223
struct eventfd_ctx * ctx = file -> private_data ;
223
- ssize_t res ;
224
224
__u64 ucnt = 0 ;
225
225
DECLARE_WAITQUEUE (wait , current );
226
226
227
- if (count < sizeof (ucnt ))
227
+ if (iov_iter_count ( to ) < sizeof (ucnt ))
228
228
return - EINVAL ;
229
-
230
229
spin_lock_irq (& ctx -> wqh .lock );
231
- res = - EAGAIN ;
232
- if (ctx -> count > 0 )
233
- res = sizeof (ucnt );
234
- else if (!(file -> f_flags & O_NONBLOCK )) {
230
+ if (!ctx -> count ) {
231
+ if ((file -> f_flags & O_NONBLOCK ) ||
232
+ (iocb -> ki_flags & IOCB_NOWAIT )) {
233
+ spin_unlock_irq (& ctx -> wqh .lock );
234
+ return - EAGAIN ;
235
+ }
235
236
__add_wait_queue (& ctx -> wqh , & wait );
236
237
for (;;) {
237
238
set_current_state (TASK_INTERRUPTIBLE );
238
- if (ctx -> count > 0 ) {
239
- res = sizeof (ucnt );
239
+ if (ctx -> count )
240
240
break ;
241
- }
242
241
if (signal_pending (current )) {
243
- res = - ERESTARTSYS ;
244
- break ;
242
+ __remove_wait_queue (& ctx -> wqh , & wait );
243
+ __set_current_state (TASK_RUNNING );
244
+ spin_unlock_irq (& ctx -> wqh .lock );
245
+ return - ERESTARTSYS ;
245
246
}
246
247
spin_unlock_irq (& ctx -> wqh .lock );
247
248
schedule ();
@@ -250,17 +251,14 @@ static ssize_t eventfd_read(struct file *file, char __user *buf, size_t count,
250
251
__remove_wait_queue (& ctx -> wqh , & wait );
251
252
__set_current_state (TASK_RUNNING );
252
253
}
253
- if (likely (res > 0 )) {
254
- eventfd_ctx_do_read (ctx , & ucnt );
255
- if (waitqueue_active (& ctx -> wqh ))
256
- wake_up_locked_poll (& ctx -> wqh , EPOLLOUT );
257
- }
254
+ eventfd_ctx_do_read (ctx , & ucnt );
255
+ if (waitqueue_active (& ctx -> wqh ))
256
+ wake_up_locked_poll (& ctx -> wqh , EPOLLOUT );
258
257
spin_unlock_irq (& ctx -> wqh .lock );
259
-
260
- if (res > 0 && put_user (ucnt , (__u64 __user * )buf ))
258
+ if (unlikely (copy_to_iter (& ucnt , sizeof (ucnt ), to ) != sizeof (ucnt )))
261
259
return - EFAULT ;
262
260
263
- return res ;
261
+ return sizeof ( ucnt ) ;
264
262
}
265
263
266
264
static ssize_t eventfd_write (struct file * file , const char __user * buf , size_t count ,
@@ -329,7 +327,7 @@ static const struct file_operations eventfd_fops = {
329
327
#endif
330
328
.release = eventfd_release ,
331
329
.poll = eventfd_poll ,
332
- .read = eventfd_read ,
330
+ .read_iter = eventfd_read ,
333
331
.write = eventfd_write ,
334
332
.llseek = noop_llseek ,
335
333
};
@@ -406,6 +404,7 @@ EXPORT_SYMBOL_GPL(eventfd_ctx_fileget);
406
404
static int do_eventfd (unsigned int count , int flags )
407
405
{
408
406
struct eventfd_ctx * ctx ;
407
+ struct file * file ;
409
408
int fd ;
410
409
411
410
/* Check the EFD_* constants for consistency. */
@@ -425,11 +424,24 @@ static int do_eventfd(unsigned int count, int flags)
425
424
ctx -> flags = flags ;
426
425
ctx -> id = ida_simple_get (& eventfd_ida , 0 , 0 , GFP_KERNEL );
427
426
428
- fd = anon_inode_getfd ("[eventfd]" , & eventfd_fops , ctx ,
429
- O_RDWR | (flags & EFD_SHARED_FCNTL_FLAGS ));
427
+ flags &= EFD_SHARED_FCNTL_FLAGS ;
428
+ flags |= O_RDWR ;
429
+ fd = get_unused_fd_flags (flags );
430
430
if (fd < 0 )
431
- eventfd_free_ctx (ctx );
431
+ goto err ;
432
+
433
+ file = anon_inode_getfile ("[eventfd]" , & eventfd_fops , ctx , flags );
434
+ if (IS_ERR (file )) {
435
+ put_unused_fd (fd );
436
+ fd = PTR_ERR (file );
437
+ goto err ;
438
+ }
432
439
440
+ file -> f_mode |= FMODE_NOWAIT ;
441
+ fd_install (fd , file );
442
+ return fd ;
443
+ err :
444
+ eventfd_free_ctx (ctx );
433
445
return fd ;
434
446
}
435
447
0 commit comments