Skip to content

Commit

Permalink
Add new media type "NULL"
Browse files Browse the repository at this point in the history
Idea here is to be able to write large amounts of data without the
disk space restrictions.

The metadata is still written - 512bytes per block..

Signed-off-by: Mark Harvey <markh794@gmail.com>
  • Loading branch information
markh794 committed Nov 8, 2013
1 parent 306fca1 commit dfb2889
Show file tree
Hide file tree
Showing 7 changed files with 78 additions and 38 deletions.
6 changes: 4 additions & 2 deletions usr/mktape.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ static void usage(char *progname)
printf("Usage: %s -l lib -m PCL -s size -t type -d density\n",
progname);
printf(" Where 'size' is in Megabytes\n");
printf(" 'type' is data | clean | WORM\n");
printf(" 'type' is data | clean | WORM | NULL\n");
printf(" 'PCL' is Physical Cartridge Label (barcode)\n");
printf(" 'lib' is Library number\n");
printf(" 'density' can be on of the following:\n");
Expand Down Expand Up @@ -145,7 +145,7 @@ int main(int argc, char *argv[])
exit(1);
}
if (mediaType == NULL) {
printf("Please supply cart type (-t data|clean|WORM)\n\n");
printf("Please supply cart type (-t data|clean|WORM|NULL)\n\n");
usage(progname);
exit(1);
}
Expand Down Expand Up @@ -213,6 +213,8 @@ int main(int argc, char *argv[])
if (!strncmp("clean", mediaType, 5)) {
mam.MediumType = MEDIA_TYPE_CLEAN; /* Cleaning cart */
mam.MediumTypeInformation = 20; /* Max cleaning loads */
} else if (!strncmp("NULL", mediaType, 4)) {
mam.MediumType = MEDIA_TYPE_NULL; /* save metadata only */
} else if (!strncmp("WORM", mediaType, 4)) {
mam.MediumType = MEDIA_TYPE_WORM; /* WORM cart */
} else {
Expand Down
11 changes: 9 additions & 2 deletions usr/ssc.c
Original file line number Diff line number Diff line change
Expand Up @@ -251,9 +251,11 @@ uint8_t ssc_write_6(struct scsi_cmd *cmd)
"Fatal: bufsize %d, requested write of %d bytes",
lu_ssc->bufsize, sz);

/* Retrieve data from kernel */
dbuf_p->sz = sz * count;
retrieve_CDB_data(cmd->cdev, dbuf_p);

/* Retrieve data from kernel - unless media type is 'null' */
if (likely(mam.MediumType != MEDIA_TYPE_NULL))
retrieve_CDB_data(cmd->cdev, dbuf_p);

if (!lu_ssc->pm->check_restrictions(cmd))
return SAM_STAT_CHECK_CONDITION;
Expand Down Expand Up @@ -324,6 +326,11 @@ uint8_t check_restrictions(struct scsi_cmd *cmd)
case MEDIA_TYPE_DATA:
*lu_ssc->OK_2_write = 1;
break;
case MEDIA_TYPE_NULL:
*lu_ssc->OK_2_write = 1;
/* Special case - no need for more checks */
return *lu_ssc->OK_2_write;
break;
default:
*lu_ssc->OK_2_write = 0;
sam_illegal_request(E_MEDIUM_INCOMPATIBLE, NULL, sam_stat);
Expand Down
33 changes: 22 additions & 11 deletions usr/vtlcart.c
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,6 @@ int create_tape(const char *pcl, const struct MAM *mamp, uint8_t *sam_stat)
/* Write the meta file consisting of the MAM and the meta_header
structure with the filemark count initialized to zero.
*/

mam = *mamp;

memset(&meta, 0, sizeof(meta));
Expand Down Expand Up @@ -779,11 +778,11 @@ int load_tape(const char *pcl, uint8_t *sam_stat)
size_t io_size;
loff_t nread;
int rc = 0;
int null_media_type;

/* KFRDEBUG - sam_stat needs updates in lots of places here. */

/* If some other PCL is already open, return. */

if (datafile >= 0)
return 1;

Expand Down Expand Up @@ -880,6 +879,8 @@ int load_tape(const char *pcl, uint8_t *sam_stat)
goto failed;
}

null_media_type = mam.MediumType == MEDIA_TYPE_NULL ? 1 : 0;

if (mam.tape_fmt_version != TAPE_FMT_VERSION) {
MHVTL_ERR("pcl %s MAM contains incorrect media format", pcl);
sam_medium_error(E_MEDIUM_FMT_CORRUPT, sam_stat);
Expand Down Expand Up @@ -957,12 +958,13 @@ int load_tape(const char *pcl, uint8_t *sam_stat)
/* Make sure that the filemark map is consistent with the size of the
indx file.
*/

if (meta.filemark_count > 0 &&
if (meta.filemark_count && eod_blk_number &&
filemarks[meta.filemark_count - 1] >= eod_blk_number) {
MHVTL_ERR("pcl %s indx file has improper length as compared "
"to the meta file, indicating possible file corruption",
pcl);
MHVTL_ERR("Filemark count: %d eod_blk_number: %d",
meta.filemark_count, eod_blk_number);
rc = 2;
goto failed;
}
Expand All @@ -982,7 +984,9 @@ int load_tape(const char *pcl, uint8_t *sam_stat)
raw_pos.hdr.disk_blk_size;
}

if ((uint64_t)data_stat.st_size != eod_data_offset) {
if (null_media_type) {
MHVTL_LOG("Loaded NULL media type"); /* Skip check */
} else if ((uint64_t)data_stat.st_size != eod_data_offset) {
MHVTL_ERR("pcl %s file %s is not the correct length, "
"expected %" PRId64 ", actual %" PRId64, pcl,
pcl_data, eod_data_offset, data_stat.st_size);
Expand Down Expand Up @@ -1127,7 +1131,7 @@ int write_filemarks(uint32_t count, uint8_t *sam_stat)

int write_tape_block(const uint8_t *buffer, uint32_t blk_size,
uint32_t comp_size, const struct encryption *encryptp,
uint8_t comp_type, uint8_t *sam_stat)
uint8_t comp_type, uint8_t null_media_type, uint8_t *sam_stat)
{
uint32_t blk_number, disk_blk_size;
uint64_t data_offset;
Expand Down Expand Up @@ -1182,7 +1186,10 @@ int write_tape_block(const uint8_t *buffer, uint32_t blk_size,
}

/* Now write out both the data and the header. */
nwrite = pwrite(datafile, buffer, disk_blk_size, data_offset);
if (null_media_type) {
nwrite = disk_blk_size;
} else
nwrite = pwrite(datafile, buffer, disk_blk_size, data_offset);
if (nwrite != disk_blk_size) {
sam_medium_error(E_WRITE_ERROR, sam_stat);

Expand All @@ -1200,7 +1207,7 @@ int write_tape_block(const uint8_t *buffer, uint32_t blk_size,
}

nwrite = pwrite(indxfile, &raw_pos, sizeof(raw_pos),
blk_number * sizeof(raw_pos));
blk_number * sizeof(raw_pos));
if (nwrite != sizeof(raw_pos)) {
long indxsz = (blk_number - 1) * sizeof(raw_pos);

Expand All @@ -1215,9 +1222,13 @@ int write_tape_block(const uint8_t *buffer, uint32_t blk_size,
MHVTL_ERR("Error truncating indx: %s", strerror(errno));
}

MHVTL_DBG(1, "Truncating data file size: %"PRId64, data_offset);
if (ftruncate(datafile, data_offset) < 0) {
MHVTL_ERR("Error truncating data: %s", strerror(errno));
if (!null_media_type) {
MHVTL_DBG(1, "Truncating data file size: %"PRId64,
data_offset);
if (ftruncate(datafile, data_offset) < 0) {
MHVTL_ERR("Error truncating data: %s",
strerror(errno));
}
}

mkEODHeader(blk_number, data_offset);
Expand Down
1 change: 1 addition & 0 deletions usr/vtllib.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ static struct state_description {
{ "Loading", },
{ "Loading Cleaning Tape", },
{ "Loading WORM media", },
{ "Loading NULL media", },
{ "Loaded", },
{ "Loaded - Idle", },
{ "Load failed", },
Expand Down
1 change: 1 addition & 0 deletions usr/vtllib.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@
*/
#define MEDIA_TYPE_DATA 0
#define MEDIA_TYPE_WORM 1
#define MEDIA_TYPE_NULL 2
#define MEDIA_TYPE_CLEAN 6

#define MHVTL_NO_COMPRESSION 0
Expand Down
62 changes: 40 additions & 22 deletions usr/vtltape.c
Original file line number Diff line number Diff line change
Expand Up @@ -862,7 +862,7 @@ static void setup_crypto(struct scsi_cmd *cmd, struct priv_lu_ssc *lu_priv)
*
* Zero on error with sense buffer already filled in
*/
int writeBlock_nocomp(struct scsi_cmd *cmd, uint32_t src_sz)
int writeBlock_nocomp(struct scsi_cmd *cmd, uint32_t src_sz, uint8_t null_wr)
{
uint8_t *sam_stat = &cmd->dbuf_p->sam_stat;
uint8_t *src_buf = (uint8_t *)cmd->dbuf_p->data;
Expand All @@ -873,8 +873,8 @@ int writeBlock_nocomp(struct scsi_cmd *cmd, uint32_t src_sz)

setup_crypto(cmd, lu_priv);

rc = write_tape_block(src_buf, src_sz, 0, lu_priv->cryptop,
0, sam_stat);
rc = write_tape_block(src_buf, src_sz, 0, lu_priv->cryptop, 0,
null_wr, sam_stat);

lu_priv->bytesWritten_M += src_sz;
lu_priv->bytesWritten_I += src_sz;
Expand All @@ -890,7 +890,7 @@ int writeBlock_nocomp(struct scsi_cmd *cmd, uint32_t src_sz)
*
* Zero on error with sense buffer already filled in
*/
int writeBlock_lzo(struct scsi_cmd *cmd, uint32_t src_sz)
int writeBlock_lzo(struct scsi_cmd *cmd, uint32_t src_sz, uint8_t null_wr)
{
lzo_uint dest_len;
lzo_uint src_len = src_sz;
Expand All @@ -909,7 +909,7 @@ int writeBlock_lzo(struct scsi_cmd *cmd, uint32_t src_sz)

/* No compression - use the no-compression function */
if (*lu_priv->compressionFactor == MHVTL_NO_COMPRESSION)
return writeBlock_nocomp(cmd, src_sz);
return writeBlock_nocomp(cmd, src_sz, null_wr);

setup_crypto(cmd, lu_priv);

Expand Down Expand Up @@ -942,7 +942,7 @@ int writeBlock_lzo(struct scsi_cmd *cmd, uint32_t src_sz)
src_sz, (unsigned long)dest_len);

rc = write_tape_block(dest_buf, src_len, dest_len, lu_priv->cryptop,
LZO, sam_stat);
LZO, null_wr, sam_stat);

free(dest_buf);
free(wrkmem);
Expand All @@ -960,7 +960,7 @@ int writeBlock_lzo(struct scsi_cmd *cmd, uint32_t src_sz)
*
* Zero on error with sense buffer already filled in
*/
int writeBlock_zlib(struct scsi_cmd *cmd, uint32_t src_sz)
int writeBlock_zlib(struct scsi_cmd *cmd, uint32_t src_sz, uint8_t null_wr)
{
Bytef *dest_buf;
uLong dest_len;
Expand All @@ -975,7 +975,7 @@ int writeBlock_zlib(struct scsi_cmd *cmd, uint32_t src_sz)

/* No compression - use the no-compression function */
if (*lu_priv->compressionFactor == MHVTL_NO_COMPRESSION)
return writeBlock_nocomp(cmd, src_sz);
return writeBlock_nocomp(cmd, src_sz, null_wr);

setup_crypto(cmd, lu_priv);

Expand Down Expand Up @@ -1011,7 +1011,7 @@ int writeBlock_zlib(struct scsi_cmd *cmd, uint32_t src_sz)
*lu_priv->compressionFactor);

rc = write_tape_block(dest_buf, src_len, dest_len, lu_priv->cryptop,
ZLIB, sam_stat);
ZLIB, null_wr, sam_stat);

free(dest_buf);
lu_priv->bytesWritten_M += dest_len;
Expand Down Expand Up @@ -1043,16 +1043,21 @@ int writeBlock(struct scsi_cmd *cmd, uint32_t src_sz)
return src_len;
}

switch (lu_priv->compressionType) {
case LZO:
src_len = writeBlock_lzo(cmd, src_sz);
break;
case ZLIB:
src_len = writeBlock_zlib(cmd, src_sz);
break;
default:
src_len = writeBlock_nocomp(cmd, src_sz);
break;
if (lu_priv->mamp->MediumType == MEDIA_TYPE_NULL) {
/* Don't compress if null tape media */
src_len = writeBlock_nocomp(cmd, src_sz, TRUE);
} else {
switch (lu_priv->compressionType) {
case LZO:
src_len = writeBlock_lzo(cmd, src_sz, FALSE);
break;
case ZLIB:
src_len = writeBlock_zlib(cmd, src_sz, FALSE);
break;
default:
src_len = writeBlock_nocomp(cmd, src_sz, FALSE);
break;
}
}

if (!src_len) {
Expand Down Expand Up @@ -1755,6 +1760,12 @@ static int loadTape(char *PCL, uint8_t *sam_stat)
lu_ssc.pm->set_WORM(&lu->mode_pg);
MHVTL_DBG(1, "Write Once Read Many (WORM) media loaded");
break;
case MEDIA_TYPE_NULL: /* Special - don't save data, just metadata */
current_state = MHVTL_STATE_LOADING;
OK_to_write = 1; /* Reset flag to OK. */
lu_ssc.max_capacity = get_unaligned_be64(&mam.max_capacity);
sam_unit_attention(E_NOT_READY_TO_TRANSITION, sam_stat);
break;
}

/* Set TapeAlert flg 32h => */
Expand Down Expand Up @@ -1807,7 +1818,8 @@ static int loadTape(char *PCL, uint8_t *sam_stat)
MHVTL_DBG(2, "Load Capability: 0x%02x", m_detail->load_capability);

/* Now check for WORM support */
if (mam.MediumType == MEDIA_TYPE_WORM) {
switch (mam.MediumType) {
case MEDIA_TYPE_WORM:
/* If media is WORM, check drive will allow mount */
if (m_detail->load_capability & (LOAD_WORM | LOAD_RW)) {
/* Prev check will correctly set OK_to_write flag */
Expand All @@ -1819,7 +1831,8 @@ static int loadTape(char *PCL, uint8_t *sam_stat)
MHVTL_ERR("Load failed: Unable to load as WORM");
goto mismatchmedia;
}
} else if (mam.MediumType == MEDIA_TYPE_DATA) {
break;
case MEDIA_TYPE_DATA:
/* Allow media to be either RO or RW */
if (m_detail->load_capability & LOAD_RO) {
MHVTL_DBG(2, "Mounting READ ONLY");
Expand All @@ -1840,8 +1853,13 @@ static int loadTape(char *PCL, uint8_t *sam_stat)
"read/write or read-only");
goto mismatchmedia;
}
} else /* Can't write to cleaning media */
break;
case MEDIA_TYPE_NULL:
break;
default: /* Can't write to cleaning media */
OK_to_write = 0;
break;
}

/* Update TapeAlert flags */
update_TapeAlert(lu, fg);
Expand Down
2 changes: 1 addition & 1 deletion usr/vtltape.h
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ uint32_t read_tape_block(uint8_t *buf, uint32_t size, uint8_t *sam_stat);
int write_filemarks(uint32_t count, uint8_t *sam_stat);
int write_tape_block(const uint8_t *buf, uint32_t uncomp_size,
uint32_t comp_size, const struct encryption *cp,
uint8_t comp_type, uint8_t *sam_stat);
uint8_t comp_type, uint8_t null_type, uint8_t *sam_stat);
int format_tape(uint8_t *sam_stat);

int rewriteMAM(uint8_t *sam_stat);
Expand Down

0 comments on commit dfb2889

Please sign in to comment.