From b6c30ddcdf921bb1c94633caf64eb993d82003eb Mon Sep 17 00:00:00 2001 From: Terraneo Federico <fede.tft@hotmail.it> Date: Sun, 7 Jul 2013 15:35:45 +0200 Subject: [PATCH] Continuing filesystem work --- main.cpp | 6 ++++++ miosix/filesystem/devfs/devfs.cpp | 34 +++++++++++++++++++++++-------- miosix/filesystem/devfs/devfs.h | 34 ++++++++++++++++++++++++++++++- miosix/filesystem/file.h | 15 +++++++++++++- miosix/filesystem/file_access.cpp | 15 ++++++++++++++ miosix/filesystem/file_access.h | 34 ++++++++++++++++++++++++++----- 6 files changed, 123 insertions(+), 15 deletions(-) diff --git a/main.cpp b/main.cpp index 8764b9fa..c72a394f 100644 --- a/main.cpp +++ b/main.cpp @@ -1,6 +1,7 @@ #include <cstdio> #include "miosix.h" +#include "filesystem/devfs/devfs.h" using namespace std; using namespace miosix; @@ -8,4 +9,9 @@ using namespace miosix; int main() { //iprintf("Hello world, write your application here\n"); + DevFs *dfs=new DevFs; + FilesystemManager& fsm=FilesystemManager::instance(); + fsm.kmount("/dev",dfs); + FileDescriptorTable fdt; + } diff --git a/miosix/filesystem/devfs/devfs.cpp b/miosix/filesystem/devfs/devfs.cpp index 7a5fc8b8..0170eae0 100644 --- a/miosix/filesystem/devfs/devfs.cpp +++ b/miosix/filesystem/devfs/devfs.cpp @@ -35,22 +35,40 @@ namespace miosix { // class DevFs // -int DevFs::open(intrusive_ref_ptr<FileBase>& file, std::string name, int flags, +DevFs::DevFs() +{ + files["null"]=intrusive_ref_ptr<FileBase>(new NullFile(this)); + files["zero"]=intrusive_ref_ptr<FileBase>(new ZeroFile(this)); +} + +int DevFs::open(intrusive_ref_ptr<FileBase>& file, StringPart& name, int flags, int mode) { - + return -1; //FIXME +} + +int DevFs::lstat(StringPart& name, struct stat *pstat) +{ + return -1; //FIXME } -/** - * \return true if all files belonging to this filesystem are closed - */ +int DevFs::readlink(StringPart& name, std::string& target) +{ + return -1; //FIXME +} + +bool DevFs::supportsSymlinks() const { return false; } + bool DevFs::areAllFilesClosed() { + //Lock the mutex just in case we'll want to support dynamically removing + //device files at runtime + Lock<Mutex> l(mutex); //Can't use openFileCount in devFS, as one instance of each file is stored //in the map. Rather, check the reference count value. No need to use - //atomic ops to make a copy of the file before calling use_count() as - //the existence of at least one reference in the map guarantees the file - //won't be deleted + //atomic ops to make a copy of the file before calling use_count() as the + //existence of at least one reference in the map guarantees the file won't + //be deleted. map<string,intrusive_ref_ptr<FileBase> >::iterator it; for(it=files.begin();it!=files.end();++it) if(it->second.use_count()>1) return false; diff --git a/miosix/filesystem/devfs/devfs.h b/miosix/filesystem/devfs/devfs.h index d7f9181f..50d7b58f 100644 --- a/miosix/filesystem/devfs/devfs.h +++ b/miosix/filesystem/devfs/devfs.h @@ -38,6 +38,11 @@ namespace miosix { class DevFs : public FilesystemBase { public: + /** + * Constructor + */ + DevFs(); + /** * Open a file * \param file the file object will be stored here, if the call succeeds @@ -45,11 +50,38 @@ public: * filesystem * \param flags file flags (open for reading, writing, ...) * \param mode file permissions + * \return 0 on success, or a negative number on failure */ - virtual int open(intrusive_ref_ptr<FileBase>& file, std::string name, + virtual int open(intrusive_ref_ptr<FileBase>& file, StringPart& name, int flags, int mode); + /** + * Obtain information on a file, identified by a path name. Does not follow + * symlinks + * \param name path name, relative to the local filesystem + * \param pstat file information is stored here + * \return 0 on success, or a negative number on failure + */ + virtual int lstat(StringPart& name, struct stat *pstat); + + /** + * Follows a symbolic link + * \param path path identifying a symlink, relative to the local filesystem + * \param target the link target is returned here if the call succeeds. + * Note that the returned path is not relative to this filesystem, and can + * be either relative or absolute. + * \return 0 on success, a negative number on failure + */ + virtual int readlink(StringPart& name, std::string& target); + + /** + * \return true if the filesystem supports symbolic links. + * In this case, the filesystem should override readlink + */ + virtual bool supportsSymlinks() const; + /** + * \internal * \return true if all files belonging to this filesystem are closed */ virtual bool areAllFilesClosed(); diff --git a/miosix/filesystem/file.h b/miosix/filesystem/file.h index 1a919cfe..94536720 100644 --- a/miosix/filesystem/file.h +++ b/miosix/filesystem/file.h @@ -48,7 +48,8 @@ class FileBase : public IntrusiveRefCounted { public: /** - * Construcotr + * Constructor + * \param parent the filesystem to which this file belongs */ FileBase(FilesystemBase *parent) : parent(parent) {} @@ -123,6 +124,12 @@ private: class NullFile : public FileBase { public: + /** + * Constructor + * \param parent the filesystem to which this file belongs + */ + NullFile(FilesystemBase *parent) : FileBase(parent) {} + /** * Write data to the file, if the file supports writing. * \param data the data to write @@ -178,6 +185,12 @@ public: class ZeroFile : public FileBase { public: + /** + * Constructor + * \param parent the filesystem to which this file belongs + */ + ZeroFile(FilesystemBase *parent) : FileBase(parent) {} + /** * Write data to the file, if the file supports writing. * \param data the data to write diff --git a/miosix/filesystem/file_access.cpp b/miosix/filesystem/file_access.cpp index 6c4aca81..7b6820b7 100644 --- a/miosix/filesystem/file_access.cpp +++ b/miosix/filesystem/file_access.cpp @@ -88,11 +88,18 @@ FilesystemBase::~FilesystemBase() {} // class FileDescriptorTable // +FileDescriptorTable::FileDescriptorTable() : mutex(Mutex::RECURSIVE), cwd("/") +{ + FilesystemManager::instance().addFileDescriptorTable(this); +} + FileDescriptorTable::FileDescriptorTable(const FileDescriptorTable& rhs) + : mutex(Mutex::RECURSIVE), cwd(rhs.cwd) { //No need to lock the mutex since we are in a constructor and there can't //be pointers to this in other threads yet for(int i=0;i<MAX_OPEN_FILES;i++) this->files[i]=atomic_load(&rhs.files[i]); + FilesystemManager::instance().addFileDescriptorTable(this); } FileDescriptorTable& FileDescriptorTable::operator=( @@ -174,6 +181,14 @@ int FileDescriptorTable::statImpl(const char* name, struct stat* pstat, bool f) return openData.fs->lstat(sp,pstat); } +FileDescriptorTable::~FileDescriptorTable() +{ + FilesystemManager::instance().removeFileDescriptorTable(this); + //There's no need to lock the mutex and explicitly close files eventually + //left open, because if there are other threads accessing this while we are + //being deleted we have bigger problems anyway +} + string FileDescriptorTable::absolutePath(const char* path) { int len=strlen(path); diff --git a/miosix/filesystem/file_access.h b/miosix/filesystem/file_access.h index bf46adb9..c3b51a97 100644 --- a/miosix/filesystem/file_access.h +++ b/miosix/filesystem/file_access.h @@ -138,7 +138,7 @@ public: /** * Constructor */ - FileDescriptorTable() : mutex(Mutex::RECURSIVE), cwd("/") {} + FileDescriptorTable(); /** * Copy constructor @@ -292,9 +292,10 @@ public: return atomic_load(files+fd); } - //Using default destructor as there's no need to lock the mutex while - //closing files eventually left open, because if there are other threads - //accessing this while we are being deleted we have bigger problems anyway + /** + * Destructor + */ + ~FileDescriptorTable(); private: /** @@ -498,7 +499,8 @@ public: * and board support packages. It is the only mount operation that can * mount the root filesystem. * \param path path where to mount the filesystem - * \param fs filesystem to mount + * \param fs filesystem to mount. Ownership of the pointer is transferred + * to the FilesystemManager class * \return 0 on success, a negative number on failure */ int kmount(const char *path, FilesystemBase *fs); @@ -528,6 +530,28 @@ public: */ ResolvedPath resolvePath(std::string& path, bool followLastSymlink=true); + /** + * \internal + * Called by FileDescriptorTable's constructor. Never call this function + * from user code. + */ + void addFileDescriptorTable(FileDescriptorTable *fdt) + { + Lock<Mutex> l(mutex); + fileTables.push_back(fdt); + } + + /** + * \internal + * Called by FileDescriptorTable's constructor. Never call this function + * from user code. + */ + void removeFileDescriptorTable(FileDescriptorTable *fdt) + { + Lock<Mutex> l(mutex); + fileTables.remove(fdt); + } + private: /** * Constructor, private as it is a singleton -- GitLab