Commit 1819a904 authored by Namjae Jeon's avatar Namjae Jeon Committed by Steve French

ksmbd: reorganize ksmbd_iov_pin_rsp()

If ksmbd_iov_pin_rsp fail, io vertor should be rollback.
This patch moves memory allocations to before setting the io vector
to avoid rollbacks.

Fixes: e2b76ab8 ("ksmbd: add support for read compound")
Signed-off-by: default avatarNamjae Jeon <linkinjeon@kernel.org>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent eacc655e
...@@ -95,11 +95,28 @@ bool ksmbd_queue_work(struct ksmbd_work *work) ...@@ -95,11 +95,28 @@ bool ksmbd_queue_work(struct ksmbd_work *work)
return queue_work(ksmbd_wq, &work->work); return queue_work(ksmbd_wq, &work->work);
} }
static int ksmbd_realloc_iov_pin(struct ksmbd_work *work, void *ib, static inline void __ksmbd_iov_pin(struct ksmbd_work *work, void *ib,
unsigned int ib_len) unsigned int ib_len)
{ {
work->iov[++work->iov_idx].iov_base = ib;
work->iov[work->iov_idx].iov_len = ib_len;
work->iov_cnt++;
}
static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len,
void *aux_buf, unsigned int aux_size)
{
struct aux_read *ar;
int need_iov_cnt = 1;
if (work->iov_alloc_cnt <= work->iov_cnt) { if (aux_size) {
need_iov_cnt++;
ar = kmalloc(sizeof(struct aux_read), GFP_KERNEL);
if (!ar)
return -ENOMEM;
}
if (work->iov_alloc_cnt < work->iov_cnt + need_iov_cnt) {
struct kvec *new; struct kvec *new;
work->iov_alloc_cnt += 4; work->iov_alloc_cnt += 4;
...@@ -111,16 +128,6 @@ static int ksmbd_realloc_iov_pin(struct ksmbd_work *work, void *ib, ...@@ -111,16 +128,6 @@ static int ksmbd_realloc_iov_pin(struct ksmbd_work *work, void *ib,
work->iov = new; work->iov = new;
} }
work->iov[++work->iov_idx].iov_base = ib;
work->iov[work->iov_idx].iov_len = ib_len;
work->iov_cnt++;
return 0;
}
static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len,
void *aux_buf, unsigned int aux_size)
{
/* Plus rfc_length size on first iov */ /* Plus rfc_length size on first iov */
if (!work->iov_idx) { if (!work->iov_idx) {
work->iov[work->iov_idx].iov_base = work->response_buf; work->iov[work->iov_idx].iov_base = work->response_buf;
...@@ -129,19 +136,13 @@ static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len, ...@@ -129,19 +136,13 @@ static int __ksmbd_iov_pin_rsp(struct ksmbd_work *work, void *ib, int len,
work->iov_cnt++; work->iov_cnt++;
} }
ksmbd_realloc_iov_pin(work, ib, len); __ksmbd_iov_pin(work, ib, len);
inc_rfc1001_len(work->iov[0].iov_base, len); inc_rfc1001_len(work->iov[0].iov_base, len);
if (aux_size) { if (aux_size) {
struct aux_read *ar; __ksmbd_iov_pin(work, aux_buf, aux_size);
ksmbd_realloc_iov_pin(work, aux_buf, aux_size);
inc_rfc1001_len(work->iov[0].iov_base, aux_size); inc_rfc1001_len(work->iov[0].iov_base, aux_size);
ar = kmalloc(sizeof(struct aux_read), GFP_KERNEL);
if (!ar)
return -ENOMEM;
ar->buf = aux_buf; ar->buf = aux_buf;
list_add(&ar->entry, &work->aux_read_list); list_add(&ar->entry, &work->aux_read_list);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment