[2/9] cifs: make [init|free]_transform_rq take an array of requests

Message ID 20180620011350.12328-3-lsahlber@redhat.com
State New
Headers show
Series
  • cifs: compounding
Related show

Commit Message

Ronnie Sahlberg June 20, 2018, 1:13 a.m.
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(-)

Patch

diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 0f486dac8e69..c26e30b73110 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -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);
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 240267378baf..687d9cdd3042 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -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)
 {
diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c
index 7a8b601b144e..6153b0d55704 100644
--- a/fs/cifs/transport.c
+++ b/fs/cifs/transport.c
@@ -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;