Skip to content

Commit

Permalink
If you backup a large file that is mostly holes, previously we'd issue
Browse files Browse the repository at this point in the history
a seek for every block...  For large (Exabyte sized files) this would
issue lots of unneeded seeks, so combine them...

Thanks for the work Jan, sorry took so long to commit...  And an item
completed off the IdeasPage!

Submitted by:	Jan Sucan
  • Loading branch information
jmgurney committed Nov 16, 2015
1 parent b708fe1 commit 9ba7847
Showing 1 changed file with 27 additions and 3 deletions.
30 changes: 27 additions & 3 deletions sbin/restore/tape.c
Expand Up @@ -107,6 +107,7 @@ static char *setupextattr(int);
static void xtrattr(char *, long);
static void set_extattr_link(char *, void *, int);
static void set_extattr_fd(int, char *, void *, int);
static void skiphole(void (*)(char *, long), long *);
static int gethead(struct s_spcl *);
static void readtape(char *);
static void setdumpnum(void);
Expand Down Expand Up @@ -926,6 +927,20 @@ skipfile(void)
getfile(xtrnull, xtrnull, xtrnull);
}

/*
* Skip a hole in an output file
*/
static void
skiphole(void (*skip)(char *, long), long *seekpos)
{
char buf[MAXBSIZE];

if (*seekpos > 0) {
(*skip)(buf, *seekpos);
*seekpos = 0;
}
}

/*
* Extract a file from the tape.
* When an allocated block is found it is passed to the fill function;
Expand All @@ -938,14 +953,15 @@ getfile(void (*datafill)(char *, long), void (*attrfill)(char *, long),
{
int i;
off_t size;
long seekpos;
int curblk, attrsize;
void (*fillit)(char *, long);
static char clearedbuf[MAXBSIZE];
char buf[MAXBSIZE / TP_BSIZE][TP_BSIZE];
char junk[TP_BSIZE];

curblk = 0;
size = spcl.c_size;
seekpos = 0;
attrsize = spcl.c_extsize;
if (spcl.c_type == TS_END)
panic("ran off end of tape\n");
Expand Down Expand Up @@ -974,22 +990,30 @@ getfile(void (*datafill)(char *, long), void (*attrfill)(char *, long),
if (readmapflag || spcl.c_addr[i]) {
readtape(&buf[curblk++][0]);
if (curblk == fssize / TP_BSIZE) {
skiphole(skip, &seekpos);
(*fillit)((char *)buf, (long)(size > TP_BSIZE ?
fssize : (curblk - 1) * TP_BSIZE + size));
curblk = 0;
}
} else {
if (curblk > 0) {
skiphole(skip, &seekpos);
(*fillit)((char *)buf, (long)(size > TP_BSIZE ?
curblk * TP_BSIZE :
(curblk - 1) * TP_BSIZE + size));
curblk = 0;
}
(*skip)(clearedbuf, (long)(size > TP_BSIZE ?
TP_BSIZE : size));
/*
* We have a block of a hole. Don't skip it
* now, because there may be next adjacent
* block of the hole in the file. Postpone the
* seek until next file write.
*/
seekpos += (long)(size > TP_BSIZE ? TP_BSIZE : size);
}
if ((size -= TP_BSIZE) <= 0) {
if (size > -TP_BSIZE && curblk > 0) {
skiphole(skip, &seekpos);
(*fillit)((char *)buf,
(long)((curblk * TP_BSIZE) + size));
curblk = 0;
Expand Down

0 comments on commit 9ba7847

Please sign in to comment.