15a1d355fSStephan Aßmus // ServerVolume.cpp
25a1d355fSStephan Aßmus
35a1d355fSStephan Aßmus #include "ServerVolume.h"
45a1d355fSStephan Aßmus
55a1d355fSStephan Aßmus #include <new>
65a1d355fSStephan Aßmus
75a1d355fSStephan Aßmus #include <AutoDeleter.h>
85a1d355fSStephan Aßmus #include <AutoLocker.h>
95a1d355fSStephan Aßmus
105a1d355fSStephan Aßmus #include "Compatibility.h"
115a1d355fSStephan Aßmus #include "DebugSupport.h"
125a1d355fSStephan Aßmus #include "ExtendedServerInfo.h"
135a1d355fSStephan Aßmus #include "QueryManager.h"
145a1d355fSStephan Aßmus #include "SendReceiveRequest.h"
155a1d355fSStephan Aßmus #include "ServerConnection.h"
165a1d355fSStephan Aßmus #include "ServerConnectionProvider.h"
175a1d355fSStephan Aßmus #include "ServerQueryIterator.h"
185a1d355fSStephan Aßmus #include "ShareVolume.h"
195a1d355fSStephan Aßmus #include "VolumeEvent.h"
205a1d355fSStephan Aßmus #include "VolumeManager.h"
215a1d355fSStephan Aßmus #include "VolumeSupport.h"
225a1d355fSStephan Aßmus
235a1d355fSStephan Aßmus // constructor
ServerVolume(VolumeManager * volumeManager,ExtendedServerInfo * serverInfo)245a1d355fSStephan Aßmus ServerVolume::ServerVolume(VolumeManager* volumeManager,
255a1d355fSStephan Aßmus ExtendedServerInfo* serverInfo)
265a1d355fSStephan Aßmus : VirtualVolume(volumeManager),
275a1d355fSStephan Aßmus fServerInfo(serverInfo),
285a1d355fSStephan Aßmus fConnectionProvider(NULL)
295a1d355fSStephan Aßmus {
3088e38c17SIngo Weinhold fServerInfo->AcquireReference();
315a1d355fSStephan Aßmus }
325a1d355fSStephan Aßmus
335a1d355fSStephan Aßmus // destructor
~ServerVolume()345a1d355fSStephan Aßmus ServerVolume::~ServerVolume()
355a1d355fSStephan Aßmus {
365a1d355fSStephan Aßmus if (fConnectionProvider)
3788e38c17SIngo Weinhold fConnectionProvider->ReleaseReference();
385a1d355fSStephan Aßmus if (fServerInfo)
3988e38c17SIngo Weinhold fServerInfo->ReleaseReference();
405a1d355fSStephan Aßmus }
415a1d355fSStephan Aßmus
425a1d355fSStephan Aßmus // GetServerAddress
435a1d355fSStephan Aßmus NetAddress
GetServerAddress()445a1d355fSStephan Aßmus ServerVolume::GetServerAddress()
455a1d355fSStephan Aßmus {
465a1d355fSStephan Aßmus AutoLocker<Locker> _(fLock);
475a1d355fSStephan Aßmus return fServerInfo->GetAddress();
485a1d355fSStephan Aßmus }
495a1d355fSStephan Aßmus
505a1d355fSStephan Aßmus // SetServerInfo
515a1d355fSStephan Aßmus void
SetServerInfo(ExtendedServerInfo * serverInfo)525a1d355fSStephan Aßmus ServerVolume::SetServerInfo(ExtendedServerInfo* serverInfo)
535a1d355fSStephan Aßmus {
545a1d355fSStephan Aßmus if (!serverInfo)
555a1d355fSStephan Aßmus return;
565a1d355fSStephan Aßmus
575a1d355fSStephan Aßmus // set the new info
585a1d355fSStephan Aßmus fLock.Lock();
5988e38c17SIngo Weinhold fServerInfo->ReleaseReference();
605a1d355fSStephan Aßmus fServerInfo = serverInfo;
6188e38c17SIngo Weinhold fServerInfo->AcquireReference();
6288e38c17SIngo Weinhold BReference<ExtendedServerInfo> newReference(fServerInfo);
635a1d355fSStephan Aßmus
645a1d355fSStephan Aßmus // remove shares, that are no longer there
655a1d355fSStephan Aßmus
665a1d355fSStephan Aßmus // init a directory iterator
675a1d355fSStephan Aßmus VirtualDirIterator iterator;
685a1d355fSStephan Aßmus iterator.SetDirectory(fRootNode, true);
695a1d355fSStephan Aßmus
705a1d355fSStephan Aßmus // iterate through the directory
715a1d355fSStephan Aßmus const char* name;
725a1d355fSStephan Aßmus Node* node;
735a1d355fSStephan Aßmus while (iterator.GetCurrentEntry(&name, &node)) {
745a1d355fSStephan Aßmus iterator.NextEntry();
755a1d355fSStephan Aßmus // TODO: Searching by name is currently O(n).
765a1d355fSStephan Aßmus bool remove = (!serverInfo->GetShareInfo(name));
775a1d355fSStephan Aßmus fLock.Unlock();
785a1d355fSStephan Aßmus
795a1d355fSStephan Aßmus if (remove) {
80*3c1afd35SPawel Dziepak PRINT(" removing share: %s\n", name);
815a1d355fSStephan Aßmus if (Volume* volume = GetChildVolume(name)) {
825a1d355fSStephan Aßmus volume->SetUnmounting(true);
835a1d355fSStephan Aßmus volume->PutVolume();
845a1d355fSStephan Aßmus }
855a1d355fSStephan Aßmus }
865a1d355fSStephan Aßmus
875a1d355fSStephan Aßmus fLock.Lock();
885a1d355fSStephan Aßmus }
895a1d355fSStephan Aßmus
905a1d355fSStephan Aßmus // uninit the directory iterator
915a1d355fSStephan Aßmus iterator.SetDirectory(NULL);
925a1d355fSStephan Aßmus fLock.Unlock();
935a1d355fSStephan Aßmus
945a1d355fSStephan Aßmus // add new shares
955a1d355fSStephan Aßmus int32 count = serverInfo->CountShares();
965a1d355fSStephan Aßmus for (int32 i = 0; i < count; i++) {
975a1d355fSStephan Aßmus ExtendedShareInfo* shareInfo = serverInfo->ShareInfoAt(i);
985a1d355fSStephan Aßmus const char* shareName = shareInfo->GetShareName();
995a1d355fSStephan Aßmus
1005a1d355fSStephan Aßmus Volume* volume = GetChildVolume(shareName);
1015a1d355fSStephan Aßmus if (volume) {
1025a1d355fSStephan Aßmus volume->PutVolume();
1035a1d355fSStephan Aßmus } else {
104*3c1afd35SPawel Dziepak PRINT(" adding share: %s\n",
105*3c1afd35SPawel Dziepak shareInfo->GetShareName());
1065a1d355fSStephan Aßmus status_t error = _AddShare(shareInfo);
1075a1d355fSStephan Aßmus if (error != B_OK) {
1085a1d355fSStephan Aßmus ERROR("ServerVolume::SetServerInfo(): ERROR: Failed to add "
1095a1d355fSStephan Aßmus "share `%s': %s\n", shareName, strerror(error));
1105a1d355fSStephan Aßmus }
1115a1d355fSStephan Aßmus }
1125a1d355fSStephan Aßmus }
1135a1d355fSStephan Aßmus }
1145a1d355fSStephan Aßmus
1155a1d355fSStephan Aßmus // Init
1165a1d355fSStephan Aßmus status_t
Init(const char * name)1175a1d355fSStephan Aßmus ServerVolume::Init(const char* name)
1185a1d355fSStephan Aßmus {
1195a1d355fSStephan Aßmus status_t error = VirtualVolume::Init(name);
1205a1d355fSStephan Aßmus if (error != B_OK)
1215a1d355fSStephan Aßmus return error;
1225a1d355fSStephan Aßmus
1235a1d355fSStephan Aßmus // create the server connection provider
1245a1d355fSStephan Aßmus fConnectionProvider = new ServerConnectionProvider(fVolumeManager,
1255a1d355fSStephan Aßmus fServerInfo, GetRootID());
1265a1d355fSStephan Aßmus if (!fConnectionProvider) {
1275a1d355fSStephan Aßmus Uninit();
1285a1d355fSStephan Aßmus return B_NO_MEMORY;
1295a1d355fSStephan Aßmus }
1305a1d355fSStephan Aßmus error = fConnectionProvider->Init();
1315a1d355fSStephan Aßmus if (error != B_OK) {
1325a1d355fSStephan Aßmus Uninit();
1335a1d355fSStephan Aßmus return error;
1345a1d355fSStephan Aßmus }
1355a1d355fSStephan Aßmus
1365a1d355fSStephan Aßmus // add share volumes
1375a1d355fSStephan Aßmus int32 count = fServerInfo->CountShares();
1385a1d355fSStephan Aßmus for (int32 i = 0; i < count; i++) {
1395a1d355fSStephan Aßmus ExtendedShareInfo* shareInfo = fServerInfo->ShareInfoAt(i);
1405a1d355fSStephan Aßmus
1415a1d355fSStephan Aßmus error = _AddShare(shareInfo);
1425a1d355fSStephan Aßmus if (error != B_OK) {
1435a1d355fSStephan Aßmus ERROR("ServerVolume::Init(): ERROR: Failed to add share `%s': "
1445a1d355fSStephan Aßmus "%s\n", shareInfo->GetShareName(), strerror(error));
1455a1d355fSStephan Aßmus }
1465a1d355fSStephan Aßmus }
1475a1d355fSStephan Aßmus
1485a1d355fSStephan Aßmus return B_OK;
1495a1d355fSStephan Aßmus }
1505a1d355fSStephan Aßmus
1515a1d355fSStephan Aßmus // Uninit
1525a1d355fSStephan Aßmus void
Uninit()1535a1d355fSStephan Aßmus ServerVolume::Uninit()
1545a1d355fSStephan Aßmus {
1555a1d355fSStephan Aßmus if (fConnectionProvider)
1565a1d355fSStephan Aßmus fConnectionProvider->CloseServerConnection();
1575a1d355fSStephan Aßmus
1585a1d355fSStephan Aßmus VirtualVolume::Uninit();
1595a1d355fSStephan Aßmus }
1605a1d355fSStephan Aßmus
1615a1d355fSStephan Aßmus // PrepareToUnmount
1625a1d355fSStephan Aßmus void
PrepareToUnmount()1635a1d355fSStephan Aßmus ServerVolume::PrepareToUnmount()
1645a1d355fSStephan Aßmus {
1655a1d355fSStephan Aßmus VirtualVolume::PrepareToUnmount();
1665a1d355fSStephan Aßmus }
1675a1d355fSStephan Aßmus
1685a1d355fSStephan Aßmus // HandleEvent
1695a1d355fSStephan Aßmus void
HandleEvent(VolumeEvent * event)1705a1d355fSStephan Aßmus ServerVolume::HandleEvent(VolumeEvent* event)
1715a1d355fSStephan Aßmus {
1725a1d355fSStephan Aßmus if (event->GetType() == CONNECTION_BROKEN_EVENT) {
1735a1d355fSStephan Aßmus // tell all share volumes that they have been disconnected
1745a1d355fSStephan Aßmus
1755a1d355fSStephan Aßmus // init a directory iterator
1765a1d355fSStephan Aßmus fLock.Lock();
1775a1d355fSStephan Aßmus VirtualDirIterator iterator;
1785a1d355fSStephan Aßmus iterator.SetDirectory(fRootNode, true);
1795a1d355fSStephan Aßmus
1805a1d355fSStephan Aßmus // iterate through the directory
1815a1d355fSStephan Aßmus const char* name;
1825a1d355fSStephan Aßmus Node* node;
1835a1d355fSStephan Aßmus while (iterator.GetCurrentEntry(&name, &node)) {
1845a1d355fSStephan Aßmus iterator.NextEntry();
1855a1d355fSStephan Aßmus Volume* volume = fVolumeManager->GetVolume(node->GetID());
1865a1d355fSStephan Aßmus fLock.Unlock();
1875a1d355fSStephan Aßmus if (ShareVolume* shareVolume = dynamic_cast<ShareVolume*>(volume))
1885a1d355fSStephan Aßmus shareVolume->ConnectionClosed();
1895a1d355fSStephan Aßmus if (volume)
1905a1d355fSStephan Aßmus volume->PutVolume();
1915a1d355fSStephan Aßmus fLock.Lock();
1925a1d355fSStephan Aßmus }
1935a1d355fSStephan Aßmus
1945a1d355fSStephan Aßmus // uninit the directory iterator
1955a1d355fSStephan Aßmus iterator.SetDirectory(NULL);
1965a1d355fSStephan Aßmus
1975a1d355fSStephan Aßmus // mark ourselves unmounting
1985a1d355fSStephan Aßmus SetUnmounting(true);
1995a1d355fSStephan Aßmus fLock.Unlock();
2005a1d355fSStephan Aßmus }
2015a1d355fSStephan Aßmus }
2025a1d355fSStephan Aßmus
2035a1d355fSStephan Aßmus
2045a1d355fSStephan Aßmus // #pragma mark -
2055a1d355fSStephan Aßmus // #pragma mark ----- FS -----
2065a1d355fSStephan Aßmus
2075a1d355fSStephan Aßmus // Unmount
2085a1d355fSStephan Aßmus status_t
Unmount()2095a1d355fSStephan Aßmus ServerVolume::Unmount()
2105a1d355fSStephan Aßmus {
2115a1d355fSStephan Aßmus return B_OK;
2125a1d355fSStephan Aßmus }
2135a1d355fSStephan Aßmus
2145a1d355fSStephan Aßmus
2155a1d355fSStephan Aßmus // #pragma mark -
2165a1d355fSStephan Aßmus // #pragma mark ----- queries -----
2175a1d355fSStephan Aßmus
2185a1d355fSStephan Aßmus // OpenQuery
2195a1d355fSStephan Aßmus status_t
OpenQuery(const char * queryString,uint32 flags,port_id port,int32 token,QueryIterator ** _iterator)2205a1d355fSStephan Aßmus ServerVolume::OpenQuery(const char* queryString, uint32 flags, port_id port,
2215a1d355fSStephan Aßmus int32 token, QueryIterator** _iterator)
2225a1d355fSStephan Aßmus {
2235a1d355fSStephan Aßmus // TODO: Do nothing when there are no (mounted) shares.
2245a1d355fSStephan Aßmus // get connection
2255a1d355fSStephan Aßmus ServerConnection* serverConnection
2265a1d355fSStephan Aßmus = fConnectionProvider->GetExistingServerConnection();
2275a1d355fSStephan Aßmus if (!serverConnection)
2285a1d355fSStephan Aßmus return ERROR_NOT_CONNECTED;
2295a1d355fSStephan Aßmus RequestConnection* connection = serverConnection->GetRequestConnection();
2305a1d355fSStephan Aßmus
2315a1d355fSStephan Aßmus // create a query iterator and add it to the query manager
2325a1d355fSStephan Aßmus ServerQueryIterator* iterator = new(std::nothrow) ServerQueryIterator(this);
2335a1d355fSStephan Aßmus if (!iterator)
2345a1d355fSStephan Aßmus return B_NO_MEMORY;
2355a1d355fSStephan Aßmus QueryManager* queryManager = fVolumeManager->GetQueryManager();
2365a1d355fSStephan Aßmus status_t error = queryManager->AddIterator(iterator);
2375a1d355fSStephan Aßmus if (error != B_OK) {
2385a1d355fSStephan Aßmus delete iterator;
2395a1d355fSStephan Aßmus return error;
2405a1d355fSStephan Aßmus }
2415a1d355fSStephan Aßmus QueryIteratorPutter iteratorPutter(queryManager, iterator);
2425a1d355fSStephan Aßmus
2435a1d355fSStephan Aßmus // prepare the request
2445a1d355fSStephan Aßmus OpenQueryRequest request;
2455a1d355fSStephan Aßmus request.queryString.SetTo(queryString);
2465a1d355fSStephan Aßmus request.flags = flags;
2475a1d355fSStephan Aßmus request.port = port;
2485a1d355fSStephan Aßmus request.token = token;
2495a1d355fSStephan Aßmus
2505a1d355fSStephan Aßmus // send the request
2515a1d355fSStephan Aßmus OpenQueryReply* reply;
2525a1d355fSStephan Aßmus error = SendRequest(connection, &request, &reply);
2535a1d355fSStephan Aßmus if (error != B_OK)
2545a1d355fSStephan Aßmus RETURN_ERROR(error);
2555a1d355fSStephan Aßmus ObjectDeleter<Request> replyDeleter(reply);
2565a1d355fSStephan Aßmus if (reply->error != B_OK)
2575a1d355fSStephan Aßmus RETURN_ERROR(reply->error);
2585a1d355fSStephan Aßmus
2595a1d355fSStephan Aßmus // set the result
2605a1d355fSStephan Aßmus iterator->SetRemoteCookie(reply->cookie);
2615a1d355fSStephan Aßmus *_iterator = iterator;
2625a1d355fSStephan Aßmus iteratorPutter.Detach();
2635a1d355fSStephan Aßmus return B_OK;
2645a1d355fSStephan Aßmus }
2655a1d355fSStephan Aßmus
2665a1d355fSStephan Aßmus // FreeQueryIterator
2675a1d355fSStephan Aßmus void
FreeQueryIterator(QueryIterator * _iterator)2685a1d355fSStephan Aßmus ServerVolume::FreeQueryIterator(QueryIterator* _iterator)
2695a1d355fSStephan Aßmus {
2705a1d355fSStephan Aßmus ServerQueryIterator* iterator
2715a1d355fSStephan Aßmus = dynamic_cast<ServerQueryIterator*>(_iterator);
2725a1d355fSStephan Aßmus
2735a1d355fSStephan Aßmus int32 cookie = iterator->GetRemoteCookie();
2745a1d355fSStephan Aßmus if (cookie >= 0) {
2755a1d355fSStephan Aßmus // prepare the close request
2765a1d355fSStephan Aßmus CloseRequest request;
2775a1d355fSStephan Aßmus request.volumeID = -1;
2785a1d355fSStephan Aßmus request.cookie = cookie;
2795a1d355fSStephan Aßmus
2805a1d355fSStephan Aßmus // send the request
2815a1d355fSStephan Aßmus ServerConnection* serverConnection
2825a1d355fSStephan Aßmus = fConnectionProvider->GetExistingServerConnection();
2835a1d355fSStephan Aßmus if (serverConnection && serverConnection->IsConnected()) {
2845a1d355fSStephan Aßmus CloseReply* reply;
2855a1d355fSStephan Aßmus status_t error = SendRequest(
2865a1d355fSStephan Aßmus serverConnection->GetRequestConnection(), &request, &reply);
2875a1d355fSStephan Aßmus if (error == B_OK)
2885a1d355fSStephan Aßmus delete reply;
2895a1d355fSStephan Aßmus }
2905a1d355fSStephan Aßmus }
2915a1d355fSStephan Aßmus
2925a1d355fSStephan Aßmus delete iterator;
2935a1d355fSStephan Aßmus }
2945a1d355fSStephan Aßmus
2955a1d355fSStephan Aßmus // ReadQuery
2965a1d355fSStephan Aßmus status_t
ReadQuery(QueryIterator * _iterator,struct dirent * buffer,size_t bufferSize,int32 count,int32 * countRead)2975a1d355fSStephan Aßmus ServerVolume::ReadQuery(QueryIterator* _iterator, struct dirent* buffer,
2985a1d355fSStephan Aßmus size_t bufferSize, int32 count, int32* countRead)
2995a1d355fSStephan Aßmus {
3005a1d355fSStephan Aßmus // get connection
3015a1d355fSStephan Aßmus ServerConnection* serverConnection
3025a1d355fSStephan Aßmus = fConnectionProvider->GetExistingServerConnection();
3035a1d355fSStephan Aßmus if (!serverConnection)
3045a1d355fSStephan Aßmus return ERROR_NOT_CONNECTED;
3055a1d355fSStephan Aßmus RequestConnection* connection = serverConnection->GetRequestConnection();
3065a1d355fSStephan Aßmus
3075a1d355fSStephan Aßmus ServerQueryIterator* iterator
3085a1d355fSStephan Aßmus = dynamic_cast<ServerQueryIterator*>(_iterator);
3095a1d355fSStephan Aßmus
3105a1d355fSStephan Aßmus *countRead = 0;
3115a1d355fSStephan Aßmus
3125a1d355fSStephan Aßmus for (;;) {
3135a1d355fSStephan Aßmus // if the iterator hasn't cached any more share volume IDs, we need to
3145a1d355fSStephan Aßmus // ask the server for the next entry
3155a1d355fSStephan Aßmus if (!iterator->HasNextShareVolumeID()) {
3165a1d355fSStephan Aßmus // prepare the request
3175a1d355fSStephan Aßmus ReadQueryRequest request;
3185a1d355fSStephan Aßmus request.cookie = iterator->GetRemoteCookie();
3195a1d355fSStephan Aßmus request.count = 1;
3205a1d355fSStephan Aßmus
3215a1d355fSStephan Aßmus // send the request
3225a1d355fSStephan Aßmus ReadQueryReply* reply;
3235a1d355fSStephan Aßmus status_t error = SendRequest(connection, &request, &reply);
3245a1d355fSStephan Aßmus if (error != B_OK)
3255a1d355fSStephan Aßmus RETURN_ERROR(error);
3265a1d355fSStephan Aßmus ObjectDeleter<Request> replyDeleter(reply);
3275a1d355fSStephan Aßmus if (reply->error != B_OK)
3285a1d355fSStephan Aßmus RETURN_ERROR(reply->error);
3295a1d355fSStephan Aßmus
3305a1d355fSStephan Aßmus // check, if anything has been read at all
3315a1d355fSStephan Aßmus if (reply->count == 0) {
3325a1d355fSStephan Aßmus *countRead = 0;
3335a1d355fSStephan Aßmus return B_OK;
3345a1d355fSStephan Aßmus }
3355a1d355fSStephan Aßmus
3365a1d355fSStephan Aßmus // update the iterator
3375a1d355fSStephan Aßmus error = iterator->SetEntry(reply->clientVolumeIDs.GetElements(),
3385a1d355fSStephan Aßmus reply->clientVolumeIDs.CountElements(), reply->dirInfo,
3395a1d355fSStephan Aßmus reply->entryInfo);
3405a1d355fSStephan Aßmus if (error != B_OK)
3415a1d355fSStephan Aßmus return error;
3425a1d355fSStephan Aßmus }
3435a1d355fSStephan Aßmus
3445a1d355fSStephan Aßmus // get the next concerned share volume and delegate the rest of the work
3455a1d355fSStephan Aßmus int32 volumeID = iterator->NextShareVolumeID();
3465a1d355fSStephan Aßmus ShareVolume* shareVolume = _GetShareVolume(volumeID);
3475a1d355fSStephan Aßmus if (!shareVolume)
3485a1d355fSStephan Aßmus continue;
3495a1d355fSStephan Aßmus VolumePutter volumePutter(shareVolume);
3505a1d355fSStephan Aßmus
3515a1d355fSStephan Aßmus return shareVolume->GetQueryEntry(iterator->GetEntryInfo(),
3525a1d355fSStephan Aßmus iterator->GetDirectoryInfo(), buffer, bufferSize, countRead);
3535a1d355fSStephan Aßmus }
3545a1d355fSStephan Aßmus }
3555a1d355fSStephan Aßmus
3565a1d355fSStephan Aßmus
3575a1d355fSStephan Aßmus // #pragma mark -
3585a1d355fSStephan Aßmus // #pragma mark ----- private -----
3595a1d355fSStephan Aßmus
3605a1d355fSStephan Aßmus // _AddShare
3615a1d355fSStephan Aßmus status_t
_AddShare(ExtendedShareInfo * shareInfo)3625a1d355fSStephan Aßmus ServerVolume::_AddShare(ExtendedShareInfo* shareInfo)
3635a1d355fSStephan Aßmus {
3645a1d355fSStephan Aßmus // create the share volume
3655a1d355fSStephan Aßmus ShareVolume* shareVolume = new(std::nothrow) ShareVolume(fVolumeManager,
3665a1d355fSStephan Aßmus fConnectionProvider, fServerInfo, shareInfo);
3675a1d355fSStephan Aßmus if (!shareVolume)
3685a1d355fSStephan Aßmus return B_NO_MEMORY;
3695a1d355fSStephan Aßmus status_t error = shareVolume->Init(shareInfo->GetShareName());
3705a1d355fSStephan Aßmus if (error != B_OK) {
3715a1d355fSStephan Aßmus delete shareVolume;
3725a1d355fSStephan Aßmus return error;
3735a1d355fSStephan Aßmus }
3745a1d355fSStephan Aßmus
3755a1d355fSStephan Aßmus // add the volume to the volume manager
3765a1d355fSStephan Aßmus error = fVolumeManager->AddVolume(shareVolume);
3775a1d355fSStephan Aßmus if (error != B_OK) {
3785a1d355fSStephan Aßmus delete shareVolume;
3795a1d355fSStephan Aßmus return error;
3805a1d355fSStephan Aßmus }
3815a1d355fSStephan Aßmus VolumePutter volumePutter(shareVolume);
3825a1d355fSStephan Aßmus
3835a1d355fSStephan Aßmus // add the volume to us
3845a1d355fSStephan Aßmus error = AddChildVolume(shareVolume);
3855a1d355fSStephan Aßmus if (error != B_OK) {
3865a1d355fSStephan Aßmus shareVolume->SetUnmounting(true);
3875a1d355fSStephan Aßmus return error;
3885a1d355fSStephan Aßmus }
3895a1d355fSStephan Aßmus
3905a1d355fSStephan Aßmus return B_OK;
3915a1d355fSStephan Aßmus }
3925a1d355fSStephan Aßmus
3935a1d355fSStephan Aßmus // _GetShareVolume
3945a1d355fSStephan Aßmus ShareVolume*
_GetShareVolume(int32 volumeID)3955a1d355fSStephan Aßmus ServerVolume::_GetShareVolume(int32 volumeID)
3965a1d355fSStephan Aßmus {
3975a1d355fSStephan Aßmus AutoLocker<Locker> locker(fLock);
3985a1d355fSStephan Aßmus VirtualDirIterator dirIterator;
3995a1d355fSStephan Aßmus dirIterator.SetDirectory(fRootNode, true);
4005a1d355fSStephan Aßmus
4015a1d355fSStephan Aßmus // iterate through the directory
4025a1d355fSStephan Aßmus const char* name;
4035a1d355fSStephan Aßmus Node* node;
4045a1d355fSStephan Aßmus while (dirIterator.GetCurrentEntry(&name, &node)) {
4055a1d355fSStephan Aßmus Volume* volume = fVolumeManager->GetVolume(node->GetID());
4065a1d355fSStephan Aßmus ShareVolume* shareVolume = dynamic_cast<ShareVolume*>(volume);
4075a1d355fSStephan Aßmus if (shareVolume && shareVolume->GetID() == volumeID)
4085a1d355fSStephan Aßmus return shareVolume;
4095a1d355fSStephan Aßmus
4105a1d355fSStephan Aßmus volume->PutVolume();
4115a1d355fSStephan Aßmus dirIterator.NextEntry();
4125a1d355fSStephan Aßmus }
4135a1d355fSStephan Aßmus
4145a1d355fSStephan Aßmus return NULL;
4155a1d355fSStephan Aßmus }
4165a1d355fSStephan Aßmus
417