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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user