xref: /haiku/src/add-ons/kernel/file_systems/exfat/Volume.h (revision 2b76973fa2401f7a5edf68e6470f3d3210cbcff3)
1 /*
2  * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
3  * Copyright 2008-2010, Axel Dörfler, axeld@pinc-software.de.
4  * This file may be used under the terms of the MIT License.
5  */
6 #ifndef VOLUME_H
7 #define VOLUME_H
8 
9 
10 #include <lock.h>
11 #include <string.h>
12 
13 #include "exfat.h"
14 #include "SplayTree.h"
15 
16 
17 struct node_key {
18 	cluster_t cluster;
19 	uint32 offset;
20 };
21 
22 struct node {
23 	struct node_key key;
24 	ino_t ino;
25 	ino_t parent;
26 	SplayTreeLink<struct node> nodeTreeLink;
27 	SplayTreeLink<struct node> inoTreeLink;
28 };
29 
30 
31 struct NodeTreeDefinition {
32 	typedef struct node_key KeyType;
33 	typedef	struct node NodeType;
34 
35 	static KeyType GetKey(const NodeType* node)
36 	{
37 		return node->key;
38 	}
39 
40 	static SplayTreeLink<NodeType>* GetLink(NodeType* node)
41 	{
42 		return &node->nodeTreeLink;
43 	}
44 
45 	static int Compare(KeyType key, const NodeType* node)
46 	{
47 		if (key.cluster == node->key.cluster) {
48 			if (key.offset == node->key.offset)
49 				return 0;
50 			return key.offset < node->key.offset ? -1 : 1;
51 		}
52 		return key.cluster < node->key.cluster ? -1 : 1;
53 	}
54 };
55 
56 struct InoTreeDefinition {
57 	typedef ino_t KeyType;
58 	typedef	struct node NodeType;
59 
60 	static KeyType GetKey(const NodeType* node)
61 	{
62 		return node->ino;
63 	}
64 
65 	static SplayTreeLink<NodeType>* GetLink(NodeType* node)
66 	{
67 		return &node->inoTreeLink;
68 	}
69 
70 	static int Compare(KeyType key, const NodeType* node)
71 	{
72 		if (key != node->ino)
73 			return key < node->ino ? -1 : 1;
74 		return 0;
75 	}
76 };
77 
78 
79 typedef SplayTree<NodeTreeDefinition> NodeTree;
80 typedef SplayTree<InoTreeDefinition> InoTree;
81 class Inode;
82 struct InodesInoTreeDefinition;
83 typedef IteratableSplayTree<InodesInoTreeDefinition> InodesInoTree;
84 struct InodesClusterTreeDefinition;
85 typedef IteratableSplayTree<InodesClusterTreeDefinition> InodesClusterTree;
86 
87 
88 enum volume_flags {
89 	VOLUME_READ_ONLY	= 0x0001
90 };
91 
92 
93 class Volume {
94 public:
95 								Volume(fs_volume* volume);
96 								~Volume();
97 
98 			status_t			Mount(const char* device, uint32 flags);
99 			status_t			Unmount();
100 
101 			bool				IsValidSuperBlock();
102 			bool				IsReadOnly() const
103 								{ return (fFlags & VOLUME_READ_ONLY) != 0; }
104 
105 			Inode*				RootNode() const { return fRootNode; }
106 			int					Device() const { return fDevice; }
107 
108 			dev_t				ID() const
109 								{ return fFSVolume ? fFSVolume->id : -1; }
110 			fs_volume*			FSVolume() const { return fFSVolume; }
111 			const char*			Name() const;
112 			void				SetName(const char* name)
113 								{ strlcpy(fName, name, sizeof(fName)); }
114 
115 			uint32				BlockSize() const { return fBlockSize; }
116 			uint32				EntriesPerBlock() const
117 								{ return fEntriesPerBlock; }
118 			uint32				EntriesPerCluster()
119 								{ return fEntriesPerBlock
120 									<< SuperBlock().BlocksPerClusterShift(); }
121 			size_t				ClusterSize() { return fBlockSize
122 									<< SuperBlock().BlocksPerClusterShift(); }
123 			exfat_super_block&	SuperBlock() { return fSuperBlock; }
124 
125 			status_t			LoadSuperBlock();
126 
127 			// cache access
128 			void*				BlockCache() { return fBlockCache; }
129 
130 	static	status_t			Identify(int fd, exfat_super_block* superBlock);
131 
132 			status_t			ClusterToBlock(cluster_t cluster,
133 									fsblock_t &block);
134 			Inode *				FindInode(ino_t id);
135 			Inode *				FindInode(cluster_t cluster);
136 			cluster_t			NextCluster(cluster_t cluster);
137 			ino_t				GetIno(cluster_t cluster, uint32 offset, ino_t parent);
138 			struct node_key*	GetNode(ino_t ino, ino_t &parent);
139 private:
140 			ino_t				_NextID() { return fNextId++; }
141 
142 			mutex				fLock;
143 			fs_volume*			fFSVolume;
144 			int					fDevice;
145 			exfat_super_block	fSuperBlock;
146 			char				fName[32];
147 
148 			uint16				fFlags;
149 			uint32				fBlockSize;
150 			uint32				fEntriesPerBlock;
151 			Inode*				fRootNode;
152 			ino_t				fNextId;
153 
154 			void*				fBlockCache;
155 			InodesInoTree*		fInodesInoTree;
156 			InodesClusterTree*	fInodesClusterTree;
157 			NodeTree			fNodeTree;
158 			InoTree				fInoTree;
159 };
160 
161 #endif	// VOLUME_H
162 
163