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