|
[ 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 (struct 059 * 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 (ie size, permissions) is located at sector 64589 on 068 * disk. By retrieving this meta information directly from disk, we 069 * can build the struct sos_fs_node, which would (for example) tell 070 * that the corresponding file spans (for example) over sectors 071 * 4345, 5645, 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_type_t; 175 176 177 #define SOS_FS_MANAGER_NAME_MAXLEN 32 178 /** 179 * Description of a supported Filesystem type. 180 * 181 * These descriptions are listed in an internal list (see 182 * fs.c:fs_list), and each time we want to mount a FS, we precise a 183 * name (eg "FAT", "EXT2", ...). The VFS will look for this name into 184 * the list of supported filesystem types, and, when found, call its 185 * sos_fs_manager_type::mount() method. 186 * 187 * New filesystem types are registered using sos_fs_register_fs_type() 188 */ 189 struct sos_fs_manager_type 190 { 191 char name[SOS_FS_MANAGER_NAME_MAXLEN]; 192 193 /** 194 * Responsible for making sure the underlying device (if any) really 195 * stores the correct filesystem format, for creating the hash of fs 196 * nodes and for calling sos_fs_register_fs_instance 197 * 198 * @param device May be NULL 199 * 200 * @note mandatory, may block 201 */ 202 sos_ret_t (*mount)(struct sos_fs_manager_type * this, 203 struct sos_fs_node * device, 204 const char * args, 205 struct sos_fs_manager_instance ** mounted_fs); 206 207 /** 208 * Responsible for de-allocating the hash of fs nodes and for 209 * calling sos_fs_unregister_fs_instance 210 * 211 * @note mandatory, may block 212 */ 213 sos_ret_t (*umount)(struct sos_fs_manager_type * this, 214 struct sos_fs_manager_instance * mounted_fs); 215 216 /** Free of use */ 217 void * custom_data; 218 219 /** List of filesystem instances of this type currently mounted 220 somewhere in the system */ 221 struct sos_fs_manager_instance * instances; 222 223 /** Linkage for the list of filesystem types registered in the 224 system */ 225 struct sos_fs_manager_type *prev, *next; 226 }; 227 228 229 /** 230 * Data related to a particular "mounting" of a file system. A so-called "superblock" under Linux 231 * 232 * This holds the FUNDAMENTAL functions responsible for loading struct 233 * sos_fs_node from disk, or for allocating thom on disk. It also 234 * holds the hash-table of struct sos_fs_node already loaded into 235 * memory. 236 */ 237 struct sos_fs_manager_instance 238 { 239 /** 240 * @note Publicly readable. Written only by sos_fs_manager_type::mount() 241 */ 242 struct sos_fs_manager_type * fs_type; 243 244 /** 245 * Usually, a filesystem relies on a device (disk, network, ram, 246 * ...) to fetch its data. This is the location of the device. 247 * 248 * @note Publicly readable. Written only by fs.c 249 */ 250 struct sos_fs_node * device; 251 252 #define SOS_FS_MOUNT_SYNC (1 << 0) 253 #define SOS_FS_MOUNT_READONLY (1 << 1) 254 #define SOS_FS_MOUNT_NOEXEC (1 << 2) 255 /** 256 * Is this FS read-only, without EXEC file permission, write-through 257 * ? Or-red combination of the SOS_FS_MOUNT_ flags 258 * 259 * @note Publicly readable. Written only by fs.c 260 */ 261 sos_ui32_t flags; 262 263 /** 264 * The namespace node that is the root of THIS file system mounting 265 * 266 * @note Publicly readable. Written only by fs.c 267 */ 268 struct sos_fs_nscache_node * root; 269 270 /** 271 * List of dirty nodes. These are the nodes that need to be written 272 * back to disk. With FS supporting deferred-writes, the 273 * sos_fs_sync() function will use this list to flush the dirty 274 * nodes back to disk. 275 * 276 * @note Reserved to fs.c 277 */ 278 struct sos_fs_node * dirty_nodes; 279 280 /** 281 * Build a fresh new FS node at the given location. This implies 282 * the allocation of a new sos_fs_node structure in memory 283 * 284 * @note Mandatory, may block. Appropriate locking MUST be implemented 285 */ 286 sos_ret_t (*fetch_node_from_disk)(struct sos_fs_manager_instance * this, 287 sos_ui64_t storage_location, 288 struct sos_fs_node ** result); 289 290 /** 291 * Build a fresh new FS node ON THE DISK of the given type (dir, 292 * plain file, symlink, ...), completely empty ; return a newly 293 * allocated IN-MEMORY node structure representing it 294 * 295 * @param open_creat_flags is the open_flags parameter passed to 296 * sos_fs_open() when O_CREAT is set. 0 when allocated trough 297 * creat/mkdir/mknod/symlink 298 * 299 * @note Mandatory, may block. Appropriate locking MUST be implemented 300 */ 301 sos_ret_t (*allocate_new_node)(struct sos_fs_manager_instance * this, 302 sos_fs_node_type_t type, 303 const struct sos_process * creator, 304 sos_ui32_t access_rights, 305 sos_ui32_t open_creat_flags, 306 struct sos_fs_node ** result); 307 308 /** 309 * Return filesystem status (RTFM df) 310 * 311 * @note Optional, may block. Appropriate locking MUST be implemented 312 */ 313 sos_ret_t (*statfs)(struct sos_fs_manager_instance * this, 314 struct sos_fs_statfs * result); 315 316 /** 317 * Comparison callback called when looking for file/dirs in the 318 * namespace cache. Normally, a usual lexicographical comparison is 319 * done (when this function points to NULL). But for some FS, it 320 * might be useful to use another comparison function (eg for 321 * case-insensitive FS) 322 * 323 * @note Optional (may be NULL), must NOT block 324 */ 325 sos_bool_t (*nsnode_same_name)(const char * name1, sos_ui16_t namelen1, 326 const char * name2, sos_ui16_t namelen2); 327 328 /** 329 * Hash table of the struct sos_fs_node of this filesystem instance 330 * loaded in memory: key=storage_location, element=sos_fs_node 331 */ 332 struct sos_hash_table * nodecache; 333 334 /** 335 * Unique identifier of this FS (used in sync method, updated by 336 * fs.c). This enables sync_all_fs to be resilient to mount/umount 337 * and (un)register_fs_type/instance 338 */ 339 sos_ui64_t uid; 340 341 void * custom_data; 342 343 /** Linkage for the list of instances for the underlying fs type */ 344 struct sos_fs_manager_instance * prev, * next; 345 }; 346 347 348 /** 349 * The CENTRAL data structure of the whole thing. A so-called "inode" 350 * 351 * This represents the meta-information related to a file on disk: its 352 * permission, where its data is located. Actually, in SOS, these 353 * information are not stored in this structure. Instead, we define a 354 * series of methods in this structure that MUST be implemented by the 355 * FS and that realize the higher level operations needed by the 356 * OS. These operations will rely on the meta-information that the FS 357 * code MUST define and manage by itself (hence the 358 * sos_fs_node::custom_data field). 359 */ 360 struct sos_fs_node 361 { 362 /** 363 * An struct sos_fs_node always belong to exactly ONE file system 364 */ 365 struct sos_fs_manager_instance * fs; 366 367 /** 368 * The so-called "inode": location of this node inside the FS 369 * instance. Updated by struct 370 * sos_fs_manager_instance::fetch_node_from_disk() 371 */ 372 sos_ui64_t storage_location; 373 374 /** 375 * Number of ON-DISK links to this node. 376 * 377 * - For everything but directories: the number of hard links to the file 378 * - For directories: 1 + the number of children nodes 379 * 380 * @note Publicly readable. Written only by 381 * sos_fs_node_ops_dir::link() and sos_fs_node_ops_dir::unlink() 382 */ 383 sos_count_t ondisk_lnk_cnt; 384 385 /** 386 * Number of IN-MEMORY nscache_nodes referencing this FS node. 387 * 388 * Corresponds to the number of struct sos_fs_nscache_node pointing 389 * to this node. This could be as much as ondisk_lnk_cnt + 1, but is 390 * usually less 391 * 392 * @note Reserved to fs.c 393 */ 394 sos_count_t inmem_ref_cnt; 395 396 /** 397 * Directory, symlink, ... 398 * 399 * @see sos_fs_node_type_t 400 * 401 * @note Publicly readable. Written only by fs.c 402 */ 403 sos_fs_node_type_t type; 404 405 #define SOS_FS_READABLE 00400 406 #define SOS_FS_WRITABLE 00200 407 #define SOS_FS_EXECUTABLE 00100 408 /** 409 * read/write, ... @see the SOS_FS_*ABLE flags 410 * @note Publicly readable. Written only by fs.c 411 */ 412 sos_ui32_t access_rights; 413 414 /** 415 * @note Reserved to fs.c 416 */ 417 sos_bool_t dirty; 418 419 /** 420 * Incremented each time one of the opened files for this node is 421 * modified 422 * @note Publicly readable. Written only by fs.c 423 */ 424 sos_lcount_t generation; 425 426 /** Operations common to all node types */ 427 struct sos_fs_node_ops_file *ops_file; 428 429 /** Operations specific to some node types */ 430 union 431 { 432 /** when type == SOS_FS_NODE_DIRECTORY */ 433 struct sos_fs_node_ops_dir *ops_dir; 434 435 /** when type == SOS_FS_NODE_SYMLINK */ 436 struct sos_fs_node_ops_symlink *ops_symlink; 437 }; /* Anonymous union (gcc extension) */ 438 439 440 /** 441 * Simply free this FS node from the kernel memory: it does NOT 442 * mean that the corresponding on-disk node is free ! Actually, the 443 * corresponding ON-DISK node is free iff ondisk_lnk_cnt == 0. No 444 * need to sync anything to disk, as the VFS will sync the node 445 * before calling this method 446 * 447 * @note Mandatory, may block, no special locking needed 448 */ 449 sos_ret_t (*destructor)(struct sos_fs_node * this); 450 451 /** 452 * Called when a process opens the node 453 * 454 * @note Mandatory, may block. Appropriate locking MUST be implemented 455 */ 456 sos_ret_t (*new_opened_file)(struct sos_fs_node * this, 457 const struct sos_process * owner, 458 sos_ui32_t open_flags, 459 struct sos_fs_opened_file ** result_of); 460 461 /** 462 * Called when a process opens the node 463 * 464 * @note Mandatory, may block. Appropriate locking MUST be implemented 465 */ 466 sos_ret_t (*close_opened_file)(struct sos_fs_node * this, 467 struct sos_fs_opened_file * of); 468 469 /** 470 * This should hold the meta information for this node as needed by 471 * the FS instance. 472 */ 473 void * custom_data; 474 475 /** Hash linkage entry for this FS node in the nodecache 476 dictionary */ 477 struct sos_hash_linkage hlink_nodecache; 478 479 /** Linkage to list the dirty nodes of the given FS */ 480 struct sos_fs_node *prev_dirty, *next_dirty; 481 }; 482 483 484 485 /** 486 * The list of methods implementing the basic VFS operations on the 487 * given struct sos_fs_node 488 * 489 * @see sos_fs_node::ops_file 490 */ 491 struct sos_fs_node_ops_file 492 { 493 /** 494 * Change size of file 495 * 496 * @note Optional, may block. Appropriate locking MUST be implemented 497 */ 498 sos_ret_t (*truncate)(struct sos_fs_node *this, 499 sos_lsoffset_t length); 500 501 /** 502 * Retrieve the status (eg size) of the file 503 * 504 * @note Mandatory, may block. Appropriate locking MUST be implemented 505 */ 506 sos_ret_t (*stat)(struct sos_fs_node * this, 507 struct sos_fs_stat * result); 508 509 /** 510 * Flush any change to disk 511 * 512 * @note Mandatory, may block. Appropriate locking MUST be implemented 513 */ 514 sos_ret_t (*sync)(struct sos_fs_node *this); 515 516 /** 517 * Change the sos_fs_node::access_rights attribute 518 * 519 * @note Mandatory, may block. Appropriate locking MUST be implemented 520 */ 521 sos_ret_t (*chmod)(struct sos_fs_node * this, 522 sos_ui32_t new_access_rights); 523 }; 524 525 526 /** 527 * The list of methods implementing the basic VFS symlink operations 528 * 529 * @see sos_fs_node::ops_symlink 530 */ 531 struct sos_fs_node_ops_symlink 532 { 533 /** 534 * Used by the _kernel_ to resolve the symlinks. To change/create a 535 * symlink target, it is needed only from userland: the read/write 536 * methods are made for this 537 * 538 * @param target Pointer to the string representing the target's 539 * path, allocated for the fs_node's lifetime ! 540 * 541 * @note Mandatory, may block. Appropriate locking MUST be implemented 542 */ 543 sos_ret_t (*expand)(struct sos_fs_node *this, 544 char const ** target, 545 sos_size_t * target_len); 546 }; 547 548 549 /** 550 * The list of methods implementing the basic VFS directory operations 551 * 552 * @see sos_fs_node::ops_dir 553 */ 554 struct sos_fs_node_ops_dir 555 { 556 /** 557 * Look for the on-disk location of the sos_fs_node having the given 558 * name 559 * 560 * @note Mandatory, may block. Appropriate locking MUST be implemented 561 */ 562 sos_ret_t (*lookup)(struct sos_fs_node *this, 563 const char * name, sos_ui16_t namelen, 564 sos_ui64_t * result_storage_location); 565 566 /** 567 * Add a new reference in the current sos_fs_node to the on-disk 568 * location of the given sos_fs_node 569 * 570 * @note Responsible for updating this->ondisk_lnk_cnt 571 * @note Mandatory for writable directories, may block. Appropriate 572 * locking MUST be implemented 573 */ 574 sos_ret_t (*link)(struct sos_fs_node *this, 575 const struct sos_process *actor, 576 const char * entry_name, sos_ui16_t entry_namelen, 577 struct sos_fs_node * node); 578 579 /** 580 * Remove the entry in the current sos_fs_node for the on-disk 581 * location with the given name 582 * 583 * @note Responsible for updating this->ondisk_lnk_cnt 584 * @note Mandatory for writable directories, may block. Appropriate 585 * locking MUST be implemented 586 */ 587 sos_ret_t (*unlink)(struct sos_fs_node *this, 588 const struct sos_process *actor, 589 const char * entry_name, sos_ui16_t entry_namelen); 590 }; 591 592 593 /** 594 * The data structure holding information and method related to a 595 * particular usage of a file. A so-called "struct file" 596 * 597 * This represents the kernel structure behind a "file descriptor" or 598 * behind a chdir/chroot. Among other things, it holds the methods 599 * responsible for reading/writing into the file, and for moving the 600 * file pointer (see @sos_fs_opened_file::position) inside it. 601 */ 602 struct sos_fs_opened_file 603 { 604 /** The process that opened the file/dir */ 605 const struct sos_process * owner; 606 607 /** 608 * The reference to the sos_fs_nscache_node and, hence, to the underlying sos_fs_node. 609 * 610 * Used to cache the in-memory fs nodes 611 */ 612 struct sos_fs_nscache_node * direntry; 613 614 /** Use for memory-management */ 615 sos_count_t ref_cnt; 616 617 /** 618 * Always > 0 (ie max size = 2^63-1 = 9.2 10^18). We make it 619 * "signed" here to limit its range. Because we must be able to 620 * seek to the begining of the file with SEEK_END and a negative 621 * offset, so the max size of the file must be reachable by a lseek 622 * offset 623 * 624 * @note reserved to filesystem instance code. Not modified nor used 625 * by fs.c 626 */ 627 sos_lsoffset_t position; 628 629 /** 630 * Incremented each time this opened file is modified 631 * 632 * Used to implement a readdir method resilient to 633 * creat/mkdir/rmdir/unlink 634 */ 635 sos_lcount_t generation; 636 637 /** 638 * @see SOS_FS_OPEN_* flags 639 */ 640 sos_ui32_t open_flags; 641 642 /** Operations common to all node types */ 643 struct sos_fs_ops_opened_file * ops_file; 644 645 /** Operations specific to some node types */ 646 union 647 { 648 /** when direntry->fs_node->type == SOS_FS_NODE_DIRECTORY */ 649 struct sos_fs_ops_opened_dir * ops_dir; 650 }; /* Anonymous union (gcc extension) */ 651 652 /** 653 * Called upon fork() to duplicate all the opened files 654 */ 655 sos_ret_t (*duplicate)(struct sos_fs_opened_file *this, 656 const struct sos_process * for_owner, 657 struct sos_fs_opened_file **result); 658 659 void * custom_data; 660 }; 661 662 663 /** 664 * Reference position for sos_fs_seek 665 */ 666 typedef enum { SOS_SEEK_SET=42, 667 SOS_SEEK_CUR=24, 668 SOS_SEEK_END=84 } sos_seek_whence_t; 669 /** 670 * The list of methods implementing the basic VFS opened file 671 * operations 672 * 673 * See the Unix manual pages, they basically form the interfaces to to 674 * these functions 675 * 676 * @see sos_fs_opened_file::ops_file 677 */ 678 struct sos_fs_ops_opened_file 679 { 680 /** 681 * @note Mandatory, may block. Appropriate locking MUST be implemented 682 * @note Please call sos_fs_mark_dirty() if disk contents is changed 683 */ 684 sos_ret_t (*seek)(struct sos_fs_opened_file *this, 685 sos_lsoffset_t offset, 686 sos_seek_whence_t whence, 687 /* out */ sos_lsoffset_t * result_position); 688 689 /** 690 * @note Mandatory, may block. Appropriate locking MUST be implemented 691 * @note Please call sos_fs_mark_dirty() if disk contents is changed 692 */ 693 sos_ret_t (*read)(struct sos_fs_opened_file *this, 694 sos_uaddr_t dest_buf, 695 sos_size_t * /* in/out */len); 696 697 /** 698 * @note Optional (might be NULL), may block. Appropriate locking 699 * MUST be implemented 700 * @note Please call sos_fs_mark_dirty() if disk contents is changed 701 */ 702 sos_ret_t (*write)(struct sos_fs_opened_file *this, 703 sos_uaddr_t src_buf, 704 sos_size_t * /* in/out */len); 705 706 /** 707 * @note Optional (might be NULL), may block. Appropriate locking 708 * MUST be implemented 709 * @note Please call sos_fs_mark_dirty() if disk contents is changed 710 */ 711 sos_ret_t (*mmap)(struct sos_fs_opened_file *this, 712 sos_uaddr_t *uaddr, sos_size_t size, 713 sos_ui32_t access_rights, 714 sos_ui32_t flags, 715 sos_luoffset_t offset); 716 717 /** 718 * @note Optional (might be NULL), may block. Appropriate locking 719 * MUST be implemented 720 * @note Please call sos_fs_mark_dirty() if disk contents is changed 721 */ 722 sos_ret_t (*fcntl)(struct sos_fs_opened_file *this, 723 int req_id, 724 sos_ui32_t req_arg /* Usually: sos_uaddr_t */); 725 }; 726 727 728 /** Data structure that is to be filled by readdir */ 729 struct sos_fs_dirent 730 { 731 sos_ui64_t storage_location; 732 sos_si64_t offset_in_dirfile; 733 sos_ui32_t type; 734 sos_ui16_t namelen; 735 736 #define SOS_FS_DIRENT_NAME_MAXLEN 128 737 char name[SOS_FS_DIRENT_NAME_MAXLEN]; 738 }; 739 740 741 /** 742 * The list of methods implementing the basic VFS opened directory 743 * operations 744 * 745 * @see sos_fs_opened_file::ops_file 746 */ 747 struct sos_fs_ops_opened_dir 748 { 749 /** 750 * Each time it is called, responsible for filling the sos_fs_dirent 751 * structure, return -SOS_ENOENT when done. 752 * 753 * @note Mandatory, may block. Appropriate locking MUST be implemented 754 * @note Please call sos_fs_mark_dirty() if disk contents is changed 755 */ 756 sos_ret_t (*readdir)(struct sos_fs_opened_file *this, 757 struct sos_fs_dirent * result); 758 }; 759 760 761 762 /** 763 * Used by the stat calls 764 * 765 * @see sos_fs_node_ops_file::stat 766 */ 767 struct sos_fs_stat 768 { 769 sos_fs_node_type_t st_type; 770 sos_ui64_t st_storage_location; 771 sos_ui32_t st_access_rights; 772 sos_count_t st_nlink; 773 sos_si64_t st_size; 774 }; 775 776 777 /** 778 * Used by the statvfs calls 779 * 780 * @see sos_fs_manager_instance::statfs 781 */ 782 struct sos_fs_statfs 783 { 784 sos_size_t f_sz_total; /**< Total size */ 785 sos_size_t f_sz_free; /**< Size left on device */ 786 sos_count_t f_node_total;/**< Total allocatable FS nodes */ 787 sos_count_t f_node_avail;/**< Number of available free FS nodes */ 788 sos_ui32_t f_flags; 789 }; 790 791 792 /** 793 * Must be called AFTER the FS manager types needed to mount the root 794 * filesystem have been registered 795 */ 796 sos_ret_t sos_fs_subsystem_setup(const char * root_device, 797 const char * fs_type, 798 const char * mount_args, 799 struct sos_fs_manager_instance ** result_rootfs); 800 801 802 /* *************************************************************** 803 * The Following functions are relatively standard 804 * 805 * @see Unix manual pages for details 806 */ 807 808 809 /** 810 * mount a file system 811 * 812 * @param actor process calling mount 813 * @param _src_path(len) may be NULL (as for virtfs or /proc) 814 * @fsname the name of the filesystem type to mount 815 * @args any args passed to the sos_fs_manager_type::mount method 816 * @result_fs the resulting filesystem instance 817 */ 818 sos_ret_t sos_fs_mount(struct sos_process * actor, 819 const char * _src_path, 820 sos_size_t _src_pathlen, 821 const char * _dst_path, 822 sos_size_t _dst_pathlen, 823 const char * fsname, 824 sos_ui32_t mountflags, 825 const char * args, 826 struct sos_fs_manager_instance ** /*out*/result_fs); 827 828 /** 829 * unmount the filesystem at the given location 830 */ 831 sos_ret_t sos_fs_umount(struct sos_process * actor, 832 const char * _mountpoint_path, 833 sos_size_t _mountpoint_pathlen); 834 835 /** 836 * Flush all the dirty nodes of all the FS to disk 837 */ 838 sos_ret_t sos_fs_sync_all_fs(); 839 840 /** 841 * Retrieve filesystem status, or return -SOS_ENOSUP if filesystem 842 * cannot report this 843 */ 844 sos_ret_t sos_fs_vfstat(const struct sos_process * actor, 845 const char * _path, 846 sos_size_t _pathlen, 847 struct sos_fs_statfs * result); 848 849 /** 850 * Open flags 851 */ 852 #define SOS_FS_OPEN_EXCL (1 << 0) 853 #define SOS_FS_OPEN_CREAT (1 << 1) 854 #define SOS_FS_OPEN_NOFOLLOW (1 << 2) 855 #define SOS_FS_OPEN_DIRECTORY (1 << 3) /* Incompatible with CREAT */ 856 #define SOS_FS_OPEN_SYNC (1 << 4) 857 #define SOS_FS_OPEN_KEEPONEXEC (1 << 5) /* By default, files are closed 858 upon an exec() */ 859 860 #define SOS_FS_OPEN_READ (1 << 16) 861 #define SOS_FS_OPEN_WRITE (1 << 17) 862 863 864 /** 865 * FS access rights 866 */ 867 #define SOS_FS_S_IRUSR 00400 868 #define SOS_FS_S_IWUSR 00200 869 #define SOS_FS_S_IXUSR 00100 870 871 #define SOS_FS_S_IRWXALL 07777 /* For symlinks */ 872 873 sos_ret_t sos_fs_open(const struct sos_process *owner, 874 const char *_path, 875 sos_size_t _pathlen, 876 sos_ui32_t open_flags, 877 sos_ui32_t creat_access_rights, 878 struct sos_fs_opened_file ** of); 879 880 sos_ret_t sos_fs_close(struct sos_fs_opened_file * of); 881 882 sos_ret_t sos_fs_read(struct sos_fs_opened_file * of, 883 sos_uaddr_t dest_buf, 884 sos_size_t * /* in/ou */len); 885 886 sos_ret_t sos_fs_readdir(struct sos_fs_opened_file * of, 887 struct sos_fs_dirent * result); 888 889 sos_ret_t sos_fs_write(struct sos_fs_opened_file * of, 890 sos_uaddr_t src_buf, 891 sos_size_t * /* in/out */len); 892 893 sos_ret_t sos_fs_seek(struct sos_fs_opened_file *of, 894 sos_lsoffset_t offset, 895 sos_seek_whence_t whence, 896 sos_lsoffset_t * result_position); 897 898 sos_ret_t sos_fs_ftruncate(struct sos_fs_opened_file *of, 899 sos_lsoffset_t length); 900 901 sos_ret_t sos_fs_mmap(struct sos_fs_opened_file *of, 902 sos_uaddr_t *uaddr, sos_size_t size, 903 sos_ui32_t access_rights, 904 sos_ui32_t flags, 905 sos_luoffset_t offset); 906 907 sos_ret_t sos_fs_fsync(struct sos_fs_opened_file * of); 908 909 sos_ret_t sos_fs_fcntl(struct sos_fs_opened_file *of, 910 int req_id, 911 sos_ui32_t req_arg /* Usually: sos_uaddr_t */); 912 913 sos_ret_t sos_fs_creat(const struct sos_process * creator, 914 const char * _path, 915 sos_size_t _pathlen, 916 sos_ui32_t access_rights); 917 918 sos_ret_t sos_fs_link(const struct sos_process * creator, 919 const char * _old_path, 920 sos_size_t _old_pathlen, 921 const char * _dest_path, 922 sos_size_t _dest_pathlen); 923 924 sos_ret_t sos_fs_rename(const struct sos_process * creator, 925 const char * _old_path, 926 sos_size_t _old_pathlen, 927 const char * _dest_path, 928 sos_size_t _dest_pathlen); 929 930 sos_ret_t sos_fs_unlink(const struct sos_process * actor, 931 const char * _path, 932 sos_size_t _pathlen); 933 934 sos_ret_t sos_fs_symlink(const struct sos_process * creator, 935 const char * _path, 936 sos_size_t _pathlen, 937 sos_uaddr_t symlink_target, 938 sos_size_t symlink_target_len); 939 940 sos_ret_t sos_fs_mkdir(const struct sos_process * creator, 941 const char * _path, 942 sos_size_t _pathlen, 943 sos_ui32_t access_rights); 944 945 sos_ret_t sos_fs_rmdir(const struct sos_process * actor, 946 const char * _path, 947 sos_size_t _pathlen); 948 949 sos_ret_t sos_fs_chmod(const struct sos_process * actor, 950 const char * _path, 951 sos_size_t _pathlen, 952 sos_ui32_t access_rights); 953 954 sos_ret_t sos_fs_stat(const struct sos_process * actor, 955 const char * _path, 956 sos_size_t _pathlen, 957 int nofollow, 958 struct sos_fs_stat * result); 959 960 961 /* *************************************************************** 962 * Restricted functions reserved to FS code and block/char devices 963 */ 964 965 /** 966 * Function to be called when proposing a new File system type 967 */ 968 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_fs_manager_type * fstype); 970 971 /** 972 * Marthe given file as dirty, for FS supporting deferred write access 973 * mode 974 */ 975 sos_ret_t sos_fs_mark_dirty(struct sos_fs_opened_file * of); 976 977 /** 978 * Helper function to be called from the mount() method of the FS 979 * instance code. Responsible for creating and updating the "root" 980 * field of the FS instance structure and for connecting this FS in 981 * the nscache 982 * @param root_fsnode The root of the FS being mounted 983 */ 984 sos_ret_t sos_fs_register_fs_instance(struct sos_fs_manager_instance * fs, 985 struct sos_fs_node * root_fsnode); 986 987 /** 988 * Helper function to be called from the umount() method of the FS 989 * instance code. Responsible for unregistering the instance from the 990 * FS type's instances list and for disconnecting this mountpoint in 991 * the nscache. 992 */ 993 sos_ret_t sos_fs_unregister_fs_instance(struct sos_fs_manager_instance * fs); 994 995 996 /* *************************************************************** 997 * Restricted functions reserved to syscall.c 998 */ 999 sos_ret_t sos_fs_ref_opened_file(struct sos_fs_opened_file * of); 1000 sos_ret_t _sos_fs_unref_opened_file(struct sos_fs_opened_file ** of); 1001 #define sos_fs_unref_opened_file(f) _sos_fs_unref_opened_file(&(f)) 1002 1003 1004 /* *************************************************************** 1005 * Restricted functions to be used only by fs_nscache.c 1006 */ 1007 1008 sos_ret_t sos_fs_ref_fsnode(struct sos_fs_node * fsnode); 1009 1010 sos_ret_t _sos_fs_unref_fsnode(struct sos_fs_node * fsnode); 1011 #define sos_fs_unref_fsnode(n) \ 1012 ({ sos_ret_t __retval = _sos_fs_unref_fsnode(n); (n)=NULL; __retval; }) 1013 1014 1015 /* *************************************************************** 1016 * Restricted functions reserved to process.c and main.c:start_init() 1017 */ 1018 sos_ret_t sos_fs_new_opened_file(const struct sos_process * proc, 1019 struct sos_fs_nscache_node * nsnode, 1020 sos_ui32_t open_flags, 1021 struct sos_fs_opened_file ** result_of); 1022 1023 1024 sos_ret_t sos_fs_duplicate_opened_file(struct sos_fs_opened_file * src_of, 1025 const struct sos_process * dst_proc, 1026 struct sos_fs_opened_file ** result_of); 1027 1028 1029 1030 #endif /* _SOS_FS_H_ */
[ source navigation ] | [ diff markup ] | [ identifier search ] | [ general search ] |