Skip to content

Commit bc925c1

Browse files
Paulo AlcantaraSteve French
authored andcommitted
smb: client: improve compound padding in encryption
After commit f7f291e ("cifs: fix oops during encryption"), the encryption layer can handle vmalloc'd buffers as well as kmalloc'd buffers, so there is no need to inefficiently squash request iovs into a single one to handle padding in compound requests. Cc: David Howells <[email protected]> Signed-off-by: Paulo Alcantara (Red Hat) <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 9ed9d83 commit bc925c1

File tree

3 files changed

+18
-63
lines changed

3 files changed

+18
-63
lines changed

fs/smb/client/cifsglob.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2230,7 +2230,7 @@ static inline int cifs_get_num_sgs(const struct smb_rqst *rqst,
22302230
struct kvec *iov = &rqst[i].rq_iov[j];
22312231

22322232
addr = (unsigned long)iov->iov_base + skip;
2233-
if (unlikely(is_vmalloc_addr((void *)addr))) {
2233+
if (is_vmalloc_or_module_addr((void *)addr)) {
22342234
len = iov->iov_len - skip;
22352235
nents += DIV_ROUND_UP(offset_in_page(addr) + len,
22362236
PAGE_SIZE);
@@ -2257,7 +2257,7 @@ static inline void cifs_sg_set_buf(struct sg_table *sgtable,
22572257
unsigned int off = offset_in_page(addr);
22582258

22592259
addr &= PAGE_MASK;
2260-
if (unlikely(is_vmalloc_addr((void *)addr))) {
2260+
if (is_vmalloc_or_module_addr((void *)addr)) {
22612261
do {
22622262
unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off);
22632263

fs/smb/client/smb2ops.c

Lines changed: 3 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2606,7 +2606,7 @@ smb2_set_next_command(struct cifs_tcon *tcon, struct smb_rqst *rqst)
26062606
struct cifs_ses *ses = tcon->ses;
26072607
struct TCP_Server_Info *server = ses->server;
26082608
unsigned long len = smb_rqst_len(server, rqst);
2609-
int i, num_padding;
2609+
int num_padding;
26102610

26112611
shdr = (struct smb2_hdr *)(rqst->rq_iov[0].iov_base);
26122612
if (shdr == NULL) {
@@ -2615,44 +2615,13 @@ smb2_set_next_command(struct cifs_tcon *tcon, struct smb_rqst *rqst)
26152615
}
26162616

26172617
/* SMB headers in a compound are 8 byte aligned. */
2618-
2619-
/* No padding needed */
2620-
if (!(len & 7))
2621-
goto finished;
2622-
2623-
num_padding = 8 - (len & 7);
2624-
if (!smb3_encryption_required(tcon)) {
2625-
/*
2626-
* If we do not have encryption then we can just add an extra
2627-
* iov for the padding.
2628-
*/
2618+
if (!IS_ALIGNED(len, 8)) {
2619+
num_padding = 8 - (len & 7);
26292620
rqst->rq_iov[rqst->rq_nvec].iov_base = smb2_padding;
26302621
rqst->rq_iov[rqst->rq_nvec].iov_len = num_padding;
26312622
rqst->rq_nvec++;
26322623
len += num_padding;
2633-
} else {
2634-
/*
2635-
* We can not add a small padding iov for the encryption case
2636-
* because the encryption framework can not handle the padding
2637-
* iovs.
2638-
* We have to flatten this into a single buffer and add
2639-
* the padding to it.
2640-
*/
2641-
for (i = 1; i < rqst->rq_nvec; i++) {
2642-
memcpy(rqst->rq_iov[0].iov_base +
2643-
rqst->rq_iov[0].iov_len,
2644-
rqst->rq_iov[i].iov_base,
2645-
rqst->rq_iov[i].iov_len);
2646-
rqst->rq_iov[0].iov_len += rqst->rq_iov[i].iov_len;
2647-
}
2648-
memset(rqst->rq_iov[0].iov_base + rqst->rq_iov[0].iov_len,
2649-
0, num_padding);
2650-
rqst->rq_iov[0].iov_len += num_padding;
2651-
len += num_padding;
2652-
rqst->rq_nvec = 1;
26532624
}
2654-
2655-
finished:
26562625
shdr->NextCommand = cpu_to_le32(len);
26572626
}
26582627

fs/smb/client/transport.c

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -418,19 +418,16 @@ __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
418418
return rc;
419419
}
420420

421-
struct send_req_vars {
422-
struct smb2_transform_hdr tr_hdr;
423-
struct smb_rqst rqst[MAX_COMPOUND];
424-
struct kvec iov;
425-
};
426-
427421
static int
428422
smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
429423
struct smb_rqst *rqst, int flags)
430424
{
431-
struct send_req_vars *vars;
432-
struct smb_rqst *cur_rqst;
433-
struct kvec *iov;
425+
struct smb2_transform_hdr tr_hdr;
426+
struct smb_rqst new_rqst[MAX_COMPOUND] = {};
427+
struct kvec iov = {
428+
.iov_base = &tr_hdr,
429+
.iov_len = sizeof(tr_hdr),
430+
};
434431
int rc;
435432

436433
if (flags & CIFS_COMPRESS_REQ)
@@ -447,26 +444,15 @@ smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,
447444
return -EIO;
448445
}
449446

450-
vars = kzalloc(sizeof(*vars), GFP_NOFS);
451-
if (!vars)
452-
return -ENOMEM;
453-
cur_rqst = vars->rqst;
454-
iov = &vars->iov;
455-
456-
iov->iov_base = &vars->tr_hdr;
457-
iov->iov_len = sizeof(vars->tr_hdr);
458-
cur_rqst[0].rq_iov = iov;
459-
cur_rqst[0].rq_nvec = 1;
447+
new_rqst[0].rq_iov = &iov;
448+
new_rqst[0].rq_nvec = 1;
460449

461450
rc = server->ops->init_transform_rq(server, num_rqst + 1,
462-
&cur_rqst[0], rqst);
463-
if (rc)
464-
goto out;
465-
466-
rc = __smb_send_rqst(server, num_rqst + 1, &cur_rqst[0]);
467-
smb3_free_compound_rqst(num_rqst, &cur_rqst[1]);
468-
out:
469-
kfree(vars);
451+
new_rqst, rqst);
452+
if (!rc) {
453+
rc = __smb_send_rqst(server, num_rqst + 1, new_rqst);
454+
smb3_free_compound_rqst(num_rqst, &new_rqst[1]);
455+
}
470456
return rc;
471457
}
472458

0 commit comments

Comments
 (0)