@@ -449,8 +449,8 @@ struct smb_version_operations {
long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t,
loff_t);
/* init transform request - used for encryption for now */
- int (*init_transform_rq)(struct TCP_Server_Info *, struct smb_rqst *,
- struct smb_rqst *);
+ int (*init_transform_rq)(struct TCP_Server_Info *, int num_rqst,
+ struct smb_rqst *, struct smb_rqst *);
/* free transform request */
void (*free_transform_rq)(int num_rqst, struct smb_rqst *);
int (*is_transform_hdr)(void *buf);
@@ -2359,58 +2359,75 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst,
return rc;
}
+static void
+smb3_free_transform_rq(int num_rqst, struct smb_rqst *rqst)
+{
+ int i, j;
+
+ for (i = 1; i < num_rqst; i++) {
+ if (rqst[i].rq_pages) {
+ for (j = rqst[i].rq_npages - 1; j >= 0; j--)
+ put_page(rqst[i].rq_pages[j]);
+ kfree(rqst[i].rq_pages);
+ }
+ }
+}
+
static int
-smb3_init_transform_rq(struct TCP_Server_Info *server, struct smb_rqst *new_rq,
- struct smb_rqst *old_rq)
+smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst,
+ struct smb_rqst *new_rq, struct smb_rqst *old_rq)
{
struct page **pages;
struct smb2_transform_hdr *tr_hdr = new_rq[0].rq_iov[0].iov_base;
- unsigned int npages = old_rq->rq_npages;
+ unsigned int npages;
unsigned int orig_len = 0;
- int j;
+ int i, j;
int rc = -ENOMEM;
- pages = kmalloc_array(npages, sizeof(struct page *), GFP_KERNEL);
- if (!pages)
- goto err_free;
-
- new_rq[1].rq_pages = pages;
- new_rq[1].rq_npages = npages;
- new_rq[1].rq_offset = old_rq->rq_offset;
- new_rq[1].rq_pagesz = old_rq->rq_pagesz;
- new_rq[1].rq_tailsz = old_rq->rq_tailsz;
- new_rq[1].rq_iov = old_rq->rq_iov;
- new_rq[1].rq_nvec = old_rq->rq_nvec;
-
- for (j = 0; j < old_rq->rq_nvec; j++)
- orig_len += old_rq->rq_iov[j].iov_len;
-
- for (j = 0; j < npages; j++) {
- pages[j] = alloc_page(GFP_KERNEL|__GFP_HIGHMEM);
- if (!pages[j])
+ for (i = 1; i < num_rqst; i++) {
+ npages = old_rq[i - 1].rq_npages;
+ pages = kmalloc_array(npages, sizeof(struct page *),
+ GFP_KERNEL);
+ if (!pages)
goto err_free;
- }
- /* copy pages form the old */
- for (j = 0; j < npages; j++) {
- char *dst, *src;
- unsigned int offset, len;
+ new_rq[i].rq_pages = pages;
+ new_rq[i].rq_npages = npages;
+ new_rq[i].rq_offset = old_rq[i - 1].rq_offset;
+ new_rq[i].rq_pagesz = old_rq[i - 1].rq_pagesz;
+ new_rq[i].rq_tailsz = old_rq[i - 1].rq_tailsz;
+ new_rq[i].rq_iov = old_rq[i - 1].rq_iov;
+ new_rq[i].rq_nvec = old_rq[i - 1].rq_nvec;
+
+ for (j = 0; j < old_rq[i - 1].rq_nvec; j++)
+ orig_len += old_rq[i - 1].rq_iov[j].iov_len;
+
+ for (j = 0; j < npages; j++) {
+ pages[j] = alloc_page(GFP_KERNEL|__GFP_HIGHMEM);
+ if (!pages[j])
+ goto err_free;
+ }
- rqst_page_get_length(&new_rq[1], j, &len, &offset);
+ /* copy pages form the old */
+ for (j = 0; j < npages; j++) {
+ char *dst, *src;
+ unsigned int offset, len;
- dst = (char *) kmap(new_rq[1].rq_pages[j]) + offset;
- src = (char *) kmap(old_rq->rq_pages[j]) + offset;
+ rqst_page_get_length(&new_rq[i], j, &len, &offset);
- memcpy(dst, src, len);
- kunmap(new_rq[1].rq_pages[j]);
- kunmap(old_rq->rq_pages[j]);
- }
+ dst = (char *) kmap(new_rq[i].rq_pages[j]) + offset;
+ src = (char *) kmap(old_rq[i - 1].rq_pages[j]) + offset;
+ memcpy(dst, src, len);
+ kunmap(new_rq[i].rq_pages[j]);
+ kunmap(old_rq[i - 1].rq_pages[j]);
+ }
+ }
/* fill the 1nd iov with a transform header */
fill_transform_hdr(tr_hdr, orig_len, old_rq);
- rc = crypt_message(server, 2, new_rq, 1);
+ rc = crypt_message(server, num_rqst, new_rq, 1);
cifs_dbg(FYI, "encrypt message returned %d", rc);
if (rc)
goto err_free;
@@ -2418,26 +2435,10 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, struct smb_rqst *new_rq,
return rc;
err_free:
- if (new_rq[1].rq_pages) {
- for (j = new_rq[1].rq_npages - 1; j >= 0; j--)
- put_page(new_rq[1].rq_pages[j]);
- kfree(new_rq[1].rq_pages);
- }
+ smb3_free_transform_rq(num_rqst, new_rq);
return rc;
}
-static void
-smb3_free_transform_rq(int num_rqst, struct smb_rqst *rqst)
-{
- int i, j;
-
- for (i = 1; i < num_rqst; i++) {
- for (j = rqst[i].rq_npages - 1; j >= 0; j--)
- put_page(rqst[i].rq_pages[j]);
- kfree(rqst[i].rq_pages);
- }
-}
-
static int
smb3_is_transform_hdr(void *buf)
{
@@ -377,7 +377,7 @@ smb_send_rqst(struct TCP_Server_Info *server, struct smb_rqst *rqst, int flags)
return -EIO;
}
- rc = server->ops->init_transform_rq(server, &cur_rqst[0], rqst);
+ rc = server->ops->init_transform_rq(server, 2, &cur_rqst[0], rqst);
if (rc)
return rc;
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com> --- fs/cifs/cifsglob.h | 4 +- fs/cifs/smb2ops.c | 105 ++++++++++++++++++++++++++-------------------------- fs/cifs/transport.c | 2 +- 3 files changed, 56 insertions(+), 55 deletions(-)