The Pedigree Project  0.1
RamFs.cc
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 #include "RamFs.h"
21 #include "modules/Module.h"
22 #include "pedigree/kernel/process/Process.h"
23 #include "pedigree/kernel/process/Thread.h"
24 #include "pedigree/kernel/processor/Processor.h"
25 #include "pedigree/kernel/processor/ProcessorInformation.h"
26 #include "pedigree/kernel/utilities/new"
27 
28 String RamFs::m_VolumeLabel("ramfs");
29 
30 RamFile::RamFile(
31  const String &name, uintptr_t inode, Filesystem *pParentFS, File *pParent)
32  : File(name, 0, 0, 0, inode, pParentFS, 0, pParent), m_FileBlocks(),
33  m_nOwnerPid(0)
34 {
35  // Full permissions.
36  setPermissions(0777);
37 
38 #ifdef THREADS
39  m_nOwnerPid =
40  Processor::information().getCurrentThread()->getParent()->getId();
41 #else
42  m_nOwnerPid = 0;
43 #endif
44 }
45 
46 RamFile::~RamFile()
47 {
48  truncate();
49 }
50 
52 {
53  if (canWrite())
54  {
55  // Empty the cache.
56  m_FileBlocks.empty();
57  setSize(0);
58  }
59 }
60 
61 bool RamFile::canWrite()
62 {
63  RamFs *pParent = static_cast<RamFs *>(getFilesystem());
64  if (!pParent->getProcessOwnership())
65  {
66  return true;
67  }
68 
69 #ifdef THREADS
70  size_t pid =
71  Processor::information().getCurrentThread()->getParent()->getId();
72  return pid == m_nOwnerPid;
73 #else
74  return true;
75 #endif
76 }
77 
78 uintptr_t RamFile::readBlock(uint64_t location)
79 {
80  uintptr_t buffer = m_FileBlocks.lookup(location);
81  if (!buffer)
82  {
83  // Super trivial. But we are a ram filesystem... can't compact.
84  buffer = m_FileBlocks.insert(location);
85  pinBlock(location);
87  m_FileBlocks.markNoLongerEditing(location);
88  }
89  return buffer;
90 }
91 
92 void RamFile::pinBlock(uint64_t location)
93 {
94  m_FileBlocks.pin(location);
95 }
96 
97 void RamFile::unpinBlock(uint64_t location)
98 {
99  m_FileBlocks.release(location);
100 }
101 
102 RamDir::RamDir(
103  const String &name, size_t inode, class Filesystem *pFs, File *pParent)
104  : Directory(name, 0, 0, 0, inode, pFs, 0, pParent)
105 {
106  // Full permissions.
107  setPermissions(0777);
108 }
109 
110 RamDir::~RamDir(){};
111 
112 bool RamDir::addEntry(String filename, File *pFile)
113 {
114  addDirectoryEntry(filename, pFile);
115  return true;
116 }
117 
118 bool RamDir::removeEntry(File *pFile)
119 {
120  RamFile *pRamFile = static_cast<RamFile *>(pFile);
121  if (!pRamFile->canWrite())
122  return false;
123 
124  // Remove from cache.
125  remove(pFile->getName());
126  return true;
127 }
128 
129 RamFs::RamFs() : m_pRoot(0), m_bProcessOwners(false)
130 {
131 }
132 
133 RamFs::~RamFs()
134 {
135  if (m_pRoot)
136  delete m_pRoot;
137 }
138 
140 {
141  // Root directory with ./.. entries
142  m_pRoot = new RamDir(String(""), 0, this, 0);
143  return true;
144 }
145 
146 bool RamFs::createFile(File *parent, const String &filename, uint32_t mask)
147 {
148  if (!parent->isDirectory())
149  return false;
150 
151  File *f = new RamFile(filename, 0, this, parent);
152 
153  RamDir *p = static_cast<RamDir *>(parent);
154  return p->addEntry(filename, f);
155 }
156 
157 bool RamFs::createDirectory(File *parent, const String &filename, uint32_t mask)
158 {
159  if (!parent->isDirectory())
160  return false;
161 
162  RamDir *pDir = new RamDir(filename, 0, this, parent);
163 
164  RamDir *pParent = static_cast<RamDir *>(parent);
165  return pParent->addEntry(filename, pDir);
166 }
167 
169  File *parent, const String &filename, const String &value)
170 {
171  return false;
172 }
173 
174 bool RamFs::remove(File *parent, File *file)
175 {
176  if (file->isDirectory())
177  return false;
178 
179  RamDir *p = static_cast<RamDir *>(parent);
180  return p->removeEntry(file);
181 }
182 
183 static bool entry()
184 {
185  return true;
186 }
187 
188 static void destroy()
189 {
190 }
191 
192 MODULE_INFO("ramfs", &entry, &destroy, "vfs");
virtual void truncate()
Definition: RamFs.cc:51
virtual bool createSymlink(File *parent, const String &filename, const String &value)
Definition: RamFs.cc:168
virtual bool initialise(Disk *pDisk)
Definition: RamFs.cc:139
Node * m_pRoot
Definition: RadixTree.h:291
An in-RAM filesystem.
Definition: String.h:49
static ProcessorInformation & information()
Definition: Processor.cc:45
virtual bool createFile(File *parent, const String &filename, uint32_t mask)
Definition: RamFs.cc:146
Definition: Disk.h:32
virtual bool remove(File *parent, File *file)
Definition: RamFs.cc:174
virtual uintptr_t readBlock(uint64_t location)
Definition: RamFs.cc:78
virtual void pinBlock(uint64_t location)
Definition: RamFs.cc:92
String getName() const
Definition: File.cc:411
Definition: RamFs.h:65
Definition: RamFs.h:38
virtual void unpinBlock(uint64_t location)
Definition: RamFs.cc:97
Definition: RamFs.h:86
virtual bool isDirectory()
Definition: File.cc:436
Definition: File.h:66
virtual bool createDirectory(File *parent, const String &filename, uint32_t mask)
Definition: RamFs.cc:157