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

source navigation ] diff markup ] identifier search ] general search ]