* the sequence number before this function is called. Also, this function
  * should be called with the server->srv_mutex held.
  */
-static int cifs_calc_signature(const struct kvec *iov, int n_vec,
+static int cifs_calc_signature(struct smb_rqst *rqst,
                        struct TCP_Server_Info *server, char *signature)
 {
        int i;
        int rc;
+       struct kvec *iov = rqst->rq_iov;
+       int n_vec = rqst->rq_nvec;
 
        if (iov == NULL || signature == NULL || server == NULL)
                return -EINVAL;
 }
 
 /* must be called with server->srv_mutex held */
-int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
+int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
                   __u32 *pexpected_response_sequence_number)
 {
        int rc = 0;
        char smb_signature[20];
-       struct smb_hdr *cifs_pdu = (struct smb_hdr *)iov[0].iov_base;
+       struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
 
        if ((cifs_pdu == NULL) || (server == NULL))
                return -EINVAL;
        *pexpected_response_sequence_number = server->sequence_number++;
        server->sequence_number++;
 
-       rc = cifs_calc_signature(iov, n_vec, server, smb_signature);
+       rc = cifs_calc_signature(rqst, server, smb_signature);
        if (rc)
                memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
        else
        return rc;
 }
 
+int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *server,
+                  __u32 *pexpected_response_sequence)
+{
+       struct smb_rqst rqst = { .rq_iov = iov,
+                                .rq_nvec = n_vec };
+
+       return cifs_sign_rqst(&rqst, server, pexpected_response_sequence);
+}
+
 /* must be called with server->srv_mutex held */
 int cifs_sign_smb(struct smb_hdr *cifs_pdu, struct TCP_Server_Info *server,
                  __u32 *pexpected_response_sequence_number)
                              pexpected_response_sequence_number);
 }
 
-int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov,
+int cifs_verify_signature(struct smb_rqst *rqst,
                          struct TCP_Server_Info *server,
                          __u32 expected_sequence_number)
 {
        unsigned int rc;
        char server_response_sig[8];
        char what_we_think_sig_should_be[20];
-       struct smb_hdr *cifs_pdu = (struct smb_hdr *)iov[0].iov_base;
+       struct smb_hdr *cifs_pdu = (struct smb_hdr *)rqst->rq_iov[0].iov_base;
 
        if (cifs_pdu == NULL || server == NULL)
                return -EINVAL;
        cifs_pdu->Signature.Sequence.Reserved = 0;
 
        mutex_lock(&server->srv_mutex);
-       rc = cifs_calc_signature(iov, nr_iov, server,
-                                what_we_think_sig_should_be);
+       rc = cifs_calc_signature(rqst, server, what_we_think_sig_should_be);
        mutex_unlock(&server->srv_mutex);
 
        if (rc)
 
  *****************************************************************
  */
 
+/*
+ * A smb_rqst represents a complete request to be issued to a server. It's
+ * formed by a kvec array, followed by an array of pages. Page data is assumed
+ * to start at the beginning of the first page.
+ */
+struct smb_rqst {
+       struct kvec     *rq_iov;        /* array of kvecs */
+       unsigned int    rq_nvec;        /* number of kvecs in array */
+       struct page     **rq_pages;     /* pointer to array of page ptrs */
+       unsigned int    rq_npages;      /* number pages in array */
+       unsigned int    rq_pagesz;      /* page size to use */
+       unsigned int    rq_tailsz;      /* length of last page */
+};
+
 enum smb_version {
        Smb_1 = 1,
        Smb_21,
 
 
 struct statfs;
 struct smb_vol;
+struct smb_rqst;
 
 /*
  *****************************************************************
 extern struct cifs_tcon *tconInfoAlloc(void);
 extern void tconInfoFree(struct cifs_tcon *);
 
-extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
+extern int cifs_sign_rqst(struct smb_rqst *rqst, struct TCP_Server_Info *server,
+                  __u32 *pexpected_response_sequence_number);
 extern int cifs_sign_smbv(struct kvec *iov, int n_vec, struct TCP_Server_Info *,
                          __u32 *);
-extern int cifs_verify_signature(struct kvec *iov, unsigned int nr_iov,
+extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *, __u32 *);
+extern int cifs_verify_signature(struct smb_rqst *rqst,
                                 struct TCP_Server_Info *server,
                                __u32 expected_sequence_number);
 extern int SMBNTencrypt(unsigned char *, unsigned char *, unsigned char *,
 
        struct cifs_readdata *rdata = mid->callback_data;
        struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
        struct TCP_Server_Info *server = tcon->ses->server;
+       struct smb_rqst rqst = { .rq_iov = rdata->iov,
+                                .rq_nvec = rdata->nr_iov };
 
        cFYI(1, "%s: mid=%llu state=%d result=%d bytes=%u", __func__,
                mid->mid, mid->mid_state, rdata->result, rdata->bytes);
                    (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
                        int rc = 0;
 
-                       rc = cifs_verify_signature(rdata->iov, rdata->nr_iov,
-                                                  server,
-                                                  mid->sequence_number + 1);
+                       rc = cifs_verify_signature(&rqst, server,
+                                                 mid->sequence_number + 1);
                        if (rc)
                                cERROR(1, "SMB signature verification returned "
                                       "error = %d", rc);
 
        if (server->sec_mode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
                struct kvec iov;
                int rc = 0;
+               struct smb_rqst rqst = { .rq_iov = &iov,
+                                        .rq_nvec = 1 };
 
                iov.iov_base = mid->resp_buf;
                iov.iov_len = len;
                /* FIXME: add code to kill session */
-               rc = cifs_verify_signature(&iov, 1, server,
+               rc = cifs_verify_signature(&rqst, server,
                                           mid->sequence_number + 1);
                if (rc)
                        cERROR(1, "SMB signature verification returned error = "