The Pedigree Project 0.1
Ext2Filesystem.h
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#ifndef EXT2FILESYSTEM_H
21#define EXT2FILESYSTEM_H
22#include "pedigree/kernel/machine/DiskView.h"
23#include "pedigree/kernel/process/Mutex.h"
24#include "pedigree/kernel/processor/types.h"
25#include "pedigree/kernel/utilities/String.h"
26#include "pedigree/kernel/utilities/Tree.h"
27
28#include <config.h>
29
30#include "Ext2Quota.h"
31#include "modules/system/vfs/ExtendedAttributes.h"
32#include "modules/system/vfs/Filesystem.h"
33
34class Disk;
35class Ext2Node;
36class Ext2File;
37struct Ext2InodeState;
38class File;
39struct GroupDesc;
40struct Inode;
41struct Superblock;
42template <class T>
43class Vector;
44
46class Ext2Filesystem : public Filesystem {
47 friend class Ext2HandlesTestPeer;
48 friend class Ext2XattrTestPeer;
49 friend class Ext2FillCacheTestPeer;
50 friend class Ext2WritebackTestPeer;
51 friend class Ext2FilesystemSyncTestPeer;
52 friend class Ext2DirectorySyncTestPeer;
53 friend class Ext2AllocationTestPeer;
54 friend class Ext2QuotaTestPeer;
55 friend class Ext2File;
56 friend class Ext2Node;
57 friend class Ext2Directory;
58 friend class Ext2Symlink;
59 friend struct Ext2InodeState;
60
61 public:
63
64 virtual ~Ext2Filesystem();
65
66 //
67 // Filesystem interface.
68 //
69 virtual bool initialise(Disk* pDisk);
70 static Filesystem* probe(Disk* pDisk);
71 virtual File* getRoot() const;
72 virtual const String& getVolumeLabel() const;
73 virtual bool getUuid(String& uuid) const;
74 virtual FileHandleStatus encodeFileHandle(File&, FileHandle&);
75 virtual FileHandleStatus decodeFileHandle(const FileHandle&, RetainedFile&);
76 virtual FileHandleStatus fileHandleFsid(FileSystemId&);
77 virtual SyncStatus sync();
78 virtual SyncStatus shutdown();
79 virtual bool deviceRemoved(bool deviceAvailable = false);
80 virtual QuotaStatus quotaControl(const QuotaRequest&, QuotaResponse&, File* quotaFile = nullptr);
81
82 protected:
83 virtual bool createFile(File* parent, const String& filename, uint32_t mask);
84 virtual bool createDirectory(File* parent, const String& filename, uint32_t mask);
85 virtual bool createSymlink(File* parent, const String& filename, const String& value);
86 virtual bool createLink(File* parent, const String& filename, File* target);
87 virtual bool removeNode(File* parent, const String& filename, File* file);
88 virtual bool renameNode(Directory* oldParent, const String& oldName, File* source,
89 Directory* newParent, const String& newName, File* replaced);
90
91 private:
92 void releaseMetadata();
93 static bool quotaSucceeded(QuotaStatus status);
94 static QuotaStatus quotaIoStatus();
95 static int currentIoError();
96 QuotaStatus prepareQuotaInodeLocked(uint32_t inode);
97 QuotaStatus scanQuotaInodesLocked();
98 QuotaStatus flushQuotaLocked(QuotaType type);
99 QuotaStatus flushQuotas();
100 bool closeQuotaFiles(bool discardOnFailure = true);
101 bool beginWritableMount();
102 bool isQuotaFile(uint32_t inode);
103 Ext2QuotaLedger m_Quota;
104 Mutex m_QuotaControlLock;
105 Mutex m_QuotaNamespaceLock;
106 Ext2File* m_QuotaFiles[2] = {};
107#if defined(PEDIGREE_BUILDUTILS)
108 void (*m_QuotaOffTestHook)(void*) = nullptr;
109 void* m_QuotaOffTestContext = nullptr;
110#endif
111 class SyncSnapshot;
112 void releaseSyncState(uint32_t inode, Ext2InodeState* state);
113 Ext2InodeState* acquireInodeState(uint32_t inode, Inode* metadata);
114 Ext2InodeState* acquireInodeStateLocked(uint32_t inode, Inode* metadata);
115 FileHandleStatus validateHandleInodeLocked(uint32_t inode, uint32_t generation, Inode*&);
116 void releaseInodeState(uint32_t inode, Ext2InodeState* state, Ext2Node* lastNode);
117 void retireInodeLocked(uint32_t inode, Ext2Node* lastNode);
118 enum class AttributeWriteKind { Payload, Allocation, Inode };
120 uint64_t location = 0;
121 AttributeWriteKind kind = AttributeWriteKind::Payload;
122 bool ownsPin = false;
123 };
124 static constexpr size_t MaximumAttributeWrites = 64;
125 AttributeWrite m_AttributeWrites[MaximumAttributeWrites];
126 size_t m_AttributeWriteCount = 0;
128 AttributeRetirement() = default;
131 AttributeRetirement& operator=(const AttributeRetirement&) = delete;
132 Ext2Filesystem* filesystem = nullptr;
133 uint32_t block = 0;
134 uintptr_t buffer = 0;
135 bool provisional = false;
136 };
137 XattrStatus attributeFormatStatus() const;
138 XattrStatus readAttributeBlockLocked(Inode*, AttributeRetirement&);
139 XattrStatus prepareAttributeRetirementLocked(Inode*, AttributeRetirement&);
140 void commitAttributeRetirementLocked(AttributeRetirement&);
141 XattrStatus allocateAttributeBlockLocked(uint32_t inode, AttributeRetirement&);
142 XattrStatus reserveAttributeWritesLocked(size_t additional);
143 void recordAttributeWriteLocked(uint64_t, AttributeWriteKind, bool adoptPin = false);
144 void recordAttributeAllocationLocked(uint32_t block);
145 void recordAttributeInodeLocked(uint32_t inode);
146 void forgetAttributeBlockLocked(uint32_t block);
147 bool flushAttributeWritesLocked();
148 void drainAttributeWrites();
149 Mutex m_InodeStateLock;
151 virtual bool createNode(File* parent, const String& filename, uint32_t mask, const String& value,
152 size_t type, uint32_t inodeOverride = 0);
153
156 void operator=(const Ext2Filesystem&);
157
159 uintptr_t readBlock(uint32_t block);
160 DiskReadView readBlockView(uint32_t block);
162 void writeBlock(uint32_t block);
163
164 bool pinBlock(uint64_t location);
165 void unpinBlock(uint64_t location);
166
167 bool syncBlock(uint32_t block, bool async);
168 bool syncInode(uint32_t inode, Ext2Node& node, bool includeNamespaceMetadata = false);
169
170 uint32_t findFreeBlock(uint32_t inode);
171 bool findFreeBlocks(uint32_t inode, size_t count, Vector<uint32_t>& blocks);
172 size_t findFreeBlocksInGroup(uint32_t group, size_t maxCount, Vector<uint32_t>& blocks);
173 uint32_t findFreeInode(uint32_t uid = 0, uint32_t gid = 0);
174
175 void releaseBlock(uint32_t block, uint32_t inode = 0);
178 bool releaseInode(uint32_t inode, Ext2Node* retiringNode = nullptr);
179
180 Inode* getInode(uint32_t num);
181 void writeInode(uint32_t num);
182
183 bool ensureFreeBlockBitmapLoaded(size_t group);
184 bool ensureFreeInodeBitmapLoaded(size_t group);
185 uintptr_t loadInodeTableBlock(size_t group, size_t block);
186
187 void releaseBlockLocked(uint32_t block, uint32_t inode = 0);
188 bool prepareBlockReleaseLocked(uint32_t block);
189 bool prepareInodeWrite(uint32_t inode);
190
191 bool checkOptionalFeature(size_t feature);
192 bool checkRequiredFeature(size_t feature);
193 bool checkReadOnlyFeature(size_t feature);
194
195 void increaseInodeRefcount(uint32_t inode);
196 bool decreaseInodeRefcount(uint32_t inode);
197
200 uint16_t m_MountState = 0;
201 bool m_ShutdownComplete = false;
202 bool m_TeardownFailed = false;
203
207
214
216 uint32_t m_BlockSize;
217
219 uint32_t m_InodeSize;
220
223
224#if THREADS || defined(STANDALONE_MUTEXES)
229
232#endif
233
236
239};
240
241#endif
Definition Disk.h:35
virtual bool createNode(File *parent, const String &filename, uint32_t mask, const String &value, size_t type, uint32_t inodeOverride=0)
size_t m_nGroupDescriptors
GroupDesc ** m_pGroupDescriptors
virtual bool removeNode(File *parent, const String &filename, File *file)
virtual SyncStatus sync()
void writeBlock(uint32_t block)
void retireInodeLocked(uint32_t inode, Ext2Node *lastNode)
virtual bool initialise(Disk *pDisk)
uintptr_t readBlock(uint32_t block)
Vector< size_t > * m_pInodeTables
virtual bool createDirectory(File *parent, const String &filename, uint32_t mask)
Vector< size_t > * m_pBlockBitmaps
virtual bool createSymlink(File *parent, const String &filename, const String &value)
virtual SyncStatus shutdown()
void releaseBlockLocked(uint32_t block, uint32_t inode=0)
virtual const String & getVolumeLabel() const
size_t findFreeBlocksInGroup(uint32_t group, size_t maxCount, Vector< uint32_t > &blocks)
virtual bool deviceRemoved(bool deviceAvailable=false)
virtual bool getUuid(String &uuid) const
Vector< size_t > * m_pInodeBitmaps
virtual FileHandleStatus encodeFileHandle(File &, FileHandle &)
virtual bool renameNode(Directory *oldParent, const String &oldName, File *source, Directory *newParent, const String &newName, File *replaced)
bool releaseInode(uint32_t inode, Ext2Node *retiringNode=nullptr)
virtual bool createFile(File *parent, const String &filename, uint32_t mask)
virtual bool createLink(File *parent, const String &filename, File *target)
Ext2Filesystem(const Ext2Filesystem &)
Superblock * m_pSuperblock
virtual File * getRoot() const
Definition File.h:75
Definition Mutex.h:56
A key/value dictionary.
Definition Tree.h:33
A vector / dynamic array.
Definition Vector.h:33
Definition ext2.h:152