The Pedigree Project  0.1
FatFilesystem.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 FATFILESYSTEM_H
21 #define FATFILESYSTEM_H
22 
23 #include "FatFile.h"
24 #include "modules/system/vfs/Filesystem.h"
25 #include "pedigree/kernel/LockGuard.h"
26 #include "pedigree/kernel/process/Mutex.h"
27 #include "pedigree/kernel/utilities/Cache.h"
28 #include "pedigree/kernel/utilities/List.h"
29 #include "pedigree/kernel/utilities/Tree.h"
31 #include "pedigree/kernel/utilities/Vector.h"
32 
33 #include "FatDirectory.h"
34 #include "FatFile.h"
35 #include "fat.h"
36 
38 class FatFilesystem : public Filesystem
39 {
40  friend class FatFile;
41  friend class FatDirectory;
42 
43  public:
44  FatFilesystem();
45 
46  virtual ~FatFilesystem();
47 
48  //
49  // Filesystem interface.
50  //
51 
52  virtual bool initialise(Disk *pDisk);
53  static Filesystem *probe(Disk *pDisk);
54  virtual File *getRoot() const;
55  virtual String getVolumeLabel() const;
56  virtual uint64_t read(
57  File *pFile, uint64_t location, uint64_t size, uintptr_t buffer,
58  bool bCanBlock = true);
59  virtual uint64_t write(
60  File *pFile, uint64_t location, uint64_t size, uintptr_t buffer,
61  bool bCanBlock = true);
62  virtual void truncate(File *pFile);
63  virtual void fileAttributeChanged(File *pFile);
64  virtual void cacheDirectoryContents(File *pFile);
65  virtual void extend(File *pFile, size_t size);
66 
67  protected:
68  virtual bool
69  createFile(File *parent, const String &filename, uint32_t mask);
70  virtual bool
71  createDirectory(File *parent, const String &filename, uint32_t mask);
72  virtual bool
73  createSymlink(File *parent, const String &filename, const String &value);
74  virtual bool remove(File *parent, File *file);
75 
77  void operator=(const FatFilesystem &);
78 
79  void loadRootDir();
80 
81  void cacheVolumeLabel();
82 
84  bool readCluster(uint32_t block, uintptr_t buffer) const;
85 
87  bool writeCluster(uint32_t block, uintptr_t buffer);
88 
90  bool writeSectorBlock(uint32_t sec, size_t size, uintptr_t buffer);
91 
93  bool readSectorBlock(uint32_t sec, size_t size, uintptr_t buffer) const;
94 
96  uint32_t getSectorNumber(uint32_t cluster) const;
97 
100  uint32_t getClusterEntry(uint32_t cluster, bool bLock = true);
101 
104  uint32_t
105  setClusterEntry(uint32_t cluster, uint32_t value, bool bLock = true);
106 
108  String convertFilenameTo(String filename) const;
109 
111  String convertFilenameFrom(String filename) const;
112 
116  uint32_t findFreeCluster(bool bLock = false);
117 
119  void updateFileSize(File *pFile, int64_t sizeChange);
120 
122  void setCluster(File *pFile, uint32_t clus);
123 
126  void *readDirectoryPortion(uint32_t clus) const;
127 
129  void writeDirectoryPortion(uint32_t clus, void *p);
130 
132  File *createFile(
133  File *parentDir, const String &filename, uint32_t mask,
134  bool bDirectory = false, uint32_t dirClus = 0);
135 
137  Dir *getDirectoryEntry(uint32_t clus, uint32_t offset) const;
138 
140  void writeDirectoryEntry(Dir *dir, uint32_t clus, uint32_t offset);
141 
143  bool isEof(uint32_t cluster) const
144  {
145  return (cluster >= eofValue());
146  }
147 
149  uint32_t eofValue() const
150  {
151  if (m_Type == FAT12)
152  return 0x0FF8;
153  if (m_Type == FAT16)
154  return 0xFFF8;
155  if (m_Type == FAT32)
156  return 0x0FFFFFF8;
157  return 0;
158  }
159 
161  Time::Timestamp getUnixTimestamp(uint16_t time, uint16_t date) const
162  {
163  // struct version of the passed parameters
164  Timestamp *sTime = reinterpret_cast<Timestamp *>(&time);
165  Date *sDate = reinterpret_cast<Date *>(&date);
166 
167  // Sanity check.
168  if (!(sTime->secCount + sTime->minutes + sTime->hours))
169  if (!(sDate->day + sDate->month + sDate->years))
170  return 0;
171 
172  // grab the time information
173  uint32_t seconds = sTime->secCount * 2;
174  uint32_t minutes = sTime->minutes;
175  uint32_t hours = sTime->hours;
176 
177  // grab the date information
178  uint32_t day = sDate->day ? sDate->day - 1 : 0;
179  uint32_t month = sDate->month;
180  uint32_t years = sDate->years + 10; // FAT timestamps start at 1980
181 
183  uint32_t realYear = years + 1970;
184  uint32_t leapDays =
185  ((realYear / 4) - (realYear / 100) + (realYear / 400));
186  leapDays -= ((1980 / 4) - (1980 / 100) + (1980 / 400));
187 
188  // Cumulative days as the year progresses. Added to the current day's
189  // month to get the proper offset into the year. The leap days are added
190  // to this as well to give the proper final answer.
191  static uint16_t cumulativeDays[] = {0, 31, 59, 90, 120, 151, 181,
192  212, 243, 273, 304, 334, 365};
193  uint32_t cumulDays = cumulativeDays[month ? month - 1 : 0];
194 
195  Time::Timestamp ret = 0;
196 
197  // add the time
198  ret += seconds;
199  ret += minutes * 60;
200  ret += hours * 60 * 60;
201 
202  // and finally the date
203  ret += day * 24 * 60 * 60;
204  ret += cumulDays * 24 * 60 * 60;
205  ret += leapDays * 24 * 60 * 60;
206  ret += years * 365 * 24 * 60 * 60;
207 
208  // completed
209  return ret;
210  }
211 
213  uint16_t getFatDate(Time::Timestamp timestamp) const
214  {
216  return 0;
217  }
218 
221  Superblock16 m_Superblock16;
222  Superblock32 m_Superblock32;
223  FSInfo32 m_FsInfo;
224 
226  FatType m_Type;
227 
229  uint64_t m_DataAreaStart; // data area can potentially start above 4 GB
230  uint32_t m_RootDirCount;
231 
233  uint16_t m_FatSector;
234 
237  {
238  uint32_t sector; // FAT12 and 16 don't use a cluster
239  uint32_t cluster; // but FAT32 does...
240  } m_RootDir;
241 
243  uint32_t m_BlockSize;
244 
246  uint8_t *m_pFatCache;
247 
249  // Mutex m_FatLock;
251 
254 
255  // FAT cache
256  // Cache<uint8_t*, 512> m_FatCache;
257  Tree<uintptr_t, uintptr_t> m_FatCache;
258 
264 
267 };
268 
269 #endif
void writeDirectoryEntry(Dir *dir, uint32_t clus, uint32_t offset)
void updateFileSize(File *pFile, int64_t sizeChange)
virtual bool initialise(Disk *pDisk)
uint16_t m_FatSector
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)
void fileAttributeChanged()
UnlikelyLock m_FatLock
bool readSectorBlock(uint32_t sec, size_t size, uintptr_t buffer) const
void truncate()
Definition: FatDirectory.h:47
void writeDirectoryPortion(uint32_t clus, void *p)
Dir * getDirectoryEntry(uint32_t clus, uint32_t offset) const
uint32_t findFreeCluster(bool bLock=false)
Definition: String.h:49
uint32_t m_BlockSize
uint32_t getClusterEntry(uint32_t cluster, bool bLock=true)
Definition: Disk.h:32
uint64_t m_DataAreaStart
virtual bool createFile(File *parent, const String &filename, uint32_t mask)
void * readDirectoryPortion(uint32_t clus) const
uint32_t m_FreeClusterHint
bool writeCluster(uint32_t block, uintptr_t buffer)
String convertFilenameFrom(String filename) const
bool readCluster(uint32_t block, uintptr_t buffer) const
String m_VolumeLabel
virtual String getVolumeLabel() const
Definition: ext2.h:175
virtual uint64_t read(uint64_t location, uint64_t size, uintptr_t buffer, bool bCanBlock=true) final
Definition: File.cc:116
virtual void cacheDirectoryContents()
Definition: fat.h:101
Definition: fat.h:151
Definition: fat.h:143
Superblock m_Superblock
String convertFilenameTo(String filename) const
Time::Timestamp getUnixTimestamp(uint16_t time, uint16_t date) const
uint8_t * m_pFatCache
bool isEof(uint32_t cluster) const
uint32_t getSectorNumber(uint32_t cluster) const
Definition: File.h:66
uint32_t eofValue() const
virtual void extend(size_t newSize)
Definition: File.cc:615
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
Definition: File.cc:183
uint16_t getFatDate(Time::Timestamp timestamp) const