diff options
-rw-r--r-- | fs/cifs/smb2pdu.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 29f011d8d8e2..710ceb875161 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
@@ -2538,11 +2538,25 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, | |||
2538 | struct kvec *iov = rqst->rq_iov; | 2538 | struct kvec *iov = rqst->rq_iov; |
2539 | unsigned int total_len; | 2539 | unsigned int total_len; |
2540 | int rc; | 2540 | int rc; |
2541 | char *in_data_buf; | ||
2541 | 2542 | ||
2542 | rc = smb2_plain_req_init(SMB2_IOCTL, tcon, (void **) &req, &total_len); | 2543 | rc = smb2_plain_req_init(SMB2_IOCTL, tcon, (void **) &req, &total_len); |
2543 | if (rc) | 2544 | if (rc) |
2544 | return rc; | 2545 | return rc; |
2545 | 2546 | ||
2547 | if (indatalen) { | ||
2548 | /* | ||
2549 | * indatalen is usually small at a couple of bytes max, so | ||
2550 | * just allocate through generic pool | ||
2551 | */ | ||
2552 | in_data_buf = kmalloc(indatalen, GFP_NOFS); | ||
2553 | if (!in_data_buf) { | ||
2554 | cifs_small_buf_release(req); | ||
2555 | return -ENOMEM; | ||
2556 | } | ||
2557 | memcpy(in_data_buf, in_data, indatalen); | ||
2558 | } | ||
2559 | |||
2546 | req->CtlCode = cpu_to_le32(opcode); | 2560 | req->CtlCode = cpu_to_le32(opcode); |
2547 | req->PersistentFileId = persistent_fid; | 2561 | req->PersistentFileId = persistent_fid; |
2548 | req->VolatileFileId = volatile_fid; | 2562 | req->VolatileFileId = volatile_fid; |
@@ -2563,7 +2577,7 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, | |||
2563 | cpu_to_le32(offsetof(struct smb2_ioctl_req, Buffer)); | 2577 | cpu_to_le32(offsetof(struct smb2_ioctl_req, Buffer)); |
2564 | rqst->rq_nvec = 2; | 2578 | rqst->rq_nvec = 2; |
2565 | iov[0].iov_len = total_len - 1; | 2579 | iov[0].iov_len = total_len - 1; |
2566 | iov[1].iov_base = in_data; | 2580 | iov[1].iov_base = in_data_buf; |
2567 | iov[1].iov_len = indatalen; | 2581 | iov[1].iov_len = indatalen; |
2568 | } else { | 2582 | } else { |
2569 | rqst->rq_nvec = 1; | 2583 | rqst->rq_nvec = 1; |
@@ -2605,8 +2619,11 @@ SMB2_ioctl_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, | |||
2605 | void | 2619 | void |
2606 | SMB2_ioctl_free(struct smb_rqst *rqst) | 2620 | SMB2_ioctl_free(struct smb_rqst *rqst) |
2607 | { | 2621 | { |
2608 | if (rqst && rqst->rq_iov) | 2622 | if (rqst && rqst->rq_iov) { |
2609 | cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ | 2623 | cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ |
2624 | if (rqst->rq_iov[1].iov_len) | ||
2625 | kfree(rqst->rq_iov[1].iov_base); | ||
2626 | } | ||
2610 | } | 2627 | } |
2611 | 2628 | ||
2612 | 2629 | ||