FreeNOS
FileSystemServer.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Niek Linnenbank
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <FreeNOS/User.h>
19 #include <Assert.h>
20 #include <Vector.h>
21 #include <HashTable.h>
22 #include <HashIterator.h>
23 #include <DatastoreClient.h>
24 #include <KernelTimer.h>
25 #include "FileSystemClient.h"
26 #include "FileSystemMount.h"
27 #include "FileSystemServer.h"
28 
31  , m_pid(ProcessCtl(SELF, GetPID))
32  , m_root(ZERO)
33  , m_mountPath(path)
34  , m_mounts(ZERO)
35  , m_requests(new List<FileSystemRequest *>())
36 {
37  setRoot(root);
38 
39  // Register message handlers
49 }
50 
52 {
53  if (m_requests)
54  {
55  delete m_requests;
56  }
57 
59 }
60 
61 const char * FileSystemServer::getMountPath() const
62 {
63  return m_mountPath;
64 }
65 
67 {
68  static u32 next = 2;
69 
70  // Ensure that the inode is not already used
71  while (m_inodeMap.get(++next) != ZERO)
72  ;
73 
74  return next;
75 }
76 
78 {
79  // The rootfs server manages the mounts table. Retrieve it from the datastore.
80  if (m_pid == ROOTFS_PID)
81  {
82  const DatastoreClient datastore;
83  const Datastore::Result result =
84  datastore.registerBuffer("mounts", &m_mounts, sizeof(FileSystemMount) * MaximumFileSystemMounts);
85 
86  if (result != Datastore::Success)
87  return FileSystem::IOError;
88 
89  assert(m_mounts != NULL);
90 
91  // Fill the mounts table
93  return FileSystem::Success;
94  }
95  // Other file systems send a request to root file system to mount.
96  else if (m_mountPath != ZERO)
97  {
98  const FileSystemClient rootfs(ROOTFS_PID);
99  const FileSystem::Result result = rootfs.mountFileSystem(m_mountPath);
100 
101  assert(result == FileSystem::Success);
102  return result;
103  }
104  else
105  {
106  return FileSystem::Success;
107  }
108 }
109 
111 {
112  return (File *) ZERO;
113 }
114 
116 {
117  // Add to the filesystem cache
118  FileCache *cache = insertFileCache(file, path);
119  if (cache == ZERO)
120  {
121  return FileSystem::IOError;
122  }
123 
124  // Also add to the parent directory
125  Directory *parent = getParentDirectory(path);
126  if (parent != ZERO)
127  {
128  const FileSystemPath p(path);
129  parent->insert(file->getType(), *p.base());
130  return FileSystem::Success;
131  }
132  else
133  {
134  return FileSystem::NotFound;
135  }
136 }
137 
139  const char *path)
140 {
141  // Add the directory itself first
142  FileSystem::Result result = registerFile(dir, path);
143  if (result != FileSystem::Success)
144  {
145  ERROR("failed to register directory " << path <<
146  ": result = " << (int) result);
147  return result;
148  }
149 
150  String dot;
151  dot << path;
152  dot << "/.";
153 
154  // Insert the '.' directory which points to itself
155  result = registerFile(dir, *dot);
156  if (result != FileSystem::Success)
157  {
158  ERROR("failed to register '.' for directory " << path <<
159  ": result = " << (int) result);
160  return result;
161  }
162 
163  // Insert the '..' directory which points to its parent
164  Directory *parent = getParentDirectory(path);
165  if (parent == ZERO)
166  {
167  ERROR("failed to retrieve parent directory for " << path);
168  return FileSystem::NotFound;
169  }
170 
171  dot << ".";
172  return registerFile(parent, *dot);
173 }
174 
176 {
177  DEBUG("path = " << path);
178 
179  FileCache *cache = findFileCache(path);
180  if (!cache)
181  {
182  return FileSystem::NotFound;
183  }
184 
185  if (cache->entries.count() != 0)
186  {
188  }
189 
190  clearFileCache(cache);
191  return FileSystem::Success;
192 }
193 
195 {
196  // Prepare request
197  FileSystemRequest req(msg);
198 
199  // Process the request.
201  {
202  FileSystemRequest *reqCopy = new FileSystemRequest(msg);
203  assert(reqCopy != NULL);
204  m_requests->append(reqCopy);
205  }
206 }
207 
209 {
210  Size savedMountLength = 0;
211  FileSystemMount *mnt = ZERO;
212 
213  // Search for the longest matching mount
214  for (Size i = 0; i < MaximumFileSystemMounts; i++)
215  {
216  if (m_mounts[i].path[0] != ZERO)
217  {
218  const String mountStr(m_mounts[i].path, false);
219  const Size mountStrLen = mountStr.length();
220 
221  if (mountStrLen > savedMountLength && mountStr.compareTo(path, true, mountStrLen) == 0)
222  {
223  savedMountLength = mountStrLen;
224  mnt = &m_mounts[i];
225  }
226  }
227  }
228 
229  // If no match was found, no redirect is needed
230  if (!mnt)
231  return false;
232 
234 
237  else
239  msg->pid = mnt->procID;
240  msg->pathMountLength = savedMountLength;
241 
242  sendResponse(msg);
243  return true;
244 }
245 
247 {
248  FileSystemMessage *msg = req.getMessage();
249  File *file = ZERO;
250 
251  DEBUG(m_self << ": inode = " << msg->inode << " action = " << msg->action);
252 
253  File *const *f = m_inodeMap.get(msg->inode);
254  if (f == ZERO)
255  {
256 
258  sendResponse(msg);
259  return msg->result;
260  }
261  file = (*f);
262 
263  if (msg->action == FileSystem::ReadFile)
264  {
265  msg->result = file->read(req.getBuffer(), msg->size, msg->offset);
266 
267  if (msg->result == FileSystem::Success)
268  {
269  if (req.getBuffer().getCount())
270  {
271  req.getBuffer().flushWrite();
272  }
273  }
274 
275  DEBUG(m_self << ": read = " << (int)msg->result);
276  }
277  else if (msg->action == FileSystem::WriteFile)
278  {
279  if (!req.getBuffer().getCount())
280  {
281  req.getBuffer().bufferedRead();
282  }
283 
284  msg->result = file->write(req.getBuffer(), msg->size, msg->offset);
285  DEBUG(m_self << ": write = " << (int)msg->result);
286  }
287  else
288  {
290  }
291 
292  // Only send reply if completed (not RetryAgain)
293  if (msg->result != FileSystem::RetryAgain)
294  {
295  sendResponse(msg);
296  }
297 
298  return msg->result;
299 }
300 
302 {
303  FileSystemMessage *msg = req.getMessage();
305  const Size count = msg->size / sizeof(FileSystem::WaitSet) < MaximumWaitSetCount ?
307  IOBuffer & ioBuffer = req.getBuffer();
308 
309  // Read waitset input struct
310  msg->result = ioBuffer.read(&waitBuf, count * sizeof(FileSystem::WaitSet), 0);
311  if (msg->result != FileSystem::Success)
312  {
313  ERROR("failed to read WaitSet input from PID " << msg->from << ": result = " << (int) msg->result);
314  sendResponse(msg);
315  return msg->result;
316  }
317 
318  // By default, retry again
320 
321  // fill the struct
322  for (Size i = 0; i < count; i++)
323  {
324  File *const *f = m_inodeMap.get(waitBuf[i].inode);
325  if (f != ZERO)
326  {
327  waitBuf[i].current = 0;
328 
329  if ((waitBuf[i].requested & FileSystem::Readable) && (*f)->canRead())
330  {
331  DEBUG("inode " << waitBuf[i].inode << " is readable");
332  waitBuf[i].current |= FileSystem::Readable;
334  }
335 
336  if ((waitBuf[i].requested & FileSystem::Writable) && (*f)->canWrite())
337  {
338  DEBUG("inode " << waitBuf[i].inode << " is writable");
339  waitBuf[i].current |= FileSystem::Writable;
341  }
342  }
343  }
344 
345  // write back
346  ioBuffer.write(&waitBuf, count * sizeof(FileSystem::WaitSet), 0);
348  {
349  ERROR("failed to write WaitSet output to PID " << msg->from << ": result = " << (int) msg->result);
350  sendResponse(msg);
351  return msg->result;
352  }
353 
354  // Check for timeout
355  if (msg->timeout.frequency != 0 && msg->result == FileSystem::RetryAgain)
356  {
357  KernelTimer timer;
358  timer.tick();
359 
360  if (timer.isExpired(msg->timeout))
361  {
363  }
364  else
365  {
366  if (!m_expiry.frequency || m_expiry.ticks > msg->timeout.ticks)
367  {
368  m_expiry.ticks = msg->timeout.ticks;
369  }
371  }
372  }
373 
374  // Only send reply if completed (not RetryAgain)
375  if (msg->result != FileSystem::RetryAgain)
376  {
377  sendResponse(msg);
378  }
379 
380  return msg->result;
381 }
382 
384 {
386  FileCache *cache = ZERO;
387  File *file = ZERO;
388  FileSystemMessage *msg = req.getMessage();
390 
391  // Retrieve file by inode or by file path?
393  {
394  return inodeHandler(req);
395  }
396  else if (msg->action == FileSystem::WaitFile)
397  {
398  return waitFileHandler(req);
399  }
400 
401  // Copy the file path
402  const API::Result result = VMCopy(msg->from, API::Read, (Address) buf,
404  if (result != API::Success)
405  {
406  ERROR("VMCopy failed: result = " << (int)result << " from = " << msg->from <<
407  " addr = " << (void *) msg->buffer << " action = " << (int) msg->action);
409  sendResponse(msg);
410  return msg->result;
411  }
412  DEBUG(m_self << ": path = " << buf << " action = " << msg->action);
413 
414  // Handle mounted file system paths (will result in redirect messages)
415  if (m_pid == ROOTFS_PID && redirectRequest(buf, msg))
416  {
417  DEBUG(m_self << ": redirect " << buf << " to " << msg->pid);
418  return msg->result;
419  }
420 
421  const FileSystemPath path(buf + String::length(m_mountPath));
422 
423  // Do we have this file cached?
424  if ((cache = findFileCache(path)) ||
425  (cache = lookupFile(path)))
426  {
427  file = cache->file;
428  }
429 
430  // Check for File not found
431  if (file == ZERO &&
432  msg->action != FileSystem::CreateFile &&
434  {
435  DEBUG(m_self << ": not found");
437  sendResponse(msg);
438  return msg->result;
439  }
440 
441  // Perform I/O on the file
442  switch (msg->action)
443  {
445  if (cache)
446  {
448  }
449  else
450  {
451  const API::Result stResult = VMCopy(msg->from, API::Read, (Address) &st,
452  (Address) msg->stat, sizeof(st));
453  if (stResult != API::Success)
454  {
455  ERROR("VMCopy failed for FileStat: result = " << (int) stResult <<
456  " from = " << msg->from << " addr = " << (void *) msg->stat <<
457  " action = " << (int) msg->action);
459  }
460  else
461  {
462  // Attempt to create the new file
463  file = createFile(st.type);
464  if (!file)
465  {
467  }
468  else
469  {
470  msg->result = registerFile(file, *path.full());
471  }
472  }
473  }
474  DEBUG(m_self << ": create = " << (int)msg->result);
475  break;
476 
478  msg->result = unregisterFile(*path.full());
479  DEBUG(m_self << ": delete = " << (int)msg->result);
480  break;
481 
483  if (file->status(st) == FileSystem::Success)
484  {
485  st.pid = m_self;
486 
487  // Copy to the remote process
488  const API::Result stResult = VMCopy(msg->from, API::Write, (Address) &st,
489  (Address) msg->stat, sizeof(st));
490  if (stResult == API::Success)
491  {
493  }
494  else
495  {
496  ERROR("VMCopy failed of FileStat for PID " << msg->from << ": result = " << (int) stResult);
498  }
499  }
500  else
501  {
503  }
504  DEBUG(m_self << ": stat = " << (int)msg->result);
505  break;
506 
510  break;
511 
513  // Do nothing here. Once the targeted file system is mounted
514  // this function will send a redirect message when called again
515  DEBUG(m_self << ": wait for " << buf);
517  break;
518  }
519 
520  default: {
521  ERROR("unhandled file I/O operation: " << (int)msg->action);
523  break;
524  }
525  }
526 
527  // Only send reply if completed (not RetryAgain)
528  if (msg->result != FileSystem::RetryAgain)
529  {
530  sendResponse(msg);
531  }
532 
533  return msg->result;
534 }
535 
537 {
539 
540  DEBUG(m_self << ": sending response to PID " << msg->from <<
541  " for action = " << (int) msg->action <<
542  " with result = " << (int) msg->result);
543 
544  Channel *channel = m_registry.getProducer(msg->from);
545  if (channel == ZERO)
546  {
547  ERROR("failed to retrieve channel for PID " << msg->from);
548  return;
549  }
550 
551  const Channel::Result result = channel->write(msg);
552  if (result != Channel::Success)
553  {
554  ERROR("failed to write channel for PID " << msg->from);
555  return;
556  }
557 
558  ProcessCtl(msg->from, Wakeup, 0);
559 }
560 
562 {
563  char buf[FileSystemPath::MaximumLength + 1];
564 
565  // Copy the file path
566  const API::Result result = VMCopy(msg->from, API::Read, (Address) buf,
568  if (result != API::Success)
569  {
570  ERROR("failed to copy mount path: result = " << (int) result);
572  return;
573  }
574 
575  // Null-terminate
577  const String path(buf);
578 
579  // Check for already existing entry (re-mount)
580  for (Size i = 0; i < MaximumFileSystemMounts; i++)
581  {
582  const String entry(m_mounts[i].path);
583 
584  if (path.equals(entry))
585  {
586  m_mounts[i].procID = msg->from;
587  m_mounts[i].options = ZERO;
588  NOTICE("remounted " << m_mounts[i].path);
590  return;
591  }
592  }
593 
594  // Append to our filesystem mounts table
595  for (Size i = 0; i < MaximumFileSystemMounts; i++)
596  {
597  if (!m_mounts[i].path[0])
598  {
599  MemoryBlock::copy(m_mounts[i].path, buf, sizeof(m_mounts[i].path));
600  m_mounts[i].procID = msg->from;
601  m_mounts[i].options = ZERO;
602  NOTICE("mounted " << m_mounts[i].path);
604  return;
605  }
606  }
607 
608  // Not space left
610 }
611 
613 {
614  // Copy mounts table to the requesting process
615  const Size mountsSize = sizeof(FileSystemMount) * MaximumFileSystemMounts;
616  const Size numBytes = msg->size < mountsSize ? msg->size : mountsSize;
617  const API::Result result = VMCopy(msg->from, API::Write, (Address) m_mounts,
618  (Address) msg->buffer, numBytes);
619  if (result != API::Success)
620  {
621  ERROR("failed to copy mount table: result = " << (int) result);
623  return;
624  }
625 
627 }
628 
630 {
631  bool restartNeeded = false;
632 
633  DEBUG("");
634 
636  {
637  FileSystem::Result result = processRequest(*i.current());
638  if (result != FileSystem::RetryAgain)
639  {
640  delete i.current();
641  i.remove();
642  restartNeeded = true;
643  }
644  }
645 
646  return restartNeeded;
647 }
648 
650 {
651  if (newRoot != ZERO)
652  {
653  m_root = new FileCache(newRoot, "/", ZERO);
654  insertFileCache(newRoot, ".");
655  insertFileCache(newRoot, "..");
656  }
657 }
658 
660 {
661  const FileSystemPath p(path);
662  Directory *parent = ZERO;
663 
664  if (p.parent().length() > 0)
665  {
666  FileCache *cache = findFileCache(*p.parent());
667  if (cache != ZERO)
668  {
669  parent = static_cast<Directory *>(cache->file);
670  }
671  }
672  else
673  {
674  parent = static_cast<Directory *>(m_root->file);
675  }
676 
677  return parent;
678 }
679 
681 {
682  const List<String> &entries = path.split();
683  FileCache *c = m_root;
684  File *file = ZERO;
685  Directory *dir;
686 
687  // Loop the entire path
688  for (ListIterator<String> i(entries); i.hasCurrent(); i++)
689  {
690  // Do we have this entry cached already?
691  if (!c->entries.contains(i.current()))
692  {
693  // If this isn't a directory, we cannot perform a lookup
695  {
696  return ZERO;
697  }
698  dir = (Directory *) c->file;
699 
700  // Fetch the file, if possible
701  if (!(file = dir->lookup(*i.current())))
702  {
703  return ZERO;
704  }
705  // Insert into the FileCache
706  c = new FileCache(file, *i.current(), c);
707  assert(c != NULL);
708 
709  // Add file to the inode map
710  if (!m_inodeMap.insert(file->getInode(), file))
711  {
712  return ZERO;
713  }
714  }
715  // Move to the next entry
716  else if (c != ZERO)
717  {
718  c = (FileCache *) c->entries.value(i.current());
719  }
720  else
721  {
722  break;
723  }
724  }
725 
726 
727  // All done
728  return c;
729 }
730 
731 FileCache * FileSystemServer::insertFileCache(File *file, const char *pathStr)
732 {
733  const FileSystemPath path(pathStr);
734  FileCache *parent = ZERO;
735 
736  // Lookup our parent
737  if (path.parent().length() == 0)
738  {
739  parent = m_root;
740  }
741  else if (!(parent = findFileCache(path.parent())))
742  {
743  return ZERO;
744  }
745 
746  // Add file to the inode map
747  if (!m_inodeMap.insert(file->getInode(), file))
748  {
749  return ZERO;
750  }
751 
752  // Create new cache
753  FileCache *c = new FileCache(file, *path.base(), parent);
754  assert(c != NULL);
755  return c;
756 }
757 
759 {
760  const FileSystemPath p(path);
761  return findFileCache(p);
762 }
763 
765 {
766  return findFileCache(*path);
767 }
768 
770 {
771  const List<String> &entries = path.split();
772  FileCache *c = m_root;
773 
774  // Root is treated special
775  if (path.parent().length() == 0 && path.length() == 0)
776  {
777  return m_root;
778  }
779 
780  // Loop the entire path
781  for (ListIterator<String> i(entries); i.hasCurrent(); i++)
782  {
783  if (!c->entries.contains(i.current()))
784  {
785  return ZERO;
786  }
787  c = (FileCache *) c->entries.value(i.current());
788  }
789 
790  // Return what we got
791  return c;
792 }
793 
795 {
796  assert(cache != ZERO);
797  assert(file != ZERO);
798 
799  // Walk all our childs
800  for (HashIterator<String, FileCache *> i(cache->entries); i.hasCurrent(); i++)
801  {
802  FileCache *child = i.current();
803 
804  if (child->file == cache->file)
805  {
806  static_cast<Directory *>(cache->file)->remove(*child->name);
807  removeFileFromCache(child, file);
808  child->file = ZERO;
809  }
810  }
811 }
812 
814 {
815  // Start from root?
816  if (!cache)
817  {
818  cache = m_root;
819  }
820 
821  // Make sure the current file is removed from all childs and below
822  if (cache->file != ZERO)
823  {
824  removeFileFromCache(cache, cache->file);
825  }
826 
827  // Walk all our childs
829  {
830  FileCache *child = i.current();
831 
832  static_cast<Directory *>(cache->file)->remove(*child->name);
833  if (cache->parent && cache->parent->file == child->file)
834  {
835  child->file = ZERO;
836  }
837  clearFileCache(child);
838  i.remove();
839  }
840 
841  // Cleanup this cache object
842  assert(cache->entries.count() == 0);
843 
844  if (cache->file != ZERO)
845  {
846  // Remove entry from parent */
847  if (cache->parent)
848  {
849  if (cache->parent->file)
850  {
851  static_cast<Directory *>(cache->parent->file)->remove(*cache->name);
852  }
853  cache->parent->entries.remove(cache->name);
854  }
855 
856  m_inodeMap.remove(cache->file->getInode());
857  delete cache->file;
858  }
859  delete cache;
860 }
FileSystem::AlreadyExists
@ AlreadyExists
Definition: FileSystem.h:60
File::write
virtual FileSystem::Result write(IOBuffer &buffer, Size &size, const Size offset)
Write bytes to the file.
Definition: File.cpp:55
Channel
Unidirectional point-to-point messaging channel.
Definition: Channel.h:34
MemoryBlock::copy
static Size copy(void *dest, const void *src, Size count)
Copy memory from one place to another.
Definition: MemoryBlock.cpp:36
IOBuffer::flushWrite
FileSystem::Result flushWrite()
Flush write buffers.
Definition: IOBuffer.cpp:204
FileSystemPath
Simple filesystem path parser.
Definition: FileSystemPath.h:37
FileSystemRequest::getBuffer
IOBuffer & getBuffer()
Get IOBuffer.
Definition: FileSystemRequest.cpp:32
FileSystemServer::m_requests
List< FileSystemRequest * > * m_requests
Contains ongoing requests.
Definition: FileSystemServer.h:317
Channel::Success
@ Success
Definition: Channel.h:43
FileSystemServer::redirectRequest
bool redirectRequest(const char *path, FileSystemMessage *msg)
Try to forward the given FileSystemMessage to a mount file system.
Definition: FileSystemServer.cpp:208
API::Result
Result
Enumeration of generic kernel API result codes.
Definition: API.h:68
Vector.h
DatastoreClient
Datastore client.
Definition: DatastoreClient.h:39
FileSystemMount.h
NOTICE
#define NOTICE(msg)
Output a notice message.
Definition: Log.h:75
FileSystemServer::findFileCache
FileCache * findFileCache(const char *path) const
Search the cache for an entry.
Definition: FileSystemServer.cpp:758
FileSystemServer::setRoot
void setRoot(Directory *newRoot)
Change the filesystem root directory.
Definition: FileSystemServer.cpp:649
String::length
Size length() const
Same as count().
Definition: String.cpp:105
MemoryBlock::set
static void * set(void *dest, int ch, unsigned count)
Fill memory with a constant byte.
Definition: MemoryBlock.cpp:25
IOBuffer::getCount
Size getCount() const
Get byte count.
Definition: IOBuffer.cpp:109
FileSystem::WaitFileSystem
@ WaitFileSystem
Definition: FileSystem.h:45
FileSystemMessage::buffer
char * buffer
Points to a buffer for I/O.
Definition: FileSystemMessage.h:41
FileSystemServer::getNextInode
u32 getNextInode()
Get next unused inode.
Definition: FileSystemServer.cpp:66
FileCache::parent
FileCache * parent
Parent.
Definition: FileCache.h:65
FileCache::entries
HashTable< String, FileCache * > entries
Contains childs.
Definition: FileCache.h:62
Directory::lookup
virtual File * lookup(const char *name)
Retrieve a File from storage.
Definition: Directory.cpp:61
FileSystem::FileType
FileType
All possible filetypes.
Definition: FileSystem.h:70
FileSystemServer::lookupFile
FileCache * lookupFile(const FileSystemPath &path)
Retrieve a File from storage.
Definition: FileSystemServer.cpp:680
FileSystemMount
Represents a mounted filesystem.
Definition: FileSystemMount.h:35
FileSystemServer::retryRequests
virtual bool retryRequests()
Retry any pending requests.
Definition: FileSystemServer.cpp:629
FileSystemServer.h
DatastoreClient.h
String
Abstraction of strings.
Definition: String.h:41
HashTable.h
Directory
Directory File functionality.
Definition: Directory.h:59
FileSystem::WriteFile
@ WriteFile
Definition: FileSystem.h:40
FileSystemClient
FileSystemClient provides a simple interface to a FileSystemServer.
Definition: FileSystemClient.h:42
HashIterator
Iterate through a HashTable.
Definition: HashIterator.h:39
FileSystemMessage::stat
FileSystem::FileStat * stat
File Statistics.
Definition: FileSystemMessage.h:45
FileSystemPath::full
const String & full() const
Get the full path as a String.
Definition: FileSystemPath.cpp:58
FileSystem::WaitSet
Provides information about an inode.
Definition: FileSystem.h:127
API::Write
@ Write
Definition: API.h:99
Directory::insert
void insert(FileSystem::FileType type, const char *name)
Insert a new directory entry.
Definition: Directory.cpp:66
ChannelServer< FileSystemServer, FileSystemMessage >::m_registry
ChannelRegistry & m_registry
Contains registered channels.
Definition: ChannelServer.h:532
HashIterator.h
ChannelMessage::type
Type type
Message type is either a request or response.
Definition: ChannelMessage.h:48
FileSystemClient::mountFileSystem
FileSystem::Result mountFileSystem(const char *mountPath) const
Mount the current process as a file system on the rootfs.
Definition: FileSystemClient.cpp:324
KernelTimer
Provides the timer of the kernel.
Definition: KernelTimer.h:36
Assert.h
Timer::Info::frequency
Size frequency
Definition: Timer.h:45
FileSystemServer::sendResponse
void sendResponse(FileSystemMessage *msg) const
Send response for a FileSystemMessage.
Definition: FileSystemServer.cpp:536
FileSystemServer::unregisterFile
FileSystem::Result unregisterFile(const char *path)
Remove a File from the FileSystemServer.
Definition: FileSystemServer.cpp:175
Wakeup
@ Wakeup
Definition: ProcessCtl.h:53
Address
unsigned long Address
A memory address.
Definition: Types.h:131
File::getType
FileSystem::FileType getType() const
Retrieve our filetype.
Definition: File.cpp:43
FileSystemMessage
FileSystem IPC message.
Definition: FileSystemMessage.h:37
FileSystem::IOError
@ IOError
Definition: FileSystem.h:58
FileSystemServer
Abstract filesystem class.
Definition: FileSystemServer.h:44
FileSystemMessage::offset
Size offset
Offset in the file for I/O.
Definition: FileSystemMessage.h:43
FileCache::name
String name
Our name.
Definition: FileCache.h:59
FileSystem::Success
@ Success
Definition: FileSystem.h:54
ProcessCtl
API::Result ProcessCtl(const ProcessID proc, const ProcessOperation op, const Address addr=0, const Address output=0)
Prototype for user applications.
Definition: ProcessCtl.h:93
String::compareTo
virtual int compareTo(const String &str) const
Compares this String to the given String.
Definition: String.cpp:231
FileSystemMessage::result
FileSystem::Result result
Result code.
Definition: FileSystemMessage.h:40
File::getInode
u32 getInode() const
Get inode number.
Definition: File.cpp:38
FileSystemRequest::getMessage
FileSystemMessage * getMessage()
Get message.
Definition: FileSystemRequest.cpp:27
File
Represents a file present on a FileSystem.
Definition: File.h:39
FileSystemPath::base
const String & base() const
The name of the last element in the path.
Definition: FileSystemPath.cpp:53
FileSystemMount
struct FileSystemMount FileSystemMount
Represents a mounted filesystem.
HashTable::remove
virtual int remove(const K &key)
Remove value(s) for the given key.
Definition: HashTable.h:178
API::Read
@ Read
Definition: API.h:98
FileSystemMessage::inode
u32 inode
Inode number of the file.
Definition: FileSystemMessage.h:44
FileSystemServer::removeFileFromCache
void removeFileFromCache(FileCache *cache, File *file)
Remove a File from the cache.
Definition: FileSystemServer.cpp:794
SELF
#define SELF
Definition: ProcessID.h:35
ChannelServer< FileSystemServer, FileSystemMessage >::m_self
ProcessID m_self
ProcessID of ourselves.
Definition: ChannelServer.h:544
FileSystemServer::mountHandler
void mountHandler(FileSystemMessage *msg)
Process a filesystem mount request message.
Definition: FileSystemServer.cpp:561
FileSystem::NotSupported
@ NotSupported
Definition: FileSystem.h:61
DEBUG
#define DEBUG(msg)
Output a debug message to standard output.
Definition: Log.h:89
FileSystemServer::insertFileCache
FileCache * insertFileCache(File *file, const char *pathFormat)
Inserts a file into the in-memory filesystem tree.
Definition: FileSystemServer.cpp:731
FileSystemPath::MaximumLength
static const Size MaximumLength
Maximum length of a filesystem path in bytes.
Definition: FileSystemPath.h:47
FileSystemRequest
Encapsulates a pending FileSystemMessage.
Definition: FileSystemRequest.h:35
FileSystemServer::waitFileHandler
FileSystem::Result waitFileHandler(FileSystemRequest &req)
Handle a WaitFile request.
Definition: FileSystemServer.cpp:301
FileSystemServer::m_mounts
FileSystemMount * m_mounts
Table with mounted file systems (only used by the root file system).
Definition: FileSystemServer.h:314
Associative::contains
virtual bool contains(const K &key) const
Check if the given key exists.
Definition: Associative.h:111
Channel::write
virtual Result write(const void *buffer)
Write a message.
Definition: Channel.cpp:40
Datastore::Success
@ Success
Definition: Datastore.h:44
FileSystem::GetFileSystems
@ GetFileSystems
Definition: FileSystem.h:46
ListIterator::hasCurrent
virtual bool hasCurrent() const
Check if there is a current item on the List.
Definition: ListIterator.h:104
FileSystemMount::options
ulong options
Mount options.
Definition: FileSystemMount.h:44
FileSystem::RedirectRequest
@ RedirectRequest
Definition: FileSystem.h:62
HashTable::get
virtual const V * get(const K &key) const
Returns the first value for the given key.
Definition: HashTable.h:287
FileSystemPath::split
const List< String > & split() const
Returns a List of separate path elements.
Definition: FileSystemPath.cpp:63
GetPID
@ GetPID
Definition: ProcessCtl.h:41
FileSystemServer::FileSystemServer
FileSystemServer(Directory *root, const char *path)
Constructor function.
Definition: FileSystemServer.cpp:29
FileSystemMount::procID
ProcessID procID
Server which is responsible for the mount.
Definition: FileSystemMount.h:41
List::append
void append(T t)
Insert an item at the end of the list.
Definition: List.h:139
FileSystemServer::m_inodeMap
HashTable< u32, File * > m_inodeMap
Contains a mapping of inode number to file of all cached files.
Definition: FileSystemServer.h:308
FileSystem::MountFileSystem
@ MountFileSystem
Definition: FileSystem.h:44
FileSystemServer::m_mountPath
const char * m_mountPath
Mount point path.
Definition: FileSystemServer.h:311
FileSystemServer::pathHandler
void pathHandler(FileSystemMessage *msg)
Process an incoming filesystem request using a path.
Definition: FileSystemServer.cpp:194
IOBuffer
Abstract Input/Output buffer.
Definition: IOBuffer.h:37
HashTable::count
virtual Size count() const
Get the number of values stored in the HashTable.
Definition: HashTable.h:211
DatastoreClient::registerBuffer
Datastore::Result registerBuffer(const char *key, void *buffer, const Size size) const
Add a new buffer.
Definition: DatastoreClient.cpp:28
NULL
#define NULL
NULL means zero.
Definition: Macros.h:39
u32
unsigned int u32
Unsigned 32-bit number.
Definition: Types.h:53
FileSystemServer::inodeHandler
FileSystem::Result inodeHandler(FileSystemRequest &req)
Handle a request for a File specified by its inode.
Definition: FileSystemServer.cpp:246
Size
unsigned int Size
Any sane size indicator cannot go negative.
Definition: Types.h:128
FileSystem::Readable
@ Readable
Definition: FileSystem.h:139
FileCache::file
File * file
File pointer.
Definition: FileCache.h:56
FileSystem::WaitFile
@ WaitFile
Definition: FileSystem.h:43
Datastore::Result
Result
Result codes.
Definition: Datastore.h:42
ROOTFS_PID
#define ROOTFS_PID
Definition: ProcessID.h:41
FileSystemServer::createFile
virtual File * createFile(const FileSystem::FileType type)
Create a new file.
Definition: FileSystemServer.cpp:110
Timer::isExpired
bool isExpired(const Info &info) const
Check if a timer value is expired.
Definition: Timer.cpp:85
FileSystemPath::length
Size length() const
Get Length of our full path.
Definition: FileSystemPath.cpp:68
Timer::Info::ticks
u32 ticks
Definition: Timer.h:44
FileSystem::DirectoryFile
@ DirectoryFile
Definition: FileSystem.h:73
FileSystemServer::processRequest
FileSystem::Result processRequest(FileSystemRequest &req)
Process a FileSystemRequest.
Definition: FileSystemServer.cpp:383
FileSystemServer::registerDirectory
FileSystem::Result registerDirectory(Directory *dir, const char *path)
Register a new Directory.
Definition: FileSystemServer.cpp:138
File::status
virtual FileSystem::Result status(FileSystem::FileStat &st)
Retrieve file statistics.
Definition: File.cpp:62
FileCache
struct FileCache FileCache
Cached in-memory file.
File::read
virtual FileSystem::Result read(IOBuffer &buffer, Size &size, const Size offset)
Read bytes from the file.
Definition: File.cpp:48
KernelTimer.h
ChannelServer
Template class which serves incoming messages from Channels using MessageHandlers.
Definition: ChannelServer.h:79
FileSystemServer::mount
FileSystem::Result mount()
Mount the FileSystem.
Definition: FileSystemServer.cpp:77
FileSystemServer::MaximumFileSystemMounts
static const Size MaximumFileSystemMounts
Maximum number of supported file system mount entries.
Definition: FileSystemServer.h:49
FileSystemServer::getMountPath
const char * getMountPath() const
Get mount path.
Definition: FileSystemServer.cpp:61
FileSystem::WaitSet::current
u16 current
< Requested status flags of the inode
Definition: FileSystem.h:131
FileSystemServer::m_pid
const ProcessID m_pid
Process identifier.
Definition: FileSystemServer.h:302
FileSystemPath::parent
const String & parent() const
Retrieve the full path of our parent.
Definition: FileSystemPath.cpp:48
FileSystemClient.h
assert
#define assert(exp)
Insert program diagnostics.
Definition: assert.h:60
FileSystem::FileStat
Contains file information.
Definition: FileSystem.h:113
ERROR
#define ERROR(msg)
Output an error message.
Definition: Log.h:61
entry
u32 entry[]
Definition: IntelACPI.h:64
FileSystemServer::~FileSystemServer
virtual ~FileSystemServer()
Destructor function.
Definition: FileSystemServer.cpp:51
KernelTimer::tick
virtual Result tick()
Process timer tick.
Definition: KernelTimer.cpp:23
FileSystem::Result
Result
Result code for filesystem Actions.
Definition: FileSystem.h:52
Channel::Result
Result
Result codes.
Definition: Channel.h:41
ChannelServer< FileSystemServer, FileSystemMessage >::m_expiry
Timer::Info m_expiry
System timer expiration value.
Definition: ChannelServer.h:550
FileSystem::RetryAgain
@ RetryAgain
Definition: FileSystem.h:57
FileSystemServer::MaximumWaitSetCount
static const Size MaximumWaitSetCount
Maximum number of WaitSet entries supported.
Definition: FileSystemServer.h:52
FileSystem::DeleteFile
@ DeleteFile
Definition: FileSystem.h:42
API::Success
@ Success
Definition: API.h:70
FileSystem::ReadFile
@ ReadFile
Definition: FileSystem.h:39
ChannelMessage::from
ProcessID from
Source process of the message.
Definition: ChannelMessage.h:54
FileSystemMessage::pathMountLength
Size pathMountLength
Length of the mounted path (used for redirection)
Definition: FileSystemMessage.h:48
FileSystemMessage::pid
ProcessID pid
Process identifier (used for redirection)
Definition: FileSystemMessage.h:47
ChannelServer< FileSystemServer, FileSystemMessage >::addIPCHandler
void addIPCHandler(const Size slot, IPCHandlerFunction h, const bool sendReply=true)
Register a new IPC message action handler.
Definition: ChannelServer.h:203
IOBuffer::bufferedRead
FileSystem::Result bufferedRead()
Buffered read bytes from the I/O buffer.
Definition: IOBuffer.cpp:130
FileSystemMessage::action
FileSystem::Action action
Action to perform.
Definition: FileSystemMessage.h:39
FileSystem::NotFound
@ NotFound
Definition: FileSystem.h:56
IOBuffer::read
FileSystem::Result read(void *buffer, const Size size, const Size offset=ZERO)
Read bytes from the I/O buffer.
Definition: IOBuffer.cpp:156
FileSystem::StatFile
@ StatFile
Definition: FileSystem.h:41
HashIterator::hasCurrent
virtual bool hasCurrent() const
Check if there is a current item.
Definition: HashIterator.h:83
List
Simple linked list template class.
Definition: List.h:36
IOBuffer::write
FileSystem::Result write(const void *buffer, const Size size, const Size offset=ZERO)
Write bytes to the I/O buffer.
Definition: IOBuffer.cpp:180
ChannelMessage::Response
@ Response
Definition: ChannelMessage.h:44
ChannelRegistry::getProducer
Channel * getProducer(const ProcessID pid)
Get one producer.
Definition: ChannelRegistry.cpp:44
FileSystem::TimedOut
@ TimedOut
Definition: FileSystem.h:64
VMCopy
API::Result VMCopy(const ProcessID proc, const API::Operation how, const Address ours, const Address theirs, const Size sz)
Prototype for user applications.
Definition: VMCopy.h:42
type
u8 type
Definition: IntelACPI.h:63
FileSystem::Writable
@ Writable
< File can be read without blocking
Definition: FileSystem.h:140
FileSystemMessage::timeout
Timer::Info timeout
Timeout value for the action.
Definition: FileSystemMessage.h:46
FileCache
Cached in-memory file.
Definition: FileCache.h:35
FileSystem::FileStat::pid
ProcessID pid
< Inode number
Definition: FileSystem.h:117
ZERO
#define ZERO
Zero value.
Definition: Macros.h:43
FileSystem::PermissionDenied
@ PermissionDenied
Definition: FileSystem.h:59
FileSystemServer::clearFileCache
void clearFileCache(FileCache *cache=ZERO)
Cleans up the entire file cache (except opened file caches and root).
Definition: FileSystemServer.cpp:813
HashTable::insert
virtual bool insert(const K &key, const V &value)
Inserts the given item to the HashTable.
Definition: HashTable.h:133
FileSystemServer::m_root
FileCache * m_root
Root entry of the filesystem tree.
Definition: FileSystemServer.h:305
HashTable::value
virtual const V value(const K &key, const V defaultValue=V()) const
Return the first value for the given key.
Definition: HashTable.h:325
FileSystemServer::getParentDirectory
Directory * getParentDirectory(const char *path)
Retrieve parent Directory for a file.
Definition: FileSystemServer.cpp:659
FileSystem::CreateFile
@ CreateFile
Definition: FileSystem.h:38
FileSystemMessage::size
Size size
Size of the buffer.
Definition: FileSystemMessage.h:42
ListIterator
Iterate through a List.
Definition: ListIterator.h:37
FileSystemServer::getFileSystemsHandler
void getFileSystemsHandler(FileSystemMessage *msg)
Read the file system mounts table.
Definition: FileSystemServer.cpp:612
FileSystemServer::registerFile
FileSystem::Result registerFile(File *file, const char *path)
Register a new File.
Definition: FileSystemServer.cpp:115