Skip to content

Commit

Permalink
Add support for Solaris ufsdump volumes with more than 512*1024 inodes.
Browse files Browse the repository at this point in the history
Here the bitmaps are written as

	CLRI or BITS with c_count <= 512
	ADDR* for the remaining blocks

Remove the bitmap handling from getfile(), remove xtrmap() and xtrmapskip().
Add new function getbitmap() modeled after getfile() that does bitmap
allocation, bitmap expansion and sets maxino.

Reviewed by: Manuel Bouyer <bouyer@netbsd.org>
  • Loading branch information
hannken committed Feb 9, 2007
1 parent 041a77b commit e81f911
Showing 1 changed file with 56 additions and 63 deletions.
119 changes: 56 additions & 63 deletions sbin/restore/tape.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* $NetBSD: tape.c,v 1.58 2006/12/18 20:07:32 christos Exp $ */
/* $NetBSD: tape.c,v 1.59 2007/02/09 09:36:02 hannken Exp $ */

/*
* Copyright (c) 1983, 1993
Expand Down Expand Up @@ -39,7 +39,7 @@
#if 0
static char sccsid[] = "@(#)tape.c 8.9 (Berkeley) 5/1/95";
#else
__RCSID("$NetBSD: tape.c,v 1.58 2006/12/18 20:07:32 christos Exp $");
__RCSID("$NetBSD: tape.c,v 1.59 2007/02/09 09:36:02 hannken Exp $");
#endif
#endif /* not lint */

Expand Down Expand Up @@ -87,7 +87,6 @@ static const char *host = NULL;
#endif

static int ofile;
static char *map;
static char lnkbuf[MAXPATHLEN + 1];
static int pathlen;

Expand Down Expand Up @@ -157,15 +156,14 @@ static void accthdr(struct s_spcl *);
static int checksum(int *);
static void findinode(struct s_spcl *);
static void findtapeblksize(void);
static void getbitmap(char **);
static int gethead(struct s_spcl *);
static void readtape(char *);
static void setdumpnum(void);
static void terminateinput(void);
static void xtrfile(char *, long);
static void xtrlnkfile(char *, long);
static void xtrlnkskip(char *, long);
static void xtrmap(char *, long);
static void xtrmapskip(char *, long);
static void xtrskip(char *, long);
static void swap_header(struct s_spcl *);
static void swap_old_header(struct s_ospcl *);
Expand Down Expand Up @@ -324,24 +322,8 @@ setup(void)
fprintf(stderr, "Cannot find file removal list\n");
exit(1);
}
maxino = (spcl.c_count * TP_BSIZE * NBBY) + 1;
dprintf(stdout, "maxino = %llu\n", (unsigned long long)maxino);
map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY));
if (map == NULL)
panic("no memory for active inode map\n");
usedinomap = map;
curfile.action = USING;
getfile(xtrmap, xtrmapskip);
if (spcl.c_type != TS_BITS) {
fprintf(stderr, "Cannot find file dump list\n");
exit(1);
}
map = calloc((unsigned)1, (unsigned)howmany(maxino, NBBY));
if (map == (char *)NULL)
panic("no memory for file dump list\n");
dumpmap = map;
curfile.action = USING;
getfile(xtrmap, xtrmapskip);
getbitmap(&usedinomap);
getbitmap(&dumpmap);
/*
* If there may be whiteout entries on the tape, pretend that the
* whiteout inode exists, so that the whiteout entries can be
Expand Down Expand Up @@ -804,6 +786,53 @@ skipfile(void)
getfile(xtrnull, xtrnull);
}

/*
* Extract a bitmap from the tape.
* The first bitmap sets maxino;
* other bitmaps must be of same size.
*/
void
getbitmap(char **map)
{
int i;
size_t volatile size = spcl.c_size;
size_t volatile mapsize = size;
char *mapptr;

curfile.action = USING;
if (spcl.c_type == TS_END)
panic("ran off end of tape\n");
if (spcl.c_magic != FS_UFS2_MAGIC)
panic("not at beginning of a file\n");
if (!gettingfile && setjmp(restart) != 0)
return;
gettingfile++;
mapptr = *map = malloc(size);
loop:
if (*map == NULL)
panic("no memory for %s\n", curfile.name);
for (i = 0; i < spcl.c_count && size >= TP_BSIZE; i++) {
readtape(mapptr);
mapptr += TP_BSIZE;
size -= TP_BSIZE;
}
if (size != 0 || i != spcl.c_count)
panic("%s: inconsistent map size\n", curfile.name);
if (gethead(&spcl) == GOOD && spcl.c_type == TS_ADDR) {
size = spcl.c_count * TP_BSIZE;
*map = realloc(*map, mapsize + size);
mapptr = *map + mapsize;
mapsize += size;
goto loop;
}
if (maxino == 0)
maxino = mapsize * NBBY + 1;
else if (maxino != mapsize * NBBY + 1)
panic("%s: map size changed\n", curfile.name);
findinode(&spcl);
gettingfile = 0;
}

/*
* Extract a file from the tape.
* When an allocated block is found it is passed to the fill function;
Expand Down Expand Up @@ -833,8 +862,7 @@ getfile(void (*fill)(char *buf, long size),
gettingfile++;
loop:
for (i = 0; i < spcl.c_count; i++) {
if (spcl.c_type == TS_BITS || spcl.c_type == TS_CLRI ||
spcl.c_addr[i]) {
if (spcl.c_addr[i]) {
readtape(&buf[curblk++][0]);
if (curblk == fssize / TP_BSIZE) {
(*fill)((char *)buf, (long)(size > TP_BSIZE ?
Expand All @@ -852,21 +880,9 @@ getfile(void (*fill)(char *buf, long size),
TP_BSIZE : size));
}
if ((size -= TP_BSIZE) <= 0) {
if (spcl.c_type == TS_BITS || spcl.c_type == TS_CLRI) {
/*
* In this case, the following expression
* should always be false since the size was
* initially set to spcl.c_size and
* it is initialized to spcl.c_count * TP_BSIZE
* in gethead().
*/
if (!(size == 0 && i == spcl.c_count - 1))
panic("inconsistent map size\n");
} else {
for (i++; i < spcl.c_count; i++)
if (spcl.c_addr[i])
readtape(junk);
}
for (i++; i < spcl.c_count; i++)
if (spcl.c_addr[i])
readtape(junk);
break;
}
}
Expand Down Expand Up @@ -953,29 +969,6 @@ xtrlnkskip(char *buf __unused, long size __unused)
exit(1);
}

/*
* Collect the next block of a bit map.
*/
static void
xtrmap(char *buf, long size)
{

memmove(map, buf, size);
map += size;
}

/*
* Skip over a hole in a bit map (should never happen).
*/
/* ARGSUSED */
static void
xtrmapskip(char *buf __unused, long size)
{

panic("hole in map\n");
map += size;
}

/*
* Noop, when an extraction function is not needed.
*/
Expand Down

0 comments on commit e81f911

Please sign in to comment.