From 4f4d71b941e568b158da73978e25105b94afd7fd Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Mon, 29 Sep 2014 21:01:51 +0200 Subject: [PATCH] hgfs: make data files with meta headers having the right size after open to get the right data size of a file, the revlog needs to have been opened and the metaheader parsed. as an optimization, we used to open revlog only on the first read resulting revlogs with metaheaders having the wrong size returned by fstat() until the first read(). tar relies on fstat() giving the correct file size, so just open the revlog on open. reading directories can still yield the wrong size but it is not that critical. --- sys/src/cmd/hgfs/fs.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/sys/src/cmd/hgfs/fs.c b/sys/src/cmd/hgfs/fs.c index ab820f656..09644b8a5 100644 --- a/sys/src/cmd/hgfs/fs.c +++ b/sys/src/cmd/hgfs/fs.c @@ -606,6 +606,19 @@ fsopen(Req *r) if(rf->node == nil || rf->node->mode != 'x') break; case OREAD: + if(rf->level == Qlog){ + if((rf->fd = revlogopentemp(&changelog, hashrev(&changelog, rf->info->chash))) < 0){ + responderror(r); + return; + } + rf->doff = rf->info->logoff; + } else if(rf->level == Qtree && rf->node->down == nil){ + if((rf->fd = revlogopentemp(rf->rlog, hashrev(rf->rlog, rf->node->hash))) < 0){ + responderror(r); + return; + } + rf->doff = fmetaheader(rf->fd); + } respond(r, nil); return; } @@ -697,13 +710,6 @@ fsread(Req *r) len = 0; else if((off + len) >= rf->info->loglen) len = rf->info->loglen - off; - if(rf->fd >= 0) - goto Fdgen; - if((rf->fd = revlogopentemp(&changelog, hashrev(&changelog, rf->info->chash))) < 0){ - responderror(r); - return; - } - rf->doff = rf->info->logoff; goto Fdgen; case Qwho: s = rf->info->who; @@ -724,14 +730,9 @@ fsread(Req *r) respond(r, nil); return; } - if(rf->fd >= 0) - goto Fdgen; - if((rf->fd = revlogopentemp(rf->rlog, hashrev(rf->rlog, rf->node->hash))) < 0){ - responderror(r); - return; - } - rf->doff = fmetaheader(rf->fd); Fdgen: + if(rf->fd < 0) + break; if((n = pread(rf->fd, r->ofcall.data, len, off + rf->doff)) < 0){ responderror(r); return;