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