/*
 * Copyright 2001-2009, Ingo Weinhold, ingo_weinhold@gmx.de.
 * Distributed under the terms of the MIT License.
 */
#ifndef USERLAND_FS_FILE_SYSTEM_H
#define USERLAND_FS_FILE_SYSTEM_H
 
 
#include <fs_interface.h>
 
#include <util/OpenHashTable.h>
 
#include <lock.h>
 
#include "FSCapabilities.h"
#include "LazyInitializable.h"
#include "Locker.h"
#include "RequestPort.h"
#include "RequestPortPool.h"
#include "String.h"
#include "Vector.h"
 
 
struct IOCtlInfo;
namespace BPrivate { class KMessage; }
using BPrivate::KMessage;
class Settings;
class Volume;
 
 
struct VNodeOps {
	int32				refCount;
	FSVNodeCapabilities	capabilities;
	fs_vnode_ops*		ops;
	VNodeOps*			hash_link;
 
	VNodeOps(const FSVNodeCapabilities& capabilities, fs_vnode_ops* ops)
		:
		refCount(1),
		capabilities(capabilities),
		ops(ops)
	{
	}
 
	~VNodeOps()
	{
		delete ops;
	}
};
 
 
struct VNodeOpsHashDefinition {
	typedef FSVNodeCapabilities	KeyType;
	typedef	VNodeOps			ValueType;
 
	size_t HashKey(const FSVNodeCapabilities& key) const
		{ return key.GetHashCode(); }
	size_t Hash(const VNodeOps* value) const
		{ return HashKey(value->capabilities); }
	bool Compare(const FSVNodeCapabilities& key, const VNodeOps* value) const
		{ return value->capabilities == key; }
	VNodeOps*& GetLink(VNodeOps* value) const
		{ return value->hash_link; }
};
 
 
class FileSystem {
public:
								FileSystem();
								~FileSystem();
 
			status_t			Init(const char* name, team_id team,
									Port::Info* infos, int32 infoCount,
									const FSCapabilities& capabilities);
 
			const char*			GetName() const;
			team_id				GetTeam() const	{ return fTeam; }
 
			const FSCapabilities& GetCapabilities() const;
	inline	bool				HasCapability(uint32 capability) const;
 
			RequestPortPool*	GetPortPool();
 
			status_t			Mount(fs_volume* fsVolume, const char* device,
									uint32 flags, const char* parameters,
									Volume** volume);
//			status_t			Initialize(const char* deviceName,
//									const char* parameters, size_t len);
			void				VolumeUnmounted(Volume* volume);
 
			Volume*				GetVolume(dev_t id);
 
			const IOCtlInfo*	GetIOCtlInfo(int command) const;
 
			status_t			AddSelectSyncEntry(selectsync* sync);
			void				RemoveSelectSyncEntry(selectsync* sync);
			bool				KnowsSelectSyncEntry(selectsync* sync);
 
			status_t			AddNodeListener(dev_t device, ino_t node,
									uint32 flags, void* listener);
			status_t			RemoveNodeListener(dev_t device, ino_t node,
									void* listener);
 
			VNodeOps*			GetVNodeOps(
									const FSVNodeCapabilities& capabilities);
			void				PutVNodeOps(VNodeOps* ops);
 
			bool				IsUserlandServerThread() const;
 
private:
			struct SelectSyncMap;
			struct NodeListenerKey;
			struct NodeListenerProxy;
			struct NodeListenerHashDefinition;
 
			friend class KernelDebug;
			friend struct NodeListenerProxy;
 
			typedef BOpenHashTable<VNodeOpsHashDefinition> VNodeOpsMap;
			typedef BOpenHashTable<NodeListenerHashDefinition> NodeListenerMap;
 
 
private:
			void				_InitVNodeOpsVector(fs_vnode_ops* ops,
									const FSVNodeCapabilities& capabilities);
 
			void				_NodeListenerEventOccurred(
									NodeListenerProxy* proxy,
									const KMessage* event);
 
	static	int32				_NotificationThreadEntry(void* data);
			int32				_NotificationThread();
 
private:
			Vector<Volume*>		fVolumes;
			mutex				fVolumeLock;
			VNodeOpsMap			fVNodeOps;
			mutex				fVNodeOpsLock;
			String				fName;
			team_id				fTeam;
			FSCapabilities		fCapabilities;
			RequestPort*		fNotificationPort;
			thread_id			fNotificationThread;
			RequestPortPool		fPortPool;
			SelectSyncMap*		fSelectSyncs;
			mutex				fNodeListenersLock;
			NodeListenerMap*	fNodeListeners;
			Settings*			fSettings;
			team_id				fUserlandServerTeam;
			bool				fInitialized;
	volatile bool				fTerminating;
};
 
 
// HasCapability
inline bool
FileSystem::HasCapability(uint32 capability) const
{
	return fCapabilities.Get(capability);
}
 
#endif	// USERLAND_FS_FILE_SYSTEM_H

V730 Not all members of a class are initialized inside the constructor. Consider inspecting: hash_link.