public inbox for [email protected]
 help / color / mirror / Atom feed
* [PATCH 0/2] two bug fixes about direct fd install
@ 2022-05-27 16:53 Xiaoguang Wang
  2022-05-27 16:53 ` [PATCH 1/2] io_uring: fix file leaks around io_fixed_fd_install() Xiaoguang Wang
  2022-05-27 16:53 ` [PATCH 2/2] io_uring: defer alloc_hint update to io_file_bitmap_set() Xiaoguang Wang
  0 siblings, 2 replies; 9+ messages in thread
From: Xiaoguang Wang @ 2022-05-27 16:53 UTC (permalink / raw)
  To: io-uring; +Cc: axboe, asml.silence

Both two patches have passed liburing test.

Xiaoguang Wang (2):
  io_uring: fix file leaks around io_fixed_fd_install()
  io_uring: defer alloc_hint update to io_file_bitmap_set()

 fs/io_uring.c | 100 ++++++++++++++++++++++++++--------------------------------
 1 file changed, 45 insertions(+), 55 deletions(-)

-- 
2.14.4.44.g2045bb6



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/2] io_uring: fix file leaks around io_fixed_fd_install()
  2022-05-27 16:53 [PATCH 0/2] two bug fixes about direct fd install Xiaoguang Wang
@ 2022-05-27 16:53 ` Xiaoguang Wang
  2022-05-27 16:53 ` [PATCH 2/2] io_uring: defer alloc_hint update to io_file_bitmap_set() Xiaoguang Wang
  1 sibling, 0 replies; 9+ messages in thread
From: Xiaoguang Wang @ 2022-05-27 16:53 UTC (permalink / raw)
  To: io-uring; +Cc: axboe, asml.silence

io_fixed_fd_install() may fail for many reasons, such as short of
free fixed file bitmap, memory allocation failures, etc. When these
errors happen, current code forgets to fput(file) correspondingly.

This patch will fix resource leaks around io_fixed_fd_install(),
meanwhile io_fixed_fd_install() and io_install_fixed_file() are
basically similar, fold them into one function.

Signed-off-by: Xiaoguang Wang <[email protected]>
---
 fs/io_uring.c | 77 ++++++++++++++++++++++++++---------------------------------
 1 file changed, 34 insertions(+), 43 deletions(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index d50bbf8de4fb..ff50e5f1753d 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -1364,8 +1364,8 @@ static void io_req_task_queue(struct io_kiocb *req);
 static void __io_submit_flush_completions(struct io_ring_ctx *ctx);
 static int io_req_prep_async(struct io_kiocb *req);
 
-static int io_install_fixed_file(struct io_kiocb *req, struct file *file,
-				 unsigned int issue_flags, u32 slot_index);
+static int io_install_fixed_file(struct io_kiocb *req, unsigned int issue_flags,
+				 struct file *file, u32 slot);
 static int io_close_fixed(struct io_kiocb *req, unsigned int issue_flags);
 
 static enum hrtimer_restart io_link_timeout_fn(struct hrtimer *timer);
@@ -5438,36 +5438,6 @@ static int io_file_bitmap_get(struct io_ring_ctx *ctx)
 	return -ENFILE;
 }
 
-static int io_fixed_fd_install(struct io_kiocb *req, unsigned int issue_flags,
-			       struct file *file, unsigned int file_slot)
-{
-	bool alloc_slot = file_slot == IORING_FILE_INDEX_ALLOC;
-	struct io_ring_ctx *ctx = req->ctx;
-	int ret;
-
-	if (alloc_slot) {
-		io_ring_submit_lock(ctx, issue_flags);
-		ret = io_file_bitmap_get(ctx);
-		if (unlikely(ret < 0)) {
-			io_ring_submit_unlock(ctx, issue_flags);
-			return ret;
-		}
-
-		file_slot = ret;
-	} else {
-		file_slot--;
-	}
-
-	ret = io_install_fixed_file(req, file, issue_flags, file_slot);
-	if (alloc_slot) {
-		io_ring_submit_unlock(ctx, issue_flags);
-		if (!ret)
-			return file_slot;
-	}
-
-	return ret;
-}
-
 static int io_openat2(struct io_kiocb *req, unsigned int issue_flags)
 {
 	struct open_flags op;
@@ -5520,11 +5490,14 @@ static int io_openat2(struct io_kiocb *req, unsigned int issue_flags)
 		file->f_flags &= ~O_NONBLOCK;
 	fsnotify_open(file);
 
-	if (!fixed)
+	if (!fixed) {
 		fd_install(ret, file);
-	else
-		ret = io_fixed_fd_install(req, issue_flags, file,
-						req->open.file_slot);
+	} else {
+		ret = io_install_fixed_file(req, issue_flags, file,
+					    req->open.file_slot);
+		if (ret < 0)
+			fput(file);
+	}
 err:
 	putname(req->open.filename);
 	req->flags &= ~REQ_F_NEED_CLEANUP;
@@ -6603,8 +6576,10 @@ static int io_accept(struct io_kiocb *req, unsigned int issue_flags)
 		fd_install(fd, file);
 		ret = fd;
 	} else {
-		ret = io_fixed_fd_install(req, issue_flags, file,
-						accept->file_slot);
+		ret = io_install_fixed_file(req, issue_flags, file,
+					    accept->file_slot);
+		if (ret < 0)
+			fput(file);
 	}
 
 	if (!(req->flags & REQ_F_APOLL_MULTISHOT)) {
@@ -6676,8 +6651,10 @@ static int io_socket(struct io_kiocb *req, unsigned int issue_flags)
 		fd_install(fd, file);
 		ret = fd;
 	} else {
-		ret = io_fixed_fd_install(req, issue_flags, file,
+		ret = io_install_fixed_file(req, issue_flags, file,
 					    sock->file_slot);
+		if (ret < 0)
+			fput(file);
 	}
 	__io_req_complete(req, issue_flags, ret, 0);
 	return 0;
@@ -10130,15 +10107,27 @@ static int io_queue_rsrc_removal(struct io_rsrc_data *data, unsigned idx,
 	return 0;
 }
 
-static int io_install_fixed_file(struct io_kiocb *req, struct file *file,
-				 unsigned int issue_flags, u32 slot_index)
+static int io_install_fixed_file(struct io_kiocb *req, unsigned int issue_flags,
+				 struct file *file, u32 slot)
 {
 	struct io_ring_ctx *ctx = req->ctx;
 	bool needs_switch = false;
 	struct io_fixed_file *file_slot;
 	int ret = -EBADF;
+	bool alloc_slot = slot == IORING_FILE_INDEX_ALLOC;
+	int slot_index;
 
 	io_ring_submit_lock(ctx, issue_flags);
+	if (alloc_slot) {
+		slot_index = io_file_bitmap_get(ctx);
+		if (unlikely(slot_index < 0)) {
+			io_ring_submit_unlock(ctx, issue_flags);
+			return slot_index;
+		}
+	} else {
+		slot_index = slot - 1;
+	}
+
 	if (file->f_op == &io_uring_fops)
 		goto err;
 	ret = -ENXIO;
@@ -10178,8 +10167,10 @@ static int io_install_fixed_file(struct io_kiocb *req, struct file *file,
 	if (needs_switch)
 		io_rsrc_node_switch(ctx, ctx->file_data);
 	io_ring_submit_unlock(ctx, issue_flags);
-	if (ret)
-		fput(file);
+	if (alloc_slot) {
+		if (!ret)
+			return slot_index;
+	}
 	return ret;
 }
 
-- 
2.14.4.44.g2045bb6



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/2] io_uring: defer alloc_hint update to io_file_bitmap_set()
  2022-05-27 16:53 [PATCH 0/2] two bug fixes about direct fd install Xiaoguang Wang
  2022-05-27 16:53 ` [PATCH 1/2] io_uring: fix file leaks around io_fixed_fd_install() Xiaoguang Wang
@ 2022-05-27 16:53 ` Xiaoguang Wang
  2022-05-27 17:09   ` Jens Axboe
  1 sibling, 1 reply; 9+ messages in thread
From: Xiaoguang Wang @ 2022-05-27 16:53 UTC (permalink / raw)
  To: io-uring; +Cc: axboe, asml.silence

io_file_bitmap_get() returns a free bitmap slot, but if it isn't
used later, such as io_queue_rsrc_removal() returns error, in this
case, we should not update alloc_hint at all, which still should
be considered as a valid candidate for next io_file_bitmap_get()
calls.

To fix this issue, only update alloc_hint in io_file_bitmap_set().

Signed-off-by: Xiaoguang Wang <[email protected]>
---
 fs/io_uring.c | 23 +++++++++++------------
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index ff50e5f1753d..811007e055c6 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -5419,15 +5419,11 @@ static int io_file_bitmap_get(struct io_ring_ctx *ctx)
 	unsigned long nr = ctx->nr_user_files;
 	int ret;
 
-	if (table->alloc_hint >= nr)
-		table->alloc_hint = 0;
-
 	do {
 		ret = find_next_zero_bit(table->bitmap, nr, table->alloc_hint);
-		if (ret != nr) {
-			table->alloc_hint = ret + 1;
+		if (ret != nr)
 			return ret;
-		}
+
 		if (!table->alloc_hint)
 			break;
 
@@ -9650,12 +9646,15 @@ static void io_free_file_tables(struct io_file_table *table)
 	table->bitmap = NULL;
 }
 
-static inline void io_file_bitmap_set(struct io_file_table *table, int bit)
+static inline void io_file_bitmap_set(struct io_ring_ctx *ctx, int bit)
 {
+	struct io_file_table *table = &ctx->file_table;
+
 	WARN_ON_ONCE(test_bit(bit, table->bitmap));
 	__set_bit(bit, table->bitmap);
-	if (bit == table->alloc_hint)
-		table->alloc_hint++;
+	table->alloc_hint = bit + 1;
+	if (table->alloc_hint >= ctx->nr_user_files)
+		table->alloc_hint = 0;
 }
 
 static inline void io_file_bitmap_clear(struct io_file_table *table, int bit)
@@ -10080,7 +10079,7 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg,
 		}
 		file_slot = io_fixed_file_slot(&ctx->file_table, i);
 		io_fixed_file_set(file_slot, file);
-		io_file_bitmap_set(&ctx->file_table, i);
+		io_file_bitmap_set(ctx, i);
 	}
 
 	io_rsrc_node_switch(ctx, NULL);
@@ -10161,7 +10160,7 @@ static int io_install_fixed_file(struct io_kiocb *req, unsigned int issue_flags,
 	if (!ret) {
 		*io_get_tag_slot(ctx->file_data, slot_index) = 0;
 		io_fixed_file_set(file_slot, file);
-		io_file_bitmap_set(&ctx->file_table, slot_index);
+		io_file_bitmap_set(ctx, slot_index);
 	}
 err:
 	if (needs_switch)
@@ -10284,7 +10283,7 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx,
 			}
 			*io_get_tag_slot(data, i) = tag;
 			io_fixed_file_set(file_slot, file);
-			io_file_bitmap_set(&ctx->file_table, i);
+			io_file_bitmap_set(ctx, i);
 		}
 	}
 
-- 
2.14.4.44.g2045bb6



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH 2/2] io_uring: defer alloc_hint update to io_file_bitmap_set()
  2022-05-27 16:53 ` [PATCH 2/2] io_uring: defer alloc_hint update to io_file_bitmap_set() Xiaoguang Wang
@ 2022-05-27 17:09   ` Jens Axboe
  2022-05-27 17:39     ` [PATCH v2] " Xiaoguang Wang
  0 siblings, 1 reply; 9+ messages in thread
From: Jens Axboe @ 2022-05-27 17:09 UTC (permalink / raw)
  To: Xiaoguang Wang, io-uring; +Cc: asml.silence

On 5/27/22 10:53 AM, Xiaoguang Wang wrote:
> @@ -9650,12 +9646,15 @@ static void io_free_file_tables(struct io_file_table *table)
>  	table->bitmap = NULL;
>  }
>  
> -static inline void io_file_bitmap_set(struct io_file_table *table, int bit)
> +static inline void io_file_bitmap_set(struct io_ring_ctx *ctx, int bit)
>  {
> +	struct io_file_table *table = &ctx->file_table;
> +
>  	WARN_ON_ONCE(test_bit(bit, table->bitmap));
>  	__set_bit(bit, table->bitmap);
> -	if (bit == table->alloc_hint)
> -		table->alloc_hint++;
> +	table->alloc_hint = bit + 1;
> +	if (table->alloc_hint >= ctx->nr_user_files)
> +		table->alloc_hint = 0;
>  }

This branch isn't needed, we'll reset it when failing to get one anyway.
Much better than adding a branch to the fast path.

-- 
Jens Axboe



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2] io_uring: defer alloc_hint update to io_file_bitmap_set()
  2022-05-27 17:09   ` Jens Axboe
@ 2022-05-27 17:39     ` Xiaoguang Wang
  2022-05-27 18:03       ` Jens Axboe
  0 siblings, 1 reply; 9+ messages in thread
From: Xiaoguang Wang @ 2022-05-27 17:39 UTC (permalink / raw)
  To: io-uring; +Cc: axboe, asml.silence

io_file_bitmap_get() returns a free bitmap slot, but if it isn't
used later, such as io_queue_rsrc_removal() returns error, in this
case, we should not update alloc_hint at all, which still should
be considered as a valid candidate for next io_file_bitmap_get()
calls.

To fix this issue, only update alloc_hint in io_file_bitmap_set().

Signed-off-by: Xiaoguang Wang <[email protected]>
---
V2:
  Delete unnecessary check against to alloc_hint.
---
 fs/io_uring.c | 21 +++++++++------------
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index ff50e5f1753d..212d6ae88114 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -5419,15 +5419,11 @@ static int io_file_bitmap_get(struct io_ring_ctx *ctx)
 	unsigned long nr = ctx->nr_user_files;
 	int ret;
 
-	if (table->alloc_hint >= nr)
-		table->alloc_hint = 0;
-
 	do {
 		ret = find_next_zero_bit(table->bitmap, nr, table->alloc_hint);
-		if (ret != nr) {
-			table->alloc_hint = ret + 1;
+		if (ret != nr)
 			return ret;
-		}
+
 		if (!table->alloc_hint)
 			break;
 
@@ -9650,12 +9646,13 @@ static void io_free_file_tables(struct io_file_table *table)
 	table->bitmap = NULL;
 }
 
-static inline void io_file_bitmap_set(struct io_file_table *table, int bit)
+static inline void io_file_bitmap_set(struct io_ring_ctx *ctx, int bit)
 {
+	struct io_file_table *table = &ctx->file_table;
+
 	WARN_ON_ONCE(test_bit(bit, table->bitmap));
 	__set_bit(bit, table->bitmap);
-	if (bit == table->alloc_hint)
-		table->alloc_hint++;
+	table->alloc_hint = bit + 1;
 }
 
 static inline void io_file_bitmap_clear(struct io_file_table *table, int bit)
@@ -10080,7 +10077,7 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg,
 		}
 		file_slot = io_fixed_file_slot(&ctx->file_table, i);
 		io_fixed_file_set(file_slot, file);
-		io_file_bitmap_set(&ctx->file_table, i);
+		io_file_bitmap_set(ctx, i);
 	}
 
 	io_rsrc_node_switch(ctx, NULL);
@@ -10161,7 +10158,7 @@ static int io_install_fixed_file(struct io_kiocb *req, unsigned int issue_flags,
 	if (!ret) {
 		*io_get_tag_slot(ctx->file_data, slot_index) = 0;
 		io_fixed_file_set(file_slot, file);
-		io_file_bitmap_set(&ctx->file_table, slot_index);
+		io_file_bitmap_set(ctx, slot_index);
 	}
 err:
 	if (needs_switch)
@@ -10284,7 +10281,7 @@ static int __io_sqe_files_update(struct io_ring_ctx *ctx,
 			}
 			*io_get_tag_slot(data, i) = tag;
 			io_fixed_file_set(file_slot, file);
-			io_file_bitmap_set(&ctx->file_table, i);
+			io_file_bitmap_set(ctx, i);
 		}
 	}
 
-- 
2.14.4.44.g2045bb6



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] io_uring: defer alloc_hint update to io_file_bitmap_set()
  2022-05-27 17:39     ` [PATCH v2] " Xiaoguang Wang
@ 2022-05-27 18:03       ` Jens Axboe
  2022-05-28  1:45         ` Xiaoguang Wang
  2022-05-28  1:51         ` [PATCH v3] " Xiaoguang Wang
  0 siblings, 2 replies; 9+ messages in thread
From: Jens Axboe @ 2022-05-27 18:03 UTC (permalink / raw)
  To: Xiaoguang Wang, io-uring; +Cc: asml.silence

On 5/27/22 11:39 AM, Xiaoguang Wang wrote:
> io_file_bitmap_get() returns a free bitmap slot, but if it isn't
> used later, such as io_queue_rsrc_removal() returns error, in this
> case, we should not update alloc_hint at all, which still should
> be considered as a valid candidate for next io_file_bitmap_get()
> calls.
> 
> To fix this issue, only update alloc_hint in io_file_bitmap_set().

Why are you changing the io_file_bitmap_set() type?


-- 
Jens Axboe



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH v2] io_uring: defer alloc_hint update to io_file_bitmap_set()
  2022-05-27 18:03       ` Jens Axboe
@ 2022-05-28  1:45         ` Xiaoguang Wang
  2022-05-28  1:51         ` [PATCH v3] " Xiaoguang Wang
  1 sibling, 0 replies; 9+ messages in thread
From: Xiaoguang Wang @ 2022-05-28  1:45 UTC (permalink / raw)
  To: Jens Axboe, io-uring; +Cc: asml.silence

hi,

> On 5/27/22 11:39 AM, Xiaoguang Wang wrote:
>> io_file_bitmap_get() returns a free bitmap slot, but if it isn't
>> used later, such as io_queue_rsrc_removal() returns error, in this
>> case, we should not update alloc_hint at all, which still should
>> be considered as a valid candidate for next io_file_bitmap_get()
>> calls.
>>
>> To fix this issue, only update alloc_hint in io_file_bitmap_set().
> Why are you changing the io_file_bitmap_set() type?
Oh sorry, it was introduced in patch v1 to check whether alloc_hint
is greater than nr_user_files, but forgot to revert it in patch v2.

Regards,
Xiaoguang Wang
>
>



^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v3] io_uring: defer alloc_hint update to io_file_bitmap_set()
  2022-05-27 18:03       ` Jens Axboe
  2022-05-28  1:45         ` Xiaoguang Wang
@ 2022-05-28  1:51         ` Xiaoguang Wang
  2022-05-28  2:14           ` Jens Axboe
  1 sibling, 1 reply; 9+ messages in thread
From: Xiaoguang Wang @ 2022-05-28  1:51 UTC (permalink / raw)
  To: io-uring; +Cc: axboe, asml.silence

io_file_bitmap_get() returns a free bitmap slot, but if it isn't
used later, such as io_queue_rsrc_removal() returns error, in this
case, we should not update alloc_hint at all, which still should
be considered as a valid candidate for next io_file_bitmap_get()
calls.

To fix this issue, only update alloc_hint in io_file_bitmap_set().

Signed-off-by: Xiaoguang Wang <[email protected]>
---
v3:
  Revert io_file_bitmap_set() type changes.
V2:
  Delete unnecessary check against to alloc_hint.
---
 fs/io_uring.c | 11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/fs/io_uring.c b/fs/io_uring.c
index ff50e5f1753d..8f476e8760bf 100644
--- a/fs/io_uring.c
+++ b/fs/io_uring.c
@@ -5419,15 +5419,11 @@ static int io_file_bitmap_get(struct io_ring_ctx *ctx)
 	unsigned long nr = ctx->nr_user_files;
 	int ret;
 
-	if (table->alloc_hint >= nr)
-		table->alloc_hint = 0;
-
 	do {
 		ret = find_next_zero_bit(table->bitmap, nr, table->alloc_hint);
-		if (ret != nr) {
-			table->alloc_hint = ret + 1;
+		if (ret != nr)
 			return ret;
-		}
+
 		if (!table->alloc_hint)
 			break;
 
@@ -9654,8 +9650,7 @@ static inline void io_file_bitmap_set(struct io_file_table *table, int bit)
 {
 	WARN_ON_ONCE(test_bit(bit, table->bitmap));
 	__set_bit(bit, table->bitmap);
-	if (bit == table->alloc_hint)
-		table->alloc_hint++;
+	table->alloc_hint = bit + 1;
 }
 
 static inline void io_file_bitmap_clear(struct io_file_table *table, int bit)
-- 
2.14.4.44.g2045bb6



^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH v3] io_uring: defer alloc_hint update to io_file_bitmap_set()
  2022-05-28  1:51         ` [PATCH v3] " Xiaoguang Wang
@ 2022-05-28  2:14           ` Jens Axboe
  0 siblings, 0 replies; 9+ messages in thread
From: Jens Axboe @ 2022-05-28  2:14 UTC (permalink / raw)
  To: xiaoguang.wang, io-uring; +Cc: asml.silence

On Sat, 28 May 2022 09:51:09 +0800, Xiaoguang Wang wrote:
> io_file_bitmap_get() returns a free bitmap slot, but if it isn't
> used later, such as io_queue_rsrc_removal() returns error, in this
> case, we should not update alloc_hint at all, which still should
> be considered as a valid candidate for next io_file_bitmap_get()
> calls.
> 
> To fix this issue, only update alloc_hint in io_file_bitmap_set().
> 
> [...]

Applied, thanks!

[1/1] io_uring: defer alloc_hint update to io_file_bitmap_set()
      commit: e2d547c6e3caa4b6278bcb30686e1faf6777b3f6

Best regards,
-- 
Jens Axboe




^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2022-05-28  2:14 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-05-27 16:53 [PATCH 0/2] two bug fixes about direct fd install Xiaoguang Wang
2022-05-27 16:53 ` [PATCH 1/2] io_uring: fix file leaks around io_fixed_fd_install() Xiaoguang Wang
2022-05-27 16:53 ` [PATCH 2/2] io_uring: defer alloc_hint update to io_file_bitmap_set() Xiaoguang Wang
2022-05-27 17:09   ` Jens Axboe
2022-05-27 17:39     ` [PATCH v2] " Xiaoguang Wang
2022-05-27 18:03       ` Jens Axboe
2022-05-28  1:45         ` Xiaoguang Wang
2022-05-28  1:51         ` [PATCH v3] " Xiaoguang Wang
2022-05-28  2:14           ` Jens Axboe

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox