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,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 ]