* Copyright 2012 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Paweł Dziepak, pdziepak@quarnos.org
*/
#ifndef INODE_H
#define INODE_H
#include "DirectoryCache.h"
#include "MetadataCache.h"
#include "NFS4Inode.h"
#include "OpenState.h"
class Delegation;
class Inode : public NFS4Inode {
public:
static status_t CreateInode(FileSystem* fs, const FileInfo& fi,
Inode** inode);
virtual ~Inode();
inline ino_t ID() const;
inline mode_t Type() const;
virtual const char* Name() const;
inline FileSystem* GetFileSystem() const;
inline void SetOpenState(OpenState* state);
inline void* FileCache();
status_t RevalidateFileCache();
inline uint64 MaxFileSize();
inline uint64 Change();
inline bool Dirty();
inline OpenState* GetOpenState();
inline Delegation* GetDelegation() const;
void SetDelegation(Delegation* delegation);
void RecallDelegation(bool truncate = false);
void PrepareDelegationRecall(bool truncate = false);
void RecallDelegationAsync(bool truncate = false);
void RecallReadDelegation();
void UnlockAndRelockStateLocks();
void UnlockAndRelockWriteLock();
status_t LookUp(const char* name, ino_t* id);
status_t Access(int mode);
status_t Sync(bool force = false, bool wait = true);
status_t Commit(uid_t uid, gid_t gid);
status_t SyncAndCommit(bool force = false, OpenStateCookie* cookie = NULL);
status_t CreateObject(const char* name, const char* path,
int mode, FileType type, ino_t* id);
status_t CreateLink(const char* name, const char* path,
int mode, ino_t* id);
status_t Link(Inode* dir, const char* name);
status_t Remove(const char* name, FileType type,
ino_t* id = NULL);
static status_t Rename(Inode* from, Inode* to,
const char* fromName, const char* toName,
bool attribute = false, ino_t* id = NULL,
ino_t* oldID = NULL);
status_t Stat(struct stat* st,
OpenAttrCookie* attr = NULL, bool revalidate = false);
status_t WriteStat(const struct stat* st, uint32 mask,
OpenAttrCookie* attr = NULL);
status_t Create(const char* name, int mode, int perms,
OpenFileCookie* cookie,
OpenDelegationData* data, ino_t* id);
status_t Open(int mode, OpenFileCookie* cookie);
status_t Close(OpenFileCookie* cookie);
status_t OpenAttr(const char* name, int mode,
OpenAttrCookie* cookie, bool create,
int32 type = 0);
status_t CloseAttr(OpenAttrCookie* cookie);
status_t Read(OpenFileCookie* cookie, off_t pos,
void* buffer, size_t* length);
status_t Write(OpenFileCookie* cookie, off_t pos,
const void* buffer, size_t* _length);
status_t ReadDirect(OpenStateCookie* cookie, off_t pos,
void* buffer, size_t* length, bool* eof);
status_t WriteDirect(OpenStateCookie* cookie, off_t pos,
const void* buffer, size_t* _length);
status_t CreateDir(const char* name, int mode,
ino_t* id);
status_t OpenDir(OpenDirCookie* cookie);
status_t ReadDir(void* buffer, uint32 size,
uint32* count, OpenDirCookie* cookie);
status_t OpenAttrDir(OpenDirCookie* cookie);
status_t TestLock(OpenFileCookie* cookie,
struct flock* lock);
status_t AcquireLock(OpenFileCookie* cookie,
const struct flock* lock, bool wait);
status_t ReleaseLock(OpenFileCookie* cookie,
const struct flock* lock);
status_t ReleaseAllLocks(OpenFileCookie* cookie);
status_t GetDirSnapshot(DirectoryCacheSnapshot**
_snapshot, OpenDirCookie* cookie,
uint64* _change, bool attribute);
status_t LoadAttrDirHandle();
static inline ino_t FileIdToInoT(uint64 fileid);
void BeginAIOOp();
void EndAIOOp();
bool AIOIncomplete();
inline void WaitAIOComplete();
inline void SetStale(bool stale = true);
inline bool IsStale() const;
void Dump(void (*xprintf)(const char*, ...) = dprintf);
protected:
Inode();
void ReleaseOpenState();
status_t CreateState(const char* name, int mode,
int perms, OpenState* state,
OpenDelegationData* data);
void ReturnDelegation(bool truncate);
status_t ReadDirUp(struct dirent* de, uint32 pos,
uint32 size);
status_t FillDirEntry(struct dirent* de, ino_t id,
const char* name, uint32 pos, uint32 size);
status_t ChildAdded(const char* name, uint64 fileID,
const FileHandle& fileHandle);
status_t GetStat(struct stat* st,
OpenAttrCookie* attr = NULL);
char* AttrToFileName(const char* path);
static inline status_t CheckLockType(short ltype, uint32 mode);
private:
void _DumpLocked(void (*xprintf)(const char*, ...), bool dumpDelegation,
bool dumpAIO) const;
private:
uint32 fType;
MetadataCache fMetaCache;
DirectoryCache* fCache;
DirectoryCache* fAttrCache;
rw_lock fDelegationLock;
Delegation* fDelegation;
uint64 fChange;
void* fFileCache;
mutex fFileCacheLock;
uint64 fMaxFileSize;
OpenState* fOpenState;
mutex fStateLock;
rw_lock fWriteLock;
bool fWriteDirty;
sem_id fAIOWait;
uint32 fAIOCount;
mutex fAIOLock;
uint32 fOpenStateReleasesPending;
bool fStale;
};
inline void
Inode::WaitAIOComplete()
{
acquire_sem(fAIOWait);
release_sem(fAIOWait);
}
inline ino_t
Inode::FileIdToInoT(uint64 fileid)
{
if (sizeof(ino_t) >= sizeof(uint64))
return fileid;
else
return (ino_t)fileid ^ (fileid >>
(sizeof(uint64) - sizeof(ino_t)) * 8);
}
inline ino_t
Inode::ID() const
{
return FileIdToInoT(fInfo.fFileId);
}
inline mode_t
Inode::Type() const
{
return sNFSFileTypeToHaiku[fType];
}
inline FileSystem*
Inode::GetFileSystem() const
{
ASSERT(fFileSystem != NULL);
return fFileSystem;
}
inline void*
Inode::FileCache()
{
return fFileCache;
}
inline void
Inode::SetOpenState(OpenState* state)
{
ASSERT(state != NULL);
fOpenState = state;
}
inline uint64
Inode::MaxFileSize()
{
return fMaxFileSize;
}
inline uint64
Inode::Change()
{
return fChange;
}
inline bool
Inode::Dirty()
{
return fWriteDirty;
}
inline OpenState*
Inode::GetOpenState()
{
return fOpenState;
}
inline Delegation*
Inode::GetDelegation() const
{
return fDelegation;
}
inline void
Inode::SetStale(bool stale)
{
fStale = stale;
}
inline bool
Inode::IsStale() const
{
return fStale;
}
#endif