* Copyright 2012 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Paweł Dziepak, pdziepak@quarnos.org
*/
#ifndef FILESYSTEM_H
#define FILESYSTEM_H
#include <fs_interface.h>
#include "Debug.h"
#include "Delegation.h"
#include "InodeIdMap.h"
#include "NFS4Defs.h"
#include "NFS4Server.h"
class Inode;
class RootInode;
struct MountConfiguration {
bool fReadOnly;
bool fHard;
int fRetryLimit;
bigtime_t fRequestTimeout;
bool fEmulateNamedAttrs;
bool fCacheMetadata;
bigtime_t fDirectoryCacheTime;
};
class FileSystem : public DoublyLinkedListLinkImpl<FileSystem> {
public:
static status_t Mount(FileSystem** pfs, RPC::Server* serv,
const char* serverName, const char* path,
fs_volume* volume,
const MountConfiguration& configuration);
~FileSystem();
status_t GetInode(ino_t id, Inode** inode);
inline RootInode* Root();
status_t Migrate(const RPC::Server* serv);
DoublyLinkedList<OpenState>& OpenFilesLock();
void OpenFilesUnlock();
inline uint32 OpenFilesCount();
void AddOpenFile(OpenState* state);
void RemoveOpenFile(OpenState* state);
DoublyLinkedList<Delegation>& DelegationsLock();
void DelegationsUnlock();
void AddDelegation(Delegation* delegation);
void RemoveDelegation(Delegation* delegation);
Delegation* GetDelegation(const FileHandle& handle);
inline bool IsAttrSupported(Attribute attr) const;
inline uint32 ExpireType() const;
inline RPC::Server* Server();
inline NFS4Server* NFSServer();
inline const char** Path() const;
inline const FileSystemId& FsId() const;
inline uint64 AllocFileId();
inline dev_t DevId() const;
inline InodeIdMap* InoIdMap();
inline uint64 OpenOwner() const;
inline uint32 OpenOwnerSequenceLock();
inline void OpenOwnerSequenceUnlock(uint32 sequence);
inline bool NamedAttrs();
inline void SetNamedAttrs(bool attrs);
inline const MountConfiguration& GetConfiguration();
inline mutex& CreateFileLock();
status_t TrashStaleNode(Inode* inode);
status_t TrashIfStale(Inode* inode);
void EnsureNoCollision(ino_t newId, const FileHandle& handle);
void ServerUnlinkCleanup(ino_t id, Inode* parent,
const char* missingName);
void Dump(void (*xprintf)(const char*, ...) = dprintf);
private:
FileSystem(const MountConfiguration& config);
static status_t _ParsePath(RequestBuilder& req, uint32& count,
const char* _path);
void _DumpLocked(void (*xprintf)(const char*, ...),
bool dumpDelegations, bool dumpOpenFiles) const;
mutex fCreateFileLock;
mutex fDelegationLock;
DoublyLinkedList<Delegation> fDelegationList;
AVLTreeMap<FileHandle, Delegation*> fHandleToDelegation;
DoublyLinkedList<OpenState> fOpenFiles;
uint32 fOpenCount;
mutex fOpenLock;
uint64 fOpenOwner;
uint32 fOpenOwnerSequence;
mutex fOpenOwnerLock;
uint32 fExpireType;
uint32 fSupAttrs[2];
bool fNamedAttrs;
FileSystemId fFsId;
const char** fPath;
RootInode* fRoot;
RPC::Server* fServer;
int64 fId;
dev_t fDevId;
InodeIdMap fInoIdMap;
MountConfiguration fConfiguration;
fs_volume* fFsVolume;
};
inline RootInode*
FileSystem::Root()
{
return fRoot;
}
inline uint32
FileSystem::OpenFilesCount()
{
return fOpenCount;
}
inline bool
FileSystem::IsAttrSupported(Attribute attr) const
{
return sIsAttrSet(attr, fSupAttrs, 2);
}
inline uint32
FileSystem::ExpireType() const
{
return fExpireType;
}
inline RPC::Server*
FileSystem::Server()
{
ASSERT(fServer != NULL);
return fServer;
}
inline NFS4Server*
FileSystem::NFSServer()
{
ASSERT(fServer->PrivateData() != NULL);
return reinterpret_cast<NFS4Server*>(fServer->PrivateData());
}
inline const char**
FileSystem::Path() const
{
ASSERT(fPath != NULL);
return fPath;
}
inline const FileSystemId&
FileSystem::FsId() const
{
return fFsId;
}
inline uint64
FileSystem::AllocFileId()
{
return atomic_add64(&fId, 1);
}
inline dev_t
FileSystem::DevId() const
{
return fDevId;
}
inline InodeIdMap*
FileSystem::InoIdMap()
{
return &fInoIdMap;
}
inline uint64
FileSystem::OpenOwner() const
{
return fOpenOwner;
}
inline uint32
FileSystem::OpenOwnerSequenceLock()
{
mutex_lock(&fOpenOwnerLock);
return fOpenOwnerSequence;
}
inline void
FileSystem::OpenOwnerSequenceUnlock(uint32 sequence)
{
fOpenOwnerSequence = sequence;
mutex_unlock(&fOpenOwnerLock);
}
inline bool
FileSystem::NamedAttrs()
{
return fNamedAttrs;
}
inline void
FileSystem::SetNamedAttrs(bool attrs)
{
fNamedAttrs = attrs;
}
inline const MountConfiguration&
FileSystem::GetConfiguration()
{
return fConfiguration;
}
inline mutex&
FileSystem::CreateFileLock()
{
return fCreateFileLock;
}
#endif