int format_tape(uint8_t *sam_stat) { if (!tape_loaded(sam_stat)) return -1; if (check_for_overwrite(sam_stat)) return -1; zero_filemark_count(); return mkEODHeader(raw_pos.hdr.blk_number, raw_pos.data_offset); }
int format_tape(uint8_t *sam_stat) { MHVTL_DBG(1, "format_tape"); if (!tape_loaded(sam_stat)) return -1; if (check_for_overwrite(sam_stat)) return -1; zero_filemark_count(); return mkEODHeader(raw_pos.hdr.blk_number); }
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 null_media_type, uint8_t *sam_stat) { uint32_t blk_number, disk_blk_size; uint32_t max_blk_number; uint64_t data_offset; ssize_t nwrite; /* Medium format limits to unsigned 32bit blks */ max_blk_number = 0xfffffff0; if (!tape_loaded(sam_stat)) return -1; if (check_for_overwrite(sam_stat)) return -1; /* Preserve existing raw_pos data we need, then clear out raw_pos and fill it in with new data. */ blk_number = raw_pos.hdr.blk_number; data_offset = raw_pos.data_offset; if (blk_number > max_blk_number) { MHVTL_ERR("Too many tape blocks - 32byte overflow"); return -1; } memset(&raw_pos, 0, sizeof(raw_pos)); raw_pos.data_offset = data_offset; raw_pos.hdr.blk_type = B_DATA; /* Header type */ raw_pos.hdr.blk_flags = 0; raw_pos.hdr.blk_number = blk_number; raw_pos.hdr.blk_size = blk_size; /* Size of uncompressed data */ if (comp_size) { if (comp_type == LZO) raw_pos.hdr.blk_flags |= BLKHDR_FLG_LZO_COMPRESSED; else raw_pos.hdr.blk_flags |= BLKHDR_FLG_ZLIB_COMPRESSED; raw_pos.hdr.disk_blk_size = disk_blk_size = comp_size; } else raw_pos.hdr.disk_blk_size = disk_blk_size = blk_size; if (encryptp != NULL) { unsigned int i; raw_pos.hdr.blk_flags |= BLKHDR_FLG_ENCRYPTED; raw_pos.hdr.encryption.ukad_length = encryptp->ukad_length; for (i = 0; i < encryptp->ukad_length; ++i) raw_pos.hdr.encryption.ukad[i] = encryptp->ukad[i]; raw_pos.hdr.encryption.akad_length = encryptp->akad_length; for (i = 0; i < encryptp->akad_length; ++i) raw_pos.hdr.encryption.akad[i] = encryptp->akad[i]; raw_pos.hdr.encryption.key_length = encryptp->key_length; for (i = 0; i < encryptp->key_length; ++i) raw_pos.hdr.encryption.key[i] = encryptp->key[i]; } /* Now write out both the data and the header. */ 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); MHVTL_ERR("Data file write failure, pos: %" PRId64 ": %s", data_offset, strerror(errno)); /* Truncate last partital write */ 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); return -1; } nwrite = pwrite(indxfile, &raw_pos, sizeof(raw_pos), blk_number * sizeof(raw_pos)); if (nwrite != sizeof(raw_pos)) { long indxsz = (blk_number - 1) * sizeof(raw_pos); sam_medium_error(E_WRITE_ERROR, sam_stat); MHVTL_ERR("Index file write failure, pos: %" PRId64 ": %s", (uint64_t)blk_number * sizeof(raw_pos), strerror(errno)); MHVTL_DBG(1, "Truncating index file size to: %ld", indxsz); if (ftruncate(indxfile, indxsz) < 0) { MHVTL_ERR("Error truncating indx: %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); return -1; } MHVTL_DBG(3, "Successfully wrote block: %u", blk_number); return mkEODHeader(blk_number + 1, data_offset + disk_blk_size); }
int write_filemarks(uint32_t count, uint8_t *sam_stat) { uint32_t blk_number; uint64_t data_offset; ssize_t nwrite; if (!tape_loaded(sam_stat)) return -1; /* Applications assume that writing a filemark (even writing zero filemarks) will force-flush any data buffered in the drive to media so that after the write-filemarks call returns there is no possibility that any data previously written could be lost due to a power hit. Provide a similar guarantee here. */ if (count == 0) { MHVTL_DBG(2, "Flushing data - 0 filemarks written"); fsync(datafile); fsync(indxfile); fsync(metafile); return 0; } if (check_for_overwrite(sam_stat)) return -1; /* Preserve existing raw_pos data we need, then clear raw_pos and fill it in with new data. */ blk_number = raw_pos.hdr.blk_number; data_offset = raw_pos.data_offset; memset(&raw_pos, 0, sizeof(raw_pos)); raw_pos.data_offset = data_offset; raw_pos.hdr.blk_type = B_FILEMARK; /* Header type */ raw_pos.hdr.blk_flags = 0; raw_pos.hdr.blk_number = blk_number; raw_pos.hdr.blk_size = 0; raw_pos.hdr.disk_blk_size = 0; /* Now write out one header per filemark. */ for ( ; count > 0; count--, blk_number++) { raw_pos.hdr.blk_number = blk_number; MHVTL_DBG(3, "Writing filemark: block %d", blk_number); nwrite = pwrite(indxfile, &raw_pos, sizeof(raw_pos), blk_number * sizeof(raw_pos)); if (nwrite != sizeof(raw_pos)) { sam_medium_error(E_WRITE_ERROR, sam_stat); MHVTL_ERR("Index file write failure," " pos: %" PRId64 ": %s", (uint64_t)blk_number * sizeof(raw_pos), strerror(errno)); return -1; } add_filemark(blk_number); } /* Provide the force-flush guarantee. */ fsync(datafile); fsync(indxfile); fsync(metafile); return mkEODHeader(blk_number, data_offset); }
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) { uint32_t blk_number, disk_blk_size; uint64_t data_offset; ssize_t nwrite; if (!tape_loaded(sam_stat)) { return -1; } if (check_for_overwrite(sam_stat)) { return -1; } /* Preserve existing raw_pos data we need, then clear out raw_pos and fill it in with new data. */ blk_number = raw_pos.hdr.blk_number; data_offset = raw_pos.data_offset; memset(&raw_pos, 0, sizeof(raw_pos)); raw_pos.data_offset = data_offset; raw_pos.hdr.blk_type = B_DATA; /* Header type */ raw_pos.hdr.blk_flags = 0; raw_pos.hdr.blk_number = blk_number; raw_pos.hdr.blk_size = blk_size; /* Size of uncompressed data */ if (comp_size) { if (comp_type == LZO) raw_pos.hdr.blk_flags |= BLKHDR_FLG_LZO_COMPRESSED; else raw_pos.hdr.blk_flags |= BLKHDR_FLG_ZLIB_COMPRESSED; raw_pos.hdr.disk_blk_size = disk_blk_size = comp_size; } else { raw_pos.hdr.disk_blk_size = disk_blk_size = blk_size; } if (encryptp != NULL) { unsigned int i; raw_pos.hdr.blk_flags |= BLKHDR_FLG_ENCRYPTED; raw_pos.hdr.encryption.ukad_length = encryptp->ukad_length; for (i = 0; i < encryptp->ukad_length; ++i) { raw_pos.hdr.encryption.ukad[i] = encryptp->ukad[i]; } raw_pos.hdr.encryption.akad_length = encryptp->akad_length; for (i = 0; i < encryptp->akad_length; ++i) { raw_pos.hdr.encryption.akad[i] = encryptp->akad[i]; } raw_pos.hdr.encryption.key_length = encryptp->key_length; for (i = 0; i < encryptp->key_length; ++i) { raw_pos.hdr.encryption.key[i] = encryptp->key[i]; } } /* Now write out both the header and the data. */ nwrite = pwrite(indxfile, &raw_pos, sizeof(raw_pos), blk_number * sizeof(raw_pos)); if (nwrite != sizeof(raw_pos)) { mkSenseBuf(MEDIUM_ERROR, E_WRITE_ERROR, sam_stat); MHVTL_ERR("Index file write failure, pos: %" PRId64 ": %s", (uint64_t)blk_number * sizeof(raw_pos), strerror(errno)); return -1; } nwrite = pwrite(datafile, buffer, disk_blk_size, data_offset); if (nwrite != disk_blk_size) { mkSenseBuf(MEDIUM_ERROR, E_WRITE_ERROR, sam_stat); MHVTL_ERR("Data file write failure, pos: %" PRId64 ": %s", data_offset, strerror(errno)); return -1; } MHVTL_DBG(3, "Successfully wrote block: %u", blk_number); return mkEODHeader(blk_number + 1, data_offset + disk_blk_size); }