aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorJeff Layton <jlayton@redhat.com>2011-10-19 15:28:27 -0400
committerJeff Layton <jlayton@redhat.com>2011-10-19 15:28:27 -0400
commit1041e3f9919999b22c9c2a453aa0d92cd16b76ee (patch)
tree8793a5d636e7c565722bb4353b23c74d185cb28e /fs/cifs/connect.c
parent42c4dfc213190fafffc53815c2ee6064430bc379 (diff)
cifs: keep a reusable kvec array for receives
Having to continually allocate a new kvec array is expensive. Allocate one that's big enough, and only reallocate it as needed. Reviewed-and-Tested-by: Pavel Shilovsky <piastry@etersoft.ru> Signed-off-by: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 4860940b748..ee70075c5fb 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -410,6 +410,24 @@ kvec_array_init(struct kvec *new, struct kvec *iov, unsigned int nr_segs,
410 return nr_segs; 410 return nr_segs;
411} 411}
412 412
413static struct kvec *
414get_server_iovec(struct TCP_Server_Info *server, unsigned int nr_segs)
415{
416 struct kvec *new_iov;
417
418 if (server->iov && nr_segs <= server->nr_iov)
419 return server->iov;
420
421 /* not big enough -- allocate a new one and release the old */
422 new_iov = kmalloc(sizeof(*new_iov) * nr_segs, GFP_NOFS);
423 if (new_iov) {
424 kfree(server->iov);
425 server->iov = new_iov;
426 server->nr_iov = nr_segs;
427 }
428 return new_iov;
429}
430
413static int 431static int
414readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig, 432readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig,
415 unsigned int nr_segs, unsigned int to_read) 433 unsigned int nr_segs, unsigned int to_read)
@@ -420,7 +438,7 @@ readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig,
420 struct msghdr smb_msg; 438 struct msghdr smb_msg;
421 struct kvec *iov; 439 struct kvec *iov;
422 440
423 iov = kmalloc(sizeof(*iov_orig) * nr_segs, GFP_NOFS); 441 iov = get_server_iovec(server, nr_segs);
424 if (!iov) 442 if (!iov)
425 return -ENOMEM; 443 return -ENOMEM;
426 444
@@ -464,7 +482,6 @@ readv_from_socket(struct TCP_Server_Info *server, struct kvec *iov_orig,
464 break; 482 break;
465 } 483 }
466 } 484 }
467 kfree(iov);
468 return total_read; 485 return total_read;
469} 486}
470 487
@@ -669,6 +686,7 @@ static void clean_demultiplex_info(struct TCP_Server_Info *server)
669 } 686 }
670 687
671 kfree(server->hostname); 688 kfree(server->hostname);
689 kfree(server->iov);
672 kfree(server); 690 kfree(server);
673 691
674 length = atomic_dec_return(&tcpSesAllocCount); 692 length = atomic_dec_return(&tcpSesAllocCount);