提交 29d9ee6a 编写于 作者: J Jens Axboe 提交者: Shile Zhang

io_uring: allow sparse fixed file sets

commit 08a451739a9b5783f67de51e84cb6d9559bb9dc4 upstream.

This is in preparation for allowing updates to fixed file sets without
requiring a full unregister+register.
Reviewed-by: NJeff Moyer <jmoyer@redhat.com>
Signed-off-by: NJens Axboe <axboe@kernel.dk>
Signed-off-by: NJoseph Qi <joseph.qi@linux.alibaba.com>
Reviewed-by: NXiaoguang Wang <xiaoguang.wang@linux.alibaba.com>
上级 183e3851
...@@ -2378,6 +2378,8 @@ static int io_req_set_file(struct io_ring_ctx *ctx, const struct sqe_submit *s, ...@@ -2378,6 +2378,8 @@ static int io_req_set_file(struct io_ring_ctx *ctx, const struct sqe_submit *s,
if (unlikely(!ctx->user_files || if (unlikely(!ctx->user_files ||
(unsigned) fd >= ctx->nr_user_files)) (unsigned) fd >= ctx->nr_user_files))
return -EBADF; return -EBADF;
if (!ctx->user_files[fd])
return -EBADF;
req->file = ctx->user_files[fd]; req->file = ctx->user_files[fd];
req->flags |= REQ_F_FIXED_FILE; req->flags |= REQ_F_FIXED_FILE;
} else { } else {
...@@ -2998,7 +3000,8 @@ static void __io_sqe_files_unregister(struct io_ring_ctx *ctx) ...@@ -2998,7 +3000,8 @@ static void __io_sqe_files_unregister(struct io_ring_ctx *ctx)
int i; int i;
for (i = 0; i < ctx->nr_user_files; i++) for (i = 0; i < ctx->nr_user_files; i++)
fput(ctx->user_files[i]); if (ctx->user_files[i])
fput(ctx->user_files[i]);
#endif #endif
} }
...@@ -3066,7 +3069,7 @@ static int __io_sqe_files_scm(struct io_ring_ctx *ctx, int nr, int offset) ...@@ -3066,7 +3069,7 @@ static int __io_sqe_files_scm(struct io_ring_ctx *ctx, int nr, int offset)
struct sock *sk = ctx->ring_sock->sk; struct sock *sk = ctx->ring_sock->sk;
struct scm_fp_list *fpl; struct scm_fp_list *fpl;
struct sk_buff *skb; struct sk_buff *skb;
int i; int i, nr_files;
if (!capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) { if (!capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN)) {
unsigned long inflight = ctx->user->unix_inflight + nr; unsigned long inflight = ctx->user->unix_inflight + nr;
...@@ -3086,21 +3089,31 @@ static int __io_sqe_files_scm(struct io_ring_ctx *ctx, int nr, int offset) ...@@ -3086,21 +3089,31 @@ static int __io_sqe_files_scm(struct io_ring_ctx *ctx, int nr, int offset)
} }
skb->sk = sk; skb->sk = sk;
skb->destructor = io_destruct_skb;
nr_files = 0;
fpl->user = get_uid(ctx->user); fpl->user = get_uid(ctx->user);
for (i = 0; i < nr; i++) { for (i = 0; i < nr; i++) {
fpl->fp[i] = get_file(ctx->user_files[i + offset]); if (!ctx->user_files[i + offset])
unix_inflight(fpl->user, fpl->fp[i]); continue;
fpl->fp[nr_files] = get_file(ctx->user_files[i + offset]);
unix_inflight(fpl->user, fpl->fp[nr_files]);
nr_files++;
} }
fpl->max = fpl->count = nr; if (nr_files) {
UNIXCB(skb).fp = fpl; fpl->max = SCM_MAX_FD;
refcount_add(skb->truesize, &sk->sk_wmem_alloc); fpl->count = nr_files;
skb_queue_head(&sk->sk_receive_queue, skb); UNIXCB(skb).fp = fpl;
skb->destructor = io_destruct_skb;
refcount_add(skb->truesize, &sk->sk_wmem_alloc);
skb_queue_head(&sk->sk_receive_queue, skb);
for (i = 0; i < nr; i++) for (i = 0; i < nr_files; i++)
fput(fpl->fp[i]); fput(fpl->fp[i]);
} else {
kfree_skb(skb);
kfree(fpl);
}
return 0; return 0;
} }
...@@ -3131,7 +3144,8 @@ static int io_sqe_files_scm(struct io_ring_ctx *ctx) ...@@ -3131,7 +3144,8 @@ static int io_sqe_files_scm(struct io_ring_ctx *ctx)
return 0; return 0;
while (total < ctx->nr_user_files) { while (total < ctx->nr_user_files) {
fput(ctx->user_files[total]); if (ctx->user_files[total])
fput(ctx->user_files[total]);
total++; total++;
} }
...@@ -3162,10 +3176,15 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, ...@@ -3162,10 +3176,15 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg,
if (!ctx->user_files) if (!ctx->user_files)
return -ENOMEM; return -ENOMEM;
for (i = 0; i < nr_args; i++) { for (i = 0; i < nr_args; i++, ctx->nr_user_files++) {
ret = -EFAULT; ret = -EFAULT;
if (copy_from_user(&fd, &fds[i], sizeof(fd))) if (copy_from_user(&fd, &fds[i], sizeof(fd)))
break; break;
/* allow sparse sets */
if (fd == -1) {
ret = 0;
continue;
}
ctx->user_files[i] = fget(fd); ctx->user_files[i] = fget(fd);
...@@ -3183,13 +3202,13 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg, ...@@ -3183,13 +3202,13 @@ static int io_sqe_files_register(struct io_ring_ctx *ctx, void __user *arg,
fput(ctx->user_files[i]); fput(ctx->user_files[i]);
break; break;
} }
ctx->nr_user_files++;
ret = 0; ret = 0;
} }
if (ret) { if (ret) {
for (i = 0; i < ctx->nr_user_files; i++) for (i = 0; i < ctx->nr_user_files; i++)
fput(ctx->user_files[i]); if (ctx->user_files[i])
fput(ctx->user_files[i]);
kfree(ctx->user_files); kfree(ctx->user_files);
ctx->user_files = NULL; ctx->user_files = NULL;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册