cleanup load_blocks: make the common error path more visible
[hed.git] / libhed / access.h
blobffa2e7b3fd293086c07a1dd4151068000a5fd75c
1 /* Low-level file accessors */
3 /* This is a libhed PRIVATE file.
4 * Do not include outside of libhed. Do not install on the system.
5 */
7 /*
8 * hed - Hexadecimal editor
9 * Copyright (C) 2012 Petr Tesarik <petr@tesarici.cz>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of version 2 of the GNU General Public License as
13 * published by the Free Software Foundation.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 * Definitions in this file abstract from the low-level file access
27 * method. There are currently two access methods:
28 * read()
29 * mmap()
31 * However, there might be more methods in the future, such as
32 * a BIOS-call based one for making a standalone disk editor
33 * directly loadable from the boot manager.
36 #ifndef LIBHED__ACCESS_H
37 #define LIBHED__ACCESS_H
39 #include "config.h"
41 #include <assert.h>
43 /* Prevent polluting linker namespace with internal symbols */
44 #include "private.h"
45 #define sys_page_shift internal_name(sys_page_shift)
46 #define sys_page_size internal_name(sys_page_size)
47 #define file_access_init internal_name(file_access_init)
49 #define FILE_BLOCK_MASK ((signed long)FILE_BLOCK_SIZE-1)
50 #define FILE_BLOCK_OFF(x) ((hed_off_t)(x) & FILE_BLOCK_MASK)
51 #define FILE_BLOCK_ROUND(x) ((hed_off_t)(x) & ~FILE_BLOCK_MASK)
52 #define FILE_BLOCK_END(x) ((hed_off_t)(x) | FILE_BLOCK_MASK)
54 #if defined(HED_CONFIG_MMAP) || defined(HED_CONFIG_SWAP_MMAP)
56 #define HED_USES_MMAP 1 /* We use mmap() in some way */
58 extern unsigned int sys_page_shift; /* Page size bits */
59 extern unsigned long sys_page_size; /* Page size (in bytes) */
61 #endif
63 #ifdef HED_CONFIG_MMAP
65 #include <sys/mman.h>
66 #include <util/lists.h>
67 #include "file_priv.h"
69 #define FILE_BLOCK_SHIFT sys_page_shift
70 #define FILE_BLOCK_SIZE sys_page_size
72 /* Space to be allocated for each block's data */
73 #define FILE_BLOCK_ALLOC 0
75 struct remap_control {
76 void *start; /* start address of mapped region */
77 void *end; /* end address of mapped region */
80 static inline void
81 remap_init(struct remap_control *rc)
83 rc->start = rc->end = NULL;
86 static inline void
87 remap_finish(struct remap_control *rc)
89 if (rc->start != rc->end)
90 munmap(rc->start, rc->end - rc->start);
93 #define remap_compact(rc,cache,preload,n) do { } while(0)
95 static inline void
96 remap_add(struct remap_control *rc, void *data)
98 if (data == rc->end)
99 rc->end = data + FILE_BLOCK_SIZE;
100 else if (data + FILE_BLOCK_SIZE == rc->start)
101 rc->start = data;
102 else if (data) {
103 remap_finish(rc);
104 rc->start = data;
105 rc->end = data + FILE_BLOCK_SIZE;
109 #define fixup_files internal_name(fixup_files)
110 extern struct list_head fixup_files;
112 static inline void
113 fixup_register(struct file_priv *file)
115 list_add(&file->fixup_list, &fixup_files);
118 static inline void
119 fixup_deregister(struct file_priv *file)
121 list_del(&file->fixup_list);
124 #else /* !HED_CONFIG_MMAP */
126 #include "cache.h"
128 /* More or less arbitrarily chosen: */
129 #define FILE_BLOCK_SHIFT 12
130 #define FILE_BLOCK_SIZE (1U << FILE_BLOCK_SHIFT)
132 /* Space to be allocated for each block's data */
133 #define FILE_BLOCK_ALLOC FILE_BLOCK_SIZE
135 struct remap_control { };
137 #define remap_init(rc) do {} while(0)
138 #define remap_finish(rc) do {} while(0)
139 #define remap_add(rc,data) do {} while(0)
141 static inline void
142 remap_compact(struct remap_control *rc, struct hed_cache *cache,
143 struct hed_block_data **preload, int n)
145 #ifdef HED_CONFIG_READAHEAD
146 cache_compact(cache, preload, n);
147 #endif
150 #define fixup_register(f) do {} while(0)
151 #define fixup_deregister(f) do {} while(0)
153 #endif /* HED_CONFIG_MMAP */
155 #if HED_USES_MMAP
157 #include <unistd.h>
158 #include "util/numbers.h"
160 #define SWAP_BLOCK_SHIFT sys_page_shift
161 #define SWAP_BLOCK_SIZE sys_page_size
163 int file_access_init(void);
165 #else
167 #define SWAP_BLOCK_SHIFT FILE_BLOCK_SHIFT
168 #define SWAP_BLOCK_SIZE FILE_BLOCK_SIZE
170 static inline int
171 file_access_init(void)
173 return 0;
176 #endif
178 #endif /* LIBHED__ACCESS_H */