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: e2b76ab8b5
("ksmbd: add support for read compound")
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Steve French <stfrench@microsoft.com>
This commit is contained in:
parent
eacc655e18
commit
1819a90429
1 changed files with 22 additions and 21 deletions
|
@ -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++;
|
||||||
|
}
|
||||||
|
|
||||||
if (work->iov_alloc_cnt <= 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 (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,
|
||||||
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,
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue