20 #include "Ext2Directory.h" 22 #include "Ext2Filesystem.h" 23 #include "Ext2Symlink.h" 25 #include "modules/system/vfs/File.h" 26 #include "pedigree/kernel/Log.h" 27 #include "pedigree/kernel/stddef.h" 28 #include "pedigree/kernel/syscallError.h" 29 #include "pedigree/kernel/utilities/Pointers.h" 30 #include "pedigree/kernel/utilities/Vector.h" 31 #include "pedigree/kernel/utilities/assert.h" 32 #include "pedigree/kernel/utilities/utility.h" 40 name, LITTLE_TO_HOST32(inode->i_atime),
41 LITTLE_TO_HOST32(inode->i_mtime), LITTLE_TO_HOST32(inode->i_ctime),
43 LITTLE_TO_HOST32(inode->i_size),
47 uint32_t mode = LITTLE_TO_HOST32(inode->i_mode);
77 for (i = 0; i < m_Blocks.
count(); i++)
80 uintptr_t buffer = m_pExt2Fs->
readBlock(m_Blocks[i]);
82 pDir =
reinterpret_cast<Dir *
>(buffer);
83 pBlockEnd = adjust_pointer(pDir, m_pExt2Fs->
m_BlockSize);
84 while (pDir < pBlockEnd)
87 size_t thisReclen = 4 + 2 + 1 + 1 + pDir->d_namelen;
91 thisReclen += 4 - (thisReclen % 4);
95 uint16_t entryReclen = LITTLE_TO_HOST16(pDir->d_reclen);
96 if (pDir->d_inode > 0)
100 if (entryReclen - thisReclen >= length)
104 uint16_t oldReclen = entryReclen;
106 pDir->d_reclen = HOST_TO_LITTLE16(thisReclen);
108 pDir = adjust_pointer(pDir, thisReclen);
110 uint16_t newReclen = oldReclen - thisReclen;
112 pDir->d_reclen = HOST_TO_LITTLE16(newReclen);
116 else if (entryReclen == 0)
121 else if (entryReclen - thisReclen >= length)
131 pDir = adjust_pointer(pDir, entryReclen);
137 if (!bFound || !pDir)
140 uint32_t block = m_pExt2Fs->findFreeBlock(getInodeNumber());
144 SYSCALL_ERROR(NoSpaceLeftOnDevice);
147 if (!addBlock(block))
149 i = m_Blocks.
count() - 1;
158 ensureBlockLoaded(i);
159 uintptr_t buffer = m_pExt2Fs->
readBlock(m_Blocks[i]);
161 ByteSet(reinterpret_cast<void *>(buffer), 0, m_pExt2Fs->
m_BlockSize);
162 pDir =
reinterpret_cast<Dir *
>(buffer);
163 pDir->d_reclen = HOST_TO_LITTLE16(m_pExt2Fs->
m_BlockSize);
169 uint32_t entryInode = pFile->getInode();
170 pDir->d_inode = HOST_TO_LITTLE32(entryInode);
171 m_pExt2Fs->increaseInodeRefcount(entryInode);
173 if (m_pExt2Fs->checkRequiredFeature(2))
179 pDir->d_file_type = EXT2_FILE;
182 pDir->d_file_type = EXT2_DIRECTORY;
185 pDir->d_file_type = EXT2_SYMLINK;
188 ERROR(
"Unrecognised filetype.");
189 pDir->d_file_type = EXT2_UNKNOWN;
195 pDir->d_file_type = 0;
198 pDir->d_namelen = filename.length();
200 pDir->d_name, static_cast<const char *>(filename), filename.length());
216 size_t fileInode = pFile->getInodeNumber();
221 Dir *pDir, *pLastDir = 0;
222 for (i = 0; i < m_Blocks.
count(); i++)
224 ensureBlockLoaded(i);
225 uintptr_t buffer = m_pExt2Fs->
readBlock(m_Blocks[i]);
226 pDir =
reinterpret_cast<Dir *
>(buffer);
228 while (reinterpret_cast<uintptr_t>(pDir) <
231 if (LITTLE_TO_HOST32(pDir->d_inode) == fileInode)
233 if (pDir->d_namelen == filename.length())
236 pDir->d_name, static_cast<const char *>(filename),
240 uint16_t old_reclen = LITTLE_TO_HOST16(pDir->d_reclen);
241 ByteSet(pDir, 0, old_reclen);
249 pDir->d_reclen = HOST_TO_LITTLE16(old_reclen);
257 else if (!pDir->d_reclen)
263 pDir =
reinterpret_cast<Dir *
>(
264 reinterpret_cast<uintptr_t
>(pDir) +
265 LITTLE_TO_HOST16(pDir->d_reclen));
285 SYSCALL_ERROR(DoesNotExist);
299 for (i = 0; i < m_Blocks.
count(); i++)
301 ensureBlockLoaded(i);
304 uintptr_t buffer = m_pExt2Fs->
readBlock(m_Blocks[i]);
306 pDir =
reinterpret_cast<Dir *
>(buffer);
308 while (reinterpret_cast<uintptr_t>(pDir) <
311 size_t reclen = LITTLE_TO_HOST16(pDir->d_reclen);
313 Dir *pNextDir = adjust_pointer(pDir, reclen);
314 if (pDir->d_inode == 0)
316 if (pDir == pNextDir)
328 size_t copylen = offsetof(
Dir, d_name);
331 meta.pDirectory =
this;
334 MemoryCopy(meta.opaque.get(), pDir, copylen);
336 size_t namelen = pDir->d_namelen;
339 size_t fileType = EXT2_UNKNOWN;
341 if (m_pExt2Fs->checkRequiredFeature(2))
343 fileType = pDir->d_file_type;
352 "EXT2: Directory entry has unsupported file type: " 353 << pDir->d_file_type);
360 uint32_t inodeNum = LITTLE_TO_HOST32(pDir->d_inode);
361 Inode *inode = m_pExt2Fs->getInode(inodeNum);
364 size_t inode_ftype = inode->i_mode & 0xF000;
373 "EXT2: Inode has unsupported file type: " 374 << inode_ftype <<
".");
381 namelen |= pDir->d_file_type << 8;
386 String filename(pDir->d_name, namelen);
387 meta.filename = filename;
396 m_pExt2Fs->unpinBlock(m_Blocks[i]);
405 m_Size, m_AccessedTime, m_ModifiedTime, m_CreationTime);
407 getUid(), getGid(), permissionsToMode(getPermissions()));
412 Dir *pDir =
reinterpret_cast<Dir *
>(meta.opaque.get());
414 uint32_t inodeNum = LITTLE_TO_HOST32(pDir->d_inode);
415 Inode *inode = m_pExt2Fs->getInode(inodeNum);
418 size_t fileType = EXT2_UNKNOWN;
419 if (m_pExt2Fs->checkRequiredFeature(2))
422 fileType = pDir->d_file_type;
427 size_t inode_ftype = inode->i_mode & 0xF000;
431 fileType = EXT2_SYMLINK;
434 fileType = EXT2_FILE;
437 fileType = EXT2_DIRECTORY;
441 FATAL(
"Bad inode file type in Ext2Directory::convertToFile");
451 new Ext2File(meta.filename, inodeNum, inode, m_pExt2Fs,
this);
455 meta.filename, inodeNum, inode, m_pExt2Fs,
this);
459 meta.filename, inodeNum, inode, m_pExt2Fs,
this);
463 FATAL(
"Bad file type in Ext2Directory::convertToFile");
virtual bool addEntry(String filename, File *pFile, size_t type)
Ext2Directory(const Ext2Directory &file)
void setUidOnly(size_t uid)
virtual File * convertToFile(const DirectoryEntryMetadata &meta)
void addDirectoryEntry(const String &name, File *pTarget)
void setPermissionsOnly(uint32_t perms)
void updateMetadata(uint16_t uid, uint16_t gid, uint32_t perms)
bool releaseInode(uint32_t inode)
void setGidOnly(size_t gid)
uintptr_t readBlock(uint32_t block)
void fileAttributeChanged()
void writeBlock(uint32_t block)
virtual bool removeEntry(const String &filename, Ext2Node *pFile)
void markCachePopulated()
virtual void cacheDirectoryContents()
virtual bool isCachePopulated() const