@@ -123,10 +123,9 @@ struct io_rsrc_node *io_rsrc_node_alloc(struct io_ring_ctx *ctx, int type)
struct io_rsrc_node *node;
node = kzalloc(sizeof(*node), GFP_KERNEL);
- if (node) {
- node->type = type;
- node->refs = 1;
- }
+ if (node)
+ io_rsrc_node_init(node, type, IORING_RSRC_F_NEED_FREE);
+
return node;
}
@@ -444,6 +443,8 @@ int io_files_update(struct io_kiocb *req, unsigned int issue_flags)
void io_free_rsrc_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node)
{
+ bool need_free = node->flags & IORING_RSRC_F_NEED_FREE;
+
lockdep_assert_held(&ctx->uring_lock);
if (node->tag)
@@ -463,7 +464,8 @@ void io_free_rsrc_node(struct io_ring_ctx *ctx, struct io_rsrc_node *node)
break;
}
- kfree(node);
+ if (need_free)
+ kfree(node);
}
int io_sqe_files_unregister(struct io_ring_ctx *ctx)
@@ -10,11 +10,15 @@
enum {
IORING_RSRC_FILE = 0,
- IORING_RSRC_BUFFER = 1,
+ IORING_RSRC_BUFFER,
+ __IORING_RSRC_LAST_TYPE,
+
+ IORING_RSRC_F_NEED_FREE = 1 << 0,
};
struct io_rsrc_node {
unsigned char type;
+ unsigned char flags;
int refs;
u64 tag;
@@ -66,6 +70,15 @@ int io_register_rsrc_update(struct io_ring_ctx *ctx, void __user *arg,
int io_register_rsrc(struct io_ring_ctx *ctx, void __user *arg,
unsigned int size, unsigned int type);
+static inline void io_rsrc_node_init(struct io_rsrc_node *node, int type,
+ unsigned char flags)
+{
+ WARN_ON_ONCE(type >= __IORING_RSRC_LAST_TYPE);
+
+ node->type = type;
+ node->refs = 1;
+ node->flags = flags;
+}
static inline struct io_rsrc_node *io_rsrc_node_lookup(struct io_rsrc_data *data,
int index)
{
Now 'io_rsrc_node' is just one buffer, and it may be provided from other subsystem, such as the coming group kernel buffer. So add flag IORING_RSRC_F_NEED_FREE for external 'io_rsrc_node'. Signed-off-by: Ming Lei <ming.lei@redhat.com> --- io_uring/rsrc.c | 12 +++++++----- io_uring/rsrc.h | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 6 deletions(-)