Improve MO support by removing capacity restrictions (#284)

* Improve MO support by removing capacity restrictions, resolves #283

* Updated geometry handling
This commit is contained in:
Uwe Seimet 2021-09-29 18:05:30 +02:00 committed by GitHub
parent b3b740e3cc
commit 682d35f1e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 24 additions and 47 deletions

View File

@ -28,7 +28,7 @@ DeviceFactory::DeviceFactory()
sector_sizes[SAHD] = { 256, 1024 };
sector_sizes[SCHD] = { 512, 1024, 2048, 4096 };
sector_sizes[SCRM] = { 512, 1024, 2048, 4096 };
sector_sizes[SCMO] = {};
sector_sizes[SCMO] = { 512, 1024, 2048, 4096 };
// Some old Sun CD-ROM drives support 512 bytes per sector
sector_sizes[SCCD] = { 512, 2048};
sector_sizes[SCBR] = {};
@ -170,6 +170,7 @@ Device *DeviceFactory::CreateDevice(PbDeviceType type, const string& filename)
device->SetRemovable(true);
device->SetLockable(true);
device->SetProduct("SCSI MO");
((Disk *)device)->SetSectorSizes(sector_sizes[SCRM]);
((Disk *)device)->SetGeometries(geometries[SCMO]);
break;

View File

@ -46,6 +46,7 @@ private:
map<PbDeviceType, set<uint32_t>> sector_sizes;
// Optional mapping of drive capacities to drive geometries
map<PbDeviceType, map<uint64_t, Geometry>> geometries;
map<PbDeviceType, map<string, string>> default_params;

View File

@ -1690,33 +1690,19 @@ bool Disk::SetConfiguredSectorSize(uint32_t configured_sector_size)
void Disk::SetGeometries(const map<uint64_t, Geometry>& geometries)
{
if (!IsMo()) {
throw illegal_argument_exception("Can't set geometry for");
}
this->geometries = geometries;
}
void Disk::SetGeometryForCapacity(uint64_t capacity) {
bool Disk::SetGeometryForCapacity(uint64_t capacity) {
const auto& geometry = geometries.find(capacity);
if (geometry != geometries.end()) {
SetSectorSizeInBytes(geometry->second.first, false);
SetBlockCount(geometry->second.second);
if (geometry == geometries.end()) {
ostringstream error;
error << "Invalid file size of " << capacity << " bytes. Supported file sizes are ";
bool isFirst = true;
for (const auto& g : geometries) {
if (!isFirst) {
error << ", ";
}
error << g.first << " bytes";
isFirst = false;
}
error << ".";
throw io_exception(error.str());
return true;
}
SetSectorSizeInBytes(geometry->second.first, false);
SetBlockCount(geometry->second.second);
return false;
}
uint64_t Disk::GetBlockCount() const

View File

@ -134,7 +134,7 @@ public:
uint32_t GetConfiguredSectorSize() const;
bool SetConfiguredSectorSize(uint32_t);
void SetGeometries(const map<uint64_t, Geometry>&);
void SetGeometryForCapacity(uint64_t);
bool SetGeometryForCapacity(uint64_t);
uint64_t GetBlockCount() const;
void SetBlockCount(uint32_t);
bool GetStartAndCount(SASIDEV *, uint64_t&, uint32_t&, access_mode);

View File

@ -19,6 +19,7 @@
#include "../rascsi.h"
#include "fileio.h"
#include "exceptions.h"
#include <sstream>
//===========================================================================
//
@ -55,7 +56,19 @@ void SCSIMO::Open(const Filepath& path)
off_t size = fio.GetFileSize();
fio.Close();
SetGeometryForCapacity(size);
// For some priorities there are hard-coded, well-defined sector sizes and block counts
if (!SetGeometryForCapacity(size)) {
// Sector size (default 512 bytes) and number of blocks
SetSectorSizeInBytes(GetConfiguredSectorSize() ? GetConfiguredSectorSize() : 512, true);
SetBlockCount(size >> GetSectorSize());
}
// File size must be a multiple of the sector size
if (size % GetSectorSizeInBytes()) {
stringstream error;
error << "File size must be a multiple of " << GetSectorSizeInBytes() << " bytes but is " << size << " bytes";
throw io_exception(error.str());
}
SetReadOnly(false);
SetProtectable(true);

View File

@ -65,10 +65,6 @@ PbDeviceProperties *ProtobufResponseHandler::GetDeviceProperties(const Device *d
properties->add_block_sizes(block_size);
}
for (const auto& capacity : device_factory.GetCapacities(t)) {
properties->add_capacities(capacity);
}
return properties;
}

View File

@ -160,8 +160,6 @@ message PbDeviceProperties {
uint32 luns = 9;
// Unordered list of permitted block sizes in bytes, empty if the block size is not configurable
repeated uint32 block_sizes = 10;
// Unordered list of permitted media capacities in bytes, empty if there is no capacity restriction
repeated uint64 capacities = 11;
}
// The status of a device, only meaningful if the respective feature is supported

View File

@ -231,24 +231,6 @@ void DisplayDeviceTypesInfo(const PbDeviceTypesInfo& device_types_info)
}
cout << endl;
}
if (properties.capacities_size()) {
list<uint64_t> capacities = { properties.capacities().begin(), properties.capacities().end() };
capacities.sort([](const auto& a, const auto& b) { return a < b; });
cout << " Media capacities in bytes: ";
bool isFirst = true;
for (const auto& capacity : capacities) {
if (!isFirst) {
cout << ", ";
}
cout << capacity;
isFirst = false;
}
cout << endl;
}
}
}