source: trunk/kernel/mm/mapper.h @ 606

Last change on this file since 606 was 606, checked in by alain, 5 years ago

Improve the FAT32 file system to support cat, rm, cp commands.

File size: 13.9 KB
RevLine 
[1]1/*
[606]2 * mapper.h - Kernel cache for FS files or directories definition.
[1]3 *
4 * Authors   Mohamed Lamine Karaoui (2015)
[440]5 *           Alain Greiner (2016,2017,2018)
[1]6 *
7 * Copyright (c)  UPMC Sorbonne Universites
8 *
9 * This file is part of ALMOS-MKH.
10 *
11 * ALMOS-MKH is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; version 2.0 of the License.
14 *
15 * ALMOS-MKH is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18 * General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with ALMOS-MKH; if not, write to the Free Software Foundation,
22 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25#ifndef _MAPPER_H_
26#define _MAPPER_H_
27
[457]28#include <hal_kernel_types.h>
[1]29#include <hal_atomic.h>
30#include <xlist.h>
31#include <grdxt.h>
32#include <rwlock.h>
33
34/****  Forward declarations ****/
35
36struct page_s;
37struct vfs_inode_s;
38
39/*******************************************************************************************
[18]40 * The mapper implements the kernel cache for a given file or directory.
[23]41 * There is one mapper per file/dir. It is implemented as a three levels radix tree,
[1]42 * entirely stored in the same cluster as the inode representing the file/dir.
[18]43 * - The fast retrieval key is the page index in the file.
[1]44 *   The ix1_width, ix2_width, ix3_width sub-indexes are configuration parameters.
45 * - The leaves are pointers on physical page descriptors, dynamically allocated
46 *   in the local cluster.
47 * - In a given cluster, a mapper is a "private" structure: a thread accessing the mapper
48 *   must be running in the cluster containing it (can be a local thread or a RPC thread).
49 * - The mapper is protected by a blocking "rwlock", to support several simultaneous
50 *   readers, and only one writer. This lock implement a busy waiting policy.
[246]51 * - The mapper_get_page() function that return a page descriptor pointer from a page
52 *   index in file is in charge of handling the miss on the mapper cache.
[265]53 * - The vfs_mapper_move_page() function access the file system to handle a mapper miss,
[246]54 *   or update a dirty page on device.
[265]55 * - The vfs_mapper_load_all() functions is used to load all pages of a given file
56 *   or directory into the mapper.
57 * - the mapper_move_user() function is used to move data to or from an user buffer.
[238]58 *   This user space buffer can be physically distributed in several clusters.
[313]59 * - the mapper_move_kernel() function is used to move data to or from a remote kernel
60 *   buffer, that can be physically located in any cluster.
[246]61 * - In the present implementation the cache size for a given file increases on demand,
62 *   and the  allocated memory is only released when the mapper/inode is destroyed.
[1]63 ******************************************************************************************/
64
65
66/*******************************************************************************************
67 * This structure defines the mapper descriptor.
68 ******************************************************************************************/
69
70typedef struct mapper_s
71{
[23]72        struct vfs_inode_s * inode;           /*! owner inode                                     */
[246]73    uint32_t             type;        /*! file system type                                */
[606]74        grdxt_t              rt;              /*! embedded pages cache descriptor (radix tree)    */
75        remote_rwlock_t      lock;        /*! several readers / only one writer               */
[1]76        uint32_t                 refcount;    /*! several vsegs can refer the same file           */
77        xlist_entry_t        vsegs_root;  /*! root of list of vsegs refering this mapper      */
78        xlist_entry_t        wait_root;   /*! root of list of threads waiting on mapper       */
79    list_entry_t         dirty_root;  /*! root of list of dirty pages                     */
80}
81mapper_t;
82
83/*******************************************************************************************
84 * This structure defines a "fragment". It is used to move data between the kernel mapper,
85 * and an user buffer, that can be split in several distributed physical pages located
86 * in different clusters. A fragment is a set of contiguous bytes in the file.
[18]87 * - It can be stored in one single physical page in the user buffer.
[1]88 * - It can spread two successive physical pages in the kernel mapper.
89 ******************************************************************************************/
90
91typedef struct fragment_s
92{
93    uint32_t    file_offset;         /*! offset of fragment in file (i.e. in mapper)      */
94    uint32_t    size;                /*! number of bytes in fragment                      */
95    cxy_t       buf_cxy;             /*! user buffer cluster identifier                   */
[23]96    void      * buf_ptr;             /*! local pointer on first byte in user buffer       */
[1]97}
98fragment_t;
99
100/*******************************************************************************************
[18]101 * This function allocates physical memory for a mapper descriptor, and initializes it
[1]102 * (refcount <= 0) / inode <= NULL).
103 * It must be executed by a thread running in the cluster containing the mapper.
104 *******************************************************************************************
[513]105 * @ type   : type of the mapper to create.
106 * @ return : pointer on created mapper if success / return NULL if no memory
[1]107 ******************************************************************************************/
[513]108mapper_t * mapper_create( vfs_fs_type_t type );
[1]109
110/*******************************************************************************************
[606]111 * This function releases all physical memory allocated for a mapper.
112 * Both the mapper descriptor and the radix tree are released.
113 * It does NOT synchronize dirty pages. Use the vfs_sync_inode() function if required.
[1]114 * It must be executed by a thread running in the cluster containing the mapper.
115 *******************************************************************************************
116 * @ mapper      : target mapper.
117 ******************************************************************************************/
[606]118void mapper_destroy( mapper_t * mapper );
[1]119
120/*******************************************************************************************
[606]121 * This function load from device a missing page identified by the <page_id> argument
122 * into the mapper identified by the <mapper> local pointer.
123 * It allocates a physical page from the local cluster, initialise by accessing device,
124 * and register the page in the mapper radix tree.
125 * It must be executed by a thread running in the cluster containing the mapper.
126 * WARNING : the calling function mapper_remote_get_page() is supposed to take and release
127 * the lock protecting the mapper in WRITE_MODE.
128 *******************************************************************************************
129 * @ mapper      : [in]  target mapper.
130 * @ page_id : [in]  missing page index in file.
131 * @ page_xp : [out] buffer for extended pointer on missing page descriptor.
132 * @ return 0 if success / return -1 if a dirty page cannot be updated on device.
133 ******************************************************************************************/
134error_t mapper_handle_miss( mapper_t * mapper,
135                            uint32_t   page_id,
136                            xptr_t   * page_xp );
137
138/*******************************************************************************************
139 * This function move data between a local mapper, and a distributed user buffer.
140 * It must be called by a thread running in cluster containing the mapper.
141 * It is called by the vfs_user_move() to implement sys_read() and sys_write() syscalls.
[313]142 * If required, the data transfer is split in "fragments", where one fragment contains
[265]143 * contiguous bytes in the same mapper page.
[313]144 * It uses "hal_uspace" accesses to move a fragment to/from the user buffer.
[1]145 * In case of write, the dirty bit is set for all pages written in the mapper.
[606]146 * The mapper being an extendable cache, it is automatically extended when required
147 * for both read and write accesses.
148 * The "offset" field in the file descriptor, and the "size" field in inode descriptor
149 * are not modified by this function.
[1]150 *******************************************************************************************
[265]151 * @ mapper       : local pointer on mapper.
152 * @ to_buffer    : mapper -> buffer if true / buffer -> mapper if false.
[23]153 * @ file_offset  : first byte to move in file.
[407]154 * @ u_buf        : user space pointer on user buffer.
[23]155 * @ size         : number of bytes to move.
[606]156 * returns O if success / returns -1 if error.
[1]157 ******************************************************************************************/
[313]158error_t mapper_move_user( mapper_t * mapper,
159                          bool_t     to_buffer,
160                          uint32_t   file_offset,
[407]161                          void     * u_buf,
[313]162                          uint32_t   size );
163
[606]164/********************************************************************************************
165 * This function move data between a remote mapper and a remote kernel buffer.
166 * It can be called by a thread running any cluster.
[313]167 * If required, the data transfer is split in "fragments", where one fragment contains
168 * contiguous bytes in the same mapper page.
169 * It uses a "remote_memcpy" to move a fragment to/from the kernel buffer.
170 * In case of write, the dirty bit is set for all pages written in the mapper.
171 *******************************************************************************************
[606]172 * @ mapper_xp    : extended pointer on mapper.
[313]173 * @ to_buffer    : mapper -> buffer if true / buffer -> mapper if false.
174 * @ file_offset  : first byte to move in file.
175 * @ buffer_xp    : extended pointer on kernel buffer.
176 * @ size         : number of bytes to move.
[606]177 * returns O if success / returns -1 if error.
[313]178 ******************************************************************************************/
[606]179error_t mapper_move_kernel( xptr_t     mapper_xp,
[265]180                            bool_t     to_buffer,
181                            uint32_t   file_offset,
[313]182                            xptr_t     buffer_xp,
[265]183                            uint32_t   size );
[1]184
185/*******************************************************************************************
[606]186 * This function removes a physical page from the mapper, and releases
187 * the page to the local PPM. It is called by the mapper_destroy() function.
[1]188 * It must be executed by a thread running in the cluster containing the mapper.
[606]189 * It takes the mapper lock in WRITE_MODE to update the mapper.
[1]190 *******************************************************************************************
191 * @ mapper     : local pointer on the mapper.
192 * @ page       : pointer on page to remove.
193 ******************************************************************************************/
[606]194void mapper_release_page( mapper_t      * mapper,
195                          struct page_s * page );
[1]196
197/*******************************************************************************************
[606]198 * This function returns an extended pointer on a mapper page, identified by <page_id>,
199 * index in the file. The - possibly remote - mapper is identified by the <mapper_xp>
200 * argument.  It can be executed by a thread running in any cluster, as it uses remote
201 * access primitives to scan the mapper.
202 * In case of miss, this function takes the mapper lock in WRITE_MODE, and call the
203 * mapper_handle_miss() to load the missing page from device to mapper, using an RPC
204 * when the mapper is remote.
205 *******************************************************************************************
206 * @ mapper_xp  : extended pointer on the mapper.
207 * @ page_id    : page index in file
208 * @ returns extended pointer on page base if success / return XPTR_NULL if error.
209 ******************************************************************************************/
210xptr_t mapper_remote_get_page( xptr_t    mapper_xp,
211                               uint32_t  page_id );
212
213/*******************************************************************************************
214 * This function allows to read a single word in a mapper seen as and array of uint32_t.
215 * It has bee designed to support remote access tho the FAT mapper of the FATFS.
216 * It can be called by any thread running in any cluster.
[1]217 * In case of miss, it takes the mapper lock in WRITE_MODE, load the missing
[606]218 * page from device to mapper, and release the mapper lock.
[1]219 *******************************************************************************************
[606]220 * @ mapper_xp  : [in]  extended pointer on the mapper.
221 * @ index          : [in]  32 bits word index in file.
222 * @ p_value    : [out] local pointer on destination buffer.
223 * @ returns 0 if success / return -1 if error.
[1]224 ******************************************************************************************/
[606]225error_t mapper_remote_get_32( xptr_t     mapper_xp,
226                              uint32_t   word_id,
227                              uint32_t * p_value );
[1]228
[606]229/*******************************************************************************************
230 * This function allows to write a single word to a mapper seen as and array of uint32_t.
231 * It has bee designed to support remote access tho the FAT mapper of the FATFS.
232 * It can be called by any thread running in any cluster.
233 * In case of miss, it takes the mapper lock in WRITE_MODE, load the missing
234 * page from device to mapper, and release the mapper lock.
235 *******************************************************************************************
236 * @ mapper_xp  : [in]  extended pointer on the mapper.
237 * @ index          : [in]  32 bits word index in file.
238 * @ p_value    : [in]  value to be written.
239 * @ returns 0 if success / return -1 if error.
240 ******************************************************************************************/
241error_t mapper_remote_set_32( xptr_t     mapper_xp,
242                              uint32_t   word_id,
243                              uint32_t   value );
[18]244
[1]245#endif /* _MAPPER_H_ */
Note: See TracBrowser for help on using the repository browser.