Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(188)

Side by Side Diff: native_client_sdk/src/libraries/nacl_mounts/mount_mem.cc

Issue 12194030: Rename mount (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix whitespace Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /* Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5 #include "nacl_mounts/mount_mem.h"
6
7 #include <errno.h>
8 #include <fcntl.h>
9 #include <string>
10
11 #include "nacl_mounts/mount.h"
12 #include "nacl_mounts/mount_node.h"
13 #include "nacl_mounts/mount_node_dir.h"
14 #include "nacl_mounts/mount_node_mem.h"
15 #include "nacl_mounts/osstat.h"
16 #include "nacl_mounts/path.h"
17 #include "utils/auto_lock.h"
18 #include "utils/ref_object.h"
19
20 // TODO(noelallen) : Grab/Redefine these in the kernel object once available.
21 #define USR_ID 1002
22 #define GRP_ID 1003
23
24 MountMem::MountMem()
25 : root_(NULL),
26 max_ino_(0) {
27 }
28
29 bool MountMem::Init(int dev, StringMap_t& args, PepperInterface* ppapi) {
30 Mount::Init(dev, args, ppapi);
31 root_ = AllocatePath(S_IREAD | S_IWRITE);
32 return (bool) (root_ != NULL);
33 }
34
35 void MountMem::Destroy() {
36 if (root_)
37 root_->Release();
38 root_ = NULL;
39 }
40
41 MountNode* MountMem::AllocatePath(int mode) {
42 MountNode *ptr = new MountNodeDir(this);
43 if (!ptr->Init(mode)) {
44 ptr->Release();
45 return NULL;
46 }
47 return ptr;
48 }
49
50 MountNode* MountMem::AllocateData(int mode) {
51 MountNode* ptr = new MountNodeMem(this);
52 if (!ptr->Init(mode)) {
53 ptr->Release();
54 return NULL;
55 }
56 return ptr;
57 }
58
59 MountNode* MountMem::FindNode(const Path& path, int type) {
60 MountNode* node = root_;
61
62 // If there is no root there, we have an error.
63 if (node == NULL) {
64 errno = ENOTDIR;
65 return NULL;
66 }
67
68 // We are expecting an "absolute" path from this mount point.
69 if (!path.IsAbsolute()) {
70 errno = EINVAL;
71 return NULL;
72 }
73
74 // Starting at the root, traverse the path parts.
75 for (size_t index = 1; node && index < path.Size(); index++) {
76 // If not a directory, then we have an error so return.
77 if (!node->IsaDir()) {
78 errno = ENOTDIR;
79 return NULL;
80 }
81
82 // Find the child node
83 node = node->FindChild(path.Part(index));
84 }
85
86 // node should be root, a found child, or a failed 'FindChild'
87 // which already has the correct errno set.
88 if (NULL == node) return NULL;
89
90 // If a directory is expected, but it's not a directory, then fail.
91 if ((type & S_IFDIR) && !node->IsaDir()) {
92 errno = ENOTDIR;
93 return NULL;
94 }
95
96 // If a file is expected, but it's not a file, then fail.
97 if ((type & S_IFREG) && node->IsaDir()) {
98 errno = EISDIR;
99 return NULL;
100 }
101
102 // We now have a valid object of the expected type, so return it.
103 return node;
104 }
105
106 MountNode* MountMem::Open(const Path& path, int mode) {
107 AutoLock lock(&lock_);
108 MountNode* node = FindNode(path);
109
110 if (NULL == node) {
111 // Now first find the parent directory to see if we can add it
112 MountNode* parent = FindNode(path.Parent(), S_IFDIR);
113 if (NULL == parent) return NULL;
114
115 // If the node does not exist and we can't create it, fail
116 if ((mode & O_CREAT) == 0) return NULL;
117
118 // Otherwise, create it with a single refernece
119 mode = OpenModeToPermission(mode);
120 node = AllocateData(mode);
121 if (NULL == node) return NULL;
122
123 if (parent->AddChild(path.Basename(), node) == -1) {
124 // Or if it fails, release it
125 node->Release();
126 return NULL;
127 }
128 return node;
129 }
130
131 // If we were expected to create it exclusively, fail
132 if (mode & O_EXCL) {
133 errno = EEXIST;
134 return NULL;
135 }
136
137 // Verify we got the requested permisions.
138 int req_mode = OpenModeToPermission(mode);
139 int obj_mode = node->GetMode() & OpenModeToPermission(O_RDWR);
140 if ((obj_mode & req_mode) != req_mode) {
141 errno = EACCES;
142 return NULL;
143 }
144
145 // We opened it, so ref count it before passing it back.
146 node->Acquire();
147 return node;
148 }
149
150 int MountMem::Mkdir(const Path& path, int mode) {
151 AutoLock lock(&lock_);
152
153 // We expect a Mount "absolute" path
154 if (!path.IsAbsolute()) {
155 errno = ENOENT;
156 return -1;
157 }
158
159 // The root of the mount is already created by the mount
160 if (path.Size() == 1) {
161 errno = EEXIST;
162 return -1;
163 }
164
165 MountNode* parent = FindNode(path.Parent(), S_IFDIR);
166 MountNode* node;
167
168 // If we failed to find the parent, the error code is already set.
169 if (NULL == parent) return -1;
170
171 node = parent->FindChild(path.Basename());
172 if (NULL != node) {
173 errno = EEXIST;
174 return -1;
175 }
176
177 // Otherwise, create a new node and attempt to add it
178 mode = OpenModeToPermission(mode);
179
180 // Allocate a node, with a RefCount of 1. If added to the parent
181 // it will get ref counted again. In either case, release the
182 // recount we have on exit.
183 node = AllocatePath(S_IREAD | S_IWRITE);
184 if (NULL == node) return -1;
185
186 if (parent->AddChild(path.Basename(), node) == -1) {
187 node->Release();
188 return -1;
189 }
190
191 node->Release();
192 return 0;
193 }
194
195 int MountMem::Unlink(const Path& path) {
196 return RemoveInternal(path, REMOVE_FILE);
197 }
198
199 int MountMem::Rmdir(const Path& path) {
200 return RemoveInternal(path, REMOVE_DIR);
201 }
202
203 int MountMem::Remove(const Path& path) {
204 return RemoveInternal(path, REMOVE_ALL);
205 }
206
207 int MountMem::RemoveInternal(const Path& path, int remove_type) {
208 AutoLock lock(&lock_);
209 bool dir_only = remove_type == REMOVE_DIR;
210 bool file_only = remove_type == REMOVE_FILE;
211 bool remove_dir = (remove_type & REMOVE_DIR) != 0;
212
213 if (dir_only) {
214 // We expect a Mount "absolute" path
215 if (!path.IsAbsolute()) {
216 errno = ENOENT;
217 return -1;
218 }
219
220 // The root of the mount is already created by the mount
221 if (path.Size() == 1) {
222 errno = EEXIST;
223 return -1;
224 }
225 }
226
227 MountNode* parent = FindNode(path.Parent(), S_IFDIR);
228
229 // If we failed to find the parent, the error code is already set.
230 if (NULL == parent) return -1;
231
232 // Verify we find a child which is a directory.
233 MountNode* child = parent->FindChild(path.Basename());
234 if (NULL == child) {
235 errno = ENOENT;
236 return -1;
237 }
238 if (dir_only && !child->IsaDir()) {
239 errno = ENOTDIR;
240 return -1;
241 }
242 if (file_only && child->IsaDir()) {
243 errno = EISDIR;
244 return -1;
245 }
246 if (remove_dir && child->ChildCount() > 0) {
247 errno = ENOTEMPTY;
248 return -1;
249 }
250 return parent->RemoveChild(path.Basename());
251 }
OLDNEW
« no previous file with comments | « native_client_sdk/src/libraries/nacl_mounts/mount_mem.h ('k') | native_client_sdk/src/libraries/nacl_mounts/mount_node.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698