|
[ source navigation ] [ diff markup ] [ identifier search ] [ general search ] |
|||
|
001 /* Copyright (C) 2005 David Decotigny 001 /* Copyright (C) 2005 David Decotigny 002 Copyright (C) 2000-2005 The KOS Team (Thoma 002 Copyright (C) 2000-2005 The KOS Team (Thomas Petazzoni, David 003 Decotigny, Julien M 003 Decotigny, Julien Munier) 004 004 005 This program is free software; you can redi 005 This program is free software; you can redistribute it and/or 006 modify it under the terms of the GNU Genera 006 modify it under the terms of the GNU General Public License 007 as published by the Free Software Foundatio 007 as published by the Free Software Foundation; either version 2 008 of the License, or (at your option) any lat 008 of the License, or (at your option) any later version. 009 009 010 This program is distributed in the hope tha 010 This program is distributed in the hope that it will be useful, 011 but WITHOUT ANY WARRANTY; without even the 011 but WITHOUT ANY WARRANTY; without even the implied warranty of 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR 012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 GNU General Public License for more details 013 GNU General Public License for more details. 014 014 015 You should have received a copy of the GNU 015 You should have received a copy of the GNU General Public License 016 along with this program; if not, write to t 016 along with this program; if not, write to the Free Software 017 Foundation, Inc., 59 Temple Place - Suite 3 017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 018 USA. 018 USA. 019 */ 019 */ 020 #ifndef _SOS_FS_H_ 020 #ifndef _SOS_FS_H_ 021 #define _SOS_FS_H_ 021 #define _SOS_FS_H_ 022 022 023 023 024 /** 024 /** 025 * @file fs.h 025 * @file fs.h 026 * 026 * 027 * (Virtual) Filesystem management. 027 * (Virtual) Filesystem management. 028 * 028 * 029 * SOS provides a complete Unix-like file syst 029 * SOS provides a complete Unix-like file system service. Supported 030 * features of this service are: 030 * features of this service are: 031 * - mountpoints 031 * - mountpoints 032 * - generic file system support (FS) throug 032 * - generic file system support (FS) through object-oriented 033 * specialization (so-called VFS) 033 * specialization (so-called VFS) 034 * - hard & symbolic links 034 * - hard & symbolic links 035 * - regular files and directories 035 * - regular files and directories 036 * - block and character device special file 036 * - block and character device special files (from article 9 onward) 037 * - file mapping 037 * - file mapping 038 * - basic permission management ("rwx" only 038 * - basic permission management ("rwx" only, no notion of owner) 039 * - chroot 039 * - chroot 040 * - separation of disk node and namespace n 040 * - separation of disk node and namespace notions allowing hard links 041 * and to move/rename/remove files or dire 041 * and to move/rename/remove files or directories that are in use 042 * - basic FS interface (open/read/seek/crea 042 * - basic FS interface (open/read/seek/creat/mkdir/rename/link 043 * / symlink/chmod/mount/fcntl/ioctl...) 043 * / symlink/chmod/mount/fcntl/ioctl...) 044 * - deferred writes (ie file caching). @see 044 * - deferred writes (ie file caching). @see sync(3) 045 * 045 * 046 * Among the unsupported features: 046 * Among the unsupported features: 047 * - no user-based permission (uid/gid, ACLS 047 * - no user-based permission (uid/gid, ACLS) 048 * - no modification / access time accountin 048 * - no modification / access time accounting 049 * - no Fifo/socket special files (yet) 049 * - no Fifo/socket special files (yet) 050 * - no generic support library for common f 050 * - no generic support library for common fcntl commands 051 * (F_SETOWN/GETLEASE/NOTIFY, etc.) 051 * (F_SETOWN/GETLEASE/NOTIFY, etc.) 052 * - no flock-style functions 052 * - no flock-style functions 053 * 053 * 054 * Rationale 054 * Rationale 055 * ========= 055 * ========= 056 * The VFS layer is based on 3 central concept 056 * The VFS layer is based on 3 central concepts: 057 * 057 * 058 * - The meta-information for each file store !! 058 * - The meta-information for each file stored on disk: size, 059 * sos_fs_node for SOS, inode for Unix) !! 059 * permissions, ... (struct sos_fs_node for SOS, inode for Unix) 060 * 060 * 061 * It is sufficient to know where this meta 061 * It is sufficient to know where this meta-information is located 062 * on disk (a simple sector number most of 062 * on disk (a simple sector number most of the time) to build the 063 * corresponding struct sos_fs_node into me 063 * corresponding struct sos_fs_node into memory and to retrieve the 064 * data of the file from the disk 064 * data of the file from the disk 065 * 065 * 066 * For example, consider that we know a sec 066 * For example, consider that we know a sector that holds the meta 067 * information (ie size, permissions) is lo !! 067 * information is located at sector 64589 on disk. By retrieving 068 * disk. By retrieving this meta informatio !! 068 * this meta information directly from disk, we can build the 069 * can build the struct sos_fs_node, which !! 069 * struct sos_fs_node, which would (for example) tell that the 070 * that the corresponding file spans (for e !! 070 * corresponding file spans (for example) over sectors 4345, 5645, 071 * 4345, 5645, 4539 and 6575, is 1.7kB long !! 071 * 4539 and 6575, is 1.7kB long 072 * 072 * 073 * Everything is stored this way on the dis 073 * Everything is stored this way on the disk, even the 074 * directories. From the disk contents' poi 074 * directories. From the disk contents' point of view, a directory 075 * is simply a file whose contents represen 075 * is simply a file whose contents represent a list of mappings 076 * "name" -> meta-information location 076 * "name" -> meta-information location 077 * 077 * 078 * - One or many nodes in the file hierarchy 078 * - One or many nodes in the file hierarchy pointing to this data 079 * (struct sos_fs_nscache_node for SOS, str 079 * (struct sos_fs_nscache_node for SOS, struct dentry for Linux). This 080 * tells that the entry "toto" in directory 080 * tells that the entry "toto" in directory "/home/zorglub" 081 * corresponds to the given struct sos_fs_n 081 * corresponds to the given struct sos_fs_node 082 * 082 * 083 * Actually, with the struct sos_fs_node ab 083 * Actually, with the struct sos_fs_node above, we can reach any 084 * file in the system. However, dealing wit 084 * file in the system. However, dealing with mountpoints requires 085 * an intermediary data structure because a 085 * an intermediary data structure because a directory on a disk 086 * cannot make reference to children struct 086 * cannot make reference to children struct sos_fs_node on other 087 * disk. This is one of the reasons why the 087 * disk. This is one of the reasons why there is this struct 088 * sos_fs_nscache_node. Another reason is t 088 * sos_fs_nscache_node. Another reason is that we kind-of "cache" the 089 * most used struct sos_fs_node: those that 089 * most used struct sos_fs_node: those that lead from the global 090 * root ("/") to the files and directories 090 * root ("/") to the files and directories currently being used 091 * (hence the name "nscache" for "namespace 091 * (hence the name "nscache" for "namespace cache"). This speeds-up 092 * the path-resolving process (aka "lookup" 092 * the path-resolving process (aka "lookup"), as the most-used path 093 * are already in-memory and the struct sos 093 * are already in-memory and the struct sos_fs_node are already 094 * in-memory too. 094 * in-memory too. 095 * 095 * 096 * A struct sos_fs_nscache_node can have at 096 * A struct sos_fs_nscache_node can have at most 1 parent (the ".." 097 * entry). It can also have 0 parent in cas 097 * entry). It can also have 0 parent in case the node is being used 098 * by a process (file is opened or mapped), 098 * by a process (file is opened or mapped), but the file is 099 * actually "removed", ie un-reachable from 099 * actually "removed", ie un-reachable from any directory. 100 * 100 * 101 * Many such structures can reference the s 101 * Many such structures can reference the same underlying struct 102 * sos_fs_node, which enables the support o 102 * sos_fs_node, which enables the support of "hard links". 103 * 103 * 104 * - The "opened file" strucures. They store 104 * - The "opened file" strucures. They store the information 105 * pertaining to a particular usage of a fi 105 * pertaining to a particular usage of a file. The most important 106 * thing they store is the "file pointer", 106 * thing they store is the "file pointer", which holds the 107 * location in the file where the next read 107 * location in the file where the next read/write operation should 108 * start 108 * start 109 * 109 * 110 * Each process has at least 2 such opened 110 * Each process has at least 2 such opened files: its "current 111 * working directory" (RTFM chdir) and its 111 * working directory" (RTFM chdir) and its "process root" (RTFM 112 * chroot). Those are heritated across fork 112 * chroot). Those are heritated across fork() and can be changed by 113 * appropriate syscalls (resp. chdir/chroot 113 * appropriate syscalls (resp. chdir/chroot). The main "root" of 114 * the system is the process root of the "i 114 * the system is the process root of the "init" process. The usual 115 * opened files (think of open() and opendi 115 * opened files (think of open() and opendir()) are stored in the 116 * file descriptor array (fds[]). This is t 116 * file descriptor array (fds[]). This is the index in this array 117 * that is commonly called a "file descript 117 * that is commonly called a "file descriptor". 118 * 118 * 119 * 119 * 120 * The whole VFS layer comprises a series of o 120 * The whole VFS layer comprises a series of objects that can be 121 * specialized to implement different FS suppo 121 * specialized to implement different FS support (fat, ext2, ffs, ...): 122 * 122 * 123 * - The notion of "file system manager", whi 123 * - The notion of "file system manager", which basically is a 124 * container to a FS name (eg "FAT", "EXT2" 124 * container to a FS name (eg "FAT", "EXT2", etc...) and a series of 125 * functions responsible for initializing a 125 * functions responsible for initializing a particular "mounting" of 126 * a FS (the "mount" method). This is SOS's 126 * a FS (the "mount" method). This is SOS's struct sos_fs_manager_type 127 * 127 * 128 * - The notion of "file system instance" whi 128 * - The notion of "file system instance" which contains the data 129 * proper to a particular mounting of an FS 129 * proper to a particular mounting of an FS. Its most important job 130 * is to allocate new struct sos_fs_node on 130 * is to allocate new struct sos_fs_node on disk, or to retrieve the 131 * meta-information (ie struct sos_fs_node) 131 * meta-information (ie struct sos_fs_node) located at the given 132 * location on disk. This is roughly THE pr 132 * location on disk. This is roughly THE primary physical interface 133 * between the VFS and the disks. This is S 133 * between the VFS and the disks. This is SOS's struct 134 * sos_fs_manager_instance, aka the Linux's 134 * sos_fs_manager_instance, aka the Linux's superblock 135 * 135 * 136 * For each struct sos_fs_node that it allo 136 * For each struct sos_fs_node that it allocates, or that is loads 137 * from disk into memory, this "instance ma 137 * from disk into memory, this "instance manager" is responsible 138 * for inidicating the functions that imple 138 * for inidicating the functions that implement the FS-dedicated 139 * routine such as read/write/mmap/ioctl/.. 139 * routine such as read/write/mmap/ioctl/... for this precise node. 140 * 140 * 141 * The nodes (struct sos_fs_node) of a stru 141 * The nodes (struct sos_fs_node) of a struct 142 * sos_fs_manager_instance that are current 142 * sos_fs_manager_instance that are currently loaded in memory are 143 * stored in a hash-table. The key of this 143 * stored in a hash-table. The key of this map is the location of the 144 * meta-information on disk. That way, it i 144 * meta-information on disk. That way, it is very fast to look for 145 * the given meta-information whose locatio 145 * the given meta-information whose location on disk is knows: if 146 * it has already been loaded into memory, 146 * it has already been loaded into memory, its memory address is 147 * quickly resolved thanks to this hash tab 147 * quickly resolved thanks to this hash table. 148 */ 148 */ 149 149 150 #include <sos/types.h> 150 #include <sos/types.h> 151 #include <sos/errno.h> 151 #include <sos/errno.h> 152 #include <sos/hash.h> 152 #include <sos/hash.h> 153 #include <sos/umem_vmm.h> 153 #include <sos/umem_vmm.h> 154 154 155 /* Forward declarations (structures defined in 155 /* Forward declarations (structures defined in this file) */ 156 struct sos_fs_manager_type; 156 struct sos_fs_manager_type; 157 struct sos_fs_manager_instance; 157 struct sos_fs_manager_instance; 158 struct sos_fs_statfs; 158 struct sos_fs_statfs; 159 struct sos_fs_node; 159 struct sos_fs_node; 160 struct sos_fs_opened_file; 160 struct sos_fs_opened_file; 161 struct sos_fs_stat; 161 struct sos_fs_stat; 162 162 163 #include "fs_nscache.h" 163 #include "fs_nscache.h" 164 164 165 /** 165 /** 166 * The type of filesystem object. 166 * The type of filesystem object. 167 * 167 * 168 * Each struct sos_fs_node has a type. Here ar 168 * Each struct sos_fs_node has a type. Here are the supported types. 169 */ 169 */ 170 typedef enum { 170 typedef enum { 171 SOS_FS_NODE_REGULAR_FILE = 0x42, 171 SOS_FS_NODE_REGULAR_FILE = 0x42, 172 SOS_FS_NODE_DIRECTORY = 0x24, 172 SOS_FS_NODE_DIRECTORY = 0x24, 173 SOS_FS_NODE_SYMLINK = 0x84, 173 SOS_FS_NODE_SYMLINK = 0x84, >> 174 SOS_FS_NODE_DEVICE_CHAR = 0x48, 174 } sos_fs_node_type_t; 175 } sos_fs_node_type_t; 175 176 176 177 177 #define SOS_FS_MANAGER_NAME_MAXLEN 32 178 #define SOS_FS_MANAGER_NAME_MAXLEN 32 178 /** 179 /** 179 * Description of a supported Filesystem type. 180 * Description of a supported Filesystem type. 180 * 181 * 181 * These descriptions are listed in an interna 182 * These descriptions are listed in an internal list (see 182 * fs.c:fs_list), and each time we want to mou 183 * fs.c:fs_list), and each time we want to mount a FS, we precise a 183 * name (eg "FAT", "EXT2", ...). The VFS will 184 * name (eg "FAT", "EXT2", ...). The VFS will look for this name into 184 * the list of supported filesystem types, and 185 * the list of supported filesystem types, and, when found, call its 185 * sos_fs_manager_type::mount() method. 186 * sos_fs_manager_type::mount() method. 186 * 187 * 187 * New filesystem types are registered using s 188 * New filesystem types are registered using sos_fs_register_fs_type() 188 */ 189 */ 189 struct sos_fs_manager_type 190 struct sos_fs_manager_type 190 { 191 { 191 char name[SOS_FS_MANAGER_NAME_MAXLEN]; 192 char name[SOS_FS_MANAGER_NAME_MAXLEN]; 192 193 193 /** 194 /** 194 * Responsible for making sure the underlyin 195 * Responsible for making sure the underlying device (if any) really 195 * stores the correct filesystem format, for 196 * stores the correct filesystem format, for creating the hash of fs 196 * nodes and for calling sos_fs_register_fs_ 197 * nodes and for calling sos_fs_register_fs_instance 197 * 198 * 198 * @param device May be NULL 199 * @param device May be NULL 199 * 200 * 200 * @note mandatory, may block 201 * @note mandatory, may block 201 */ 202 */ 202 sos_ret_t (*mount)(struct sos_fs_manager_typ 203 sos_ret_t (*mount)(struct sos_fs_manager_type * this, 203 struct sos_fs_node * devi 204 struct sos_fs_node * device, 204 const char * args, 205 const char * args, 205 struct sos_fs_manager_ins 206 struct sos_fs_manager_instance ** mounted_fs); 206 207 207 /** 208 /** 208 * Responsible for de-allocating the hash of 209 * Responsible for de-allocating the hash of fs nodes and for 209 * calling sos_fs_unregister_fs_instance 210 * calling sos_fs_unregister_fs_instance 210 * 211 * 211 * @note mandatory, may block 212 * @note mandatory, may block 212 */ 213 */ 213 sos_ret_t (*umount)(struct sos_fs_manager_ty 214 sos_ret_t (*umount)(struct sos_fs_manager_type * this, 214 struct sos_fs_manager_in 215 struct sos_fs_manager_instance * mounted_fs); 215 216 216 /** Free of use */ 217 /** Free of use */ 217 void * custom_data; 218 void * custom_data; 218 219 219 /** List of filesystem instances of this typ 220 /** List of filesystem instances of this type currently mounted 220 somewhere in the system */ 221 somewhere in the system */ 221 struct sos_fs_manager_instance * instances; 222 struct sos_fs_manager_instance * instances; 222 223 223 /** Linkage for the list of filesystem types 224 /** Linkage for the list of filesystem types registered in the 224 system */ 225 system */ 225 struct sos_fs_manager_type *prev, *next; 226 struct sos_fs_manager_type *prev, *next; 226 }; 227 }; 227 228 228 229 229 /** 230 /** 230 * Data related to a particular "mounting" of !! 231 * Data related to a particular "mounting" of a file system. A >> 232 * so-called "superblock" under Linux 231 * 233 * 232 * This holds the FUNDAMENTAL functions respon 234 * This holds the FUNDAMENTAL functions responsible for loading struct 233 * sos_fs_node from disk, or for allocating th 235 * sos_fs_node from disk, or for allocating thom on disk. It also 234 * holds the hash-table of struct sos_fs_node 236 * holds the hash-table of struct sos_fs_node already loaded into 235 * memory. 237 * memory. 236 */ 238 */ 237 struct sos_fs_manager_instance 239 struct sos_fs_manager_instance 238 { 240 { 239 /** 241 /** 240 * @note Publicly readable. Written only by 242 * @note Publicly readable. Written only by sos_fs_manager_type::mount() 241 */ 243 */ 242 struct sos_fs_manager_type * fs_type; 244 struct sos_fs_manager_type * fs_type; 243 245 244 /** 246 /** 245 * Usually, a filesystem relies on a device 247 * Usually, a filesystem relies on a device (disk, network, ram, 246 * ...) to fetch its data. This is the locat 248 * ...) to fetch its data. This is the location of the device. 247 * 249 * 248 * @note Publicly readable. Written only by 250 * @note Publicly readable. Written only by fs.c 249 */ 251 */ 250 struct sos_fs_node * device; 252 struct sos_fs_node * device; 251 253 252 #define SOS_FS_MOUNT_SYNC (1 << 0) 254 #define SOS_FS_MOUNT_SYNC (1 << 0) 253 #define SOS_FS_MOUNT_READONLY (1 << 1) 255 #define SOS_FS_MOUNT_READONLY (1 << 1) 254 #define SOS_FS_MOUNT_NOEXEC (1 << 2) 256 #define SOS_FS_MOUNT_NOEXEC (1 << 2) 255 /** 257 /** 256 * Is this FS read-only, without EXEC file p 258 * Is this FS read-only, without EXEC file permission, write-through 257 * ? Or-red combination of the SOS_FS_MOUNT_ 259 * ? Or-red combination of the SOS_FS_MOUNT_ flags 258 * 260 * 259 * @note Publicly readable. Written only by 261 * @note Publicly readable. Written only by fs.c 260 */ 262 */ 261 sos_ui32_t flags; 263 sos_ui32_t flags; 262 264 263 /** 265 /** 264 * The namespace node that is the root of TH 266 * The namespace node that is the root of THIS file system mounting 265 * 267 * 266 * @note Publicly readable. Written only by 268 * @note Publicly readable. Written only by fs.c 267 */ 269 */ 268 struct sos_fs_nscache_node * root; 270 struct sos_fs_nscache_node * root; 269 271 270 /** 272 /** 271 * List of dirty nodes. These are the nodes 273 * List of dirty nodes. These are the nodes that need to be written 272 * back to disk. With FS supporting deferred 274 * back to disk. With FS supporting deferred-writes, the 273 * sos_fs_sync() function will use this list 275 * sos_fs_sync() function will use this list to flush the dirty 274 * nodes back to disk. 276 * nodes back to disk. 275 * 277 * 276 * @note Reserved to fs.c 278 * @note Reserved to fs.c 277 */ 279 */ 278 struct sos_fs_node * dirty_nodes; 280 struct sos_fs_node * dirty_nodes; 279 281 280 /** 282 /** 281 * Build a fresh new FS node at the given lo 283 * Build a fresh new FS node at the given location. This implies 282 * the allocation of a new sos_fs_node struc 284 * the allocation of a new sos_fs_node structure in memory 283 * 285 * 284 * @note Mandatory, may block. Appropriate l 286 * @note Mandatory, may block. Appropriate locking MUST be implemented 285 */ 287 */ 286 sos_ret_t (*fetch_node_from_disk)(struct sos 288 sos_ret_t (*fetch_node_from_disk)(struct sos_fs_manager_instance * this, 287 sos_ui64_t 289 sos_ui64_t storage_location, 288 struct sos 290 struct sos_fs_node ** result); 289 291 290 /** 292 /** 291 * Build a fresh new FS node ON THE DISK of 293 * Build a fresh new FS node ON THE DISK of the given type (dir, 292 * plain file, symlink, ...), completely emp 294 * plain file, symlink, ...), completely empty ; return a newly 293 * allocated IN-MEMORY node structure repres 295 * allocated IN-MEMORY node structure representing it 294 * 296 * 295 * @param open_creat_flags is the open_flags 297 * @param open_creat_flags is the open_flags parameter passed to 296 * sos_fs_open() when O_CREAT is set. 0 when 298 * sos_fs_open() when O_CREAT is set. 0 when allocated trough 297 * creat/mkdir/mknod/symlink 299 * creat/mkdir/mknod/symlink 298 * 300 * 299 * @note Mandatory, may block. Appropriate l 301 * @note Mandatory, may block. Appropriate locking MUST be implemented 300 */ 302 */ 301 sos_ret_t (*allocate_new_node)(struct sos_fs 303 sos_ret_t (*allocate_new_node)(struct sos_fs_manager_instance * this, 302 sos_fs_node_t 304 sos_fs_node_type_t type, 303 const struct 305 const struct sos_process * creator, 304 sos_ui32_t ac 306 sos_ui32_t access_rights, 305 sos_ui32_t op 307 sos_ui32_t open_creat_flags, 306 struct sos_fs 308 struct sos_fs_node ** result); 307 309 308 /** 310 /** 309 * Return filesystem status (RTFM df) 311 * Return filesystem status (RTFM df) 310 * 312 * 311 * @note Optional, may block. Appropriate lo 313 * @note Optional, may block. Appropriate locking MUST be implemented 312 */ 314 */ 313 sos_ret_t (*statfs)(struct sos_fs_manager_in 315 sos_ret_t (*statfs)(struct sos_fs_manager_instance * this, 314 struct sos_fs_statfs * r 316 struct sos_fs_statfs * result); 315 317 316 /** 318 /** 317 * Comparison callback called when looking f 319 * Comparison callback called when looking for file/dirs in the 318 * namespace cache. Normally, a usual lexico 320 * namespace cache. Normally, a usual lexicographical comparison is 319 * done (when this function points to NULL). 321 * done (when this function points to NULL). But for some FS, it 320 * might be useful to use another comparison 322 * might be useful to use another comparison function (eg for 321 * case-insensitive FS) 323 * case-insensitive FS) 322 * 324 * 323 * @note Optional (may be NULL), must NOT bl 325 * @note Optional (may be NULL), must NOT block 324 */ 326 */ 325 sos_bool_t (*nsnode_same_name)(const char * 327 sos_bool_t (*nsnode_same_name)(const char * name1, sos_ui16_t namelen1, 326 const char * 328 const char * name2, sos_ui16_t namelen2); 327 329 328 /** 330 /** 329 * Hash table of the struct sos_fs_node of t 331 * Hash table of the struct sos_fs_node of this filesystem instance 330 * loaded in memory: key=storage_location, e 332 * loaded in memory: key=storage_location, element=sos_fs_node 331 */ 333 */ 332 struct sos_hash_table * nodecache; 334 struct sos_hash_table * nodecache; 333 335 334 /** 336 /** 335 * Unique identifier of this FS (used in syn 337 * Unique identifier of this FS (used in sync method, updated by 336 * fs.c). This enables sync_all_fs to be res 338 * fs.c). This enables sync_all_fs to be resilient to mount/umount 337 * and (un)register_fs_type/instance 339 * and (un)register_fs_type/instance 338 */ 340 */ 339 sos_ui64_t uid; 341 sos_ui64_t uid; 340 342 341 void * custom_data; 343 void * custom_data; 342 344 343 /** Linkage for the list of instances for th 345 /** Linkage for the list of instances for the underlying fs type */ 344 struct sos_fs_manager_instance * prev, * nex 346 struct sos_fs_manager_instance * prev, * next; 345 }; 347 }; 346 348 347 349 348 /** 350 /** 349 * The CENTRAL data structure of the whole thi 351 * The CENTRAL data structure of the whole thing. A so-called "inode" 350 * 352 * 351 * This represents the meta-information relate 353 * This represents the meta-information related to a file on disk: its 352 * permission, where its data is located. Actu 354 * permission, where its data is located. Actually, in SOS, these 353 * information are not stored in this structur 355 * information are not stored in this structure. Instead, we define a 354 * series of methods in this structure that MU 356 * series of methods in this structure that MUST be implemented by the 355 * FS and that realize the higher level operat 357 * FS and that realize the higher level operations needed by the 356 * OS. These operations will rely on the meta- 358 * OS. These operations will rely on the meta-information that the FS 357 * code MUST define and manage by itself (henc 359 * code MUST define and manage by itself (hence the 358 * sos_fs_node::custom_data field). 360 * sos_fs_node::custom_data field). 359 */ 361 */ 360 struct sos_fs_node 362 struct sos_fs_node 361 { 363 { 362 /** 364 /** 363 * An struct sos_fs_node always belong to ex 365 * An struct sos_fs_node always belong to exactly ONE file system 364 */ 366 */ 365 struct sos_fs_manager_instance * fs; 367 struct sos_fs_manager_instance * fs; 366 368 367 /** 369 /** 368 * The so-called "inode": location of this n 370 * The so-called "inode": location of this node inside the FS 369 * instance. Updated by struct 371 * instance. Updated by struct 370 * sos_fs_manager_instance::fetch_node_from_ 372 * sos_fs_manager_instance::fetch_node_from_disk() 371 */ 373 */ 372 sos_ui64_t storage_location; 374 sos_ui64_t storage_location; 373 375 374 /** 376 /** 375 * Number of ON-DISK links to this node. 377 * Number of ON-DISK links to this node. 376 * 378 * 377 * - For everything but directories: the num 379 * - For everything but directories: the number of hard links to the file 378 * - For directories: 1 + the number of chil 380 * - For directories: 1 + the number of children nodes 379 * 381 * 380 * @note Publicly readable. Written only by 382 * @note Publicly readable. Written only by 381 * sos_fs_node_ops_dir::link() and sos_fs_no 383 * sos_fs_node_ops_dir::link() and sos_fs_node_ops_dir::unlink() 382 */ 384 */ 383 sos_count_t ondisk_lnk_cnt; 385 sos_count_t ondisk_lnk_cnt; 384 386 385 /** 387 /** 386 * Number of IN-MEMORY nscache_nodes referen 388 * Number of IN-MEMORY nscache_nodes referencing this FS node. 387 * 389 * 388 * Corresponds to the number of struct sos_f 390 * Corresponds to the number of struct sos_fs_nscache_node pointing 389 * to this node. This could be as much as on 391 * to this node. This could be as much as ondisk_lnk_cnt + 1, but is 390 * usually less 392 * usually less 391 * 393 * 392 * @note Reserved to fs.c 394 * @note Reserved to fs.c 393 */ 395 */ 394 sos_count_t inmem_ref_cnt; 396 sos_count_t inmem_ref_cnt; 395 397 396 /** 398 /** 397 * Directory, symlink, ... 399 * Directory, symlink, ... 398 * 400 * 399 * @see sos_fs_node_type_t 401 * @see sos_fs_node_type_t 400 * 402 * 401 * @note Publicly readable. Written only by 403 * @note Publicly readable. Written only by fs.c 402 */ 404 */ 403 sos_fs_node_type_t type; 405 sos_fs_node_type_t type; 404 406 405 #define SOS_FS_READABLE 00400 407 #define SOS_FS_READABLE 00400 406 #define SOS_FS_WRITABLE 00200 408 #define SOS_FS_WRITABLE 00200 407 #define SOS_FS_EXECUTABLE 00100 409 #define SOS_FS_EXECUTABLE 00100 408 /** 410 /** 409 * read/write, ... @see the SOS_FS_*ABLE fla 411 * read/write, ... @see the SOS_FS_*ABLE flags 410 * @note Publicly readable. Written only by 412 * @note Publicly readable. Written only by fs.c 411 */ 413 */ 412 sos_ui32_t access_rights; 414 sos_ui32_t access_rights; 413 415 414 /** 416 /** 415 * @note Reserved to fs.c 417 * @note Reserved to fs.c 416 */ 418 */ 417 sos_bool_t dirty; 419 sos_bool_t dirty; 418 420 419 /** 421 /** 420 * Incremented each time one of the opened f 422 * Incremented each time one of the opened files for this node is 421 * modified 423 * modified 422 * @note Publicly readable. Written only by 424 * @note Publicly readable. Written only by fs.c 423 */ 425 */ 424 sos_lcount_t generation; 426 sos_lcount_t generation; 425 427 >> 428 /** >> 429 * @note Available only for device files (char/block) >> 430 * @note Publicly readable. Written only by >> 431 * sos_fs_manager_instance::fetch_node_from_disk() and mknod() >> 432 */ >> 433 struct sos_fs_dev_id_t >> 434 { >> 435 sos_ui32_t device_class; /**< aka "major" */ >> 436 sos_ui32_t device_instance; /**< aka "minor" */ >> 437 } dev_id; >> 438 426 /** Operations common to all node types */ 439 /** Operations common to all node types */ 427 struct sos_fs_node_ops_file *ops_file; 440 struct sos_fs_node_ops_file *ops_file; 428 441 429 /** Operations specific to some node types * 442 /** Operations specific to some node types */ 430 union 443 union 431 { 444 { 432 /** when type == SOS_FS_NODE_DIRECTORY */ 445 /** when type == SOS_FS_NODE_DIRECTORY */ 433 struct sos_fs_node_ops_dir *ops_dir; 446 struct sos_fs_node_ops_dir *ops_dir; 434 447 435 /** when type == SOS_FS_NODE_SYMLINK */ 448 /** when type == SOS_FS_NODE_SYMLINK */ 436 struct sos_fs_node_ops_symlink *ops_symli 449 struct sos_fs_node_ops_symlink *ops_symlink; 437 }; /* Anonymous union (gcc extension) */ 450 }; /* Anonymous union (gcc extension) */ 438 451 439 452 440 /** 453 /** >> 454 * Flush any change to disk >> 455 * >> 456 * @note Mandatory, may block. Appropriate locking MUST be implemented >> 457 */ >> 458 sos_ret_t (*sync)(struct sos_fs_node *this); >> 459 >> 460 >> 461 /** 441 * Simply free this FS node from the kernel 462 * Simply free this FS node from the kernel memory: it does NOT 442 * mean that the corresponding on-disk node 463 * mean that the corresponding on-disk node is free ! Actually, the 443 * corresponding ON-DISK node is free iff on 464 * corresponding ON-DISK node is free iff ondisk_lnk_cnt == 0. No 444 * need to sync anything to disk, as the VFS 465 * need to sync anything to disk, as the VFS will sync the node 445 * before calling this method 466 * before calling this method 446 * 467 * 447 * @note Mandatory, may block, no special lo 468 * @note Mandatory, may block, no special locking needed 448 */ 469 */ 449 sos_ret_t (*destructor)(struct sos_fs_node * 470 sos_ret_t (*destructor)(struct sos_fs_node * this); 450 471 451 /** 472 /** 452 * Called when a process opens the node 473 * Called when a process opens the node 453 * 474 * 454 * @note Mandatory, may block. Appropriate l 475 * @note Mandatory, may block. Appropriate locking MUST be implemented >> 476 * @note FS-specific EXCPET for device special files (char & >> 477 * block) because they are handled in an uniform way by the >> 478 * chardev/blockdev subsystems >> 479 * @note As a consequence, FS code can safely assume that "this" is >> 480 * never a character or block device 455 */ 481 */ 456 sos_ret_t (*new_opened_file)(struct sos_fs_n 482 sos_ret_t (*new_opened_file)(struct sos_fs_node * this, 457 const struct so 483 const struct sos_process * owner, 458 sos_ui32_t open 484 sos_ui32_t open_flags, 459 struct sos_fs_o 485 struct sos_fs_opened_file ** result_of); 460 486 461 /** 487 /** 462 * Called when a process opens the node 488 * Called when a process opens the node 463 * 489 * 464 * @note Mandatory, may block. Appropriate l 490 * @note Mandatory, may block. Appropriate locking MUST be implemented >> 491 * @note FS-specific EXCEPT for device special files (char & >> 492 * block) because they are handled in an uniform way by the >> 493 * chardev/blockdev subsystems >> 494 * @note As a consequence, FS code can safely assume that "this" is >> 495 * never a character or block device 465 */ 496 */ 466 sos_ret_t (*close_opened_file)(struct sos_fs 497 sos_ret_t (*close_opened_file)(struct sos_fs_node * this, 467 struct sos_fs 498 struct sos_fs_opened_file * of); 468 499 469 /** 500 /** 470 * This should hold the meta information for 501 * This should hold the meta information for this node as needed by 471 * the FS instance. 502 * the FS instance. 472 */ 503 */ 473 void * custom_data; 504 void * custom_data; 474 505 475 /** Hash linkage entry for this FS node in t 506 /** Hash linkage entry for this FS node in the nodecache 476 dictionary */ 507 dictionary */ 477 struct sos_hash_linkage hlink_nodecache; 508 struct sos_hash_linkage hlink_nodecache; 478 509 479 /** Linkage to list the dirty nodes of the g 510 /** Linkage to list the dirty nodes of the given FS */ 480 struct sos_fs_node *prev_dirty, *next_dirty; 511 struct sos_fs_node *prev_dirty, *next_dirty; 481 }; 512 }; 482 513 483 514 484 515 485 /** 516 /** 486 * The list of methods implementing the basic 517 * The list of methods implementing the basic VFS operations on the 487 * given struct sos_fs_node 518 * given struct sos_fs_node 488 * 519 * 489 * @see sos_fs_node::ops_file 520 * @see sos_fs_node::ops_file 490 */ 521 */ 491 struct sos_fs_node_ops_file 522 struct sos_fs_node_ops_file 492 { 523 { 493 /** 524 /** 494 * Change size of file 525 * Change size of file 495 * 526 * 496 * @note Optional, may block. Appropriate lo 527 * @note Optional, may block. Appropriate locking MUST be implemented 497 */ 528 */ 498 sos_ret_t (*truncate)(struct sos_fs_node *th 529 sos_ret_t (*truncate)(struct sos_fs_node *this, 499 sos_lsoffset_t length) 530 sos_lsoffset_t length); 500 531 501 /** 532 /** 502 * Retrieve the status (eg size) of the file 533 * Retrieve the status (eg size) of the file 503 * 534 * 504 * @note Mandatory, may block. Appropriate l 535 * @note Mandatory, may block. Appropriate locking MUST be implemented 505 */ 536 */ 506 sos_ret_t (*stat)(struct sos_fs_node * this, 537 sos_ret_t (*stat)(struct sos_fs_node * this, 507 struct sos_fs_stat * resul 538 struct sos_fs_stat * result); 508 539 509 /** 540 /** 510 * Flush any change to disk << 511 * << 512 * @note Mandatory, may block. Appropriate l << 513 */ << 514 sos_ret_t (*sync)(struct sos_fs_node *this); << 515 << 516 /** << 517 * Change the sos_fs_node::access_rights att 541 * Change the sos_fs_node::access_rights attribute 518 * 542 * 519 * @note Mandatory, may block. Appropriate l 543 * @note Mandatory, may block. Appropriate locking MUST be implemented 520 */ 544 */ 521 sos_ret_t (*chmod)(struct sos_fs_node * this 545 sos_ret_t (*chmod)(struct sos_fs_node * this, 522 sos_ui32_t new_access_rig 546 sos_ui32_t new_access_rights); 523 }; 547 }; 524 548 525 549 526 /** 550 /** 527 * The list of methods implementing the basic 551 * The list of methods implementing the basic VFS symlink operations 528 * 552 * 529 * @see sos_fs_node::ops_symlink 553 * @see sos_fs_node::ops_symlink 530 */ 554 */ 531 struct sos_fs_node_ops_symlink 555 struct sos_fs_node_ops_symlink 532 { 556 { 533 /** 557 /** 534 * Used by the _kernel_ to resolve the symli 558 * Used by the _kernel_ to resolve the symlinks. To change/create a 535 * symlink target, it is needed only from us 559 * symlink target, it is needed only from userland: the read/write 536 * methods are made for this 560 * methods are made for this 537 * 561 * 538 * @param target Pointer to the string repre 562 * @param target Pointer to the string representing the target's 539 * path, allocated for the fs_node's lifetim 563 * path, allocated for the fs_node's lifetime ! 540 * 564 * 541 * @note Mandatory, may block. Appropriate l 565 * @note Mandatory, may block. Appropriate locking MUST be implemented 542 */ 566 */ 543 sos_ret_t (*expand)(struct sos_fs_node *this 567 sos_ret_t (*expand)(struct sos_fs_node *this, 544 char const ** target, 568 char const ** target, 545 sos_size_t * target_len) 569 sos_size_t * target_len); 546 }; 570 }; 547 571 548 572 549 /** 573 /** 550 * The list of methods implementing the basic 574 * The list of methods implementing the basic VFS directory operations 551 * 575 * 552 * @see sos_fs_node::ops_dir 576 * @see sos_fs_node::ops_dir 553 */ 577 */ 554 struct sos_fs_node_ops_dir 578 struct sos_fs_node_ops_dir 555 { 579 { 556 /** 580 /** 557 * Look for the on-disk location of the sos_ 581 * Look for the on-disk location of the sos_fs_node having the given 558 * name 582 * name 559 * 583 * 560 * @note Mandatory, may block. Appropriate l 584 * @note Mandatory, may block. Appropriate locking MUST be implemented 561 */ 585 */ 562 sos_ret_t (*lookup)(struct sos_fs_node *this 586 sos_ret_t (*lookup)(struct sos_fs_node *this, 563 const char * name, sos_u 587 const char * name, sos_ui16_t namelen, 564 sos_ui64_t * result_stor 588 sos_ui64_t * result_storage_location); 565 589 566 /** 590 /** 567 * Add a new reference in the current sos_fs 591 * Add a new reference in the current sos_fs_node to the on-disk 568 * location of the given sos_fs_node 592 * location of the given sos_fs_node 569 * 593 * 570 * @note Responsible for updating this->ondi 594 * @note Responsible for updating this->ondisk_lnk_cnt 571 * @note Mandatory for writable directories, 595 * @note Mandatory for writable directories, may block. Appropriate 572 * locking MUST be implemented 596 * locking MUST be implemented 573 */ 597 */ 574 sos_ret_t (*link)(struct sos_fs_node *this, 598 sos_ret_t (*link)(struct sos_fs_node *this, 575 const struct sos_process * 599 const struct sos_process *actor, 576 const char * entry_name, s 600 const char * entry_name, sos_ui16_t entry_namelen, 577 struct sos_fs_node * node) 601 struct sos_fs_node * node); 578 602 579 /** 603 /** 580 * Remove the entry in the current sos_fs_no 604 * Remove the entry in the current sos_fs_node for the on-disk 581 * location with the given name 605 * location with the given name 582 * 606 * 583 * @note Responsible for updating this->ondi 607 * @note Responsible for updating this->ondisk_lnk_cnt 584 * @note Mandatory for writable directories, 608 * @note Mandatory for writable directories, may block. Appropriate 585 * locking MUST be implemented 609 * locking MUST be implemented 586 */ 610 */ 587 sos_ret_t (*unlink)(struct sos_fs_node *this 611 sos_ret_t (*unlink)(struct sos_fs_node *this, 588 const struct sos_process 612 const struct sos_process *actor, 589 const char * entry_name, 613 const char * entry_name, sos_ui16_t entry_namelen); 590 }; 614 }; 591 615 592 616 593 /** 617 /** 594 * The data structure holding information and 618 * The data structure holding information and method related to a 595 * particular usage of a file. A so-called "st 619 * particular usage of a file. A so-called "struct file" 596 * 620 * 597 * This represents the kernel structure behind 621 * This represents the kernel structure behind a "file descriptor" or 598 * behind a chdir/chroot. Among other things, 622 * behind a chdir/chroot. Among other things, it holds the methods 599 * responsible for reading/writing into the fi 623 * responsible for reading/writing into the file, and for moving the 600 * file pointer (see @sos_fs_opened_file::posi 624 * file pointer (see @sos_fs_opened_file::position) inside it. 601 */ 625 */ 602 struct sos_fs_opened_file 626 struct sos_fs_opened_file 603 { 627 { 604 /** The process that opened the file/dir */ 628 /** The process that opened the file/dir */ 605 const struct sos_process * owner; 629 const struct sos_process * owner; 606 630 607 /** 631 /** 608 * The reference to the sos_fs_nscache_node 632 * The reference to the sos_fs_nscache_node and, hence, to the underlying sos_fs_node. 609 * 633 * 610 * Used to cache the in-memory fs nodes 634 * Used to cache the in-memory fs nodes 611 */ 635 */ 612 struct sos_fs_nscache_node * direntry; 636 struct sos_fs_nscache_node * direntry; 613 637 614 /** Use for memory-management */ 638 /** Use for memory-management */ 615 sos_count_t ref_cnt; 639 sos_count_t ref_cnt; 616 640 617 /** 641 /** 618 * Always > 0 (ie max size = 2^63-1 = 9.2 10 642 * Always > 0 (ie max size = 2^63-1 = 9.2 10^18). We make it 619 * "signed" here to limit its range. Because 643 * "signed" here to limit its range. Because we must be able to 620 * seek to the begining of the file with SEE 644 * seek to the begining of the file with SEEK_END and a negative 621 * offset, so the max size of the file must 645 * offset, so the max size of the file must be reachable by a lseek 622 * offset 646 * offset 623 * 647 * 624 * @note reserved to filesystem instance cod 648 * @note reserved to filesystem instance code. Not modified nor used 625 * by fs.c 649 * by fs.c 626 */ 650 */ 627 sos_lsoffset_t position; 651 sos_lsoffset_t position; 628 652 629 /** 653 /** 630 * Incremented each time this opened file is 654 * Incremented each time this opened file is modified 631 * 655 * 632 * Used to implement a readdir method resili 656 * Used to implement a readdir method resilient to 633 * creat/mkdir/rmdir/unlink 657 * creat/mkdir/rmdir/unlink 634 */ 658 */ 635 sos_lcount_t generation; 659 sos_lcount_t generation; 636 660 637 /** 661 /** 638 * @see SOS_FS_OPEN_* flags 662 * @see SOS_FS_OPEN_* flags 639 */ 663 */ 640 sos_ui32_t open_flags; 664 sos_ui32_t open_flags; 641 665 642 /** Operations common to all node types */ 666 /** Operations common to all node types */ 643 struct sos_fs_ops_opened_file * ops_file; 667 struct sos_fs_ops_opened_file * ops_file; 644 668 645 /** Operations specific to some node types * 669 /** Operations specific to some node types */ 646 union 670 union 647 { 671 { 648 /** when direntry->fs_node->type == SOS_FS 672 /** when direntry->fs_node->type == SOS_FS_NODE_DIRECTORY */ 649 struct sos_fs_ops_opened_dir * ops_di 673 struct sos_fs_ops_opened_dir * ops_dir; >> 674 >> 675 /** when direntry->fs_node->type == SOS_FS_NODE_DEVICE_CHAR */ >> 676 struct sos_fs_ops_opened_chardev * ops_chardev; 650 }; /* Anonymous union (gcc extension) */ 677 }; /* Anonymous union (gcc extension) */ 651 678 652 /** 679 /** 653 * Called upon fork() to duplicate all the o 680 * Called upon fork() to duplicate all the opened files >> 681 * >> 682 * @note FS-specific EXCEPT for device special files (char & >> 683 * block) because they are handled in an uniform way by the >> 684 * chardev/blockdev subsystems >> 685 * @note As a consequence, FS code can safely assume that "this" is >> 686 * never a character or block device 654 */ 687 */ 655 sos_ret_t (*duplicate)(struct sos_fs_opened_ 688 sos_ret_t (*duplicate)(struct sos_fs_opened_file *this, 656 const struct sos_proc 689 const struct sos_process * for_owner, 657 struct sos_fs_opened_ 690 struct sos_fs_opened_file **result); 658 691 659 void * custom_data; 692 void * custom_data; 660 }; 693 }; 661 694 662 695 663 /** 696 /** 664 * Reference position for sos_fs_seek 697 * Reference position for sos_fs_seek 665 */ 698 */ 666 typedef enum { SOS_SEEK_SET=42, 699 typedef enum { SOS_SEEK_SET=42, 667 SOS_SEEK_CUR=24, 700 SOS_SEEK_CUR=24, 668 SOS_SEEK_END=84 } sos_seek_when 701 SOS_SEEK_END=84 } sos_seek_whence_t; 669 /** 702 /** 670 * The list of methods implementing the basic 703 * The list of methods implementing the basic VFS opened file 671 * operations 704 * operations 672 * 705 * 673 * See the Unix manual pages, they basically f 706 * See the Unix manual pages, they basically form the interfaces to to 674 * these functions 707 * these functions 675 * 708 * 676 * @see sos_fs_opened_file::ops_file 709 * @see sos_fs_opened_file::ops_file 677 */ 710 */ 678 struct sos_fs_ops_opened_file 711 struct sos_fs_ops_opened_file 679 { 712 { 680 /** 713 /** 681 * @note Mandatory, may block. Appropriate l 714 * @note Mandatory, may block. Appropriate locking MUST be implemented 682 * @note Please call sos_fs_mark_dirty() if 715 * @note Please call sos_fs_mark_dirty() if disk contents is changed 683 */ 716 */ 684 sos_ret_t (*seek)(struct sos_fs_opened_file 717 sos_ret_t (*seek)(struct sos_fs_opened_file *this, 685 sos_lsoffset_t offset, 718 sos_lsoffset_t offset, 686 sos_seek_whence_t whence, 719 sos_seek_whence_t whence, 687 /* out */ sos_lsoffset_t * 720 /* out */ sos_lsoffset_t * result_position); 688 721 689 /** 722 /** 690 * @note Mandatory, may block. Appropriate l 723 * @note Mandatory, may block. Appropriate locking MUST be implemented 691 * @note Please call sos_fs_mark_dirty() if 724 * @note Please call sos_fs_mark_dirty() if disk contents is changed 692 */ 725 */ 693 sos_ret_t (*read)(struct sos_fs_opened_file 726 sos_ret_t (*read)(struct sos_fs_opened_file *this, 694 sos_uaddr_t dest_buf, 727 sos_uaddr_t dest_buf, 695 sos_size_t * /* in/out */l 728 sos_size_t * /* in/out */len); 696 729 697 /** 730 /** 698 * @note Optional (might be NULL), may block 731 * @note Optional (might be NULL), may block. Appropriate locking 699 * MUST be implemented 732 * MUST be implemented 700 * @note Please call sos_fs_mark_dirty() if 733 * @note Please call sos_fs_mark_dirty() if disk contents is changed 701 */ 734 */ 702 sos_ret_t (*write)(struct sos_fs_opened_file 735 sos_ret_t (*write)(struct sos_fs_opened_file *this, 703 sos_uaddr_t src_buf, 736 sos_uaddr_t src_buf, 704 sos_size_t * /* in/out */ 737 sos_size_t * /* in/out */len); 705 738 706 /** 739 /** 707 * @note Optional (might be NULL), may block 740 * @note Optional (might be NULL), may block. Appropriate locking 708 * MUST be implemented 741 * MUST be implemented 709 * @note Please call sos_fs_mark_dirty() if 742 * @note Please call sos_fs_mark_dirty() if disk contents is changed 710 */ 743 */ 711 sos_ret_t (*mmap)(struct sos_fs_opened_file 744 sos_ret_t (*mmap)(struct sos_fs_opened_file *this, 712 sos_uaddr_t *uaddr, sos_si 745 sos_uaddr_t *uaddr, sos_size_t size, 713 sos_ui32_t access_rights, 746 sos_ui32_t access_rights, 714 sos_ui32_t flags, 747 sos_ui32_t flags, 715 sos_luoffset_t offset); 748 sos_luoffset_t offset); 716 749 717 /** 750 /** 718 * @note Optional (might be NULL), may block 751 * @note Optional (might be NULL), may block. Appropriate locking 719 * MUST be implemented 752 * MUST be implemented 720 * @note Please call sos_fs_mark_dirty() if 753 * @note Please call sos_fs_mark_dirty() if disk contents is changed 721 */ 754 */ 722 sos_ret_t (*fcntl)(struct sos_fs_opened_file 755 sos_ret_t (*fcntl)(struct sos_fs_opened_file *this, 723 int req_id, 756 int req_id, 724 sos_ui32_t req_arg /* Usu 757 sos_ui32_t req_arg /* Usually: sos_uaddr_t */); 725 }; 758 }; 726 759 727 760 >> 761 /** >> 762 * The list of methods implementing the basic VFS opened character device >> 763 * operations >> 764 * >> 765 * @see sos_fs_opened_file::ops_file >> 766 */ >> 767 struct sos_fs_ops_opened_chardev >> 768 { >> 769 /** >> 770 * @note Optional (might be NULL), may block. Appropriate locking >> 771 * MUST be implemented >> 772 * @note Please call sos_fs_mark_dirty() if disk contents is changed >> 773 */ >> 774 sos_ret_t (*ioctl)(struct sos_fs_opened_file *this, >> 775 int req_id, >> 776 sos_ui32_t req_arg /* Usually: sos_uaddr_t */); >> 777 }; >> 778 >> 779 728 /** Data structure that is to be filled by rea 780 /** Data structure that is to be filled by readdir */ 729 struct sos_fs_dirent 781 struct sos_fs_dirent 730 { 782 { 731 sos_ui64_t storage_location; 783 sos_ui64_t storage_location; 732 sos_si64_t offset_in_dirfile; 784 sos_si64_t offset_in_dirfile; 733 sos_ui32_t type; 785 sos_ui32_t type; 734 sos_ui16_t namelen; 786 sos_ui16_t namelen; 735 787 736 #define SOS_FS_DIRENT_NAME_MAXLEN 128 788 #define SOS_FS_DIRENT_NAME_MAXLEN 128 737 char name[SOS_FS_DIRENT_NAME_MAXLEN]; 789 char name[SOS_FS_DIRENT_NAME_MAXLEN]; 738 }; 790 }; 739 791 740 792 741 /** 793 /** 742 * The list of methods implementing the basic 794 * The list of methods implementing the basic VFS opened directory 743 * operations 795 * operations 744 * 796 * 745 * @see sos_fs_opened_file::ops_file 797 * @see sos_fs_opened_file::ops_file 746 */ 798 */ 747 struct sos_fs_ops_opened_dir 799 struct sos_fs_ops_opened_dir 748 { 800 { 749 /** 801 /** 750 * Each time it is called, responsible for f 802 * Each time it is called, responsible for filling the sos_fs_dirent 751 * structure, return -SOS_ENOENT when done. 803 * structure, return -SOS_ENOENT when done. 752 * 804 * 753 * @note Mandatory, may block. Appropriate l 805 * @note Mandatory, may block. Appropriate locking MUST be implemented 754 * @note Please call sos_fs_mark_dirty() if 806 * @note Please call sos_fs_mark_dirty() if disk contents is changed 755 */ 807 */ 756 sos_ret_t (*readdir)(struct sos_fs_opened_fi 808 sos_ret_t (*readdir)(struct sos_fs_opened_file *this, 757 struct sos_fs_dirent * 809 struct sos_fs_dirent * result); 758 }; 810 }; 759 811 760 812 761 813 762 /** 814 /** 763 * Used by the stat calls 815 * Used by the stat calls 764 * 816 * 765 * @see sos_fs_node_ops_file::stat 817 * @see sos_fs_node_ops_file::stat 766 */ 818 */ 767 struct sos_fs_stat 819 struct sos_fs_stat 768 { 820 { >> 821 struct sos_fs_dev_id_t st_rdev; 769 sos_fs_node_type_t st_type; 822 sos_fs_node_type_t st_type; 770 sos_ui64_t st_storage_location; 823 sos_ui64_t st_storage_location; 771 sos_ui32_t st_access_rights; 824 sos_ui32_t st_access_rights; 772 sos_count_t st_nlink; 825 sos_count_t st_nlink; 773 sos_si64_t st_size; 826 sos_si64_t st_size; 774 }; 827 }; 775 828 776 829 777 /** 830 /** 778 * Used by the statvfs calls 831 * Used by the statvfs calls 779 * 832 * 780 * @see sos_fs_manager_instance::statfs 833 * @see sos_fs_manager_instance::statfs 781 */ 834 */ 782 struct sos_fs_statfs 835 struct sos_fs_statfs 783 { 836 { >> 837 struct sos_fs_dev_id_t f_rdev; 784 sos_size_t f_sz_total; /**< Tot 838 sos_size_t f_sz_total; /**< Total size */ 785 sos_size_t f_sz_free; /**< Siz 839 sos_size_t f_sz_free; /**< Size left on device */ 786 sos_count_t f_node_total;/**< Tot 840 sos_count_t f_node_total;/**< Total allocatable FS nodes */ 787 sos_count_t f_node_avail;/**< Num 841 sos_count_t f_node_avail;/**< Number of available free FS nodes */ 788 sos_ui32_t f_flags; 842 sos_ui32_t f_flags; 789 }; 843 }; 790 844 791 845 792 /** 846 /** 793 * Must be called AFTER the FS manager types n 847 * Must be called AFTER the FS manager types needed to mount the root 794 * filesystem have been registered 848 * filesystem have been registered 795 */ 849 */ 796 sos_ret_t sos_fs_subsystem_setup(const char * 850 sos_ret_t sos_fs_subsystem_setup(const char * root_device, 797 const char * 851 const char * fs_type, 798 const char * 852 const char * mount_args, 799 struct sos_fs 853 struct sos_fs_manager_instance ** result_rootfs); 800 854 801 855 802 /* ****************************************** 856 /* *************************************************************** 803 * The Following functions are relatively stan 857 * The Following functions are relatively standard 804 * 858 * 805 * @see Unix manual pages for details 859 * @see Unix manual pages for details 806 */ 860 */ 807 861 808 862 809 /** 863 /** 810 * mount a file system 864 * mount a file system 811 * 865 * 812 * @param actor process calling mount 866 * @param actor process calling mount 813 * @param _src_path(len) may be NULL (as for v 867 * @param _src_path(len) may be NULL (as for virtfs or /proc) 814 * @fsname the name of the filesystem type to 868 * @fsname the name of the filesystem type to mount 815 * @args any args passed to the sos_fs_manager 869 * @args any args passed to the sos_fs_manager_type::mount method 816 * @result_fs the resulting filesystem instanc 870 * @result_fs the resulting filesystem instance 817 */ 871 */ 818 sos_ret_t sos_fs_mount(struct sos_process * ac 872 sos_ret_t sos_fs_mount(struct sos_process * actor, 819 const char * _src_path, 873 const char * _src_path, 820 sos_size_t _src_pathlen 874 sos_size_t _src_pathlen, 821 const char * _dst_path, 875 const char * _dst_path, 822 sos_size_t _dst_pathlen 876 sos_size_t _dst_pathlen, 823 const char * fsname, 877 const char * fsname, 824 sos_ui32_t mountflags, 878 sos_ui32_t mountflags, 825 const char * args, 879 const char * args, 826 struct sos_fs_manager_i 880 struct sos_fs_manager_instance ** /*out*/result_fs); 827 881 828 /** 882 /** 829 * unmount the filesystem at the given locatio 883 * unmount the filesystem at the given location 830 */ 884 */ 831 sos_ret_t sos_fs_umount(struct sos_process * a 885 sos_ret_t sos_fs_umount(struct sos_process * actor, 832 const char * _mountpoi 886 const char * _mountpoint_path, 833 sos_size_t _mountpoint 887 sos_size_t _mountpoint_pathlen); 834 888 835 /** 889 /** 836 * Flush all the dirty nodes of all the FS to 890 * Flush all the dirty nodes of all the FS to disk 837 */ 891 */ 838 sos_ret_t sos_fs_sync_all_fs(); 892 sos_ret_t sos_fs_sync_all_fs(); 839 893 840 /** 894 /** 841 * Retrieve filesystem status, or return -SOS_ !! 895 * Retrieve filesystem status, or return -SOS_ENOSYS if filesystem 842 * cannot report this 896 * cannot report this 843 */ 897 */ 844 sos_ret_t sos_fs_vfstat(const struct sos_proce 898 sos_ret_t sos_fs_vfstat(const struct sos_process * actor, 845 const char * _path, 899 const char * _path, 846 sos_size_t _pathlen, 900 sos_size_t _pathlen, 847 struct sos_fs_statfs * 901 struct sos_fs_statfs * result); 848 902 849 /** 903 /** 850 * Open flags 904 * Open flags 851 */ 905 */ 852 #define SOS_FS_OPEN_EXCL (1 << 0) 906 #define SOS_FS_OPEN_EXCL (1 << 0) 853 #define SOS_FS_OPEN_CREAT (1 << 1) 907 #define SOS_FS_OPEN_CREAT (1 << 1) 854 #define SOS_FS_OPEN_NOFOLLOW (1 << 2) !! 908 #define SOS_FS_OPEN_TRUNC (1 << 2) 855 #define SOS_FS_OPEN_DIRECTORY (1 << 3) /* In !! 909 #define SOS_FS_OPEN_NOFOLLOW (1 << 3) 856 #define SOS_FS_OPEN_SYNC (1 << 4) !! 910 #define SOS_FS_OPEN_DIRECTORY (1 << 4) /* Incompatible with CREAT/TRUNC */ 857 #define SOS_FS_OPEN_KEEPONEXEC (1 << 5) /* By !! 911 #define SOS_FS_OPEN_SYNC (1 << 5) 858 up !! 912 #define SOS_FS_OPEN_CLOSEONEXEC (1 << 6) /* By default, files are kept >> 913 open upon an exec() */ 859 914 860 #define SOS_FS_OPEN_READ (1 << 16) 915 #define SOS_FS_OPEN_READ (1 << 16) 861 #define SOS_FS_OPEN_WRITE (1 << 17) 916 #define SOS_FS_OPEN_WRITE (1 << 17) 862 917 863 918 864 /** 919 /** 865 * FS access rights 920 * FS access rights 866 */ 921 */ 867 #define SOS_FS_S_IRUSR 00400 922 #define SOS_FS_S_IRUSR 00400 868 #define SOS_FS_S_IWUSR 00200 923 #define SOS_FS_S_IWUSR 00200 869 #define SOS_FS_S_IXUSR 00100 924 #define SOS_FS_S_IXUSR 00100 870 925 871 #define SOS_FS_S_IRWXALL 07777 /* For symlinks 926 #define SOS_FS_S_IRWXALL 07777 /* For symlinks */ 872 927 873 sos_ret_t sos_fs_open(const struct sos_process 928 sos_ret_t sos_fs_open(const struct sos_process *owner, 874 const char *_path, 929 const char *_path, 875 sos_size_t _pathlen, 930 sos_size_t _pathlen, 876 sos_ui32_t open_flags, 931 sos_ui32_t open_flags, 877 sos_ui32_t creat_access_ 932 sos_ui32_t creat_access_rights, 878 struct sos_fs_opened_fil 933 struct sos_fs_opened_file ** of); 879 934 880 sos_ret_t sos_fs_close(struct sos_fs_opened_fi 935 sos_ret_t sos_fs_close(struct sos_fs_opened_file * of); 881 936 882 sos_ret_t sos_fs_read(struct sos_fs_opened_fil 937 sos_ret_t sos_fs_read(struct sos_fs_opened_file * of, 883 sos_uaddr_t dest_buf, 938 sos_uaddr_t dest_buf, 884 sos_size_t * /* in/ou */ 939 sos_size_t * /* in/ou */len); 885 940 886 sos_ret_t sos_fs_readdir(struct sos_fs_opened_ 941 sos_ret_t sos_fs_readdir(struct sos_fs_opened_file * of, 887 struct sos_fs_dirent 942 struct sos_fs_dirent * result); 888 943 889 sos_ret_t sos_fs_write(struct sos_fs_opened_fi 944 sos_ret_t sos_fs_write(struct sos_fs_opened_file * of, 890 sos_uaddr_t src_buf, 945 sos_uaddr_t src_buf, 891 sos_size_t * /* in/out 946 sos_size_t * /* in/out */len); 892 947 893 sos_ret_t sos_fs_seek(struct sos_fs_opened_fil 948 sos_ret_t sos_fs_seek(struct sos_fs_opened_file *of, 894 sos_lsoffset_t offset, 949 sos_lsoffset_t offset, 895 sos_seek_whence_t whence 950 sos_seek_whence_t whence, 896 sos_lsoffset_t * result_ 951 sos_lsoffset_t * result_position); 897 952 898 sos_ret_t sos_fs_ftruncate(struct sos_fs_opene 953 sos_ret_t sos_fs_ftruncate(struct sos_fs_opened_file *of, 899 sos_lsoffset_t leng 954 sos_lsoffset_t length); 900 955 901 sos_ret_t sos_fs_mmap(struct sos_fs_opened_fil 956 sos_ret_t sos_fs_mmap(struct sos_fs_opened_file *of, 902 sos_uaddr_t *uaddr, sos_ 957 sos_uaddr_t *uaddr, sos_size_t size, 903 sos_ui32_t access_rights 958 sos_ui32_t access_rights, 904 sos_ui32_t flags, 959 sos_ui32_t flags, 905 sos_luoffset_t offset); 960 sos_luoffset_t offset); 906 961 907 sos_ret_t sos_fs_fsync(struct sos_fs_opened_fi 962 sos_ret_t sos_fs_fsync(struct sos_fs_opened_file * of); 908 963 909 sos_ret_t sos_fs_fcntl(struct sos_fs_opened_fi 964 sos_ret_t sos_fs_fcntl(struct sos_fs_opened_file *of, 910 int req_id, 965 int req_id, 911 sos_ui32_t req_arg /* U 966 sos_ui32_t req_arg /* Usually: sos_uaddr_t */); 912 967 >> 968 sos_ret_t sos_fs_ioctl(struct sos_fs_opened_file *of, >> 969 int req_id, >> 970 sos_ui32_t req_arg /* Usually: sos_uaddr_t */); >> 971 913 sos_ret_t sos_fs_creat(const struct sos_proces 972 sos_ret_t sos_fs_creat(const struct sos_process * creator, 914 const char * _path, 973 const char * _path, 915 sos_size_t _pathlen, 974 sos_size_t _pathlen, 916 sos_ui32_t access_right 975 sos_ui32_t access_rights); 917 976 918 sos_ret_t sos_fs_link(const struct sos_process 977 sos_ret_t sos_fs_link(const struct sos_process * creator, 919 const char * _old_path, 978 const char * _old_path, 920 sos_size_t _old_pathlen, 979 sos_size_t _old_pathlen, 921 const char * _dest_path, 980 const char * _dest_path, 922 sos_size_t _dest_pathlen 981 sos_size_t _dest_pathlen); 923 982 924 sos_ret_t sos_fs_rename(const struct sos_proce 983 sos_ret_t sos_fs_rename(const struct sos_process * creator, 925 const char * _old_path 984 const char * _old_path, 926 sos_size_t _old_pathle 985 sos_size_t _old_pathlen, 927 const char * _dest_pat 986 const char * _dest_path, 928 sos_size_t _dest_pathl 987 sos_size_t _dest_pathlen); 929 988 930 sos_ret_t sos_fs_unlink(const struct sos_proce 989 sos_ret_t sos_fs_unlink(const struct sos_process * actor, 931 const char * _path, 990 const char * _path, 932 sos_size_t _pathlen); 991 sos_size_t _pathlen); 933 992 934 sos_ret_t sos_fs_symlink(const struct sos_proc 993 sos_ret_t sos_fs_symlink(const struct sos_process * creator, 935 const char * _path, 994 const char * _path, 936 sos_size_t _pathlen, 995 sos_size_t _pathlen, 937 sos_uaddr_t symlink_t 996 sos_uaddr_t symlink_target, 938 sos_size_t symlink_ta 997 sos_size_t symlink_target_len); >> 998 >> 999 sos_ret_t sos_fs_mknod(const struct sos_process * creator, >> 1000 const char * _path, >> 1001 sos_size_t _pathlen, >> 1002 sos_fs_node_type_t type /* only block/char allowed */, >> 1003 sos_ui32_t access_rights, >> 1004 const struct sos_fs_dev_id_t * devid); 939 1005 940 sos_ret_t sos_fs_mkdir(const struct sos_proces 1006 sos_ret_t sos_fs_mkdir(const struct sos_process * creator, 941 const char * _path, 1007 const char * _path, 942 sos_size_t _pathlen, 1008 sos_size_t _pathlen, 943 sos_ui32_t access_right 1009 sos_ui32_t access_rights); 944 1010 945 sos_ret_t sos_fs_rmdir(const struct sos_proces 1011 sos_ret_t sos_fs_rmdir(const struct sos_process * actor, 946 const char * _path, 1012 const char * _path, 947 sos_size_t _pathlen); 1013 sos_size_t _pathlen); 948 1014 949 sos_ret_t sos_fs_chmod(const struct sos_proces 1015 sos_ret_t sos_fs_chmod(const struct sos_process * actor, 950 const char * _path, 1016 const char * _path, 951 sos_size_t _pathlen, 1017 sos_size_t _pathlen, 952 sos_ui32_t access_right 1018 sos_ui32_t access_rights); 953 1019 954 sos_ret_t sos_fs_stat(const struct sos_process 1020 sos_ret_t sos_fs_stat(const struct sos_process * actor, 955 const char * _path, 1021 const char * _path, 956 sos_size_t _pathlen, 1022 sos_size_t _pathlen, 957 int nofollow, 1023 int nofollow, 958 struct sos_fs_stat * res 1024 struct sos_fs_stat * result); 959 1025 960 1026 961 /* ******************************************* 1027 /* *************************************************************** 962 * Restricted functions reserved to FS code an 1028 * Restricted functions reserved to FS code and block/char devices 963 */ 1029 */ 964 1030 965 /** 1031 /** 966 * Function to be called when proposing a new 1032 * Function to be called when proposing a new File system type 967 */ 1033 */ 968 sos_ret_t sos_fs_register_fs_type(struct sos_f 1034 sos_ret_t sos_fs_register_fs_type(struct sos_fs_manager_type * fstype); 969 sos_ret_t sos_fs_unregister_fs_type(struct sos 1035 sos_ret_t sos_fs_unregister_fs_type(struct sos_fs_manager_type * fstype); 970 1036 971 /** 1037 /** 972 * Marthe given file as dirty, for FS supporti 1038 * Marthe given file as dirty, for FS supporting deferred write access 973 * mode 1039 * mode 974 */ 1040 */ 975 sos_ret_t sos_fs_mark_dirty(struct sos_fs_open 1041 sos_ret_t sos_fs_mark_dirty(struct sos_fs_opened_file * of); 976 1042 977 /** 1043 /** 978 * Helper function to be called from the mount 1044 * Helper function to be called from the mount() method of the FS 979 * instance code. Responsible for creating and 1045 * instance code. Responsible for creating and updating the "root" 980 * field of the FS instance structure and for 1046 * field of the FS instance structure and for connecting this FS in 981 * the nscache 1047 * the nscache 982 * @param root_fsnode The root of the FS being 1048 * @param root_fsnode The root of the FS being mounted 983 */ 1049 */ 984 sos_ret_t sos_fs_register_fs_instance(struct s 1050 sos_ret_t sos_fs_register_fs_instance(struct sos_fs_manager_instance * fs, 985 struct s 1051 struct sos_fs_node * root_fsnode); 986 1052 987 /** 1053 /** 988 * Helper function to be called from the umoun 1054 * Helper function to be called from the umount() method of the FS 989 * instance code. Responsible for unregisterin 1055 * instance code. Responsible for unregistering the instance from the 990 * FS type's instances list and for disconnect 1056 * FS type's instances list and for disconnecting this mountpoint in 991 * the nscache. 1057 * the nscache. 992 */ 1058 */ 993 sos_ret_t sos_fs_unregister_fs_instance(struct 1059 sos_ret_t sos_fs_unregister_fs_instance(struct sos_fs_manager_instance * fs); 994 1060 995 1061 996 /* ******************************************* 1062 /* *************************************************************** 997 * Restricted functions reserved to syscall.c 1063 * Restricted functions reserved to syscall.c 998 */ 1064 */ 999 sos_ret_t sos_fs_ref_opened_file(struct sos_fs 1065 sos_ret_t sos_fs_ref_opened_file(struct sos_fs_opened_file * of); 1000 sos_ret_t _sos_fs_unref_opened_file(struct so 1066 sos_ret_t _sos_fs_unref_opened_file(struct sos_fs_opened_file ** of); 1001 #define sos_fs_unref_opened_file(f) _sos_fs_u 1067 #define sos_fs_unref_opened_file(f) _sos_fs_unref_opened_file(&(f)) 1002 1068 1003 1069 1004 /* ****************************************** 1070 /* *************************************************************** 1005 * Restricted functions to be used only by fs 1071 * Restricted functions to be used only by fs_nscache.c 1006 */ 1072 */ 1007 1073 1008 sos_ret_t sos_fs_ref_fsnode(struct sos_fs_nod 1074 sos_ret_t sos_fs_ref_fsnode(struct sos_fs_node * fsnode); 1009 1075 1010 sos_ret_t _sos_fs_unref_fsnode(struct sos_fs_ 1076 sos_ret_t _sos_fs_unref_fsnode(struct sos_fs_node * fsnode); 1011 #define sos_fs_unref_fsnode(n) \ 1077 #define sos_fs_unref_fsnode(n) \ 1012 ({ sos_ret_t __retval = _sos_fs_unref_fsnod 1078 ({ sos_ret_t __retval = _sos_fs_unref_fsnode(n); (n)=NULL; __retval; }) 1013 1079 1014 1080 1015 /* ****************************************** 1081 /* *************************************************************** 1016 * Restricted functions reserved to process.c 1082 * Restricted functions reserved to process.c and main.c:start_init() 1017 */ 1083 */ 1018 sos_ret_t sos_fs_new_opened_file(const struct 1084 sos_ret_t sos_fs_new_opened_file(const struct sos_process * proc, 1019 struct sos_f 1085 struct sos_fs_nscache_node * nsnode, 1020 sos_ui32_t o 1086 sos_ui32_t open_flags, 1021 struct sos_f 1087 struct sos_fs_opened_file ** result_of); 1022 1088 1023 1089 1024 sos_ret_t sos_fs_duplicate_opened_file(struct 1090 sos_ret_t sos_fs_duplicate_opened_file(struct sos_fs_opened_file * src_of, 1025 const 1091 const struct sos_process * dst_proc, 1026 struct 1092 struct sos_fs_opened_file ** result_of); 1027 1093 1028 1094 1029 1095 1030 #endif /* _SOS_FS_H_ */ 1096 #endif /* _SOS_FS_H_ */
[ source navigation ] | [ diff markup ] | [ identifier search ] | [ general search ] |