1/*
2 * Copyright 2011, J��r��me Duval, korli@users.berlios.de.
3 * Copyright 2008, Axel D��rfler, axeld@pinc-software.de.
4 * This file may be used under the terms of the MIT License.
5 */
6#ifndef INODE_H
7#define INODE_H
8
9
10#include <fs_cache.h>
11#include <lock.h>
12#include <string.h>
13
14#include "btrfs.h"
15#include "Volume.h"
16
17
18//#define TRACE_BTRFS
19#ifdef TRACE_BTRFS
20#	define TRACEI(x...) dprintf("\33[34mbtrfs:\33[0m " x)
21#else
22#	define TRACEI(x...) ;
23#endif
24
25
26class Inode {
27public:
28						Inode(Volume* volume, ino_t id);
29						~Inode();
30
31			status_t	InitCheck();
32
33			ino_t		ID() const { return fID; }
34
35			rw_lock*	Lock() { return &fLock; }
36
37			status_t	UpdateNodeFromDisk();
38
39			bool		IsDirectory() const
40							{ return S_ISDIR(Mode()); }
41			bool		IsFile() const
42							{ return S_ISREG(Mode()); }
43			bool		IsSymLink() const
44							{ return S_ISLNK(Mode()); }
45			status_t	CheckPermissions(int accessMode) const;
46
47			mode_t		Mode() const { return fNode.Mode(); }
48			off_t		Size() const { return fNode.Size(); }
49			uid_t		UserID() const { return fNode.UserID(); }
50			gid_t		GroupID() const { return fNode.GroupID(); }
51			void		GetChangeTime(struct timespec &timespec) const
52							{ fNode.GetChangeTime(timespec); }
53			void		GetModificationTime(struct timespec &timespec) const
54							{ fNode.GetModificationTime(timespec); }
55			void		GetCreationTime(struct timespec &timespec) const
56							{ fNode.GetCreationTime(timespec); }
57			void		GetAccessTime(struct timespec &timespec) const
58							{ fNode.GetCreationTime(timespec); }
59
60			Volume*		GetVolume() const { return fVolume; }
61
62			status_t	FindBlock(off_t logical, off_t& physical,
63							off_t *_length = NULL);
64			status_t	ReadAt(off_t pos, uint8 *buffer, size_t *length);
65			status_t	FillGapWithZeros(off_t start, off_t end);
66
67			void*		FileCache() const { return fCache; }
68			void*		Map() const { return fMap; }
69
70			status_t	FindParent(ino_t *id);
71private:
72						Inode(Volume* volume);
73						Inode(const Inode&);
74						Inode &operator=(const Inode&);
75							// no implementation
76
77			uint64		_NumBlocks();
78
79			rw_lock		fLock;
80			::Volume*	fVolume;
81			ino_t		fID;
82			void*		fCache;
83			void*		fMap;
84			status_t	fInitStatus;
85			struct btrfs_inode fNode;
86};
87
88
89// The Vnode class provides a convenience layer upon get_vnode(), so that
90// you don't have to call put_vnode() anymore, which may make code more
91// readable in some cases
92
93class Vnode {
94public:
95	Vnode(Volume* volume, ino_t id)
96		:
97		fInode(NULL)
98	{
99		SetTo(volume, id);
100	}
101
102	Vnode()
103		:
104		fStatus(B_NO_INIT),
105		fInode(NULL)
106	{
107	}
108
109	~Vnode()
110	{
111		Unset();
112	}
113
114	status_t InitCheck()
115	{
116		return fStatus;
117	}
118
119	void Unset()
120	{
121		if (fInode != NULL) {
122			put_vnode(fInode->GetVolume()->FSVolume(), fInode->ID());
123			fInode = NULL;
124			fStatus = B_NO_INIT;
125		}
126	}
127
128	status_t SetTo(Volume* volume, ino_t id)
129	{
130		Unset();
131
132		return fStatus = get_vnode(volume->FSVolume(), id, (void**)&fInode);
133	}
134
135	status_t Get(Inode** _inode)
136	{
137		*_inode = fInode;
138		return fStatus;
139	}
140
141	void Keep()
142	{
143		TRACEI("Vnode::Keep()\n");
144		fInode = NULL;
145	}
146
147private:
148	status_t	fStatus;
149	Inode*		fInode;
150};
151
152#endif	// INODE_H
153