1 /* 2 * Copyright 2008-2010, Axel Dörfler, axeld@pinc-software.de. 3 * This file may be used under the terms of the MIT License. 4 */ 5 #ifndef VOLUME_H 6 #define VOLUME_H 7 8 9 #include <lock.h> 10 11 #include "ext2.h" 12 #include "BlockAllocator.h" 13 #include "InodeAllocator.h" 14 #include "Transaction.h" 15 16 class Inode; 17 class Journal; 18 19 20 enum volume_flags { 21 VOLUME_READ_ONLY = 0x0001 22 }; 23 24 25 class Volume : public TransactionListener { 26 public: 27 Volume(fs_volume* volume); 28 ~Volume(); 29 30 status_t Mount(const char* device, uint32 flags); 31 status_t Unmount(); 32 33 bool IsValidSuperBlock(); 34 bool IsReadOnly() const 35 { return (fFlags & VOLUME_READ_ONLY) != 0; } 36 37 bool HasExtendedAttributes() const; 38 39 Inode* RootNode() const { return fRootNode; } 40 int Device() const { return fDevice; } 41 42 dev_t ID() const 43 { return fFSVolume ? fFSVolume->id : -1; } 44 fs_volume* FSVolume() const { return fFSVolume; } 45 const char* Name() const; 46 47 uint32 NumInodes() const 48 { return fNumInodes; } 49 uint32 NumGroups() const 50 { return fNumGroups; } 51 off_t NumBlocks() const 52 { return fSuperBlock.NumBlocks(); } 53 off_t NumFreeBlocks() const 54 { return fFreeBlocks; } 55 uint32 FirstDataBlock() const 56 { return fFirstDataBlock; } 57 58 uint32 BlockSize() const { return fBlockSize; } 59 uint32 BlockShift() const { return fBlockShift; } 60 uint32 BlocksPerGroup() const 61 { return fSuperBlock.BlocksPerGroup(); } 62 uint32 InodeSize() const 63 { return fSuperBlock.InodeSize(); } 64 uint32 InodesPerGroup() const 65 { return fSuperBlock.InodesPerGroup(); } 66 ext2_super_block& SuperBlock() { return fSuperBlock; } 67 68 status_t GetInodeBlock(ino_t id, uint32& block); 69 uint32 InodeBlockIndex(ino_t id) const; 70 status_t GetBlockGroup(int32 index, 71 ext2_block_group** _group); 72 status_t WriteBlockGroup(Transaction& transaction, 73 int32 index); 74 75 Journal* GetJournal() { return fJournal; } 76 77 bool IndexedDirectories() const 78 { return (fSuperBlock.CompatibleFeatures() 79 & EXT2_FEATURE_DIRECTORY_INDEX) != 0; } 80 uint8 DefaultHashVersion() const 81 { return fSuperBlock.default_hash_version; } 82 bool HugeFiles() const 83 { return (fSuperBlock.ReadOnlyFeatures() 84 & EXT2_READ_ONLY_FEATURE_HUGE_FILE) != 0; } 85 status_t ActivateLargeFiles(Transaction& transaction); 86 87 status_t SaveOrphan(Transaction& transaction, 88 ino_t newID, ino_t &oldID); 89 status_t RemoveOrphan(Transaction& transaction, 90 ino_t id); 91 92 status_t AllocateInode(Transaction& transaction, 93 Inode* parent, int32 mode, ino_t& id); 94 status_t FreeInode(Transaction& transaction, ino_t id, 95 bool isDirectory); 96 97 status_t AllocateBlocks(Transaction& transaction, 98 uint32 minimum, uint32 maximum, 99 uint32& blockGroup, uint32& start, 100 uint32& length); 101 status_t FreeBlocks(Transaction& transaction, 102 uint32 start, uint32 length); 103 104 status_t LoadSuperBlock(); 105 status_t WriteSuperBlock(Transaction& transaction); 106 107 // cache access 108 void* BlockCache() { return fBlockCache; } 109 110 status_t FlushDevice(); 111 status_t Sync(); 112 113 static status_t Identify(int fd, ext2_super_block* superBlock); 114 115 // TransactionListener functions 116 void TransactionDone(bool success); 117 void RemovedFromTransaction(); 118 119 private: 120 static uint32 _UnsupportedIncompatibleFeatures( 121 ext2_super_block& superBlock); 122 static uint32 _UnsupportedReadOnlyFeatures( 123 ext2_super_block& superBlock); 124 uint32 _GroupDescriptorBlock(uint32 blockIndex); 125 126 private: 127 mutex fLock; 128 fs_volume* fFSVolume; 129 int fDevice; 130 ext2_super_block fSuperBlock; 131 char fName[32]; 132 133 BlockAllocator fBlockAllocator; 134 InodeAllocator fInodeAllocator; 135 Journal* fJournal; 136 Inode* fJournalInode; 137 138 uint32 fFlags; 139 uint32 fBlockSize; 140 uint32 fBlockShift; 141 uint32 fFirstDataBlock; 142 143 uint32 fNumInodes; 144 uint32 fNumGroups; 145 uint32 fFreeBlocks; 146 uint32 fFreeInodes; 147 uint32 fGroupsPerBlock; 148 ext2_block_group** fGroupBlocks; 149 uint32 fInodesPerBlock; 150 151 void* fBlockCache; 152 Inode* fRootNode; 153 }; 154 155 #endif // VOLUME_H 156