SimpleOS

LXR

Navigation



Site hébergé par : enix

The LXR Cross Referencer for SOS

source navigation ]
diff markup ]
identifier search ]
general search ]
 
 
Article:1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 6.5 ] [ 7 ] [ 7.5 ] [ 8 ] [ 9 ] [ 9.5 ]

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 ]