20 #include "FatFilesystem.h" 21 #include "FatDirectory.h" 23 #include "FatSymlink.h" 25 #include "modules/Module.h" 26 #include "modules/system/vfs/Directory.h" 27 #include "modules/system/vfs/File.h" 28 #include "modules/system/vfs/VFS.h" 29 #include "pedigree/kernel/Log.h" 30 #include "pedigree/kernel/machine/Disk.h" 31 #include "pedigree/kernel/process/Scheduler.h" 32 #include "pedigree/kernel/processor/types.h" 33 #include "pedigree/kernel/syscallError.h" 34 #include "pedigree/kernel/utilities/StaticString.h" 35 #include "pedigree/kernel/utilities/String.h" 36 #include "pedigree/kernel/utilities/Tree.h" 38 #include "pedigree/kernel/utilities/utility.h" 44 static bool isPowerOf2(uint32_t n)
48 for (log = 0; log < 16; log++)
53 return (n != 0) ?
false :
true;
60 FatFilesystem::FatFilesystem()
61 : m_Superblock(), m_Superblock16(), m_Superblock32(), m_FsInfo(),
62 m_Type(FAT12), m_DataAreaStart(0), m_RootDirCount(0), m_FatSector(0),
63 m_RootDir(), m_BlockSize(0), m_pFatCache(0), m_FatLock(), m_pRoot(0),
64 m_FatCache(), m_FreeClusterHint()
68 FatFilesystem::~FatFilesystem()
81 uint8_t *buffer =
reinterpret_cast<uint8_t *
>(
m_pDisk->
read(0));
84 reinterpret_cast<void *>(&m_Superblock),
85 reinterpret_cast<void *>(buffer),
sizeof(
Superblock));
92 if (m_Superblock.BS_jmpBoot[0] != 0xE9)
94 if (!(m_Superblock.BS_jmpBoot[0] == 0xEB &&
95 m_Superblock.BS_jmpBoot[2] == 0x90))
98 "FAT: Superblock not found on device " 99 << devName <<
" [" << m_Superblock.BS_jmpBoot[0] <<
", " 100 << m_Superblock.BS_jmpBoot[2] <<
"]");
108 if (!isPowerOf2(m_Superblock.BPB_SecPerClus))
111 "FAT: SecPerClus not a power of 2 (" << m_Superblock.BPB_SecPerClus
117 if (m_Superblock.BPB_NumFATs < 1 || m_Superblock.BPB_NumFATs > 2)
120 "FAT: Too many (or too few) FATs (" << m_Superblock.BPB_NumFATs
130 reinterpret_cast<void *>(&m_Superblock16),
131 reinterpret_cast<void *>(buffer + 36),
sizeof(
Superblock16));
133 reinterpret_cast<void *>(&m_Superblock32),
134 reinterpret_cast<void *>(buffer + 36),
sizeof(
Superblock32));
137 if (!m_Superblock.BPB_BytsPerSec)
142 uint32_t rootDirSectors = ((m_Superblock.BPB_RootEntCnt * 32) +
143 (m_Superblock.BPB_BytsPerSec - 1)) /
144 m_Superblock.BPB_BytsPerSec;
147 uint32_t fatSz = (m_Superblock.BPB_FATSz16) ? m_Superblock.BPB_FATSz16 :
148 m_Superblock32.BPB_FATSz32;
151 uint32_t firstDataSector = m_Superblock.BPB_RsvdSecCnt +
152 (m_Superblock.BPB_NumFATs * fatSz) +
156 uint32_t totDataSec = 0, totSec = (m_Superblock.BPB_TotSec16) ?
157 m_Superblock.BPB_TotSec16 :
158 m_Superblock.BPB_TotSec32;
159 totDataSec = totSec - firstDataSector;
164 ERROR(
"FAT: SecPerClus is zero!");
167 uint32_t clusterCount = totDataSec / m_Superblock.BPB_SecPerClus;
171 if (clusterCount < 4085)
174 NOTICE(
"FAT: Device " << devName <<
" is type FAT12");
176 else if (clusterCount < 65525)
179 NOTICE(
"FAT: Device " << devName <<
" is type FAT16");
184 NOTICE(
"FAT: Device " << devName <<
" is type FAT32");
192 m_RootDir.sector = m_Superblock.BPB_RsvdSecCnt +
193 (m_Superblock.BPB_NumFATs * fatSz);
199 m_RootDir.cluster = m_Superblock32.BPB_RootClus;
205 m_DataAreaStart = firstDataSector;
206 m_RootDirCount = rootDirSectors;
207 m_BlockSize = m_Superblock.BPB_SecPerClus * m_Superblock.BPB_BytsPerSec;
212 uint32_t sec = m_Superblock32.BPB_FsInfo;
213 readSectorBlock(sec, 512, reinterpret_cast<uintptr_t>(&m_FsInfo));
217 m_FatSector = m_Superblock.BPB_RsvdSecCnt;
220 m_FreeClusterHint = 2;
242 void FatFilesystem::loadRootDir()
250 uint32_t cluster = 0;
252 cluster = m_RootDir.cluster;
255 info.creationTime = info.modifiedTime = info.accessedTime = 0;
265 void FatFilesystem::cacheVolumeLabel()
273 uint32_t sz = m_BlockSize;
277 clus = m_RootDir.cluster;
281 uint8_t *buffer =
reinterpret_cast<uint8_t *
>(readDirectoryPortion(clus));
284 bool endOfDir =
false;
287 for (i = 0; i < sz; i +=
sizeof(
Dir))
289 Dir *ent =
reinterpret_cast<Dir *
>(&buffer[i]);
291 if (ent->DIR_Name[0] == 0)
297 if (ent->DIR_Attr & ATTR_VOLUME_ID)
299 volid = convertFilenameFrom(
300 String(reinterpret_cast<const char *>(ent->DIR_Name)));
302 m_VolumeLabel = volid;
310 if (clus == 0 && m_Type != FAT32)
315 clus = getClusterEntry(clus);
323 readCluster(clus, reinterpret_cast<uintptr_t>(buffer));
330 str +=
"no-volume-label@";
331 str.append(reinterpret_cast<uintptr_t>(
this), 16);
332 m_VolumeLabel.assign(str, str.length(),
true);
337 return m_VolumeLabel;
342 uint64_t FatFilesystem::read(
343 File *pFile, uint64_t location, uint64_t size, uintptr_t buffer,
351 uint32_t clus = pFile->getInode();
356 if (location >= pFile->getSize())
359 "FAT: Attempting to read past the EOF [loc=" 360 << location <<
", sz=" << size <<
", fsz=" << pFile->getSize()
365 uint64_t endOffset = location + size;
366 uint64_t finalSize = size;
367 if (endOffset > pFile->getSize())
369 finalSize = pFile->getSize() - location;
372 if ((finalSize == 0) || (finalSize > pFile->getSize()))
374 WARNING(
"FAT: location + size > EOF");
381 uint32_t clusOffset =
382 location / (m_Superblock.BPB_SecPerClus * m_Superblock.BPB_BytsPerSec);
383 uint32_t firstOffset =
384 location % (m_Superblock.BPB_SecPerClus *
385 m_Superblock.BPB_BytsPerSec);
391 uint64_t bytesRead = 0;
392 uint64_t currOffset = firstOffset;
395 clus = getClusterEntry(clus);
396 if (clus == 0 || isEof(clus))
399 "FAT: CLUSTER FAIL - " 400 << clus <<
", cluster offset = " << clusOffset
404 WARNING(
" -> size: " << pFile->getSize());
411 uint8_t *tmpBuffer =
new uint8_t[m_BlockSize];
412 uint8_t *destBuffer =
reinterpret_cast<uint8_t *
>(buffer);
418 readCluster(clus, reinterpret_cast<uintptr_t>(tmpBuffer));
421 size_t bytesToCopy = finalSize - bytesRead;
422 if (bytesToCopy > m_BlockSize)
424 bytesToCopy = m_BlockSize;
428 MemoryCopy(&destBuffer[bytesRead], &tmpBuffer[currOffset], bytesToCopy);
429 bytesRead += bytesToCopy;
432 if (bytesRead == finalSize)
442 clus = getClusterEntry(clus);
453 WARNING(
"FAT: read returning zero... Something's not right.");
463 uint32_t totalSectors = m_Superblock.BPB_TotSec32;
464 if (totalSectors == 0)
467 totalSectors = m_Superblock.BPB_TotSec16;
474 uint32_t mask = m_Type == FAT32 ? 0x0FFFFFFF : 0xFFFF;
476 for (j = (m_Type == FAT32 ? m_FsInfo.FSI_NxtFree : m_FreeClusterHint);
477 j < (totalSectors / m_Superblock.BPB_SecPerClus); j++)
479 clus = getClusterEntry(j,
false);
480 if ((clus & mask) == 0)
488 m_FreeClusterHint = j + 1;
493 FATAL(
"findFreeCluster returning zero!");
499 uint64_t FatFilesystem::write(
500 File *pFile, uint64_t location, uint64_t size, uintptr_t buffer,
511 NOTICE(
"FAT: readonly filesystem");
513 SYSCALL_ERROR(ReadOnlyFilesystem);
520 int64_t fileSizeChange = 0;
521 if ((location + size) > pFile->getSize())
522 fileSizeChange = (location + size) - pFile->getSize();
524 uint32_t firstClus = pFile->getInode();
529 uint32_t freeClus = findFreeCluster();
532 SYSCALL_ERROR(NoSpaceLeftOnDevice);
537 setClusterEntry(freeClus, eofValue(),
false);
538 firstClus = freeClus;
541 pFile->setInode(freeClus);
542 setCluster(pFile, freeClus);
546 m_Superblock.BPB_SecPerClus * m_Superblock.BPB_BytsPerSec;
547 uint32_t finalOffset = location + size;
548 uint32_t offsetSector = location / m_Superblock.BPB_BytsPerSec;
554 int j = pFile->getSize() / i;
555 if (pFile->getSize() % i)
560 uint32_t finalCluster = j * i;
561 uint32_t numExtraBytes = 0;
565 if (finalOffset > finalCluster)
567 numExtraBytes = finalOffset - finalCluster;
569 j = numExtraBytes / i;
570 if (numExtraBytes % i)
575 uint32_t lastClus = clus;
579 clus = getClusterEntry(clus,
false);
583 for (i = 0; i < j; i++)
586 lastClus = findFreeCluster();
589 SYSCALL_ERROR(NoSpaceLeftOnDevice);
593 setClusterEntry(prev, lastClus,
false);
596 setClusterEntry(lastClus, eofValue(),
false);
599 uint64_t finalSize = size;
603 uint32_t clusOffset =
605 m_Superblock.BPB_SecPerClus;
607 uint32_t firstOffset =
608 location % (m_Superblock.BPB_SecPerClus *
609 m_Superblock.BPB_BytsPerSec);
615 uint64_t bytesWritten = 0;
616 uint64_t currOffset = firstOffset;
618 for (uint32_t z = 0; z < clusOffset; z++)
620 clus = getClusterEntry(clus,
false);
621 if (clus == 0 || isEof(clus))
626 uint8_t *tmpBuffer =
new uint8_t[m_BlockSize];
627 uint8_t *srcBuffer =
reinterpret_cast<uint8_t *
>(buffer);
630 NOTICE(
"FAT bytesWritten=" << bytesWritten <<
" finalSize=" << finalSize);
634 while (bytesWritten < finalSize)
637 readCluster(clus, reinterpret_cast<uintptr_t>(tmpBuffer));
640 size_t len = m_BlockSize;
641 if ((bytesWritten + len) > finalSize)
642 len = finalSize - bytesWritten;
646 MemoryCopy(&tmpBuffer[currOffset], &srcBuffer[bytesWritten], len);
651 NOTICE(
"FAT write - clus=" << clus);
652 NOTICE(
"FAT write - offset=" << getSectorNumber(clus) * 512);
654 writeCluster(clus, reinterpret_cast<uintptr_t>(tmpBuffer));
661 clus = getClusterEntry(clus,
false);
667 if (bytesWritten < finalSize)
669 "EOF before written - still " 670 <<
Dec << (finalSize - bytesWritten) <<
Hex 671 <<
" bytes unwritten!!");
677 if (fileSizeChange != 0)
681 "FAT Updating file size on disk change=" <<
Dec << fileSizeChange
684 updateFileSize(pFile, fileSizeChange);
685 pFile->setSize(pFile->getSize() + fileSizeChange);
701 uint32_t dirClus =
static_cast<FatFile *
>(pFile)->getDirCluster();
702 uint32_t dirOffset =
static_cast<FatFile *
>(pFile)->getDirOffset();
704 Dir *p = getDirectoryEntry(dirClus, dirOffset);
707 p->DIR_FileSize += sizeChange;
708 writeDirectoryEntry(p, dirClus, dirOffset);
719 uint32_t dirClus =
static_cast<FatFile *
>(pFile)->getDirCluster();
720 uint32_t dirOffset =
static_cast<FatFile *
>(pFile)->getDirOffset();
722 Dir *p = getDirectoryEntry(dirClus, dirOffset);
725 p->DIR_FstClusLO = clus & 0xFFFF;
726 p->DIR_FstClusHI = (clus >> 16) & 0xFFFF;
727 writeDirectoryEntry(p, dirClus, dirOffset);
734 uint32_t dirClus = clus;
735 uint8_t *dirBuffer = 0;
741 uint32_t sec = m_RootDir.sector;
742 uint32_t sz = m_RootDirCount * m_Superblock.BPB_BytsPerSec;
744 dirBuffer =
new uint8_t[sz];
745 readSectorBlock(sec, sz, reinterpret_cast<uintptr_t>(dirBuffer));
752 dirBuffer =
new uint8_t[m_BlockSize];
753 readCluster(dirClus, reinterpret_cast<uintptr_t>(dirBuffer));
756 return reinterpret_cast<void *
>(dirBuffer);
763 bool secMethod =
false;
764 uint32_t sz = m_BlockSize;
765 uint32_t sec = m_RootDir.sector;
770 sz = m_RootDirCount * m_Superblock.BPB_BytsPerSec;
778 writeSectorBlock(sec, sz, reinterpret_cast<uintptr_t>(p));
780 writeCluster(clus, reinterpret_cast<uintptr_t>(p));
786 reinterpret_cast<uint8_t *
>(readDirectoryPortion(clus));
790 Dir *ent =
reinterpret_cast<Dir *
>(&dirBuffer[offset]);
792 MemoryCopy(ret, ent,
sizeof(
Dir));
800 Dir *dir, uint32_t clus, uint32_t offset)
808 reinterpret_cast<uint8_t *
>(readDirectoryPortion(clus));
812 Dir *ent =
reinterpret_cast<Dir *
>(&dirBuffer[offset]);
813 MemoryCopy(ent, dir,
sizeof(
Dir));
815 writeDirectoryPortion(clus, dirBuffer);
820 void FatFilesystem::fileAttributeChanged(
File *pFile)
824 void FatFilesystem::cacheDirectoryContents(
File *pFile)
830 block = getSectorNumber(block);
831 readSectorBlock(block, m_BlockSize, buffer);
845 size_t sz = (size > 512) ? 512 : size;
847 (static_cast<uint64_t>(m_Superblock.BPB_BytsPerSec) *
848 static_cast<uint64_t>(sec)) +
853 reinterpret_cast<void *>(buffer), reinterpret_cast<void *>(buff),
864 block = getSectorNumber(block);
865 writeSectorBlock(block, m_BlockSize, buffer);
870 uint32_t sec,
size_t size, uintptr_t buffer)
880 size_t sz = (size > 4096) ? 4096 : size;
882 static_cast<uint64_t>(m_Superblock.BPB_BytsPerSec) *
883 static_cast<uint64_t>(sec) +
886 reinterpret_cast<void *>(buff), reinterpret_cast<void *>(buffer),
889 static_cast<uint64_t>(m_Superblock.BPB_BytsPerSec) *
890 static_cast<uint64_t>(sec) +
901 return ((cluster - 2) * m_Superblock.BPB_SecPerClus) + m_DataAreaStart;
906 uint32_t fatOffset = 0;
910 fatOffset = cluster + (cluster / 2);
914 fatOffset = cluster * 2;
918 fatOffset = cluster * 4;
925 while (!m_FatLock.enter())
929 uint32_t *fatBlocks =
reinterpret_cast<uint32_t *
>(
930 m_FatCache.lookup(fatOffset / m_Superblock.BPB_BytsPerSec));
933 if (fatBlocks && (m_Type == FAT12))
935 FATAL(
"Oooer missus, work needed heres");
944 fatBlocks =
new uint32_t
945 [((m_Superblock.BPB_BytsPerSec * 2) /
sizeof(uint32_t)) + 1];
946 if (!readSectorBlock(
947 m_FatSector + (fatOffset / m_Superblock.BPB_BytsPerSec),
948 m_Superblock.BPB_BytsPerSec * 2,
949 reinterpret_cast<uintptr_t
>(fatBlocks)))
951 ERROR(
"FAT: getClusterEntry: reading from the FAT failed");
958 fatOffset / m_Superblock.BPB_BytsPerSec,
959 reinterpret_cast<uintptr_t>(fatBlocks));
961 (fatOffset / m_Superblock.BPB_BytsPerSec) + 1,
962 reinterpret_cast<uintptr_t>(
963 adjust_pointer(fatBlocks, m_Superblock.BPB_BytsPerSec)));
964 NOTICE(
"FAT Cache now has " << m_FatCache.count() <<
" sectors.");
970 fatOffset %= m_Superblock.BPB_BytsPerSec;
971 fatOffset /=
sizeof(uint32_t);
972 uint32_t fatEntry = fatBlocks[fatOffset];
1002 ret = fatEntry & 0x0FFFFFFF;
1016 "setClusterEntry called with invalid arguments - " << cluster <<
"/" 1021 uint32_t fatOffset = 0;
1025 fatOffset = cluster + (cluster / 2);
1029 fatOffset = cluster * 2;
1033 fatOffset = cluster * 4;
1037 uint32_t ent = getClusterEntry(cluster, bLock);
1041 uint32_t *fatBlocks =
reinterpret_cast<uint32_t *
>(
1042 m_FatCache.lookup(fatOffset / m_Superblock.BPB_BytsPerSec));
1043 if (fatBlocks && (m_Type == FAT12))
1045 FATAL(
"Ooer missus, work needed here");
1053 ERROR(
"FAT: setClusterEntry: getClusterEntry didn't read sectors from " 1059 uint32_t oldOffset = fatOffset;
1060 fatOffset %= m_Superblock.BPB_BytsPerSec;
1061 fatOffset /=
sizeof(uint32_t);
1063 uint32_t origEnt = ent;
1064 uint32_t setEnt = value;
1082 setEnt = origEnt | value;
1084 fatBlocks[fatOffset] = setEnt;
1092 fatBlocks[fatOffset] = setEnt;
1098 value &= 0x0FFFFFFF;
1099 setEnt = origEnt & 0xF0000000;
1102 fatBlocks[fatOffset] = setEnt;
1107 uint32_t fatSector =
1108 m_FatSector + (oldOffset / m_Superblock.BPB_BytsPerSec);
1111 m_FatLock.acquire();
1115 fatSector, m_Superblock.BPB_BytsPerSec * 2,
1116 reinterpret_cast<uintptr_t>(fatBlocks));
1120 oldOffset / m_Superblock.BPB_BytsPerSec,
1121 reinterpret_cast<uintptr_t>(fatBlocks));
1122 if (m_Type == FAT12)
1124 (oldOffset / m_Superblock.BPB_BytsPerSec) + 1,
1125 reinterpret_cast<uintptr_t>(
1126 fatBlocks + m_Superblock.BPB_BytsPerSec));
1129 m_FatLock.release();
1135 #if defined(DEBUGGER) && defined(ADDITIONAL_CHECKS) 1136 uint32_t val = getClusterEntry(cluster,
false);
1139 "setClusterEntry has failed on cluster " << cluster <<
": " << val
1140 <<
"/" << value <<
".");
1151 if (!StringCompare(static_cast<const char *>(fn),
".") ||
1152 !StringCompare(static_cast<const char *>(fn),
".."))
1157 return String(static_cast<const char *>(ret));
1166 size_t lastPeriod = ~0UL;
1167 for (
size_t i = 0; i < fn.length(); ++i)
1170 if (fn[i] ==
' ' || fn[i] ==
'"' || fn[i] ==
'/' || fn[i] ==
'\\' ||
1171 fn[i] ==
'[' || fn[i] ==
']' || fn[i] ==
':' || fn[i] ==
';' ||
1172 fn[i] ==
'=' || fn[i] ==
',')
1174 else if (fn[i] ==
'.')
1176 if ((i + 1) >= fn.length())
1186 filename += toUpper(fn[i]);
1193 filename.truncate(6);
1198 else if (lastPeriod != ~0UL)
1200 filename.truncate(lastPeriod);
1204 if (!filename.length())
1210 for (
size_t i = 0; i < 6; ++i)
1212 if ((lastPeriod + i) >= fn.length())
1214 filename += toUpper(fn[lastPeriod + i]);
1220 return String(static_cast<const char *>(filename));
1225 for (
size_t i = 1; i < 4; ++i)
1227 if ((lastPeriod + i) >= fn.length())
1229 ext += toUpper(fn[lastPeriod + i]);
1237 filename.append(ext);
1239 return String(static_cast<const char *>(filename));
1248 for (i = 0; i < 8; i++)
1250 if (i >= filename.length())
1252 if (filename[i] !=
' ')
1253 ret += toLower(filename[i]);
1258 for (i = 0; i < 3; i++)
1260 if ((8 + i) >= filename.length())
1262 if (filename[8 + i] !=
' ')
1266 ret += toLower(filename[8 + i]);
1274 return String(static_cast<const char *>(ret));
1277 void FatFilesystem::truncate(
File *pFile)
1279 NOTICE(
"FatFilesystem::truncate");
1283 updateFileSize(pFile, -pFile->getSize());
1288 uint32_t clus = pFile->getInode(), prev = 0;
1292 clus = getClusterEntry(clus,
true);
1293 setClusterEntry(prev, eofValue(),
true);
1298 while (!isEof(clus))
1301 clus = getClusterEntry(clus,
true);
1302 setClusterEntry(prev, 0,
true);
1304 setClusterEntry(prev, 0,
true);
1309 void FatFilesystem::extend(
File *pFile,
size_t size)
1312 if (pFile->getSize() >= size)
1318 uint32_t firstClus = pFile->getInode();
1319 int64_t sizeChange = size - pFile->getSize();
1321 size_t clusSize = m_Superblock.BPB_SecPerClus * m_Superblock.BPB_BytsPerSec;
1327 uint32_t freeClus = findFreeCluster();
1330 SYSCALL_ERROR(NoSpaceLeftOnDevice);
1335 setClusterEntry(freeClus, eofValue(),
false);
1336 firstClus = freeClus;
1339 pFile->setInode(freeClus);
1340 setCluster(pFile, freeClus);
1343 if (clusSize >= size)
1349 uint32_t finalOffset = size;
1354 int j = pFile->getSize() / i;
1355 if (pFile->getSize() % i)
1360 uint32_t finalCluster = j * i;
1361 uint32_t numExtraBytes = 0;
1364 if (finalOffset > finalCluster)
1366 numExtraBytes = finalOffset - finalCluster;
1368 j = numExtraBytes / i;
1369 if (numExtraBytes % i)
1374 uint32_t lastClus = clus;
1375 while (!isEof(clus))
1378 clus = getClusterEntry(clus,
false);
1382 for (i = 0; i < j; i++)
1385 lastClus = findFreeCluster();
1388 SYSCALL_ERROR(NoSpaceLeftOnDevice);
1392 setClusterEntry(prev, lastClus,
false);
1396 setClusterEntry(lastClus, eofValue(),
false);
1400 updateFileSize(pFile, sizeChange);
1404 File *parentDir,
const String &filename, uint32_t mask,
bool bDirectory,
1414 info.creationTime = 0;
1415 info.modifiedTime = 0;
1416 info.accessedTime = 0;
1425 pFile =
new FatDirectory(filename, dirClus,
this, parentDir, info);
1427 char *buffer =
new char[m_BlockSize];
1428 ByteSet(buffer, 0, m_BlockSize);
1432 uint32_t clus = dirClus;
1436 writeCluster(clus, reinterpret_cast<uintptr_t>(buffer));
1437 clus = getClusterEntry(clus);
1438 }
while (!isEof(clus));
1445 uint32_t clus = findFreeCluster();
1446 setClusterEntry(clus, eofValue());
1448 filename, 0, 0, 0, clus,
this, 0,
1457 if (!parent->
addEntry(filename, pFile, (bDirectory ? 1 : 0)))
1467 File *parent,
const String &filename, uint32_t mask)
1474 File *parent,
const String &filename, uint32_t mask)
1477 uint32_t clus = findFreeCluster(
true);
1484 setClusterEntry(clus, 0);
1489 setClusterEntry(clus, eofValue());
1491 setCluster(f, clus);
1496 if (!dot || !dotdot)
1509 setCluster(dot, dot->getInode());
1510 setCluster(dotdot, dotdot->getInode());
1525 info.creationTime = 0;
1526 info.modifiedTime = 0;
1527 info.accessedTime = 0;
1532 uint32_t clus = findFreeCluster();
1533 setClusterEntry(clus, eofValue());
1535 filename, 0, 0, 0, clus,
this, 0,
1540 String symlinkFilename = filename;
1541 symlinkFilename += FatDirectory::symlinkSuffix();
1545 if (!fatParent->
addEntry(symlinkFilename, pFile, 0))
1554 reinterpret_cast<uintptr_t
>(
static_cast<const char *
>(value)));
1571 uint32_t clus = file->getInode();
1578 clus = getClusterEntry(clus,
false);
1579 setClusterEntry(prev, 0,
false);
1583 ERROR(
"Found a zero cluster during FatFilesystem::remove...");
1595 static bool initFat()
1601 static void destroyFat()
1605 MODULE_INFO(
"fat", &initFat, &destroyFat,
"vfs");
void writeDirectoryEntry(Dir *dir, uint32_t clus, uint32_t offset)
void updateFileSize(File *pFile, int64_t sizeChange)
virtual bool initialise(Disk *pDisk)
virtual bool createDirectory(File *parent, const String &filename, uint32_t mask)
void setCluster(File *pFile, uint32_t clus)
virtual bool createSymlink(File *parent, const String &filename, const String &value)
virtual File * getRoot() const
uint32_t setClusterEntry(uint32_t cluster, uint32_t value, bool bLock=true)
bool readSectorBlock(uint32_t sec, size_t size, uintptr_t buffer) const
void writeDirectoryPortion(uint32_t clus, void *p)
virtual bool removeEntry(File *pFile)
Dir * getDirectoryEntry(uint32_t clus, uint32_t offset) const
static Directory * fromFile(File *pF)
bool createFile(const StringView &path, uint32_t mask, File *pStartNode=0)
uint32_t findFreeCluster(bool bLock=false)
virtual void setInode(uintptr_t inode)
void addProbeCallback(Filesystem::ProbeCallback callback)
uint32_t getClusterEntry(uint32_t cluster, bool bLock=true)
virtual bool createFile(File *parent, const String &filename, uint32_t mask)
void * readDirectoryPortion(uint32_t clus) const
bool writeCluster(uint32_t block, uintptr_t buffer)
virtual uintptr_t read(uint64_t location)
String convertFilenameFrom(String filename) const
bool readCluster(uint32_t block, uintptr_t buffer) const
virtual String getFullPath(bool bWithLabel=true)
static Scheduler & instance()
virtual void write(uint64_t location)
virtual String getVolumeLabel() const
FatFile(const File &file)
virtual void getName(String &str)
String convertFilenameTo(String filename) const
virtual bool isDirectory()
virtual bool addEntry(String filename, File *pFile, size_t type)
virtual bool remove(File *parent, File *file)
uint32_t getSectorNumber(uint32_t cluster) const
bool writeSectorBlock(uint32_t sec, size_t size, uintptr_t buffer)
virtual uint64_t write(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true) final
virtual File * getRoot() const =0