Moved the "reopen when read-only" logic into the DeviceOpener class.

Since CD-ROMs let open themselves read/write, it now also checks the device
geometry, and will make sure the device is opened read-only if the geometry
structure says so - this should reduce the number of write errors you get
during boot :-)
Volume::fFlags is now always correctly maintained.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14414 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-10-18 19:58:19 +00:00
parent 0fc0129604
commit 636d40373d
+26 -10
View File
@@ -46,11 +46,13 @@ class DeviceOpener {
void Keep();
int Device() const { return fDevice; }
int Mode() const { return fMode; }
status_t GetSize(off_t *_size, uint32 *_blockSize = NULL);
private:
int fDevice;
int fMode;
void *fBlockCache;
};
@@ -76,6 +78,27 @@ int
DeviceOpener::Open(const char *device, int mode)
{
fDevice = open(device, mode);
if (fDevice < 0 && mode == O_RDWR) {
// try again to open read-only (don't rely on a specific error code)
return Open(device, O_RDONLY);
}
if (fDevice >= 0) {
// opening succeeded
fMode = mode;
if (mode == O_RDWR) {
// check out if the device really allows for read/write access
device_geometry geometry;
if (!ioctl(fDevice, B_GET_GEOMETRY, &geometry)) {
if (geometry.read_only) {
// reopen device read-only
close(fDevice);
return Open(device, O_RDONLY);
}
}
}
}
return fDevice;
}
@@ -257,9 +280,6 @@ Volume::Panic()
status_t
Volume::Mount(const char *deviceName, uint32 flags)
{
if (flags & B_MOUNT_READ_ONLY)
fFlags |= VOLUME_READ_ONLY;
// ToDo: validate the FS in write mode as well!
#if (B_HOST_IS_LENDIAN && defined(BFS_BIG_ENDIAN_ONLY)) \
|| (B_HOST_IS_BENDIAN && defined(BFS_LITTLE_ENDIAN_ONLY))
@@ -268,17 +288,13 @@ Volume::Mount(const char *deviceName, uint32 flags)
#endif
DeviceOpener opener(deviceName, flags & B_MOUNT_READ_ONLY ? O_RDONLY : O_RDWR);
// if we couldn't open the device, try read-only (don't rely on a specific error code)
if (opener.Device() < B_OK && (flags & B_MOUNT_READ_ONLY) == 0) {
opener.Open(deviceName, O_RDONLY);
fFlags |= VOLUME_READ_ONLY;
}
fDevice = opener.Device();
if (fDevice < B_OK)
RETURN_ERROR(fDevice);
if (opener.Mode() == O_RDONLY)
fFlags |= VOLUME_READ_ONLY;
// check if it's a regular file, and if so, disable the cache for the
// underlaying file system
struct stat stat;