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