mirror of
https://github.com/SDL-Hercules-390/hyperion.git
synced 2026-04-21 19:34:47 +02:00
12 Oct 2005 cckd_comp improvements - Greg Smith
git-svn-id: file:///home/jj/hercules.svn/trunk@3074 956126f8-22a0-4046-8f4a-272fa8102e63
This commit is contained in:
506
cckdutil.c
506
cckdutil.c
@@ -356,53 +356,54 @@ union
|
||||
return (u.c[sizeof (long) - 1] == 1);
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* Remove all free space from a compressed ckd file */
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Remove all free space from a compressed ckd file
|
||||
*-------------------------------------------------------------------*/
|
||||
int comp_spctab_sort(const void *a, const void *b);
|
||||
DLL_EXPORT int cckd_comp (int fd, FILE *m)
|
||||
{
|
||||
int rc; /* Return code */
|
||||
OFF_T rcoff; /* Return value from lseek() */
|
||||
OFF_T pos; /* Current file offset */
|
||||
int i; /* Loop index */
|
||||
OFF_T rc_off; /* Return value from lseek() */
|
||||
int comp_rc=0; /* Routine return code */
|
||||
U32 pos; /* Current file position */
|
||||
int i, j, n; /* Some integers */
|
||||
int l1size; /* Primary lookup table size */
|
||||
int errs=0; /* Number of errors */
|
||||
int moves=0; /* Number of moves */
|
||||
int moved=0; /* Number bytes moved */
|
||||
int freed=0; /* Number bytes freed */
|
||||
int ckddasd; /* 1=CKD dasd 0=FBA dasd */
|
||||
CKDDASD_DEVHDR devhdr; /* CKD device header */
|
||||
CCKDDASD_DEVHDR cdevhdr; /* Compressed CKD device hdr */
|
||||
CCKD_L1ENT *l1=NULL; /* -> Primary lookup table */
|
||||
int l1tabsz; /* Primary lookup table size */
|
||||
CCKD_L2ENT l2; /* Secondary lookup table */
|
||||
CCKD_FREEBLK fb; /* Free space block */
|
||||
int len; /* Space length */
|
||||
int trksz; /* Maximum track size */
|
||||
int heads; /* Heads per cylinder */
|
||||
int blks; /* Number fba blocks */
|
||||
int trk; /* Track number */
|
||||
int l1x,l2x; /* Lookup indices */
|
||||
int freed=0; /* Total space freed */
|
||||
int imbedded=0; /* Imbedded space freed */
|
||||
int moved=0; /* Total space moved */
|
||||
int ckddasd; /* 1=CKD dasd 0=FBA dasd */
|
||||
CCKD_L2ENT **l2=NULL; /* -> Secondary lookup tables*/
|
||||
struct {
|
||||
U32 pos; /* Space offset */
|
||||
U16 len; /* Space length */
|
||||
int i, j; /* Space index */
|
||||
} *spc=NULL; /* -> Space table */
|
||||
BYTE buf[65536]; /* Buffer */
|
||||
#ifdef EXTERNALGUI
|
||||
int extgui2 = (m!= NULL && fileno(m) == fileno(stderr) && extgui);
|
||||
#endif
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* Read the headers and level 1 table */
|
||||
/*-------------------------------------------------------------------*/
|
||||
comp_restart:
|
||||
|
||||
restart:
|
||||
/* Read the headers */
|
||||
rcoff = LSEEK (fd, 0, SEEK_SET);
|
||||
if (rcoff < 0)
|
||||
/*-------------------------------------------------------------------
|
||||
* Read device header
|
||||
*-------------------------------------------------------------------*/
|
||||
rc_off = LSEEK (fd, 0, SEEK_SET);
|
||||
if (rc_off < 0)
|
||||
{
|
||||
COMPMSG (m, "lseek error offset 0: %s\n",strerror(errno));
|
||||
return -1;
|
||||
goto comp_err_exit;
|
||||
}
|
||||
rc = read (fd, &devhdr, CKDDASD_DEVHDR_SIZE);
|
||||
if (rc < (int)CKDDASD_DEVHDR_SIZE)
|
||||
if (rc < 0 || rc < (int)CKDDASD_DEVHDR_SIZE)
|
||||
{
|
||||
COMPMSG (m, "devhdr read error: %s\n",strerror(errno));
|
||||
return -1;
|
||||
goto comp_err_exit;
|
||||
}
|
||||
if (memcmp (devhdr.devid, "CKD_C370", 8) == 0
|
||||
|| memcmp (devhdr.devid, "CKD_S370", 8) == 0)
|
||||
@@ -413,13 +414,17 @@ restart:
|
||||
else
|
||||
{
|
||||
COMPMSG (m, "incorrect header id\n");
|
||||
return -1;
|
||||
goto comp_err_exit;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Read compressed device header
|
||||
*-------------------------------------------------------------------*/
|
||||
rc = read (fd, &cdevhdr, CCKDDASD_DEVHDR_SIZE);
|
||||
if (rc < (int)CCKDDASD_DEVHDR_SIZE)
|
||||
if (rc < 0 || rc < CCKDDASD_DEVHDR_SIZE)
|
||||
{
|
||||
COMPMSG (m, "cdevhdr read error: %s\n",strerror(errno));
|
||||
return -1;
|
||||
goto comp_err_exit;
|
||||
}
|
||||
cdevhdr.options |= CCKD_ORDWR;
|
||||
|
||||
@@ -428,206 +433,305 @@ restart:
|
||||
((cdevhdr.options & CCKD_BIGENDIAN) == 0 && cckd_endian() != 0))
|
||||
{
|
||||
rc = cckd_swapend (fd, m);
|
||||
if (rc < 0) return -1;
|
||||
goto restart;
|
||||
if (rc < 0) goto comp_err_exit;
|
||||
goto comp_restart;
|
||||
}
|
||||
|
||||
if (cdevhdr.free_number == 0)
|
||||
{
|
||||
COMPMSG (m, "file has no free space%s\n", "");
|
||||
return 0;
|
||||
}
|
||||
l1tabsz = cdevhdr.numl1tab * CCKD_L1ENT_SIZE;
|
||||
l1 = malloc (l1tabsz);
|
||||
/*-------------------------------------------------------------------
|
||||
* Read level 1 table
|
||||
*-------------------------------------------------------------------*/
|
||||
l1size = cdevhdr.numl1tab * CCKD_L1ENT_SIZE;
|
||||
l1 = malloc (l1size);
|
||||
if (l1 == NULL)
|
||||
{
|
||||
COMPMSG (m, "l1 table malloc error: %s\n",strerror(errno));
|
||||
return -1;
|
||||
goto comp_err_exit;
|
||||
}
|
||||
rc = read (fd, l1, l1tabsz);
|
||||
if (rc < (int)l1tabsz)
|
||||
rc = read (fd, l1, l1size);
|
||||
if (rc < 0 || rc < l1size)
|
||||
{
|
||||
COMPMSG (m, "l1 table read error: %s\n",strerror(errno));
|
||||
return -1;
|
||||
goto comp_err_exit;
|
||||
}
|
||||
|
||||
if (ckddasd)
|
||||
/*-------------------------------------------------------------------
|
||||
* Read level 2 tables
|
||||
* l2 tables will be relocated immediately after the l1 table
|
||||
*-------------------------------------------------------------------*/
|
||||
l2 = calloc (cdevhdr.numl1tab, sizeof (void *));
|
||||
if (l2 == NULL)
|
||||
{
|
||||
trksz = ((U32)(devhdr.trksize[3]) << 24)
|
||||
| ((U32)(devhdr.trksize[2]) << 16)
|
||||
| ((U32)(devhdr.trksize[1]) << 8)
|
||||
| (U32)(devhdr.trksize[0]);
|
||||
|
||||
heads = ((U32)(devhdr.heads[3]) << 24)
|
||||
| ((U32)(devhdr.heads[2]) << 16)
|
||||
| ((U32)(devhdr.heads[1]) << 8)
|
||||
| (U32)(devhdr.heads[0]);
|
||||
blks = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
trksz = CFBA_BLOCK_SIZE + CKDDASD_TRKHDR_SIZE;
|
||||
heads = -1;
|
||||
blks = ((U32)(cdevhdr.cyls[0]) << 24)
|
||||
| ((U32)(cdevhdr.cyls[2]) << 16)
|
||||
| ((U32)(cdevhdr.cyls[1]) << 8)
|
||||
| (U32)(cdevhdr.cyls[0]);
|
||||
COMPMSG (m, "l2 table calloc error: %s\n",strerror(errno));
|
||||
goto comp_err_exit;
|
||||
}
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* Relocate spaces */
|
||||
/*-------------------------------------------------------------------*/
|
||||
|
||||
/* figure out where to start; if imbedded free space
|
||||
(ie old format), start right after the level 1 table,
|
||||
otherwise start at the first free space */
|
||||
if (cdevhdr.free_imbed) pos = (OFF_T)(CCKD_L1TAB_POS + l1tabsz);
|
||||
else pos = (OFF_T)cdevhdr.free;
|
||||
|
||||
#ifdef EXTERNALGUI
|
||||
if (extgui2) fprintf (stderr,"SIZE=%llu\n",(U64)cdevhdr.size);
|
||||
#endif /*EXTERNALGUI*/
|
||||
|
||||
/* process each space in file sequence; the only spaces we expect
|
||||
are free blocks, level 2 tables, and track images */
|
||||
for ( ; pos + freed < (OFF_T)cdevhdr.size; pos += len)
|
||||
pos = CCKD_L1TAB_POS + l1size;
|
||||
for (i = 0; i < cdevhdr.numl1tab; i++)
|
||||
{
|
||||
#ifdef EXTERNALGUI
|
||||
if (extgui2) fprintf (stderr,"POS=%llu\n",(U64)pos);
|
||||
#endif /*EXTERNALGUI*/
|
||||
|
||||
/* check for free space */
|
||||
if ((U32)(pos + freed) == cdevhdr.free)
|
||||
{ /* space is free space */
|
||||
rcoff = LSEEK (fd, pos + freed, SEEK_SET);
|
||||
rc = read (fd, &fb, CCKD_FREEBLK_SIZE);
|
||||
cdevhdr.free = fb.pos;
|
||||
cdevhdr.free_number--;
|
||||
cdevhdr.free_total -= fb.len;
|
||||
freed += fb.len;
|
||||
len = 0;
|
||||
if (l1[i] == 0 || l1[i] == 0xffffffff)
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check for l2 table */
|
||||
for (i = 0; i < cdevhdr.numl1tab; i++)
|
||||
if (l1[i] == (U32)(pos + freed)) break;
|
||||
if (i < cdevhdr.numl1tab)
|
||||
{ /* space is a l2 table */
|
||||
len = CCKD_L2TAB_SIZE;
|
||||
if (freed)
|
||||
{
|
||||
rcoff = LSEEK (fd, (OFF_T)l1[i], SEEK_SET);
|
||||
rc = read (fd, buf, len);
|
||||
l1[i] -= freed;
|
||||
rcoff = LSEEK (fd, (OFF_T)l1[i], SEEK_SET);
|
||||
rc = write (fd, buf, len);
|
||||
moved += len;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check for track image */
|
||||
rcoff = LSEEK (fd, pos + freed, SEEK_SET);
|
||||
rc = read (fd, buf, 8);
|
||||
if (ckddasd)
|
||||
l2[i] = malloc (CCKD_L2TAB_SIZE);
|
||||
if (l2[i] == NULL)
|
||||
{
|
||||
trk = ((buf[1] << 8) + buf[2]) * heads
|
||||
+ ((buf[3] << 8) + buf[4]);
|
||||
COMPMSG (m, "l2[%d] table malloc error: %s\n",
|
||||
i, strerror(errno));
|
||||
goto comp_err_exit;
|
||||
}
|
||||
else
|
||||
rc_off = lseek (fd, (off_t)l1[i], SEEK_SET);
|
||||
if (rc_off < 0)
|
||||
{
|
||||
trk = (buf[1] << 24)
|
||||
| (buf[2] << 16)
|
||||
| (buf[3] << 8)
|
||||
| buf[4];
|
||||
COMPMSG (m, "l2[%d] lseek error offset %8.8x: %s\n",
|
||||
i, l1[i], strerror(errno));
|
||||
goto comp_err_exit;
|
||||
}
|
||||
l1x = trk >> 8;
|
||||
l2x = trk & 0xff;
|
||||
l2.pos = l2.len = l2.size = 0;
|
||||
if (l1[l1x])
|
||||
rc = read (fd, l2[i], CCKD_L2TAB_SIZE);
|
||||
if (rc < 0 || rc < CCKD_L2TAB_SIZE)
|
||||
{
|
||||
rcoff = LSEEK (fd, (OFF_T)(l1[l1x] + l2x * CCKD_L2ENT_SIZE), SEEK_SET);
|
||||
rc = read (fd, &l2, CCKD_L2ENT_SIZE);
|
||||
COMPMSG (m, "l2[%d] read error %d: %s\n",
|
||||
i, rc, rc < 0 ? strerror(errno) : "incomplete");
|
||||
goto comp_err_exit;
|
||||
}
|
||||
if ((OFF_T)l2.pos == pos + freed)
|
||||
{ /* space is a track image */
|
||||
len = l2.len;
|
||||
imbedded = l2.size - l2.len;
|
||||
if (freed)
|
||||
{
|
||||
rcoff = LSEEK (fd, (OFF_T)l2.pos, SEEK_SET);
|
||||
rc = read (fd, buf, len);
|
||||
l2.pos -= freed;
|
||||
rcoff = LSEEK (fd, (OFF_T)l2.pos, SEEK_SET);
|
||||
rc = write (fd, buf, len);
|
||||
}
|
||||
if (freed || imbedded )
|
||||
{
|
||||
l2.size = l2.len;
|
||||
rcoff = LSEEK (fd, (OFF_T)(l1[l1x] + l2x * CCKD_L2ENT_SIZE), SEEK_SET);
|
||||
rc = write (fd, &l2, CCKD_L2ENT_SIZE);
|
||||
}
|
||||
cdevhdr.free_imbed -= imbedded;
|
||||
cdevhdr.free_total -= imbedded;
|
||||
freed += imbedded;
|
||||
moved += len;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* space is unknown -- have to punt
|
||||
if we have freed some space, then add a free space */
|
||||
COMPMSG (m, "unknown space at offset 0x%llx : "
|
||||
"%2.2x%2.2x%2.2x%2.2x %2.2x%2.2x%2.2x%2.2x\n",
|
||||
(long long)(pos + freed), buf[0], buf[1], buf[2],
|
||||
buf[3], buf[4], buf[5], buf[6], buf[7]);
|
||||
if (freed)
|
||||
{
|
||||
fb.pos = cdevhdr.free;
|
||||
fb.len = freed;
|
||||
rcoff = LSEEK (fd, pos, SEEK_SET);
|
||||
rc = write (fd, &fb, CCKD_FREEBLK_SIZE);
|
||||
cdevhdr.free = pos;
|
||||
cdevhdr.free_number++;
|
||||
cdevhdr.free_total += freed;
|
||||
freed = 0;
|
||||
}
|
||||
break;
|
||||
l1[i] = pos;
|
||||
pos += CCKD_L2TAB_SIZE;
|
||||
}
|
||||
|
||||
/* update the largest free size -- will be zero unless we punted */
|
||||
cdevhdr.free_largest = 0;
|
||||
for (pos = cdevhdr.free; pos; pos = fb.pos)
|
||||
/*-------------------------------------------------------------------
|
||||
* Relocate any tracks within the area of the relocated l2 tables to
|
||||
* the end of the file. Also count the number of non-null tracks.
|
||||
*-------------------------------------------------------------------*/
|
||||
for (i = n = 0; i < cdevhdr.numl1tab; i++)
|
||||
{
|
||||
#ifdef EXTERNALGUI
|
||||
if (extgui2) fprintf (stderr,"POS=%llu\n",(U64)pos);
|
||||
#endif /*EXTERNALGUI*/
|
||||
rcoff = LSEEK (fd, pos, SEEK_SET);
|
||||
rc = read (fd, &fb, CCKD_FREEBLK_SIZE);
|
||||
if (fb.len > cdevhdr.free_largest)
|
||||
cdevhdr.free_largest = fb.len;
|
||||
if (l2[i] == NULL)
|
||||
continue;
|
||||
for (j = 0; j < 256; j++)
|
||||
{
|
||||
if (l2[i][j].pos == 0 || l2[i][j].pos == 0xffffffff)
|
||||
continue;
|
||||
n++;
|
||||
if (l2[i][j].pos >= pos)
|
||||
continue;
|
||||
rc_off = lseek (fd, (off_t)l2[i][j].pos, SEEK_SET);
|
||||
if (rc_off < 0)
|
||||
{
|
||||
COMPMSG (m, "%s %d lseek error offset %8.8x: %s\n",
|
||||
ckddasd ? "track" : "blkgrp", (i*256)+j,
|
||||
l2[i][j].pos, strerror(errno));
|
||||
goto comp_err_exit;
|
||||
}
|
||||
rc = read (fd, buf, l2[i][j].len);
|
||||
if (rc < 0 || rc < l2[i][j].len)
|
||||
{
|
||||
COMPMSG (m, "l2[i] read error %d: %s\n",
|
||||
i, rc, rc < 0 ? strerror(errno) : "incomplete");
|
||||
goto comp_err_exit;
|
||||
}
|
||||
rc_off = lseek (fd, (off_t)cdevhdr.size, SEEK_SET);
|
||||
if (rc_off < 0)
|
||||
{
|
||||
COMPMSG (m, "%s %d lseek error offset %8.8x: %s\n",
|
||||
ckddasd ? "track" : "blkgrp", (i*256)+j,
|
||||
cdevhdr.size, strerror(errno));
|
||||
goto comp_err_exit;
|
||||
}
|
||||
rc = write (fd, buf, l2[i][j].len);
|
||||
if (rc < 0 || rc < l2[i][j].len)
|
||||
{
|
||||
COMPMSG (m, "l2[i] write error %d: %s\n",
|
||||
i, rc, rc < 0 ? strerror(errno) : "incomplete");
|
||||
goto comp_err_exit;
|
||||
}
|
||||
l2[i][j].pos = cdevhdr.size;
|
||||
l2[i][j].size = l2[i][j].len;
|
||||
cdevhdr.size += l2[i][j].len;
|
||||
}
|
||||
}
|
||||
|
||||
/* write the compressed header and l1 table and truncate the file */
|
||||
cdevhdr.options |= CCKD_NOFUDGE;
|
||||
if (cdevhdr.free_imbed == 0)
|
||||
if (n == 0)
|
||||
{
|
||||
cdevhdr.vrm[0] = CCKD_VERSION;
|
||||
cdevhdr.vrm[1] = CCKD_RELEASE;
|
||||
cdevhdr.vrm[2] = CCKD_MODLVL;
|
||||
COMPMSG (m, "file has no non-null %s\n",
|
||||
ckddasd ? "tracks" : "blkgrps");
|
||||
goto comp_exit;
|
||||
}
|
||||
cdevhdr.size -= freed;
|
||||
rcoff = LSEEK (fd, CKDDASD_DEVHDR_SIZE, SEEK_SET);
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Build space table
|
||||
*-------------------------------------------------------------------*/
|
||||
spc = calloc (n, sizeof(spc[0]));
|
||||
if (spc == NULL)
|
||||
{
|
||||
COMPMSG (m, "space table calloc error: %s\n",strerror(errno));
|
||||
goto comp_err_exit;
|
||||
}
|
||||
for (i = n = 0; i < cdevhdr.numl1tab; i++)
|
||||
{
|
||||
if (l2[i] == NULL)
|
||||
continue;
|
||||
for (j = 0; j < 256; j++)
|
||||
{
|
||||
if (l2[i][j].pos == 0 || l2[i][j].pos == 0xffffffff)
|
||||
continue;
|
||||
spc[n].pos = l2[i][j].pos;
|
||||
spc[n].len = l2[i][j].len;
|
||||
spc[n].i = i;
|
||||
spc[n++].j = j;
|
||||
}
|
||||
}
|
||||
qsort(spc, n, sizeof(spc[0]), comp_spctab_sort);
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Relocate tracks (or blkgrps)
|
||||
*-------------------------------------------------------------------*/
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
if (spc[i].pos != pos)
|
||||
{
|
||||
rc_off = lseek (fd, (off_t)spc[i].pos, SEEK_SET);
|
||||
if (rc_off < 0)
|
||||
{
|
||||
COMPMSG (m, "%s %d lseek error offset %8.8x: %s\n",
|
||||
ckddasd ? "track" : "blkgrp",
|
||||
(spc[i].i*256)+spc[i].j,
|
||||
spc[i].pos, strerror(errno));
|
||||
l2[spc[i].i][spc[i].j].pos = l2[spc[i].i][spc[i].j].len =
|
||||
l2[spc[i].i][spc[i].j].size = 0;
|
||||
errs++;
|
||||
continue;
|
||||
}
|
||||
rc = read (fd, buf, spc[i].len);
|
||||
if (rc < 0 || rc < spc[i].len)
|
||||
{
|
||||
COMPMSG (m, "%s %d read error %d: %s\n",
|
||||
ckddasd ? "track" : "blkgrp",
|
||||
(spc[i].i*256)+spc[i].j, rc,
|
||||
rc < 0 ? strerror(errno) : "incomplete");
|
||||
l2[spc[i].i][spc[i].j].pos = l2[spc[i].i][spc[i].j].len =
|
||||
l2[spc[i].i][spc[i].j].size = 0;
|
||||
errs++;
|
||||
continue;
|
||||
}
|
||||
rc_off = lseek (fd, (off_t)pos, SEEK_SET);
|
||||
if (rc_off < 0)
|
||||
{
|
||||
COMPMSG (m, "%s %d lseek error offset %8.8x: %s\n",
|
||||
ckddasd ? "track" : "blkgrp",
|
||||
(spc[i].i*256)+spc[i].j,
|
||||
pos, strerror(errno));
|
||||
l2[spc[i].i][spc[i].j].pos = l2[spc[i].i][spc[i].j].len =
|
||||
l2[spc[i].i][spc[i].j].size = 0;
|
||||
errs++;
|
||||
continue;
|
||||
}
|
||||
rc = write (fd, buf, spc[i].len);
|
||||
if (rc < 0 || rc < spc[i].len)
|
||||
{
|
||||
COMPMSG (m, "%s %d write error %d: %s\n",
|
||||
ckddasd ? "track" : "blkgrp",
|
||||
(spc[i].i*256)+spc[i].j, rc,
|
||||
rc < 0 ? strerror(errno) : "incomplete");
|
||||
l2[spc[i].i][spc[i].j].pos = l2[spc[i].i][spc[i].j].len =
|
||||
l2[spc[i].i][spc[i].j].size = 0;
|
||||
errs++;
|
||||
continue;
|
||||
}
|
||||
l2[spc[i].i][spc[i].j].pos = pos;
|
||||
moves++;
|
||||
moved += spc[i].len;
|
||||
}
|
||||
l2[spc[i].i][spc[i].j].size = spc[i].len;
|
||||
pos += spc[i].len;
|
||||
}
|
||||
cdevhdr.size = cdevhdr.used = pos;
|
||||
ftruncate (fd, (off_t)pos);
|
||||
freed = spc[n-1].pos + spc[n-1].len - pos;
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Write headers and tables
|
||||
*-------------------------------------------------------------------*/
|
||||
cdevhdr.free = cdevhdr.free_total = cdevhdr.free_largest =
|
||||
cdevhdr.free_number = cdevhdr.free_imbed = 0;
|
||||
|
||||
rc_off = lseek (fd, (off_t)CKDDASD_DEVHDR_SIZE, SEEK_SET);
|
||||
if (rc_off < 0)
|
||||
{
|
||||
COMPMSG (m, "cdevhdr lseek error offset %8.8x: %s\n",
|
||||
CKDDASD_DEVHDR_SIZE, strerror(errno));
|
||||
goto comp_err_exit;
|
||||
}
|
||||
|
||||
rc = write (fd, &cdevhdr, CCKDDASD_DEVHDR_SIZE);
|
||||
rc = write (fd, l1, l1tabsz);
|
||||
rc = FTRUNCATE (fd, cdevhdr.size);
|
||||
if (rc < 0 || rc < CCKDDASD_DEVHDR_SIZE)
|
||||
{
|
||||
COMPMSG (m, "cdevhdr write error %d: %s\n",
|
||||
rc, rc < 0 ? strerror(errno) : "incomplete");
|
||||
goto comp_err_exit;
|
||||
}
|
||||
|
||||
COMPMSG (m, "file %ssuccessfully compacted, %d freed and %d moved\n",
|
||||
freed ? "" : "un", freed, moved);
|
||||
free (l1);
|
||||
rc = write (fd, l1, l1size);
|
||||
if (rc < 0 || rc < l1size)
|
||||
{
|
||||
COMPMSG (m, "l1 table write error %d: %s\n",
|
||||
rc, rc < 0 ? strerror(errno) : "incomplete");
|
||||
goto comp_err_exit;
|
||||
}
|
||||
for (i = 0; i < cdevhdr.numl1tab; i++)
|
||||
{
|
||||
if (l2[i] == NULL)
|
||||
continue;
|
||||
rc = write (fd, l2[i], CCKD_L2TAB_SIZE);
|
||||
if (rc < 0 || rc < CCKD_L2TAB_SIZE)
|
||||
{
|
||||
COMPMSG (m, "l2[%d] table write error %d: %s\n",
|
||||
i, rc, rc < 0 ? strerror(errno) : "incomplete");
|
||||
goto comp_err_exit;
|
||||
}
|
||||
}
|
||||
|
||||
return (freed ? freed : -1);
|
||||
}
|
||||
/*-------------------------------------------------------------------
|
||||
* Free storage and exit
|
||||
*-------------------------------------------------------------------*/
|
||||
comp_exit:
|
||||
if (spc)
|
||||
free (spc);
|
||||
|
||||
if (l2)
|
||||
{
|
||||
for (i = 0; i < cdevhdr.numl1tab; i++)
|
||||
if (l2[i])
|
||||
free (l2[i]);
|
||||
free (l2);
|
||||
}
|
||||
|
||||
if (l1)
|
||||
free (l1);
|
||||
|
||||
if (comp_rc == 0)
|
||||
COMPMSG (m, "completed%s: moves %d moved %d freed %d\n",
|
||||
errs ? " with errors" : "", moves, moved, freed);
|
||||
|
||||
return comp_rc;
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Error exit
|
||||
*-------------------------------------------------------------------*/
|
||||
comp_err_exit:
|
||||
comp_rc = -1;
|
||||
goto comp_exit;
|
||||
|
||||
} /* function cckd_comp */
|
||||
|
||||
/*-------------------------------------------------------------------
|
||||
* Sort space table
|
||||
*-------------------------------------------------------------------*/
|
||||
int comp_spctab_sort(const void *a, const void *b)
|
||||
{
|
||||
const struct {
|
||||
U32 pos; /* Space offset */
|
||||
U16 len; /* Space length */
|
||||
int i, j; /* Space index */
|
||||
} *x = a, *y = b; /* Entries to be sorted */
|
||||
|
||||
return x->pos < y->pos ? -1 : 1;
|
||||
} /* end function cckd_comp_sort */
|
||||
|
||||
/*-------------------------------------------------------------------*/
|
||||
/* Perform check function on a compressed ckd file */
|
||||
|
||||
Reference in New Issue
Block a user