| [fc840d9] | 1 | /* | 
|---|
| [7ae01d5] | 2 | * Copyright (c) 2024 Jiri Svoboda | 
|---|
| [fc840d9] | 3 | * Copyright (c) 2008 Jakub Jermar | 
|---|
| [15f3c3f] | 4 | * Copyright (c) 2008 Martin Decky | 
|---|
|  | 5 | * Copyright (c) 2011 Martin Sucha | 
|---|
| [fc840d9] | 6 | * All rights reserved. | 
|---|
|  | 7 | * | 
|---|
|  | 8 | * Redistribution and use in source and binary forms, with or without | 
|---|
|  | 9 | * modification, are permitted provided that the following conditions | 
|---|
|  | 10 | * are met: | 
|---|
|  | 11 | * | 
|---|
|  | 12 | * - Redistributions of source code must retain the above copyright | 
|---|
|  | 13 | *   notice, this list of conditions and the following disclaimer. | 
|---|
|  | 14 | * - Redistributions in binary form must reproduce the above copyright | 
|---|
|  | 15 | *   notice, this list of conditions and the following disclaimer in the | 
|---|
|  | 16 | *   documentation and/or other materials provided with the distribution. | 
|---|
|  | 17 | * - The name of the author may not be used to endorse or promote products | 
|---|
|  | 18 | *   derived from this software without specific prior written permission. | 
|---|
|  | 19 | * | 
|---|
|  | 20 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 
|---|
|  | 21 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 
|---|
|  | 22 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 
|---|
|  | 23 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | 
|---|
|  | 24 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | 
|---|
|  | 25 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 
|---|
|  | 26 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 
|---|
|  | 27 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 
|---|
|  | 28 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 
|---|
|  | 29 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 
|---|
|  | 30 | */ | 
|---|
|  | 31 |  | 
|---|
| [b7adc22] | 32 | /** @addtogroup libblock | 
|---|
| [fc840d9] | 33 | * @{ | 
|---|
| [b7adc22] | 34 | */ | 
|---|
| [fc840d9] | 35 | /** | 
|---|
|  | 36 | * @file | 
|---|
|  | 37 | */ | 
|---|
|  | 38 |  | 
|---|
|  | 39 | #ifndef LIBBLOCK_LIBBLOCK_H_ | 
|---|
| [1e4cada] | 40 | #define LIBBLOCK_LIBBLOCK_H_ | 
|---|
| [fc840d9] | 41 |  | 
|---|
| [23c8acd9] | 42 | #include <offset.h> | 
|---|
| [79ae36dd] | 43 | #include <async.h> | 
|---|
| [1e4cada] | 44 | #include <fibril_synch.h> | 
|---|
| [d9c8c81] | 45 | #include <adt/hash_table.h> | 
|---|
|  | 46 | #include <adt/list.h> | 
|---|
| [b7adc22] | 47 | #include <loc.h> | 
|---|
| [fc840d9] | 48 |  | 
|---|
| [1d8cdb1] | 49 | /* | 
|---|
|  | 50 | * Flags that can be used with block_get(). | 
|---|
|  | 51 | */ | 
|---|
|  | 52 |  | 
|---|
| [b7adc22] | 53 | /** | 
|---|
| [1d8cdb1] | 54 | * This macro is a symbolic value for situations where no special flags are | 
|---|
|  | 55 | * needed. | 
|---|
|  | 56 | */ | 
|---|
|  | 57 | #define BLOCK_FLAGS_NONE        0 | 
|---|
|  | 58 |  | 
|---|
|  | 59 | /** | 
|---|
|  | 60 | * When the client of block_get() intends to overwrite the current contents of | 
|---|
|  | 61 | * the block, this flag is used to avoid the unnecessary read. | 
|---|
|  | 62 | */ | 
|---|
|  | 63 | #define BLOCK_FLAGS_NOREAD      1 | 
|---|
|  | 64 |  | 
|---|
| [fc840d9] | 65 | typedef struct block { | 
|---|
| [4e1b57d] | 66 | /** Mutex protecting the reference count. */ | 
|---|
|  | 67 | fibril_mutex_t lock; | 
|---|
| [5cf723b] | 68 | /** Number of references to the block_t structure. */ | 
|---|
|  | 69 | unsigned refcnt; | 
|---|
|  | 70 | /** If true, the block needs to be written back to the block device. */ | 
|---|
| [fc840d9] | 71 | bool dirty; | 
|---|
| [cd688d9] | 72 | /** If true, the blcok does not contain valid data. */ | 
|---|
|  | 73 | bool toxic; | 
|---|
| [5cf723b] | 74 | /** Readers / Writer lock protecting the contents of the block. */ | 
|---|
| [4e1b57d] | 75 | fibril_rwlock_t contents_lock; | 
|---|
| [15f3c3f] | 76 | /** Service ID of service providing the block device. */ | 
|---|
|  | 77 | service_id_t service_id; | 
|---|
| [f092718] | 78 | /** Logical block address */ | 
|---|
| [a6ba0c9] | 79 | aoff64_t lba; | 
|---|
| [f092718] | 80 | /** Physical block address */ | 
|---|
|  | 81 | aoff64_t pba; | 
|---|
| [5cf723b] | 82 | /** Size of the block. */ | 
|---|
|  | 83 | size_t size; | 
|---|
| [3d35386] | 84 | /** Number of write failures. */ | 
|---|
|  | 85 | int write_failures; | 
|---|
| [5cf723b] | 86 | /** Link for placing the block into the free block list. */ | 
|---|
|  | 87 | link_t free_link; | 
|---|
| [5b0cf63] | 88 | /** Link for placing the block into the block hash table. */ | 
|---|
| [062d900] | 89 | ht_link_t hash_link; | 
|---|
| [5cf723b] | 90 | /** Buffer with the block data. */ | 
|---|
|  | 91 | void *data; | 
|---|
| [fc840d9] | 92 | } block_t; | 
|---|
|  | 93 |  | 
|---|
| [1fbe064b] | 94 | /** Caching mode */ | 
|---|
|  | 95 | enum cache_mode { | 
|---|
|  | 96 | /** Write-Through */ | 
|---|
|  | 97 | CACHE_MODE_WT, | 
|---|
|  | 98 | /** Write-Back */ | 
|---|
|  | 99 | CACHE_MODE_WB | 
|---|
|  | 100 | }; | 
|---|
|  | 101 |  | 
|---|
| [7ae01d5] | 102 | extern errno_t block_init(service_id_t); | 
|---|
| [15f3c3f] | 103 | extern void block_fini(service_id_t); | 
|---|
| [6284978] | 104 |  | 
|---|
| [b7fd2a0] | 105 | extern errno_t block_bb_read(service_id_t, aoff64_t); | 
|---|
| [15f3c3f] | 106 | extern void *block_bb_get(service_id_t); | 
|---|
| [fc840d9] | 107 |  | 
|---|
| [b7fd2a0] | 108 | extern errno_t block_cache_init(service_id_t, size_t, unsigned, enum cache_mode); | 
|---|
|  | 109 | extern errno_t block_cache_fini(service_id_t); | 
|---|
| [f1ba5d6] | 110 |  | 
|---|
| [b7fd2a0] | 111 | extern errno_t block_get(block_t **, service_id_t, aoff64_t, int); | 
|---|
|  | 112 | extern errno_t block_put(block_t *); | 
|---|
| [fc840d9] | 113 |  | 
|---|
| [b7fd2a0] | 114 | extern errno_t block_seqread(service_id_t, void *, size_t *, size_t *, aoff64_t *, | 
|---|
| [4802dd7] | 115 | void *, size_t); | 
|---|
| [fc840d9] | 116 |  | 
|---|
| [b7fd2a0] | 117 | extern errno_t block_get_bsize(service_id_t, size_t *); | 
|---|
|  | 118 | extern errno_t block_get_nblocks(service_id_t, aoff64_t *); | 
|---|
|  | 119 | extern errno_t block_read_toc(service_id_t, uint8_t, void *, size_t); | 
|---|
|  | 120 | extern errno_t block_read_direct(service_id_t, aoff64_t, size_t, void *); | 
|---|
|  | 121 | extern errno_t block_read_bytes_direct(service_id_t, aoff64_t, size_t, void *); | 
|---|
|  | 122 | extern errno_t block_write_direct(service_id_t, aoff64_t, size_t, const void *); | 
|---|
|  | 123 | extern errno_t block_sync_cache(service_id_t, aoff64_t, size_t); | 
|---|
| [00b1d20e] | 124 |  | 
|---|
| [fc840d9] | 125 | #endif | 
|---|
|  | 126 |  | 
|---|
|  | 127 | /** @} | 
|---|
|  | 128 | */ | 
|---|