Implemented rescanning the device list. A few things, e.g. notifications and change counter updates, are still missing. Added a periodical rescan event.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2694 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -9,20 +9,29 @@
|
|||||||
#include "DiskDeviceManager.h"
|
#include "DiskDeviceManager.h"
|
||||||
#include "Debug.h"
|
#include "Debug.h"
|
||||||
#include "EventMaskWatcher.h"
|
#include "EventMaskWatcher.h"
|
||||||
|
#include "EventQueue.h"
|
||||||
|
#include "MessageEvent.h"
|
||||||
#include "RDiskDevice.h"
|
#include "RDiskDevice.h"
|
||||||
#include "RDiskDeviceList.h"
|
#include "RDiskDeviceList.h"
|
||||||
#include "RPartition.h"
|
#include "RPartition.h"
|
||||||
#include "RSession.h"
|
#include "RSession.h"
|
||||||
|
|
||||||
|
// priorities of the different message kinds
|
||||||
enum {
|
enum {
|
||||||
REQUEST_PRIORITY = 0,
|
REQUEST_PRIORITY = 0,
|
||||||
|
RESCAN_PRIORITY = 5,
|
||||||
NODE_MONITOR_PRIORITY = 10,
|
NODE_MONITOR_PRIORITY = 10,
|
||||||
WATCHING_REQUEST_PRIORITY = 20,
|
WATCHING_REQUEST_PRIORITY = 20,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// time interval between device rescans
|
||||||
|
static const bigtime_t kRescanEventInterval = 5000000;
|
||||||
|
|
||||||
// constructor
|
// constructor
|
||||||
DiskDeviceManager::DiskDeviceManager()
|
DiskDeviceManager::DiskDeviceManager(EventQueue *eventQueue)
|
||||||
: BLooper("disk device manager"),
|
: BLooper("disk device manager"),
|
||||||
|
fEventQueue(eventQueue),
|
||||||
|
fRescanEvent(NULL),
|
||||||
fDeviceListLock(),
|
fDeviceListLock(),
|
||||||
fWatchingService(),
|
fWatchingService(),
|
||||||
fVolumeList(BMessenger(this), fDeviceListLock),
|
fVolumeList(BMessenger(this), fDeviceListLock),
|
||||||
@@ -45,11 +54,19 @@ DiskDeviceManager::DiskDeviceManager()
|
|||||||
if (fWorker >= 0)
|
if (fWorker >= 0)
|
||||||
resume_thread(fWorker);
|
resume_thread(fWorker);
|
||||||
}
|
}
|
||||||
|
// set up the rescan event
|
||||||
|
fRescanEvent = new MessageEvent(system_time() + kRescanEventInterval,
|
||||||
|
this, B_REG_ROSTER_DEVICE_RESCAN);
|
||||||
|
fRescanEvent->SetAutoDelete(false);
|
||||||
|
fEventQueue->AddEvent(fRescanEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
// destructor
|
// destructor
|
||||||
DiskDeviceManager::~DiskDeviceManager()
|
DiskDeviceManager::~DiskDeviceManager()
|
||||||
{
|
{
|
||||||
|
// remove the rescan event from the event queue
|
||||||
|
fEventQueue->RemoveEvent(fRescanEvent);
|
||||||
|
// terminate the worker thread
|
||||||
fTerminating = true;
|
fTerminating = true;
|
||||||
delete_sem(fMessageCounter);
|
delete_sem(fMessageCounter);
|
||||||
int32 dummy;
|
int32 dummy;
|
||||||
@@ -74,6 +91,11 @@ DiskDeviceManager::MessageReceived(BMessage *message)
|
|||||||
if (!_PushMessage(message, WATCHING_REQUEST_PRIORITY))
|
if (!_PushMessage(message, WATCHING_REQUEST_PRIORITY))
|
||||||
delete message;
|
delete message;
|
||||||
break;
|
break;
|
||||||
|
case B_REG_ROSTER_DEVICE_RESCAN:
|
||||||
|
DetachCurrentMessage();
|
||||||
|
if (!_PushMessage(message, RESCAN_PRIORITY))
|
||||||
|
delete message;
|
||||||
|
break;
|
||||||
case B_NODE_MONITOR:
|
case B_NODE_MONITOR:
|
||||||
DetachCurrentMessage();
|
DetachCurrentMessage();
|
||||||
if (!_PushMessage(message, NODE_MONITOR_PRIORITY))
|
if (!_PushMessage(message, NODE_MONITOR_PRIORITY))
|
||||||
@@ -307,6 +329,12 @@ DiskDeviceManager::_Worker()
|
|||||||
case B_REG_DEVICE_STOP_WATCHING:
|
case B_REG_DEVICE_STOP_WATCHING:
|
||||||
_StopWatchingRequest(message);
|
_StopWatchingRequest(message);
|
||||||
break;
|
break;
|
||||||
|
case B_REG_ROSTER_DEVICE_RESCAN:
|
||||||
|
fDeviceList.Rescan();
|
||||||
|
fRescanEvent->SetTime(system_time()
|
||||||
|
+ kRescanEventInterval);
|
||||||
|
fEventQueue->AddEvent(fRescanEvent);
|
||||||
|
break;
|
||||||
case B_NODE_MONITOR:
|
case B_NODE_MONITOR:
|
||||||
{
|
{
|
||||||
fVolumeList.HandleMessage(message);
|
fVolumeList.HandleMessage(message);
|
||||||
|
|||||||
@@ -15,9 +15,12 @@
|
|||||||
#include "RVolumeList.h"
|
#include "RVolumeList.h"
|
||||||
#include "WatchingService.h"
|
#include "WatchingService.h"
|
||||||
|
|
||||||
|
class EventQueue;
|
||||||
|
class MessageEvent;
|
||||||
|
|
||||||
class DiskDeviceManager : public BLooper {
|
class DiskDeviceManager : public BLooper {
|
||||||
public:
|
public:
|
||||||
DiskDeviceManager();
|
DiskDeviceManager(EventQueue *eventQueue);
|
||||||
virtual ~DiskDeviceManager();
|
virtual ~DiskDeviceManager();
|
||||||
|
|
||||||
virtual void MessageReceived(BMessage *message);
|
virtual void MessageReceived(BMessage *message);
|
||||||
@@ -37,6 +40,11 @@ private:
|
|||||||
int32 _Worker();
|
int32 _Worker();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
class RescanEvent;
|
||||||
|
|
||||||
|
private:
|
||||||
|
EventQueue *fEventQueue;
|
||||||
|
MessageEvent *fRescanEvent;
|
||||||
BLocker fDeviceListLock;
|
BLocker fDeviceListLock;
|
||||||
WatchingService fWatchingService;
|
WatchingService fWatchingService;
|
||||||
RVolumeList fVolumeList;
|
RVolumeList fVolumeList;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ RDiskDevice::RDiskDevice()
|
|||||||
: fSessions(10, true),
|
: fSessions(10, true),
|
||||||
fDeviceList(NULL),
|
fDeviceList(NULL),
|
||||||
fID(-1),
|
fID(-1),
|
||||||
fChangeCounter(0),
|
fChangeCounter(),
|
||||||
fTouched(false),
|
fTouched(false),
|
||||||
fPath(),
|
fPath(),
|
||||||
fFD(-1),
|
fFD(-1),
|
||||||
@@ -45,7 +45,7 @@ PRINT(("RDiskDevice::SetTo()\n"));
|
|||||||
Unset();
|
Unset();
|
||||||
status_t error = B_OK;
|
status_t error = B_OK;
|
||||||
fID = _NextID();
|
fID = _NextID();
|
||||||
fChangeCounter = 0;
|
fChangeCounter.Reset();
|
||||||
fTouched = true;
|
fTouched = true;
|
||||||
fPath.SetTo(path);
|
fPath.SetTo(path);
|
||||||
fFD = fd;
|
fFD = fd;
|
||||||
@@ -68,28 +68,8 @@ PRINT(("RDiskDevice::SetTo()\n"));
|
|||||||
error = fMediaStatus;
|
error = fMediaStatus;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// scan the device for sessions, if we have a media
|
// scan the device for sessions
|
||||||
if (fMediaStatus == B_OK) {
|
error = _RescanSessions(B_DEVICE_CAUSE_UNKNOWN);
|
||||||
session_info sessionInfo;
|
|
||||||
for (int32 i = 0; ; i++) {
|
|
||||||
// get the session info
|
|
||||||
status_t status = get_nth_session_info(fFD, i, &sessionInfo);
|
|
||||||
if (status != B_OK) {
|
|
||||||
if (status != B_ENTRY_NOT_FOUND)
|
|
||||||
error = status;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// create and add a RSession
|
|
||||||
if (RSession *session = new(nothrow) RSession) {
|
|
||||||
error = session->SetTo(fFD, &sessionInfo);
|
|
||||||
if (error == B_OK)
|
|
||||||
AddSession(session);
|
|
||||||
else
|
|
||||||
delete session;
|
|
||||||
} else
|
|
||||||
error = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// cleanup on error
|
// cleanup on error
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
Unset();
|
Unset();
|
||||||
@@ -102,7 +82,7 @@ void
|
|||||||
RDiskDevice::Unset()
|
RDiskDevice::Unset()
|
||||||
{
|
{
|
||||||
for (int32 i = CountSessions() - 1; i >= 0; i--)
|
for (int32 i = CountSessions() - 1; i >= 0; i--)
|
||||||
RemoveSession(i);
|
RemoveSession(i, B_DEVICE_CAUSE_UNKNOWN);
|
||||||
fID = -1;
|
fID = -1;
|
||||||
fPath.SetTo("");
|
fPath.SetTo("");
|
||||||
if (fFD >= 0) {
|
if (fFD >= 0) {
|
||||||
@@ -111,6 +91,51 @@ RDiskDevice::Unset()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MediaChanged
|
||||||
|
status_t
|
||||||
|
RDiskDevice::MediaChanged()
|
||||||
|
{
|
||||||
|
PRINT(("RDiskDevice::MediaChanged()\n"));
|
||||||
|
status_t error = B_OK;
|
||||||
|
// get the new media status
|
||||||
|
status_t mediaStatus;
|
||||||
|
if (ioctl(fFD, B_GET_MEDIA_STATUS, &mediaStatus) == 0) {
|
||||||
|
fMediaStatus = mediaStatus;
|
||||||
|
// analyze the media status
|
||||||
|
switch (fMediaStatus) {
|
||||||
|
case B_NO_ERROR:
|
||||||
|
case B_DEV_NO_MEDIA:
|
||||||
|
case B_DEV_NOT_READY:
|
||||||
|
case B_DEV_MEDIA_CHANGE_REQUESTED:
|
||||||
|
case B_DEV_DOOR_OPEN:
|
||||||
|
break;
|
||||||
|
case B_DEV_MEDIA_CHANGED:
|
||||||
|
// Ignore changes between the our ioctl() and the one before;
|
||||||
|
// we rescan the sessions anyway.
|
||||||
|
fMediaStatus = B_OK;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
error = fMediaStatus;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// rescan sessions
|
||||||
|
error = _RescanSessions(B_DEVICE_CAUSE_PARENT_CHANGED);
|
||||||
|
// TODO: send notification
|
||||||
|
// ...
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SessionLayoutChanged
|
||||||
|
status_t
|
||||||
|
RDiskDevice::SessionLayoutChanged()
|
||||||
|
{
|
||||||
|
PRINT(("RDiskDevice::SessionLayoutChanged()\n"));
|
||||||
|
status_t error = B_OK;
|
||||||
|
error = _RescanSessions(B_DEVICE_CAUSE_UNKNOWN);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
// Size
|
// Size
|
||||||
off_t
|
off_t
|
||||||
RDiskDevice::Size() const
|
RDiskDevice::Size() const
|
||||||
@@ -119,9 +144,25 @@ RDiskDevice::Size() const
|
|||||||
* fGeometry.cylinder_count * fGeometry.head_count;
|
* fGeometry.cylinder_count * fGeometry.head_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddSession
|
||||||
|
status_t
|
||||||
|
RDiskDevice::AddSession(const session_info *sessionInfo, uint32 cause)
|
||||||
|
{
|
||||||
|
status_t error = B_OK;
|
||||||
|
if (RSession *session = new(nothrow) RSession) {
|
||||||
|
error = session->SetTo(fFD, sessionInfo);
|
||||||
|
if (error == B_OK)
|
||||||
|
AddSession(session, cause);
|
||||||
|
else
|
||||||
|
delete session;
|
||||||
|
} else
|
||||||
|
error = B_NO_MEMORY;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
// AddSession
|
// AddSession
|
||||||
bool
|
bool
|
||||||
RDiskDevice::AddSession(RSession *session)
|
RDiskDevice::AddSession(RSession *session, uint32 cause)
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (session) {
|
if (session) {
|
||||||
@@ -129,7 +170,7 @@ RDiskDevice::AddSession(RSession *session)
|
|||||||
if (success) {
|
if (success) {
|
||||||
session->SetDevice(this);
|
session->SetDevice(this);
|
||||||
if (RDiskDeviceList *deviceList = DeviceList())
|
if (RDiskDeviceList *deviceList = DeviceList())
|
||||||
deviceList->SessionAdded(session);
|
deviceList->SessionAdded(session, cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
@@ -137,12 +178,12 @@ RDiskDevice::AddSession(RSession *session)
|
|||||||
|
|
||||||
// RemoveSession
|
// RemoveSession
|
||||||
bool
|
bool
|
||||||
RDiskDevice::RemoveSession(int32 index)
|
RDiskDevice::RemoveSession(int32 index, uint32 cause)
|
||||||
{
|
{
|
||||||
RSession *session = SessionAt(index);
|
RSession *session = SessionAt(index);
|
||||||
if (session) {
|
if (session) {
|
||||||
if (RDiskDeviceList *deviceList = DeviceList())
|
if (RDiskDeviceList *deviceList = DeviceList())
|
||||||
deviceList->SessionRemoved(session);
|
deviceList->SessionRemoved(session, cause);
|
||||||
session->SetDevice(NULL);
|
session->SetDevice(NULL);
|
||||||
fSessions.RemoveItemAt(index);
|
fSessions.RemoveItemAt(index);
|
||||||
delete session;
|
delete session;
|
||||||
@@ -152,13 +193,13 @@ RDiskDevice::RemoveSession(int32 index)
|
|||||||
|
|
||||||
// RemoveSession
|
// RemoveSession
|
||||||
bool
|
bool
|
||||||
RDiskDevice::RemoveSession(RSession *session)
|
RDiskDevice::RemoveSession(RSession *session, uint32 cause)
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (session) {
|
if (session) {
|
||||||
int32 index = fSessions.IndexOf(session);
|
int32 index = fSessions.IndexOf(session);
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
success = RemoveSession(index);
|
success = RemoveSession(index, cause);
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
@@ -167,7 +208,55 @@ RDiskDevice::RemoveSession(RSession *session)
|
|||||||
status_t
|
status_t
|
||||||
RDiskDevice::Update()
|
RDiskDevice::Update()
|
||||||
{
|
{
|
||||||
return B_ERROR;
|
status_t error = B_OK;
|
||||||
|
status_t mediaStatus = B_OK;
|
||||||
|
if (ioctl(fFD, B_GET_MEDIA_STATUS, &mediaStatus) == 0) {
|
||||||
|
if (mediaStatus == B_DEV_MEDIA_CHANGED
|
||||||
|
|| (mediaStatus == B_NO_ERROR) != (fMediaStatus == B_NO_ERROR)) {
|
||||||
|
// The media status is B_DEV_MEDIA_CHANGED or it changed from
|
||||||
|
// B_NO_ERROR to some error code or the other way around.
|
||||||
|
error = MediaChanged();
|
||||||
|
} else {
|
||||||
|
// TODO: notifications?
|
||||||
|
fMediaStatus = mediaStatus;
|
||||||
|
// The media has not been changed. If this is a read-only device,
|
||||||
|
// then we are safe, since nothing can have changed. Otherwise
|
||||||
|
// we check the sessions.
|
||||||
|
if (!IsReadOnly() && fMediaStatus == B_OK) {
|
||||||
|
session_info sessionInfo;
|
||||||
|
for (int32 i = 0; error == B_OK; i++) {
|
||||||
|
// get the session info
|
||||||
|
status_t status = get_nth_session_info(fFD, i,
|
||||||
|
&sessionInfo);
|
||||||
|
if (status != B_OK) {
|
||||||
|
if (status == B_ENTRY_NOT_FOUND) {
|
||||||
|
// remove disappeared sessions
|
||||||
|
for (int32 k = CountSessions() - 1; k >= i; k--)
|
||||||
|
RemoveSession(k, B_DEVICE_CAUSE_UNKNOWN);
|
||||||
|
} else
|
||||||
|
error = status;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// check the session
|
||||||
|
if (RSession *session = SessionAt(i)) {
|
||||||
|
if (session->Offset() == sessionInfo.offset
|
||||||
|
&& session->Size() == sessionInfo.size) {
|
||||||
|
session->Update(&sessionInfo);
|
||||||
|
} else {
|
||||||
|
// session layout changed
|
||||||
|
error = SessionLayoutChanged();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// session added
|
||||||
|
error = AddSession(&sessionInfo,
|
||||||
|
B_DEVICE_CAUSE_UNKNOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Archive
|
// Archive
|
||||||
@@ -179,7 +268,7 @@ RDiskDevice::Archive(BMessage *archive) const
|
|||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = archive->AddInt32("id", fID);
|
error = archive->AddInt32("id", fID);
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = archive->AddInt32("change_counter", fChangeCounter);
|
error = archive->AddInt32("change_counter", ChangeCounter());
|
||||||
// geometry
|
// geometry
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = archive->AddInt64("size", Size());
|
error = archive->AddInt64("size", Size());
|
||||||
@@ -219,6 +308,32 @@ RDiskDevice::Dump() const
|
|||||||
session->Dump();
|
session->Dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _RescanSessions
|
||||||
|
status_t
|
||||||
|
RDiskDevice::_RescanSessions(uint32 cause)
|
||||||
|
{
|
||||||
|
status_t error = B_OK;
|
||||||
|
// remove the current sessions
|
||||||
|
for (int32 i = CountSessions() - 1; i >= 0; i--)
|
||||||
|
RemoveSession(i, cause);
|
||||||
|
// scan the device for sessions, if we have a media
|
||||||
|
if (fMediaStatus == B_OK) {
|
||||||
|
session_info sessionInfo;
|
||||||
|
for (int32 i = 0; error == B_OK; i++) {
|
||||||
|
// get the session info
|
||||||
|
status_t status = get_nth_session_info(fFD, i, &sessionInfo);
|
||||||
|
if (status != B_OK) {
|
||||||
|
if (status != B_ENTRY_NOT_FOUND)
|
||||||
|
error = status;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// create and add a RSession
|
||||||
|
error = AddSession(&sessionInfo, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
}
|
||||||
|
|
||||||
// _NextID
|
// _NextID
|
||||||
int32
|
int32
|
||||||
RDiskDevice::_NextID()
|
RDiskDevice::_NextID()
|
||||||
|
|||||||
@@ -10,6 +10,10 @@
|
|||||||
#include <ObjectList.h>
|
#include <ObjectList.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
|
#include "RChangeCounter.h"
|
||||||
|
|
||||||
|
struct session_info;
|
||||||
|
|
||||||
class RDiskDeviceList;
|
class RDiskDeviceList;
|
||||||
class RPartition;
|
class RPartition;
|
||||||
class RSession;
|
class RSession;
|
||||||
@@ -27,20 +31,31 @@ public:
|
|||||||
{ fDeviceList = deviceList ;}
|
{ fDeviceList = deviceList ;}
|
||||||
RDiskDeviceList *DeviceList() const { return fDeviceList; }
|
RDiskDeviceList *DeviceList() const { return fDeviceList; }
|
||||||
|
|
||||||
|
status_t MediaChanged();
|
||||||
|
status_t SessionLayoutChanged();
|
||||||
|
|
||||||
int32 ID() const { return fID; }
|
int32 ID() const { return fID; }
|
||||||
int32 ChangeCounter() const { return fChangeCounter; }
|
int32 ChangeCounter() const { return fChangeCounter.Count(); }
|
||||||
|
void Changed() { fChangeCounter.Increment(); }
|
||||||
|
|
||||||
void SetTouched(bool touched) { fTouched = touched; }
|
void SetTouched(bool touched) { fTouched = touched; }
|
||||||
bool Touched() const { return fTouched; }
|
bool Touched() const { return fTouched; }
|
||||||
|
|
||||||
|
int FD() const { return fFD; }
|
||||||
off_t Size() const;
|
off_t Size() const;
|
||||||
int32 BlockSize() const { return fGeometry.bytes_per_sector; }
|
int32 BlockSize() const { return fGeometry.bytes_per_sector; }
|
||||||
|
bool IsReadOnly() { return fGeometry.read_only; }
|
||||||
|
|
||||||
const char *Path() const { return fPath.String(); }
|
const char *Path() const { return fPath.String(); }
|
||||||
|
|
||||||
bool AddSession(RSession *session);
|
status_t AddSession(const session_info *sessionInfo,
|
||||||
bool RemoveSession(int32 index);
|
uint32 cause/* = B_DEVICE_CAUSE_UNKNOWN*/);
|
||||||
bool RemoveSession(RSession *session);
|
bool AddSession(RSession *session,
|
||||||
|
uint32 cause/* = B_DEVICE_CAUSE_UNKNOWN*/);
|
||||||
|
bool RemoveSession(int32 index,
|
||||||
|
uint32 cause/* = B_DEVICE_CAUSE_UNKNOWN*/);
|
||||||
|
bool RemoveSession(RSession *session,
|
||||||
|
uint32 cause/* = B_DEVICE_CAUSE_UNKNOWN*/);
|
||||||
int32 CountSessions() const { return fSessions.CountItems(); }
|
int32 CountSessions() const { return fSessions.CountItems(); }
|
||||||
RSession *SessionAt(int32 index) const { return fSessions.ItemAt(index); }
|
RSession *SessionAt(int32 index) const { return fSessions.ItemAt(index); }
|
||||||
int32 IndexOfSession(const RSession *session) const
|
int32 IndexOfSession(const RSession *session) const
|
||||||
@@ -53,13 +68,15 @@ public:
|
|||||||
void Dump() const;
|
void Dump() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
status_t _RescanSessions(uint32 cause);
|
||||||
|
|
||||||
static int32 _NextID();
|
static int32 _NextID();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BObjectList<RSession> fSessions;
|
BObjectList<RSession> fSessions;
|
||||||
RDiskDeviceList *fDeviceList;
|
RDiskDeviceList *fDeviceList;
|
||||||
int32 fID;
|
int32 fID;
|
||||||
int32 fChangeCounter;
|
RChangeCounter fChangeCounter;
|
||||||
bool fTouched;
|
bool fTouched;
|
||||||
BString fPath;
|
BString fPath;
|
||||||
int fFD;
|
int fFD;
|
||||||
|
|||||||
@@ -186,6 +186,52 @@ RDiskDeviceList::MountPointMoved(const RVolume *volume,
|
|||||||
Unlock();
|
Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeviceAppeared
|
||||||
|
void
|
||||||
|
RDiskDeviceList::DeviceAppeared(const char *devicePath)
|
||||||
|
{
|
||||||
|
status_t error = (devicePath ? B_OK : B_BAD_VALUE);
|
||||||
|
if (error == B_OK) {
|
||||||
|
int fd = open(devicePath, O_RDONLY);
|
||||||
|
if (fd >= 0) {
|
||||||
|
bool closeFile = true;
|
||||||
|
device_geometry geometry;
|
||||||
|
status_t mediaStatus = B_OK;
|
||||||
|
partition_info partitionInfo;
|
||||||
|
if (ioctl(fd, B_GET_MEDIA_STATUS, &mediaStatus) == 0
|
||||||
|
&& ioctl(fd, B_GET_GEOMETRY, &geometry) == 0
|
||||||
|
&& ioctl(fd, B_GET_PARTITION_INFO, &partitionInfo) < 0) {
|
||||||
|
PRINT(("RDiskDeviceList::DeviceAppeared(`%s')\n", devicePath));
|
||||||
|
RDiskDevice *device = new(nothrow) RDiskDevice;
|
||||||
|
if (device) {
|
||||||
|
error = device->SetTo(devicePath, fd, &geometry,
|
||||||
|
mediaStatus);
|
||||||
|
if (error == B_OK) {
|
||||||
|
closeFile = false;
|
||||||
|
device->SetTouched(true);
|
||||||
|
AddDevice(device);
|
||||||
|
} else
|
||||||
|
delete device;
|
||||||
|
} else
|
||||||
|
error = B_NO_MEMORY;
|
||||||
|
}
|
||||||
|
if (closeFile)
|
||||||
|
close(fd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeviceDisappeared
|
||||||
|
void
|
||||||
|
RDiskDeviceList::DeviceDisappeared(const char *devicePath)
|
||||||
|
{
|
||||||
|
PRINT(("RDiskDeviceList::DeviceDisappeared(`%s')\n", devicePath));
|
||||||
|
if (devicePath) {
|
||||||
|
if (RDiskDevice *device = DeviceWithPath(devicePath))
|
||||||
|
RemoveDevice(device);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// AddDevice
|
// AddDevice
|
||||||
bool
|
bool
|
||||||
RDiskDeviceList::AddDevice(RDiskDevice *device)
|
RDiskDeviceList::AddDevice(RDiskDevice *device)
|
||||||
@@ -280,6 +326,9 @@ status_t
|
|||||||
RDiskDeviceList::Rescan()
|
RDiskDeviceList::Rescan()
|
||||||
{
|
{
|
||||||
FUNCTION_START();
|
FUNCTION_START();
|
||||||
|
// TODO: This method should be reworked, as soon as we react on events only
|
||||||
|
// and don't need to poll anymore. This method will then do an initial
|
||||||
|
// scan only.
|
||||||
status_t error = B_OK;
|
status_t error = B_OK;
|
||||||
if (Lock()) {
|
if (Lock()) {
|
||||||
// marked all devices untouched
|
// marked all devices untouched
|
||||||
@@ -292,8 +341,9 @@ FUNCTION_START();
|
|||||||
}
|
}
|
||||||
// remove all untouched devices
|
// remove all untouched devices
|
||||||
for (int32 i = CountDevices() - 1; i >= 0; i--) {
|
for (int32 i = CountDevices() - 1; i >= 0; i--) {
|
||||||
if (!DeviceAt(i)->Touched())
|
RDiskDevice *device = DeviceAt(i);
|
||||||
RemoveDevice(i);
|
if (!device->Touched())
|
||||||
|
DeviceDisappeared(device->Path());
|
||||||
}
|
}
|
||||||
Unlock();
|
Unlock();
|
||||||
} else
|
} else
|
||||||
@@ -410,17 +460,11 @@ RDiskDeviceList::Dump() const
|
|||||||
status_t
|
status_t
|
||||||
RDiskDeviceList::_Scan(BDirectory &dir)
|
RDiskDeviceList::_Scan(BDirectory &dir)
|
||||||
{
|
{
|
||||||
//BEntry dirEntry;
|
|
||||||
//BPath dirPath;
|
|
||||||
//dir.GetEntry(&dirEntry);
|
|
||||||
//dirEntry.GetPath(&dirPath);
|
|
||||||
//PRINT(("RDiskDeviceList::_Scan(`%s')\n", dirPath.Path()));
|
|
||||||
status_t error = B_OK;
|
status_t error = B_OK;
|
||||||
BEntry entry;
|
BEntry entry;
|
||||||
while (dir.GetNextEntry(&entry) == B_OK) {
|
while (dir.GetNextEntry(&entry) == B_OK) {
|
||||||
struct stat st;
|
struct stat st;
|
||||||
if (entry.GetStat(&st) == B_OK) {
|
if (entry.GetStat(&st) == B_OK) {
|
||||||
//PRINT(("st.st_mode: 0x%x\n", st.st_mode & S_IFMT));
|
|
||||||
if (S_ISDIR(st.st_mode)) {
|
if (S_ISDIR(st.st_mode)) {
|
||||||
BDirectory subdir;
|
BDirectory subdir;
|
||||||
if (subdir.SetTo(&entry) == B_OK)
|
if (subdir.SetTo(&entry) == B_OK)
|
||||||
@@ -444,37 +488,13 @@ RDiskDeviceList::_ScanDevice(const char *path)
|
|||||||
// search the list for a device with that path
|
// search the list for a device with that path
|
||||||
if (RDiskDevice *device = DeviceWithPath(path)) {
|
if (RDiskDevice *device = DeviceWithPath(path)) {
|
||||||
// found: just update it
|
// found: just update it
|
||||||
|
device->SetTouched(true);
|
||||||
error = device->Update();
|
error = device->Update();
|
||||||
} else {
|
} else {
|
||||||
// not found: check whether it is really a disk device and add it to
|
// not found: check whether it is really a disk device and add it to
|
||||||
// the list
|
// the list
|
||||||
int fd = open(path, O_RDONLY);
|
// The event hook does the work anyway:
|
||||||
if (fd >= 0) {
|
DeviceAppeared(path);
|
||||||
bool closeFile = true;
|
|
||||||
device_geometry geometry;
|
|
||||||
status_t mediaStatus = B_OK;
|
|
||||||
partition_info partitionInfo;
|
|
||||||
if (ioctl(fd, B_GET_MEDIA_STATUS, &mediaStatus) == 0
|
|
||||||
&& ioctl(fd, B_GET_GEOMETRY, &geometry) == 0
|
|
||||||
&& ioctl(fd, B_GET_PARTITION_INFO, &partitionInfo) < 0) {
|
|
||||||
// int32 blockSize = geometry.bytes_per_sector;
|
|
||||||
// off_t deviceSize = (off_t)blockSize
|
|
||||||
// * geometry.sectors_per_track * geometry.cylinder_count
|
|
||||||
// * geometry.head_count;
|
|
||||||
RDiskDevice *device = new(nothrow) RDiskDevice;
|
|
||||||
if (device) {
|
|
||||||
error = device->SetTo(path, fd, &geometry, mediaStatus);
|
|
||||||
if (error == B_OK) {
|
|
||||||
closeFile = false;
|
|
||||||
AddDevice(device);
|
|
||||||
} else
|
|
||||||
delete device;
|
|
||||||
} else
|
|
||||||
error = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
if (closeFile)
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,11 +43,14 @@ public:
|
|||||||
|
|
||||||
virtual void HandleMessage(BMessage *message);
|
virtual void HandleMessage(BMessage *message);
|
||||||
|
|
||||||
|
// external event hooks
|
||||||
virtual void VolumeMounted(const RVolume *volume);
|
virtual void VolumeMounted(const RVolume *volume);
|
||||||
virtual void VolumeUnmounted(const RVolume *volume);
|
virtual void VolumeUnmounted(const RVolume *volume);
|
||||||
virtual void MountPointMoved(const RVolume *volume,
|
virtual void MountPointMoved(const RVolume *volume,
|
||||||
const entry_ref *oldRoot,
|
const entry_ref *oldRoot,
|
||||||
const entry_ref *newRoot);
|
const entry_ref *newRoot);
|
||||||
|
virtual void DeviceAppeared(const char *devicePath);
|
||||||
|
virtual void DeviceDisappeared(const char *devicePath);
|
||||||
|
|
||||||
bool AddDevice(RDiskDevice *device);
|
bool AddDevice(RDiskDevice *device);
|
||||||
bool RemoveDevice(int32 index);
|
bool RemoveDevice(int32 index);
|
||||||
@@ -74,6 +77,7 @@ public:
|
|||||||
bool Lock();
|
bool Lock();
|
||||||
void Unlock();
|
void Unlock();
|
||||||
|
|
||||||
|
// internal event hooks
|
||||||
void DeviceAdded(RDiskDevice *device,
|
void DeviceAdded(RDiskDevice *device,
|
||||||
uint32 cause = B_DEVICE_CAUSE_UNKNOWN);
|
uint32 cause = B_DEVICE_CAUSE_UNKNOWN);
|
||||||
void DeviceRemoved(RDiskDevice *device,
|
void DeviceRemoved(RDiskDevice *device,
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
RPartition::RPartition()
|
RPartition::RPartition()
|
||||||
: fSession(NULL),
|
: fSession(NULL),
|
||||||
fID(-1),
|
fID(-1),
|
||||||
fChangeCounter(0),
|
fChangeCounter(),
|
||||||
fVolume(NULL)
|
fVolume(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -29,7 +29,7 @@ RPartition::SetTo(int fd, const extended_partition_info *partitionInfo)
|
|||||||
Unset();
|
Unset();
|
||||||
status_t error = B_OK;
|
status_t error = B_OK;
|
||||||
fID = _NextID();
|
fID = _NextID();
|
||||||
fChangeCounter = 0;
|
fChangeCounter.Reset();
|
||||||
fInfo = *partitionInfo;
|
fInfo = *partitionInfo;
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
@@ -55,6 +55,14 @@ RPartition::Device() const
|
|||||||
return (fSession ? fSession->Device() : NULL);
|
return (fSession ? fSession->Device() : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Changed
|
||||||
|
void
|
||||||
|
RPartition::Changed()
|
||||||
|
{
|
||||||
|
if (fChangeCounter.Increment() && fSession)
|
||||||
|
fSession->Changed();
|
||||||
|
}
|
||||||
|
|
||||||
// Index
|
// Index
|
||||||
int32
|
int32
|
||||||
RPartition::Index() const
|
RPartition::Index() const
|
||||||
@@ -76,6 +84,16 @@ RPartition::GetPath(char *path) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update
|
||||||
|
status_t
|
||||||
|
RPartition::Update(const extended_partition_info *partitionInfo)
|
||||||
|
{
|
||||||
|
status_t error = B_OK;
|
||||||
|
// TODO: Check the partition info for changes!
|
||||||
|
fInfo = *partitionInfo;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
// Archive
|
// Archive
|
||||||
status_t
|
status_t
|
||||||
RPartition::Archive(BMessage *archive) const
|
RPartition::Archive(BMessage *archive) const
|
||||||
@@ -85,7 +103,7 @@ RPartition::Archive(BMessage *archive) const
|
|||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = archive->AddInt32("id", fID);
|
error = archive->AddInt32("id", fID);
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = archive->AddInt32("change_counter", fChangeCounter);
|
error = archive->AddInt32("change_counter", ChangeCounter());
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = archive->AddInt32("index", Index());
|
error = archive->AddInt32("index", Index());
|
||||||
// fInfo.info.*
|
// fInfo.info.*
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include <disk_scanner.h>
|
#include <disk_scanner.h>
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
#include "RChangeCounter.h"
|
||||||
|
|
||||||
class BMessage;
|
class BMessage;
|
||||||
|
|
||||||
class RDiskDevice;
|
class RDiskDevice;
|
||||||
@@ -30,18 +32,23 @@ public:
|
|||||||
RSession *Session() const { return fSession; }
|
RSession *Session() const { return fSession; }
|
||||||
|
|
||||||
int32 ID() const { return fID; }
|
int32 ID() const { return fID; }
|
||||||
int32 ChangeCounter() const { return fChangeCounter; }
|
int32 ChangeCounter() const { return fChangeCounter.Count(); }
|
||||||
|
void Changed();
|
||||||
|
|
||||||
int32 Index() const;
|
int32 Index() const;
|
||||||
|
|
||||||
const extended_partition_info *Info() const { return &fInfo; }
|
const extended_partition_info *Info() const { return &fInfo; }
|
||||||
void GetPath(char *path) const;
|
void GetPath(char *path) const;
|
||||||
|
off_t Offset() const { return fInfo.info.offset; }
|
||||||
|
off_t Size() const { return fInfo.info.size; }
|
||||||
|
|
||||||
void SetVolume(const RVolume *volume) { fVolume = volume; }
|
void SetVolume(const RVolume *volume) { fVolume = volume; }
|
||||||
const RVolume *Volume() const { return fVolume; }
|
const RVolume *Volume() const { return fVolume; }
|
||||||
|
|
||||||
status_t Archive(BMessage *archive) const;
|
status_t Archive(BMessage *archive) const;
|
||||||
|
|
||||||
|
status_t Update(const extended_partition_info *partitionInfo);
|
||||||
|
|
||||||
void Dump() const;
|
void Dump() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -50,7 +57,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
RSession *fSession;
|
RSession *fSession;
|
||||||
int32 fID;
|
int32 fID;
|
||||||
int32 fChangeCounter;
|
RChangeCounter fChangeCounter;
|
||||||
extended_partition_info fInfo;
|
extended_partition_info fInfo;
|
||||||
const RVolume *fVolume;
|
const RVolume *fVolume;
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ RSession::RSession()
|
|||||||
: fPartitions(10, true),
|
: fPartitions(10, true),
|
||||||
fDevice(NULL),
|
fDevice(NULL),
|
||||||
fID(-1),
|
fID(-1),
|
||||||
fChangeCounter(0)
|
fChangeCounter()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,29 +33,10 @@ RSession::SetTo(int fd, const session_info *sessionInfo)
|
|||||||
Unset();
|
Unset();
|
||||||
status_t error = B_OK;
|
status_t error = B_OK;
|
||||||
fID = _NextID();
|
fID = _NextID();
|
||||||
fChangeCounter = 0;
|
fChangeCounter.Reset();
|
||||||
fInfo = *sessionInfo;
|
fInfo = *sessionInfo;
|
||||||
// iterate through the partitions
|
// scan for partitions
|
||||||
for (int32 i = 0; ; i++) {
|
error = _RescanPartitions(fd, B_DEVICE_CAUSE_UNKNOWN);
|
||||||
// get the partition info
|
|
||||||
extended_partition_info partitionInfo;
|
|
||||||
status_t status = get_nth_partition_info(fd, sessionInfo->index, i,
|
|
||||||
&partitionInfo, (i == 0 ? fPartitioningSystem : NULL));
|
|
||||||
if (status != B_OK) {
|
|
||||||
if (status != B_ENTRY_NOT_FOUND)
|
|
||||||
error = status;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// create and add a RPartition
|
|
||||||
if (RPartition *partition = new(nothrow) RPartition) {
|
|
||||||
error = partition->SetTo(fd, &partitionInfo);
|
|
||||||
if (error == B_OK)
|
|
||||||
AddPartition(partition);
|
|
||||||
else
|
|
||||||
delete partition;
|
|
||||||
} else
|
|
||||||
error = B_NO_MEMORY;
|
|
||||||
}
|
|
||||||
// cleanup on error
|
// cleanup on error
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
Unset();
|
Unset();
|
||||||
@@ -67,7 +48,7 @@ void
|
|||||||
RSession::Unset()
|
RSession::Unset()
|
||||||
{
|
{
|
||||||
for (int32 i = CountPartitions() - 1; i >= 0; i--)
|
for (int32 i = CountPartitions() - 1; i >= 0; i--)
|
||||||
RemovePartition(i);
|
RemovePartition(i, B_DEVICE_CAUSE_UNKNOWN);
|
||||||
fID = -1;
|
fID = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,6 +59,25 @@ RSession::DeviceList() const
|
|||||||
return (fDevice ? fDevice->DeviceList() : NULL);
|
return (fDevice ? fDevice->DeviceList() : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PartitionLayoutChanged
|
||||||
|
status_t
|
||||||
|
RSession::PartitionLayoutChanged()
|
||||||
|
{
|
||||||
|
PRINT(("RSession::PartitionLayoutChanged()\n"));
|
||||||
|
status_t error = (fDevice ? B_OK : B_ERROR);
|
||||||
|
if (error == B_OK)
|
||||||
|
error = _RescanPartitions(fDevice->FD(), B_DEVICE_CAUSE_UNKNOWN);
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Changed
|
||||||
|
void
|
||||||
|
RSession::Changed()
|
||||||
|
{
|
||||||
|
if (fChangeCounter.Increment() && fDevice)
|
||||||
|
fDevice->Changed();
|
||||||
|
}
|
||||||
|
|
||||||
// Index
|
// Index
|
||||||
int32
|
int32
|
||||||
RSession::Index() const
|
RSession::Index() const
|
||||||
@@ -87,9 +87,26 @@ RSession::Index() const
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AddPartition
|
||||||
|
status_t
|
||||||
|
RSession::AddPartition(int fd, const extended_partition_info *partitionInfo,
|
||||||
|
uint32 cause)
|
||||||
|
{
|
||||||
|
status_t error = B_OK;
|
||||||
|
if (RPartition *partition = new(nothrow) RPartition) {
|
||||||
|
error = partition->SetTo(fd, partitionInfo);
|
||||||
|
if (error == B_OK)
|
||||||
|
AddPartition(partition, cause);
|
||||||
|
else
|
||||||
|
delete partition;
|
||||||
|
} else
|
||||||
|
error = B_NO_MEMORY;
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
// AddPartition
|
// AddPartition
|
||||||
bool
|
bool
|
||||||
RSession::AddPartition(RPartition *partition)
|
RSession::AddPartition(RPartition *partition, uint32 cause)
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (partition) {
|
if (partition) {
|
||||||
@@ -97,7 +114,7 @@ RSession::AddPartition(RPartition *partition)
|
|||||||
if (success) {
|
if (success) {
|
||||||
partition->SetSession(this);
|
partition->SetSession(this);
|
||||||
if (RDiskDeviceList *deviceList = DeviceList())
|
if (RDiskDeviceList *deviceList = DeviceList())
|
||||||
deviceList->PartitionAdded(partition);
|
deviceList->PartitionAdded(partition, cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
@@ -105,12 +122,12 @@ RSession::AddPartition(RPartition *partition)
|
|||||||
|
|
||||||
// RemovePartition
|
// RemovePartition
|
||||||
bool
|
bool
|
||||||
RSession::RemovePartition(int32 index)
|
RSession::RemovePartition(int32 index, uint32 cause)
|
||||||
{
|
{
|
||||||
RPartition *partition = PartitionAt(index);
|
RPartition *partition = PartitionAt(index);
|
||||||
if (partition) {
|
if (partition) {
|
||||||
if (RDiskDeviceList *deviceList = DeviceList())
|
if (RDiskDeviceList *deviceList = DeviceList())
|
||||||
deviceList->PartitionRemoved(partition);
|
deviceList->PartitionRemoved(partition, cause);
|
||||||
partition->SetSession(NULL);
|
partition->SetSession(NULL);
|
||||||
fPartitions.RemoveItemAt(index);
|
fPartitions.RemoveItemAt(index);
|
||||||
delete partition;
|
delete partition;
|
||||||
@@ -120,17 +137,66 @@ RSession::RemovePartition(int32 index)
|
|||||||
|
|
||||||
// RemovePartition
|
// RemovePartition
|
||||||
bool
|
bool
|
||||||
RSession::RemovePartition(RPartition *partition)
|
RSession::RemovePartition(RPartition *partition, uint32 cause)
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
if (partition) {
|
if (partition) {
|
||||||
int32 index = fPartitions.IndexOf(partition);
|
int32 index = fPartitions.IndexOf(partition);
|
||||||
if (index >= 0)
|
if (index >= 0)
|
||||||
success = RemovePartition(index);
|
success = RemovePartition(index, cause);
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update
|
||||||
|
status_t
|
||||||
|
RSession::Update(const session_info *sessionInfo)
|
||||||
|
{
|
||||||
|
status_t error = (fDevice ? B_OK : B_ERROR);
|
||||||
|
// TODO: Check the session info for changes!
|
||||||
|
fInfo = *sessionInfo;
|
||||||
|
int fd = (fDevice ? fDevice->FD() : -1);
|
||||||
|
// check the partitions
|
||||||
|
for (int32 i = 0; error == B_OK; i++) {
|
||||||
|
// get the partition info
|
||||||
|
extended_partition_info partitionInfo;
|
||||||
|
char partitioningSystem[B_FILE_NAME_LENGTH];
|
||||||
|
status_t status = get_nth_partition_info(fd, sessionInfo->index, i,
|
||||||
|
&partitionInfo, (i == 0 ? partitioningSystem : NULL));
|
||||||
|
// check the partitioning system
|
||||||
|
if ((status == B_OK || status == B_ENTRY_NOT_FOUND) && i == 0
|
||||||
|
&& strcmp(partitioningSystem, fPartitioningSystem)) {
|
||||||
|
// partitioning system has changed
|
||||||
|
error = PartitionLayoutChanged();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (status != B_OK) {
|
||||||
|
if (status == B_ENTRY_NOT_FOUND) {
|
||||||
|
// remove disappeared partitions
|
||||||
|
for (int32 k = CountPartitions() - 1; k >= i; k--)
|
||||||
|
RemovePartition(k, B_DEVICE_CAUSE_UNKNOWN);
|
||||||
|
} else
|
||||||
|
error = status;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// check the partition
|
||||||
|
if (RPartition *partition = PartitionAt(i)) {
|
||||||
|
if (partition->Offset() == partitionInfo.info.offset
|
||||||
|
&& partition->Size() == partitionInfo.info.size) {
|
||||||
|
partition->Update(&partitionInfo);
|
||||||
|
} else {
|
||||||
|
// partition layout changed
|
||||||
|
error = PartitionLayoutChanged();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// partition added
|
||||||
|
error = AddPartition(fd, &partitionInfo, B_DEVICE_CAUSE_UNKNOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
// Archive
|
// Archive
|
||||||
status_t
|
status_t
|
||||||
RSession::Archive(BMessage *archive) const
|
RSession::Archive(BMessage *archive) const
|
||||||
@@ -140,7 +206,7 @@ RSession::Archive(BMessage *archive) const
|
|||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = archive->AddInt32("id", fID);
|
error = archive->AddInt32("id", fID);
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = archive->AddInt32("change_counter", fChangeCounter);
|
error = archive->AddInt32("change_counter", ChangeCounter());
|
||||||
if (error == B_OK)
|
if (error == B_OK)
|
||||||
error = archive->AddInt32("index", Index());
|
error = archive->AddInt32("index", Index());
|
||||||
// fInfo.*
|
// fInfo.*
|
||||||
@@ -188,6 +254,31 @@ RSession::Dump() const
|
|||||||
partition->Dump();
|
partition->Dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _RescanPartitions
|
||||||
|
status_t
|
||||||
|
RSession::_RescanPartitions(int fd, uint32 cause)
|
||||||
|
{
|
||||||
|
status_t error = B_OK;
|
||||||
|
// remove the current partitions
|
||||||
|
for (int32 i = CountPartitions() - 1; i >= 0; i--)
|
||||||
|
RemovePartition(i, cause);
|
||||||
|
// scan for partitions
|
||||||
|
for (int32 i = 0; error == B_OK; i++) {
|
||||||
|
// get the partition info
|
||||||
|
extended_partition_info partitionInfo;
|
||||||
|
status_t status = get_nth_partition_info(fd, fInfo.index, i,
|
||||||
|
&partitionInfo, (i == 0 ? fPartitioningSystem : NULL));
|
||||||
|
if (status != B_OK) {
|
||||||
|
if (status != B_ENTRY_NOT_FOUND)
|
||||||
|
error = status;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// create and add a RPartition
|
||||||
|
error = AddPartition(fd, &partitionInfo, cause);
|
||||||
|
}
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
// _NextID
|
// _NextID
|
||||||
int32
|
int32
|
||||||
RSession::_NextID()
|
RSession::_NextID()
|
||||||
|
|||||||
@@ -9,6 +9,8 @@
|
|||||||
#include <disk_scanner.h>
|
#include <disk_scanner.h>
|
||||||
#include <ObjectList.h>
|
#include <ObjectList.h>
|
||||||
|
|
||||||
|
#include "RChangeCounter.h"
|
||||||
|
|
||||||
class RDiskDevice;
|
class RDiskDevice;
|
||||||
class RDiskDeviceList;
|
class RDiskDeviceList;
|
||||||
class RPartition;
|
class RPartition;
|
||||||
@@ -25,14 +27,19 @@ public:
|
|||||||
RDiskDeviceList *DeviceList() const;
|
RDiskDeviceList *DeviceList() const;
|
||||||
RDiskDevice *Device() const { return fDevice; }
|
RDiskDevice *Device() const { return fDevice; }
|
||||||
|
|
||||||
|
status_t PartitionLayoutChanged();
|
||||||
|
|
||||||
int32 ID() const { return fID; }
|
int32 ID() const { return fID; }
|
||||||
int32 ChangeCounter() const { return fChangeCounter; }
|
int32 ChangeCounter() const { return fChangeCounter.Count(); }
|
||||||
|
void Changed();
|
||||||
|
|
||||||
int32 Index() const;
|
int32 Index() const;
|
||||||
|
|
||||||
bool AddPartition(RPartition *partition);
|
status_t AddPartition(int fd, const extended_partition_info *partitionInfo,
|
||||||
bool RemovePartition(int32 index);
|
uint32 cause);
|
||||||
bool RemovePartition(RPartition *partition);
|
bool AddPartition(RPartition *partition, uint32 cause);
|
||||||
|
bool RemovePartition(int32 index, uint32 cause);
|
||||||
|
bool RemovePartition(RPartition *partition, uint32 cause);
|
||||||
int32 CountPartitions() const { return fPartitions.CountItems(); }
|
int32 CountPartitions() const { return fPartitions.CountItems(); }
|
||||||
RPartition *PartitionAt(int32 index) const
|
RPartition *PartitionAt(int32 index) const
|
||||||
{ return fPartitions.ItemAt(index); }
|
{ return fPartitions.ItemAt(index); }
|
||||||
@@ -40,19 +47,25 @@ public:
|
|||||||
{ return fPartitions.IndexOf(partition); }
|
{ return fPartitions.IndexOf(partition); }
|
||||||
|
|
||||||
const session_info *Info() const { return &fInfo; }
|
const session_info *Info() const { return &fInfo; }
|
||||||
|
off_t Offset() const { return fInfo.offset; }
|
||||||
|
off_t Size() const { return fInfo.size; }
|
||||||
|
|
||||||
|
status_t Update(const session_info *sessionInfo);
|
||||||
|
|
||||||
status_t Archive(BMessage *archive) const;
|
status_t Archive(BMessage *archive) const;
|
||||||
|
|
||||||
void Dump() const;
|
void Dump() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
status_t _RescanPartitions(int fd, uint32 cause);
|
||||||
static int32 _NextID();
|
static int32 _NextID();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BObjectList<RPartition> fPartitions;
|
BObjectList<RPartition> fPartitions;
|
||||||
RDiskDevice *fDevice;
|
RDiskDevice *fDevice;
|
||||||
int32 fID;
|
int32 fID;
|
||||||
int32 fChangeCounter;
|
RChangeCounter fChangeCounter;
|
||||||
session_info fInfo;
|
session_info fInfo;
|
||||||
char fPartitioningSystem[B_FILE_NAME_LENGTH];
|
char fPartitioningSystem[B_FILE_NAME_LENGTH];
|
||||||
|
|
||||||
|
|||||||
@@ -218,6 +218,8 @@ void
|
|||||||
Registrar::ReadyToRun()
|
Registrar::ReadyToRun()
|
||||||
{
|
{
|
||||||
FUNCTION_START();
|
FUNCTION_START();
|
||||||
|
// create event queue
|
||||||
|
fEventQueue = new EventQueue(kEventQueueName);
|
||||||
// create roster
|
// create roster
|
||||||
fRoster = new TRoster;
|
fRoster = new TRoster;
|
||||||
fRoster->Init();
|
fRoster->Init();
|
||||||
@@ -228,10 +230,9 @@ Registrar::ReadyToRun()
|
|||||||
fMIMEManager = new MIMEManager;
|
fMIMEManager = new MIMEManager;
|
||||||
fMIMEManager->Run();
|
fMIMEManager->Run();
|
||||||
// create disk device manager
|
// create disk device manager
|
||||||
fDiskDeviceManager = new DiskDeviceManager;
|
fDiskDeviceManager = new DiskDeviceManager(fEventQueue);
|
||||||
fDiskDeviceManager->Run();
|
fDiskDeviceManager->Run();
|
||||||
// create message runner manager
|
// create message runner manager
|
||||||
fEventQueue = new EventQueue(kEventQueueName);
|
|
||||||
fMessageRunnerManager = new MessageRunnerManager(fEventQueue);
|
fMessageRunnerManager = new MessageRunnerManager(fEventQueue);
|
||||||
// init the global be_roster
|
// init the global be_roster
|
||||||
BRoster::Private().SetTo(be_app_messenger, BMessenger(NULL, fMIMEManager));
|
BRoster::Private().SetTo(be_app_messenger, BMessenger(NULL, fMIMEManager));
|
||||||
|
|||||||
Reference in New Issue
Block a user