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