* 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:
parent
4715069375
commit
e2fed6bae3
@ -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.
|
* This file may be used under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -40,10 +40,16 @@ class DeviceOpener {
|
|||||||
|
|
||||||
int Device() const { return fDevice; }
|
int Device() const { return fDevice; }
|
||||||
int Mode() const { return fMode; }
|
int Mode() const { return fMode; }
|
||||||
|
bool IsReadOnly() const { return _IsReadOnly(fMode); }
|
||||||
|
|
||||||
status_t GetSize(off_t *_size, uint32 *_blockSize = NULL);
|
status_t GetSize(off_t *_size, uint32 *_blockSize = NULL);
|
||||||
|
|
||||||
private:
|
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 fDevice;
|
||||||
int fMode;
|
int fMode;
|
||||||
void *fBlockCache;
|
void *fBlockCache;
|
||||||
@ -82,7 +88,7 @@ DeviceOpener::Open(const char *device, int mode)
|
|||||||
if (fDevice < 0)
|
if (fDevice < 0)
|
||||||
fDevice = errno;
|
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)
|
// try again to open read-only (don't rely on a specific error code)
|
||||||
return Open(device, O_RDONLY | O_NOCACHE);
|
return Open(device, O_RDONLY | O_NOCACHE);
|
||||||
}
|
}
|
||||||
@ -90,7 +96,7 @@ DeviceOpener::Open(const char *device, int mode)
|
|||||||
if (fDevice >= 0) {
|
if (fDevice >= 0) {
|
||||||
// opening succeeded
|
// opening succeeded
|
||||||
fMode = mode;
|
fMode = mode;
|
||||||
if (mode == O_RDWR) {
|
if (_IsReadWrite(mode)) {
|
||||||
// check out if the device really allows for read/write access
|
// check out if the device really allows for read/write access
|
||||||
device_geometry geometry;
|
device_geometry geometry;
|
||||||
if (!ioctl(fDevice, B_GET_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
|
/*! Returns the size of the device in bytes. It uses B_GET_GEOMETRY
|
||||||
* to compute the size, or fstat() if that failed.
|
to compute the size, or fstat() if that failed.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
DeviceOpener::GetSize(off_t *_size, uint32 *_blockSize)
|
DeviceOpener::GetSize(off_t *_size, uint32 *_blockSize)
|
||||||
{
|
{
|
||||||
@ -319,7 +324,7 @@ Volume::Mount(const char *deviceName, uint32 flags)
|
|||||||
if (fDevice < B_OK)
|
if (fDevice < B_OK)
|
||||||
RETURN_ERROR(fDevice);
|
RETURN_ERROR(fDevice);
|
||||||
|
|
||||||
if (opener.Mode() == O_RDONLY)
|
if (opener.IsReadOnly())
|
||||||
fFlags |= VOLUME_READ_ONLY;
|
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
|
||||||
@ -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.
|
or value of the specified attribute.
|
||||||
Don't use it if you already have all the data together to evaluate
|
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.
|
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)
|
if (opener.Device() < B_OK)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
if (opener.IsReadOnly())
|
||||||
|
return B_READ_ONLY_DEVICE;
|
||||||
|
|
||||||
fDevice = opener.Device();
|
fDevice = opener.Device();
|
||||||
|
|
||||||
uint32 deviceBlockSize;
|
uint32 deviceBlockSize;
|
||||||
|
Loading…
Reference in New Issue
Block a user