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 
003    This program is free software; you can redistribute it and/or
004    modify it under the terms of the GNU General Public License
005    as published by the Free Software Foundation; either version 2
006    of the License, or (at your option) any later version.
007 
008    This program is distributed in the hope that it will be useful,
009    but WITHOUT ANY WARRANTY; without even the implied warranty of
010    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
011    GNU General Public License for more details.
012 
013    You should have received a copy of the GNU General Public License
014    along with this program; if not, write to the Free Software
015    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
016    USA.
017 */
018 #ifndef _SOS_BLKDEV_H_
019 #define _SOS_BLKDEV_H_
020 
021 /**
022  * @file blkdev.h
023  *
024  * Interface between the VFS and the "block" devices (real devices and
025  * their partitions). The following functions provide the mechanisms
026  * to bind the "block device" nodes (@see mknod) to their device
027  * driver.
028  *
029  * The "blkdev" layer is to be perceived as a FS-agnostic layer both
030  * below and on top of the FS that binds the special "block device"
031  * nodes to a set of system-wide block_read/block_write functions and
032  * which supports the cache of blocks for the device.
033  *
034  * The differences between the char device and the block device layers are:
035  * - A character device is byte-stream-oriented: one can easily fetch
036  *   the data character by character. Theoretically, this stream has
037  *   no limitation in size: it has a beginning but not necessarly an
038  *   end. One can not necessarly rewind the stream, that is seek
039  *   anywhere in it (as for a stream of audio data coming from a
040  *   soundcard for example). But for some character devices, it is
041  *   possible, though (it is possible to seek anywhere in /dev/zero
042  *   for example). For some other devices, it is possible to seek only
043  *   in some authorized regions (as for /dev/kmem for example: only
044  *   the mapped kernel regions are available).
045  * - A block device is block-oriented: one can easily fetch fixed-size
046  *   blocks of data anywhere inside the device, possibly in a random
047  *   order. The capacity of the device is limited: there is a defined
048  *   number of contiguous blocks reachable in the device, one cannot
049  *   seek beyond its limits.
050  * - A block device is well suited to a cache layer: it is possible to
051  *   cache the most used blocks inside memory to speed up the accesses
052  *   to data. It doesn't make sense to do so on stream-oriented devices
053  *   like character devices.
054  * - A character device is limited to the interaction between
055  *   user-mode programs and the devices themselves. The kernel only acts
056  *   as an intermediary and does not take care of the operations
057  *   carried out.
058  * - A block device is used as the underlying data support for a
059  *   filesystem. As a result, it must be managed by the kernel itself
060  *   since the FS code resides inside the kernel. It must offer an API
061  *   compatible with kernel-space interaction.
062  *
063  * A partition has the same properties as a disk: both are block
064  * devices. The main difference is that a disk really "owns" its
065  * operations (ie the read/write/ioctl operations are defined by him)
066  * and its block cache, whereas a partition shares them with its
067  * parent disk/partition. The partitions may be nested: a disk can
068  * have partitions, which can have sub-partitions, which can have
069  * sub-sub-partittions, etc. As a consequence, a parent disk/partition
070  * cannot be unregistered as long as it owns any child partitions. The
071  * only constraint being that the partitions must fit completely
072  * inside their parent partition/disk. However, no check is made
073  * regarding partitions overlapping one another...
074  *
075  * This implementation is based on two subsystems:
076  * - the block cache to accelerate accesses to the hardware by caching
077  *   the most frequently used blocks in main memory
078  * - the page cache to guarantee consistency between read/write
079  *   accesses and MMU access of mapped pages (mmap API). This is a
080  *   simple dictionary of the device's mapped pages: offset -> mapped
081  *   page. The read/write vs MMU consistency is achieved in a simple
082  *   manner: before each read/write accesses, we first try to use the
083  *   page cache, and eventually the block cache if the data is not
084  *   mapped by anybody.
085  */
086 
087 /* Forward declaration */
088 struct sos_blockdev_instance;
089 
090 #include <sos/fs.h>
091 
092 /**
093  * The fundamental callbacks for a real block device (ie not a
094  * partition).
095  */
096 struct sos_blockdev_operations {
097 
098   /** @note MANDATORY */
099   sos_ret_t (*read_block)(void * blockdev_instance_custom_data,
100                           sos_vaddr_t dest_buf /* Kernel address */,
101                           sos_luoffset_t block_offset);
102 
103 
104   /** @note Optional (may be NULL) */
105   sos_ret_t (*write_block)(void * blockdev_instance_custom_data,
106                            sos_vaddr_t src_buf /* Kernel address */,
107                            sos_luoffset_t block_offset);
108 
109 
110   /**
111    * @note Optional (may be NULL)
112    * @note Also called when an ioctl is made to a partition
113    */
114   sos_ret_t (*ioctl)(void * blockdev_instance_custom_data,
115                      int req_id,
116                      sos_ui32_t req_arg /* Usually: sos_uaddr_t */);
117 };
118 
119 
120 /*
121  * Functions restricted to block device driver code
122  */
123 
124 
125 sos_ret_t sos_blockdev_subsystem_setup(void);
126 
127 
128 /**
129  * Contrary to Character devices, block devices are registered
130  * individually: any single registration corresponds to a driver for a
131  * single device instance
132  */
133 sos_ret_t
134 sos_blockdev_register_disk (sos_ui32_t     device_class,
135                             sos_ui32_t     device_instance,
136                             sos_size_t     block_size,
137                             sos_lcount_t   number_of_blocks,
138                             sos_count_t    cache_size_in_blocks,
139                             struct sos_blockdev_operations * blockdev_ops,
140                             void * blockdev_instance_custom_data);
141 
142 
143 /**
144  * @param index_of_first_block is the index of the first block
145  * relative to parent_bd, NOT relative to the top-most disk block
146  * device
147  */
148 sos_ret_t
149 sos_blockdev_register_partition(sos_ui32_t device_class,
150                                 sos_ui32_t device_instance,
151                                 struct sos_blockdev_instance * parent_bd,
152                                 sos_luoffset_t index_of_first_block,
153                                 sos_lcount_t number_of_blocks,
154                                 void * blockdev_instance_custom_data);
155 
156 
157 sos_ret_t sos_blockdev_unregister_device (sos_ui32_t device_class,
158                                           sos_ui32_t device_instance);
159 
160 
161 /**
162  * Flush all caches of all devices to disk
163  */
164 sos_ret_t sos_blockdev_sync_all_devices(void);
165 
166 
167 /**
168  * Increments the instance's reference counter: this will make any
169  * blockdev_unregister return BUSY. As a consequence, the following
170  * operations on blockdev instances should be as fast as possible and
171  * call release_instance as early as possible
172  */
173 struct sos_blockdev_instance *
174 sos_blockdev_ref_instance(sos_ui32_t device_class,
175                           sos_ui32_t device_instance);
176 
177 
178 sos_ret_t
179 sos_blockdev_release_instance(struct sos_blockdev_instance * blockdev);
180 
181 
182 /** Read data from disk and use it directly in the kernel. Mostly used
183     by the partition drivers to identify the partitions of a disk and
184     register them */
185 sos_ret_t sos_blockdev_kernel_read(struct sos_blockdev_instance * blockdev,
186                                    sos_luoffset_t offset,
187                                    sos_vaddr_t dest_buf,
188                                    sos_size_t * /* in/out */len);
189 
190 
191 /**
192  * Write data to disk directly from the kernel. Mostly used by the
193  * partition drivers to modify the partitions of a disk and register
194  * them.
195  *
196  * @note The operation is normally NOT needed (fdisk is a userspace
197  * program) and is NOT synchronous
198  */
199 sos_ret_t sos_blockdev_kernel_write(struct sos_blockdev_instance * blockdev,
200                                     sos_luoffset_t offset,
201                                     sos_vaddr_t src_buf,
202                                     sos_size_t * /* in/out */len);
203 
204 
205 /**
206  * Flush the modified blocks back to hardware (both block and page
207  * cache are flusehd)
208  */
209 sos_ret_t sos_blockdev_sync(struct sos_blockdev_instance * blockdev);
210 
211 
212 /*
213  * Callbacks and functions restricted to fs.c internals
214  */
215 
216 /**
217  * Update the FS node ops_blockdev callbacks after an FS
218  * allocate_new_node or fetch_node_from_disk, in order to point to
219  * the block layer API functions
220  */
221 sos_ret_t sos_blockdev_helper_ref_new_fsnode(struct sos_fs_node * this);
222 sos_ret_t sos_blockdev_helper_release_fsnode(struct sos_fs_node * this);
223 sos_ret_t sos_blockdev_helper_sync_fsnode(struct sos_fs_node * this);
224 
225 #endif

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