* Ever since I added O_NOCACHE to the flags BFS is using to open its

device, the read-only detection did not work anymore; I've now added
  handy methods to correctly check for this. This fixes bug #1829.
* Volume::Initialize() now also checks if the device could really be 
  opened read/write.
* Minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24212 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2008-03-02 23:17:26 +00:00
parent 4715069375
commit e2fed6bae3

View File

@ -1,5 +1,5 @@
/*
* Copyright 2001-2007, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2001-2008, Axel Dörfler, axeld@pinc-software.de.
* This file may be used under the terms of the MIT License.
*/
@ -40,10 +40,16 @@ class DeviceOpener {
int Device() const { return fDevice; }
int Mode() const { return fMode; }
bool IsReadOnly() const { return _IsReadOnly(fMode); }
status_t GetSize(off_t *_size, uint32 *_blockSize = NULL);
private:
static bool _IsReadOnly(int mode)
{ return (mode & O_RWMASK) == O_RDONLY;}
static bool _IsReadWrite(int mode)
{ return (mode & O_RWMASK) == O_RDWR;}
int fDevice;
int fMode;
void *fBlockCache;
@ -82,7 +88,7 @@ DeviceOpener::Open(const char *device, int mode)
if (fDevice < 0)
fDevice = errno;
if (fDevice < 0 && mode == O_RDWR) {
if (fDevice < 0 && _IsReadWrite(mode)) {
// try again to open read-only (don't rely on a specific error code)
return Open(device, O_RDONLY | O_NOCACHE);
}
@ -90,7 +96,7 @@ DeviceOpener::Open(const char *device, int mode)
if (fDevice >= 0) {
// opening succeeded
fMode = mode;
if (mode == O_RDWR) {
if (_IsReadWrite(mode)) {
// check out if the device really allows for read/write access
device_geometry geometry;
if (!ioctl(fDevice, B_GET_GEOMETRY, &geometry)) {
@ -145,10 +151,9 @@ DeviceOpener::Keep()
}
/** Returns the size of the device in bytes. It uses B_GET_GEOMETRY
* to compute the size, or fstat() if that failed.
/*! Returns the size of the device in bytes. It uses B_GET_GEOMETRY
to compute the size, or fstat() if that failed.
*/
status_t
DeviceOpener::GetSize(off_t *_size, uint32 *_blockSize)
{
@ -319,7 +324,7 @@ Volume::Mount(const char *deviceName, uint32 flags)
if (fDevice < B_OK)
RETURN_ERROR(fDevice);
if (opener.Mode() == O_RDONLY)
if (opener.IsReadOnly())
fFlags |= VOLUME_READ_ONLY;
// check if it's a regular file, and if so, disable the cache for the
@ -513,8 +518,7 @@ Volume::UpdateLiveQueries(Inode *inode, const char *attribute, int32 type,
}
/*!
Checks if there is a live query whose results depend on the presence
/*! Checks if there is a live query whose results depend on the presence
or value of the specified attribute.
Don't use it if you already have all the data together to evaluate
the queries - it wouldn't safe you anything in this case.
@ -595,6 +599,9 @@ Volume::Initialize(int fd, const char *name, uint32 blockSize,
if (opener.Device() < B_OK)
return B_BAD_VALUE;
if (opener.IsReadOnly())
return B_READ_ONLY_DEVICE;
fDevice = opener.Device();
uint32 deviceBlockSize;