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();
|
void Keep();
|
||||||
|
|
||||||
int Device() const { return fDevice; }
|
int Device() const { return fDevice; }
|
||||||
|
int Mode() const { return fMode; }
|
||||||
|
|
||||||
status_t GetSize(off_t *_size, uint32 *_blockSize = NULL);
|
status_t GetSize(off_t *_size, uint32 *_blockSize = NULL);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int fDevice;
|
int fDevice;
|
||||||
|
int fMode;
|
||||||
void *fBlockCache;
|
void *fBlockCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -76,6 +78,27 @@ int
|
|||||||
DeviceOpener::Open(const char *device, int mode)
|
DeviceOpener::Open(const char *device, int mode)
|
||||||
{
|
{
|
||||||
fDevice = open(device, 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;
|
return fDevice;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,9 +280,6 @@ Volume::Panic()
|
|||||||
status_t
|
status_t
|
||||||
Volume::Mount(const char *deviceName, uint32 flags)
|
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!
|
// ToDo: validate the FS in write mode as well!
|
||||||
#if (B_HOST_IS_LENDIAN && defined(BFS_BIG_ENDIAN_ONLY)) \
|
#if (B_HOST_IS_LENDIAN && defined(BFS_BIG_ENDIAN_ONLY)) \
|
||||||
|| (B_HOST_IS_BENDIAN && defined(BFS_LITTLE_ENDIAN_ONLY))
|
|| (B_HOST_IS_BENDIAN && defined(BFS_LITTLE_ENDIAN_ONLY))
|
||||||
@@ -268,17 +288,13 @@ Volume::Mount(const char *deviceName, uint32 flags)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
DeviceOpener opener(deviceName, flags & B_MOUNT_READ_ONLY ? O_RDONLY : O_RDWR);
|
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();
|
fDevice = opener.Device();
|
||||||
if (fDevice < B_OK)
|
if (fDevice < B_OK)
|
||||||
RETURN_ERROR(fDevice);
|
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
|
// check if it's a regular file, and if so, disable the cache for the
|
||||||
// underlaying file system
|
// underlaying file system
|
||||||
struct stat stat;
|
struct stat stat;
|
||||||
|
|||||||
Reference in New Issue
Block a user