1eb42cebbSPavel Begunkov // SPDX-License-Identifier: GPL-2.0 2eb42cebbSPavel Begunkov 3eb42cebbSPavel Begunkov #include <linux/net.h> 4eb42cebbSPavel Begunkov #include <linux/uio.h> 5eb42cebbSPavel Begunkov #include <net/sock.h> 6eb42cebbSPavel Begunkov #include <linux/nospec.h> 7eb42cebbSPavel Begunkov 86a9ce66fSPavel Begunkov #include "rsrc.h" 96a9ce66fSPavel Begunkov 10eb4a299bSPavel Begunkov #define IO_NOTIF_SPLICE_BATCH 32 11eb4a299bSPavel Begunkov 1214b146b6SPavel Begunkov struct io_notif_data { 1314b146b6SPavel Begunkov struct file *file; 14eb42cebbSPavel Begunkov struct ubuf_info uarg; 156a9ce66fSPavel Begunkov unsigned long account_pages; 16e307e669SStefan Metzmacher bool zc_report; 17e307e669SStefan Metzmacher bool zc_used; 18e307e669SStefan Metzmacher bool zc_copied; 19eb42cebbSPavel Begunkov }; 20eb42cebbSPavel Begunkov 21b48c312bSPavel Begunkov struct io_kiocb *io_alloc_notif(struct io_ring_ctx *ctx); 22eb42cebbSPavel Begunkov 2314b146b6SPavel Begunkov static inline struct io_notif_data *io_notif_to_data(struct io_kiocb *notif) 2414b146b6SPavel Begunkov { 25f2ccb5aeSStefan Metzmacher return io_kiocb_to_cmd(notif, struct io_notif_data); 2614b146b6SPavel Begunkov } 2714b146b6SPavel Begunkov 28*bedd20bcSPavel Begunkov static inline void io_notif_flush(struct io_kiocb *notif) 29*bedd20bcSPavel Begunkov __must_hold(¬if->ctx->uring_lock) 30*bedd20bcSPavel Begunkov { 31*bedd20bcSPavel Begunkov struct io_notif_data *nd = io_notif_to_data(notif); 32*bedd20bcSPavel Begunkov 33*bedd20bcSPavel Begunkov /* drop slot's master ref */ 34*bedd20bcSPavel Begunkov if (refcount_dec_and_test(&nd->uarg.refcnt)) 35*bedd20bcSPavel Begunkov io_req_task_work_add(notif); 36*bedd20bcSPavel Begunkov } 37*bedd20bcSPavel Begunkov 3814b146b6SPavel Begunkov static inline int io_notif_account_mem(struct io_kiocb *notif, unsigned len) 396a9ce66fSPavel Begunkov { 406a9ce66fSPavel Begunkov struct io_ring_ctx *ctx = notif->ctx; 4114b146b6SPavel Begunkov struct io_notif_data *nd = io_notif_to_data(notif); 426a9ce66fSPavel Begunkov unsigned nr_pages = (len >> PAGE_SHIFT) + 2; 436a9ce66fSPavel Begunkov int ret; 446a9ce66fSPavel Begunkov 456a9ce66fSPavel Begunkov if (ctx->user) { 466a9ce66fSPavel Begunkov ret = __io_account_mem(ctx->user, nr_pages); 476a9ce66fSPavel Begunkov if (ret) 486a9ce66fSPavel Begunkov return ret; 4914b146b6SPavel Begunkov nd->account_pages += nr_pages; 506a9ce66fSPavel Begunkov } 516a9ce66fSPavel Begunkov return 0; 526a9ce66fSPavel Begunkov } 53