2022-07-12 23:52:38 +03:00
// SPDX-License-Identifier: GPL-2.0
# include <linux/net.h>
# include <linux/uio.h>
# include <net/sock.h>
# include <linux/nospec.h>
2022-07-25 12:52:05 +03:00
# include "rsrc.h"
2022-07-12 23:52:39 +03:00
# define IO_NOTIF_SPLICE_BATCH 32
2022-07-12 23:52:42 +03:00
# define IORING_MAX_NOTIF_SLOTS (1U << 10)
2022-07-12 23:52:39 +03:00
2022-07-27 12:30:41 +03:00
struct io_notif_data {
struct file * file ;
2022-07-12 23:52:38 +03:00
struct ubuf_info uarg ;
2022-07-25 12:52:05 +03:00
unsigned long account_pages ;
2022-07-12 23:52:38 +03:00
} ;
struct io_notif_slot {
/*
* Current / active notifier . A slot holds only one active notifier at a
* time and keeps one reference to it . Flush releases the reference and
* lazily replaces it with a new notifier .
*/
2022-07-27 12:30:41 +03:00
struct io_kiocb * notif ;
2022-07-12 23:52:38 +03:00
/*
* Default - > user_data for this slot notifiers CQEs
*/
u64 tag ;
/*
* Notifiers of a slot live in generations , we create a new notifier
* only after flushing the previous one . Track the sequential number
* for all notifiers and copy it into notifiers ' s cqe - > cflags
*/
u32 seq ;
} ;
2022-07-12 23:52:42 +03:00
int io_notif_register ( struct io_ring_ctx * ctx ,
void __user * arg , unsigned int size ) ;
2022-07-12 23:52:38 +03:00
int io_notif_unregister ( struct io_ring_ctx * ctx ) ;
2022-07-12 23:52:47 +03:00
void io_notif_slot_flush ( struct io_notif_slot * slot ) ;
2022-07-27 12:30:41 +03:00
struct io_kiocb * io_alloc_notif ( struct io_ring_ctx * ctx ,
2022-07-12 23:52:38 +03:00
struct io_notif_slot * slot ) ;
2022-07-27 12:30:41 +03:00
static inline struct io_notif_data * io_notif_to_data ( struct io_kiocb * notif )
{
return io_kiocb_to_cmd ( notif ) ;
}
static inline struct io_kiocb * io_get_notif ( struct io_ring_ctx * ctx ,
2022-07-12 23:52:38 +03:00
struct io_notif_slot * slot )
{
if ( ! slot - > notif )
slot - > notif = io_alloc_notif ( ctx , slot ) ;
return slot - > notif ;
}
static inline struct io_notif_slot * io_get_notif_slot ( struct io_ring_ctx * ctx ,
2022-07-25 12:52:03 +03:00
unsigned idx )
2022-07-12 23:52:38 +03:00
__must_hold ( & ctx - > uring_lock )
{
if ( idx > = ctx - > nr_notif_slots )
return NULL ;
idx = array_index_nospec ( idx , ctx - > nr_notif_slots ) ;
return & ctx - > notif_slots [ idx ] ;
}
2022-07-12 23:52:47 +03:00
static inline void io_notif_slot_flush_submit ( struct io_notif_slot * slot ,
unsigned int issue_flags )
{
io_notif_slot_flush ( slot ) ;
}
2022-07-25 12:52:05 +03:00
2022-07-27 12:30:41 +03:00
static inline int io_notif_account_mem ( struct io_kiocb * notif , unsigned len )
2022-07-25 12:52:05 +03:00
{
struct io_ring_ctx * ctx = notif - > ctx ;
2022-07-27 12:30:41 +03:00
struct io_notif_data * nd = io_notif_to_data ( notif ) ;
2022-07-25 12:52:05 +03:00
unsigned nr_pages = ( len > > PAGE_SHIFT ) + 2 ;
int ret ;
if ( ctx - > user ) {
ret = __io_account_mem ( ctx - > user , nr_pages ) ;
if ( ret )
return ret ;
2022-07-27 12:30:41 +03:00
nd - > account_pages + = nr_pages ;
2022-07-25 12:52:05 +03:00
}
return 0 ;
}