mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 20:22:09 +00:00
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
@ -95,11 +95,28 @@ bool ksmbd_queue_work(struct ksmbd_work *work)
|
||||
return queue_work(ksmbd_wq, &work->work);
|
||||
}
|
||||
|
||||
static int ksmbd_realloc_iov_pin(struct ksmbd_work *work, void *ib,
|
||||
unsigned int ib_len)
|
||||
static inline void __ksmbd_iov_pin(struct ksmbd_work *work, void *ib,
|
||||
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;
|
||||
|
||||
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[++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 */
|
||||
if (!work->iov_idx) {
|
||||
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++;
|
||||
}
|
||||
|
||||
ksmbd_realloc_iov_pin(work, ib, len);
|
||||
__ksmbd_iov_pin(work, ib, len);
|
||||
inc_rfc1001_len(work->iov[0].iov_base, len);
|
||||
|
||||
if (aux_size) {
|
||||
struct aux_read *ar;
|
||||
|
||||
ksmbd_realloc_iov_pin(work, aux_buf, aux_size);
|
||||
__ksmbd_iov_pin(work, aux_buf, 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;
|
||||
list_add(&ar->entry, &work->aux_read_list);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user