| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright 2008 The Native Client Authors. All rights reserved. | |
| 3 * Use of this source code is governed by a BSD-style license that can | |
| 4 * be found in the LICENSE file. | |
| 5 */ | |
| 6 | |
| 7 /* | |
| 8 * NaCl Service Runtime Virtual Filesystem Support Interface. | |
| 9 * | |
| 10 * NB: this code has not been integrated with the rest of NaCl, and is | |
| 11 * likely to change. | |
| 12 * | |
| 13 * We *really* need the low-level IMC module (../../src/shared/imc) | |
| 14 * to provide a robust non-blocking / asynchronous interface. Current | |
| 15 * NACL_DONT_WAIT flag is completely bogus, since on some platforms | |
| 16 * (e.g, OSX and Windows) the flag is ignored. | |
| 17 * | |
| 18 * For now, we burn a thread per server-based filesystem. If that | |
| 19 * thread has problems, we can time out in the upper-layer's | |
| 20 * condition wait, leaving the thread stuck. | |
| 21 * | |
| 22 * Much of the design is patterned after NFSv2, except using an IMC | |
| 23 * transport instead of UDP. | |
| 24 */ | |
| 25 | |
| 26 #ifndef NATIVE_CLIENT_SERVICE_RUNTIME_FS_FS_H_ | |
| 27 #define NATIVE_CLIENT_SERVICE_RUNTIME_FS_FS_H_ | |
| 28 | |
| 29 #include "native_client/src/include/nacl_base.h" | |
| 30 | |
| 31 #include "native_client/src/trusted/service_runtime/include/machine/_types.h" | |
| 32 | |
| 33 #include "native_client/src/trusted/desc/nacl_desc_base.h" | |
| 34 | |
| 35 EXTERN_C_BEGIN | |
| 36 | |
| 37 #define NACL_MAXDATA (64 << 10) | |
| 38 #define NACL_MAXPATHLEN 1024 | |
| 39 #define NACL_MAXNAMLEN 255 | |
| 40 #define NACL_COOKIESIZE 4 | |
| 41 #define NACL_FHSIZE 32 | |
| 42 /* | |
| 43 * 256 bits, so 2 AES blocks if encryption is desired. also a random | |
| 44 * value is good enough for some use cases. we assume a secure | |
| 45 * channel in any case, so only unspoofability by the client is needed | |
| 46 * -- so if encryption is used, semantically secure encryption is | |
| 47 * required. since clients are service runtime implementations, and | |
| 48 * NaCl modules cannot directly access this channel, spoofing is not a | |
| 49 * threat. (if we allow NaCl modules to get the IMC socket and invoke | |
| 50 * the nacl_mount operation itself, then this becomes an issue.) | |
| 51 */ | |
| 52 | |
| 53 struct NaClFileSystem; | |
| 54 | |
| 55 /* | |
| 56 * An inode within the context of a NaClFileSystem. Essentialy | |
| 57 * contains the (implemented) fields of nacl_abi_stat. This is | |
| 58 * essentially what is read from/written to filesystems, though when | |
| 59 * using SRPC sans XDR or protobufs, the structure members are | |
| 60 * manually serialized/deserialized. | |
| 61 */ | |
| 62 struct NaClFileAttr { | |
| 63 nacl_abi_dev_t dev; /* fsid */ | |
| 64 nacl_abi_ino_t ino; /* fileid; a per filesystem value */ | |
| 65 nacl_abi_mode_t mode; | |
| 66 nacl_abi_uid_t uid; /* origin ID? presistent mapping to URI? */ | |
| 67 nacl_abi_gid_t gid; /* ??? */ | |
| 68 nacl_abi_nlink_t nlink; /* on-disk ref count */ | |
| 69 nacl_abi_off_t size; | |
| 70 nacl_abi_time_t atime; /* access time */ | |
| 71 nacl_abi_time_t mtime; /* modification time */ | |
| 72 nacl_abi_time_t ctime; /* inode change time */ | |
| 73 /* | |
| 74 * no need to ensure padding / structure size is the same on all | |
| 75 * platforms, since we won't be running over a real network. | |
| 76 */ | |
| 77 }; | |
| 78 | |
| 79 /* | |
| 80 * some fs/inodes tuples are mount points, so whenever we see an inode | |
| 81 * number in a directory read operation, we need to check the | |
| 82 * per-filesystem list of mount points. when a filesystem is | |
| 83 * unmounted, there should be no mount points within that file system. | |
| 84 */ | |
| 85 | |
| 86 /* | |
| 87 * Runtime / in-memory representation of an inode. The filesystem in | |
| 88 * which the inode is contained is determined by using the dev member | |
| 89 * of the inode. | |
| 90 */ | |
| 91 struct NaClMemFileAttr { | |
| 92 struct NaClFileAttr fa; | |
| 93 struct NaClDescConnCap *cc; /* if an IMC-based device */ | |
| 94 | |
| 95 /* | |
| 96 * NB: instead of mounting a filesystem, we can associate an existing | |
| 97 * connection capability with an inode and make that appear to be a | |
| 98 * filesystem object. this is just a special kind of filesystem | |
| 99 * object that contains a single entry. this allows (some) servers | |
| 100 * to advertise their availability, using the filesystem as a name | |
| 101 * server. the client is responsible for figuring out what the | |
| 102 * service is via service discovery, and of course the client should | |
| 103 * not necessarily trust the server. | |
| 104 */ | |
| 105 }; | |
| 106 | |
| 107 /* | |
| 108 * First, a NaClFileSystem base class. We will have the in-memory | |
| 109 * filesystem for the root, with files made available to the NaCl | |
| 110 * module from the browser plugin (via the secure command channel), as | |
| 111 * well as external file servers that provide filesystem services via | |
| 112 * SRPC. We must not trust such servers even though they normally would | |
| 113 * nominally be trusted processes -- all input should be validated. | |
| 114 */ | |
| 115 | |
| 116 struct NaClFileSystemVtbl; /* fwd */ | |
| 117 struct Container; /* fwd */ | |
| 118 | |
| 119 struct NaClFileSystem { | |
| 120 struct NaClFileSystemVtbl *vtbl; | |
| 121 struct NaClMutex mu; | |
| 122 uint32_t ref_count; | |
| 123 uint64_t open_files_count; | |
| 124 /* | |
| 125 * device number is assigned by NaCl, do not depend on it having a | |
| 126 * particular value. in particular, no major/minor device number | |
| 127 * encoding should be assumed. (NB: do not make available to user | |
| 128 * apps for now.) | |
| 129 */ | |
| 130 nacl_abi_dev_t dev; | |
| 131 /* where is filesystem mounted? mountpt is NULL for the root filesystem */ | |
| 132 struct NaClMemInode *mountpt; | |
| 133 /* | |
| 134 * What inodes are mount points? | |
| 135 */ | |
| 136 struct Container *mountpt_inos; | |
| 137 }; | |
| 138 | |
| 139 void NaClFileSystemIncRef(struct NaClFileSystem *fsp); | |
| 140 void NaClFileSystemDecRef(struct NaClFileSystem *fsp); | |
| 141 | |
| 142 struct NaClFileSystemVtbl { | |
| 143 void (*Dtor)(struct NaClFileSystem *fsp); | |
| 144 | |
| 145 void (*IncRef)(struct NaClFileSystem *fsp); | |
| 146 /* used when mounting */ | |
| 147 void (*DecRef)(struct NaClFileSystem *fsp); | |
| 148 /* used when unmounting */ | |
| 149 | |
| 150 /* | |
| 151 * On-disk ref count, deletion/gc, esp if file server has multiple | |
| 152 * clients. These are used, for example, for open(..., O_CREAT) and | |
| 153 * unlink syscalls. We inc refcount before modifying the containing | |
| 154 * directory, and dec the refcount after modifying the containing | |
| 155 * directory -- assuming no re-ordering of filesystem operations, | |
| 156 * this ensures that if an object's refcount is inconsistent, it | |
| 157 * would just result in an inode (and associated data blocks) which | |
| 158 * is inaccessible, rather than being put into a free list while it | |
| 159 * is still accessible. | |
| 160 */ | |
| 161 int (*RefIno)(struct NaClFileSystem *fsp, | |
| 162 nacl_abi_ino_t inum); | |
| 163 int (*UnrefIno)(struct NaClFileSystem *fsp, | |
| 164 nacl_abi_ino_t inum); | |
| 165 | |
| 166 /* | |
| 167 * In-memory refcount. Can prevent freeing of data blocks | |
| 168 * associated with an inode, even though the on-disk ref count is | |
| 169 * zero. These are used, for example, for open and close syscalls, | |
| 170 * so that open followed by unlink would not gc the inode and | |
| 171 * associated data blocks. If the inode has been unlinked between | |
| 172 * the directory lookup and the unlink, DynRefIno may return | |
| 173 * -NACL_ABI_EACCES. | |
| 174 */ | |
| 175 int (*DynRefIno)(struct NaClFileSystem *fsp, | |
| 176 nacl_abi_ino_t inum); | |
| 177 int (*DynUnrefIno)(struct NaClFileSystem *fsp, | |
| 178 nacl_abi_ino_t inum); | |
| 179 | |
| 180 /* meta data */ | |
| 181 int (*ReadIno)(struct NaClFileSystem *fsp, | |
| 182 nacl_abi_ino_t inum, | |
| 183 struct NaClFileAttr *nfap); | |
| 184 int (*WriteIno)(struct NaClFileSystem *fsp, | |
| 185 nacl_abi_ino_t inum, | |
| 186 struct NaClFileSystem *nfap); | |
| 187 | |
| 188 /* | |
| 189 * data, pread/pwrite-like interface. there's no notion of current | |
| 190 * file pointer/seek, since offset is explicit | |
| 191 */ | |
| 192 nacl_abi_ssize_t (*Read)(struct NaClFileSystem *fsp, | |
| 193 nacl_abi_ino_t inum, | |
| 194 void *buf, | |
| 195 nacl_abi_size_t count, | |
| 196 nacl_abi_off_t offset); | |
| 197 nacl_abi_ssize_t (*Write)(struct NaClFileSystem *fsp, | |
| 198 nacl_abi_ino_t inum, | |
| 199 void const *buf, | |
| 200 nacl_abi_size_t count, | |
| 201 nacl_abi_off_t offset); | |
| 202 /* mmap?, mount? */ | |
| 203 }; | |
| 204 | |
| 205 EXTERN_C_END | |
| 206 | |
| 207 #endif | |
| OLD | NEW |