Commit 8651f43b authored by Pavel Emelyanov's avatar Pavel Emelyanov

bfd: Implement buffered reads

The restore times look like

Before patch:
	  futex:      370  3.554482 (84.2%)
	 umount:       41  0.234796 (5.6%)
	   read:     4737  0.113987 (2.7%)
	recvmsg:       43  0.100083 (2.4%)
	  wait4:       10  0.033344 (0.8%)

After patch:
	  futex:      187  1.547642 (72.9%)
	 umount:       41  0.234595 (11.0%)
	recvmsg:       43  0.075738 (3.6%)
	  flock:       42  0.038696 (1.8%)
	  clone:       35  0.037699 (1.8%)

Most of the time we wait for other processes to restore,
but that's OK (would only affect parallel restore). And
we see that read-s really go away (onto 7th position).
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
Acked-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
parent b4640934
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <sys/uio.h> #include <sys/uio.h>
#include "bug.h"
#include "log.h" #include "log.h"
#include "bfd.h" #include "bfd.h"
#include "list.h" #include "list.h"
...@@ -99,6 +100,12 @@ static int bflush(struct bfd *bfd); ...@@ -99,6 +100,12 @@ static int bflush(struct bfd *bfd);
void bclose(struct bfd *f) void bclose(struct bfd *f)
{ {
if (bfd_buffered(f)) { if (bfd_buffered(f)) {
/*
* FIXME -- when we bread from images we don't
* need to flush. This call doesn't fail simply
* becase we read _all_ data from them and the
* b->sz would be 0 by the time we close them.
*/
if (bflush(f) < 0) if (bflush(f) < 0)
/* /*
* FIXME -- propagate error up. It's * FIXME -- propagate error up. It's
...@@ -131,7 +138,7 @@ static int brefill(struct bfd *f) ...@@ -131,7 +138,7 @@ static int brefill(struct bfd *f)
return 0; return 0;
b->sz += ret; b->sz += ret;
return 0; return 1;
} }
static char *strnchr(char *str, unsigned int len, char c) static char *strnchr(char *str, unsigned int len, char c)
...@@ -192,7 +199,7 @@ again: ...@@ -192,7 +199,7 @@ again:
ss = b->sz; ss = b->sz;
/* no full line in the buffer -- refill one */ /* no full line in the buffer -- refill one */
if (brefill(f)) if (brefill(f) < 0)
return BREADERR; return BREADERR;
refilled = true; refilled = true;
...@@ -267,5 +274,33 @@ int bwritev(struct bfd *bfd, const struct iovec *iov, int cnt) ...@@ -267,5 +274,33 @@ int bwritev(struct bfd *bfd, const struct iovec *iov, int cnt)
int bread(struct bfd *bfd, void *buf, int size) int bread(struct bfd *bfd, void *buf, int size)
{ {
return read(bfd->fd, buf, size); struct xbuf *b = &bfd->b;
int more = 1, filled = 0;
if (!bfd_buffered(bfd))
return read(bfd->fd, buf, size);
while (more > 0) {
int chunk;
chunk = size - filled;
if (chunk > b->sz)
chunk = b->sz;
if (chunk) {
memcpy(buf + filled, b->data, chunk);
b->data += chunk;
b->sz -= chunk;
filled += chunk;
}
if (filled < size)
more = brefill(bfd);
else {
BUG_ON(filled > size);
more = 0;
}
}
return more < 0 ? more : filled;
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment