Check-in [a42c00cfeb]

Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
SHA1 Hash:a42c00cfeb10e678593afe0ef5248c12bdaf4783
Date: 2010-03-10 13:35:49
User: stephan
Comment:woohoo! Finding the next free block in an EFS is now always O(1) (was worst-case O(N), N=block count)! Required a minor restructuring of whio_epfs_block and how the free list is managed.
Tags And Properties
Changes
hide diffs unified diffs patch

Changes to include/wh/whio/whio_epfs.h

Old (94869e8a5f0e3778) New (532372e7a87a80d1)
1 #ifndef WANDERINGHORSE_NET_WHIO_EPFS_H_INCLUDED 1 #ifndef WANDERINGHORSE_NET_WHIO_EPFS_H_INCLUDED
2 #define WANDERINGHORSE_NET_WHIO_EPFS_H_INCLUDED 2 #define WANDERINGHORSE_NET_WHIO_EPFS_H_INCLUDED
3 #include "whio_dev.h" /* core whio_dev API. */ 3 #include "whio_dev.h" /* core whio_dev API. */
4 #include "whio_encode.h" /* for whio_sizeof_encoded_xxx */ 4 #include "whio_encode.h" /* for whio_sizeof_encoded_xxx */
5 #include "whio_epfs_config.h" /* EPFS compile-time config options. */ 5 #include "whio_epfs_config.h" /* EPFS compile-time config options. */
492 hidden lines
498 block". 498 block".
499 */ 499 */
500 whio_epfs_id_t id; 500 whio_epfs_id_t id;
501 /** ID of next block in this chain, or 0 for no block. */ 501 /** ID of next block in this chain, or 0 for no block. */
502 whio_epfs_id_t nextBlock; 502 whio_epfs_id_t nextBlock;
> 503 /** Used only by free blocks. Points to the next free block. */
> 504 whio_epfs_id_t nextFree;
503 /** Internal flags. */ 505 /** Internal flags. */
504 uint8_t flags; 506 uint8_t flags;
505 }; 507 };
506 /** Convenience typedef. */ 508 /** Convenience typedef. */
507 typedef struct whio_epfs_block whio_epfs_block; 509 typedef struct whio_epfs_block whio_epfs_block;
508 /** An empty whio_epfs_block initialization object. */ 510 /** An empty whio_epfs_block initialization object. */
509 #define whio_epfs_block_empty_m {0/*id*/,0/*nextBlock*/,0/*flags*/} | 511 #define whio_epfs_block_empty_m {0/*id*/,0/*nextBlock*/,0/*nextFree*/,0/*flags*/}
510 /** An empty whio_epfs_block initialization object. */ 512 /** An empty whio_epfs_block initialization object. */
511 extern const whio_epfs_block whio_epfs_block_empty; 513 extern const whio_epfs_block whio_epfs_block_empty;
512 /** 514 /**
513 Metadata for an on-storage "inode" (a whio_epfs pseudofile 515 Metadata for an on-storage "inode" (a whio_epfs pseudofile
514 entry). 516 entry).
3 hidden lines
518 /** 520 /**
519 The inode's id. These start at 1. 0 is reserved for 521 The inode's id. These start at 1. 0 is reserved for
520 "not an inode". 522 "not an inode".
521 */ 523 */
522 whio_epfs_id_t id; 524 whio_epfs_id_t id;
> 525
523 /** 526 /**
524 ID of the first data block associated with this inode. 527 ID of the first data block associated with this inode.
525 0 means no blocks. 528 0 means no blocks.
526 */ 529 */
527 whio_epfs_id_t firstBlock; 530 whio_epfs_id_t firstBlock;
24 hidden lines
552 Client-defined flags. The whio_epfs API does 555 Client-defined flags. The whio_epfs API does
553 nothing with these flags - they are reserved for 556 nothing with these flags - they are reserved for
554 client use. 557 client use.
555 */ 558 */
556 uint32_t cflags; 559 uint32_t cflags;
> 560
> 561 /**
> 562 Used only be free inodes, to link to the next free inode.
> 563 */
> 564 whio_epfs_id_t nextFree;
557 }; 565 };
558 /** Convenience typedef. */ 566 /** Convenience typedef. */
559 typedef struct whio_epfs_inode whio_epfs_inode; 567 typedef struct whio_epfs_inode whio_epfs_inode;
560 568
561 /** An empty whio_epfs_inode initialization object. */ 569 /** An empty whio_epfs_inode initialization object. */
563 0/*id*/, \ 571 0/*id*/, \
564 0/*firstBlock*/, \ 572 0/*firstBlock*/, \
565 0/*mtime*/, \ 573 0/*mtime*/, \
566 0/*size*/, \ 574 0/*size*/, \
567 0/*flags*/, \ 575 0/*flags*/, \
568 0/*cflags*/ \ | 576 0/*cflags*/, \
| 577 0/*nextFree*/ \
569 } 578 }
570 /** An empty whio_epfs_inode initialization object. */ 579 /** An empty whio_epfs_inode initialization object. */
571 extern const whio_epfs_inode whio_epfs_inode_empty; 580 extern const whio_epfs_inode whio_epfs_inode_empty;
572 581
573 /** 582 /**
295 hidden lines
869 */ 878 */
870 whio_epfs_sizeof_hints = 1/*tag byte*/ 879 whio_epfs_sizeof_hints = 1/*tag byte*/
871 + (5 * whio_epfs_sizeof_id) /* whio_epfs_hints:: 880 + (5 * whio_epfs_sizeof_id) /* whio_epfs_hints::
872 nextFreeInode, 881 nextFreeInode,
873 maxEverUsedInode, 882 maxEverUsedInode,
874 nextFreeBlock, | 883 freeBlockList,
875 maxEverUsedBlock, 884 maxEverUsedBlock,
876 blockCount) */ 885 blockCount) */
877 , 886 ,
878 /** 887 /**
879 Encoded size of whio_epfs_inode. 888 Encoded size of whio_epfs_inode.
3 hidden lines
883 + whio_sizeof_encoded_uint32/*cflags*/ 892 + whio_sizeof_encoded_uint32/*cflags*/
884 + whio_sizeof_encoded_uint8/*flags*/ 893 + whio_sizeof_encoded_uint8/*flags*/
885 + whio_sizeof_encoded_uint32/*mtime*/ 894 + whio_sizeof_encoded_uint32/*mtime*/
886 + whio_epfs_sizeof_id/*firstBlock*/ 895 + whio_epfs_sizeof_id/*firstBlock*/
887 + whio_sizeof_encoded_size_t/*size*/ 896 + whio_sizeof_encoded_size_t/*size*/
> 897 + whio_epfs_sizeof_id/*nextFree*/
888 , 898 ,
889 /** 899 /**
890 Encoded size of whio_epfs_block. This is independent of 900 Encoded size of whio_epfs_block. This is independent of
891 whio_epfs_fsopt::blockSize. 901 whio_epfs_fsopt::blockSize.
892 */ 902 */
893 whio_epfs_sizeof_blockMeta = 1/*tag byte*/ 903 whio_epfs_sizeof_blockMeta = 1/*tag byte*/
894 + whio_epfs_sizeof_id/*id*/ 904 + whio_epfs_sizeof_id/*id*/
895 + whio_epfs_sizeof_id/*nextBlock*/ 905 + whio_epfs_sizeof_id/*nextBlock*/
> 906 + whio_epfs_sizeof_id/*nextFree*/
896 + whio_sizeof_encoded_uint8/*flags*/ 907 + whio_sizeof_encoded_uint8/*flags*/
897 , 908 ,
898 909
899 /** 910 /**
900 whio_epfs_sizeof_label_payload is an alias for 911 whio_epfs_sizeof_label_payload is an alias for
296 hidden lines
1197 normally would. 1208 normally would.
1198 */ 1209 */
1199 whio_epfs_id_t maxEverUsedInode; 1210 whio_epfs_id_t maxEverUsedInode;
1200 1211
1201 /** 1212 /**
1202 Starting point when looking for the next free block. | 1213 ID of the first free block, or 0 if there are none.
1203 */ 1214 */
1204 whio_epfs_id_t nextFreeBlock; | 1215 whio_epfs_id_t freeBlockList;
1205 |
1206 /** 1216 /**
1207 The highest block ID which has been added to the EFS. 1217 The highest block ID which has been added to the EFS.
1208 */ 1218 */
1209 whio_epfs_id_t blockCount; 1219 whio_epfs_id_t blockCount;
1210 1220
63 hidden lines
1274 {/*sizes*/0}, \ 1284 {/*sizes*/0}, \
1275 whio_epfs_handle_list_empty_m, \ 1285 whio_epfs_handle_list_empty_m, \
1276 whio_client_data_empty_m,\ 1286 whio_client_data_empty_m,\
1277 {/*hints*/1U/*nextFreeInode*/,\ 1287 {/*hints*/1U/*nextFreeInode*/,\
1278 0U/*maxEverUsedInode*/,\ 1288 0U/*maxEverUsedInode*/,\
1279 1U/*nextFreeBlock*/,\ | 1289 0U/*freeBlockList*/,\
1280 0U/*blockCount*/,\ 1290 0U/*blockCount*/,\
1281 0U/*maxEverUsedBlock*/, \ 1291 0U/*maxEverUsedBlock*/, \
1282 NULL/*allocStamp*/,\ 1292 NULL/*allocStamp*/,\
1283 -1/*storageLockingMode*/,\ 1293 -1/*storageLockingMode*/,\
1284 }, \ 1294 }, \
153 hidden lines
1438 option is ignored. 1448 option is ignored.
1439 */ 1449 */
1440 //bool failIfNoInitialLock; 1450 //bool failIfNoInitialLock;
1441 } storage; 1451 } storage;
1442 /** 1452 /**
> 1453 HIGHLY EXPERIMENTAL! Do not yet use in client code!
> 1454
1443 Options related to the fs memory allocator. 1455 Options related to the fs memory allocator.
1444 */ 1456 */
1445 struct whio_epfs_setup_opt_memory 1457 struct whio_epfs_setup_opt_memory
1446 { 1458 {
1447 /** 1459 /**
1064 hidden lines
2512 #ifdef __cplusplus 2524 #ifdef __cplusplus
2513 } /* extern "C" */ 2525 } /* extern "C" */
2514 #endif 2526 #endif
2515 2527
2516 #endif /* WANDERINGHORSE_NET_WHIO_EPFS_H_INCLUDED */ 2528 #endif /* WANDERINGHORSE_NET_WHIO_EPFS_H_INCLUDED */

Changes to include/wh/whio/whio_epfs_config.h

Old (490be4f1f2daac94) New (45c31476abd10faa)
1 #ifndef WANDERINGHORSE_NET_WHIO_EPFS_CONFIG_H_INCLUDED 1 #ifndef WANDERINGHORSE_NET_WHIO_EPFS_CONFIG_H_INCLUDED
2 #define WANDERINGHORSE_NET_WHIO_EPFS_CONFIG_H_INCLUDED 2 #define WANDERINGHORSE_NET_WHIO_EPFS_CONFIG_H_INCLUDED
3 /** @file whio_epfs_config.h 3 /** @file whio_epfs_config.h
4 4
5 This file contains the compile-time-configurable parts of whio_epfs. 5 This file contains the compile-time-configurable parts of whio_epfs.
57 hidden lines
63 63
64 /** @def WHIO_EPFS_CONFIG_AUTO_FLUSH_HINTS 64 /** @def WHIO_EPFS_CONFIG_AUTO_FLUSH_HINTS
65 65
66 Experimental. 66 Experimental.
67 67
> 68 This will go away once the way the free-lists are reworked.
> 69
68 If WHIO_EPFS_CONFIG_AUTO_FLUSH_HINTS is a true value 70 If WHIO_EPFS_CONFIG_AUTO_FLUSH_HINTS is a true value
69 then certain inode and block operations which update 71 then certain inode and block operations which update
70 internal FS hints will try to write such changes to 72 internal FS hints will try to write such changes to
71 the FS. 73 the FS.
72 <
73 */ 74 */
74 #define WHIO_EPFS_CONFIG_AUTO_FLUSH_HINTS 1 | 75 #define WHIO_EPFS_CONFIG_AUTO_FLUSH_HINTS 0
75 76
76 /** @def WHIO_EPFS_CONFIG_ENABLE_STORAGE_LOCKING 77 /** @def WHIO_EPFS_CONFIG_ENABLE_STORAGE_LOCKING
77 78
78 If WHIO_EPFS_CONFIG_ENABLE_STORAGE_LOCKING is set to a true value then 79 If WHIO_EPFS_CONFIG_ENABLE_STORAGE_LOCKING is set to a true value then
79 the library is compiled with some interal support for byte-range 80 the library is compiled with some interal support for byte-range
110 hidden lines
190 #ifdef __cplusplus 191 #ifdef __cplusplus
191 } /* extern "C" */ 192 } /* extern "C" */
192 #endif 193 #endif
193 194
194 #endif /* WANDERINGHORSE_NET_WHIO_EPFS_CONFIG_H_INCLUDED */ 195 #endif /* WANDERINGHORSE_NET_WHIO_EPFS_CONFIG_H_INCLUDED */

Changes to pfs/Makefile

Old (47e0f40566fb41ab) New (b9f3dfec3cf60fcc)
1 #!/usr/bin/make -f 1 #!/usr/bin/make -f
2 include ../config.make 2 include ../config.make
3 3
4 CFLAGS += -O0 4 CFLAGS += -O0
5 WHIO_BINS_LDFLAGS := -L$(LIBWHIO.LIBDIR) -lwhio -L. -lwhio_epfs # $(LIBWHIO_CLIENT_LDFLAGS) 5 WHIO_BINS_LDFLAGS := -L$(LIBWHIO.LIBDIR) -lwhio -L. -lwhio_epfs # $(LIBWHIO_CLIENT_LDFLAGS)
18 hidden lines
24 pfs.o inode.o: $(PACKAGE.MAKEFILE) 24 pfs.o inode.o: $(PACKAGE.MAKEFILE)
25 $(libwhio_epfs.LIB): $(WHIO_BINS_DEPS) 25 $(libwhio_epfs.LIB): $(WHIO_BINS_DEPS)
26 $(libwhio_epfs.DLL): $(WHIO_BINS_DEPS) 26 $(libwhio_epfs.DLL): $(WHIO_BINS_DEPS)
27 all: $(libwhio_epfs.LIB) $(libwhio_epfs.DLL) 27 all: $(libwhio_epfs.LIB) $(libwhio_epfs.DLL)
28 28
29 pfs.BIN.OBJECTS := test.o $(libwhio_epfs.LIB) | 29 test.BIN.OBJECTS := test.o $(libwhio_epfs.LIB)
30 pfs.BIN.LDFLAGS := $(WHIO_BINS_LDFLAGS) | 30 test.BIN.LDFLAGS := $(WHIO_BINS_LDFLAGS)
31 $(call ShakeNMake.CALL.RULES.BINS,pfs) | 31 $(call ShakeNMake.CALL.RULES.BINS,test)
32 pfs.o: $(PACKAGE.MAKEFILE) | 32 test.o: $(PACKAGE.MAKEFILE)
33 $(pfs.BIN): $(WHIO_BINS_DEPS) | 33 $(test.BIN): $(WHIO_BINS_DEPS)
34 all: $(pfs.BIN) | 34 all: $(test.BIN)
35 35
36 # .o files used by the applications... 36 # .o files used by the applications...
37 APP.OBJ := # $(libwhio_epfs.LIB) 37 APP.OBJ := # $(libwhio_epfs.LIB)
38 38
39 whio-epfs-mkfs.BIN.OBJECTS := mkfs.o $(APP.OBJ) 39 whio-epfs-mkfs.BIN.OBJECTS := mkfs.o $(APP.OBJ)
50 hidden lines
90 bash sanityCheck.sh || break; \ 90 bash sanityCheck.sh || break; \
91 done; echo "Sanity rc=$$?" 91 done; echo "Sanity rc=$$?"
92 #http: http.o 92 #http: http.o
93 # gcc -o $@ $^ -lmicrohttpd 93 # gcc -o $@ $^ -lmicrohttpd
94 #all: http 94 #all: http

Changes to pfs/block.c

Old (88ea4e0224cce1d5) New (eb21a33dd6a91117)
1 /************************************************************************ 1 /************************************************************************
2 FAR FROM COMPLETE. 2 FAR FROM COMPLETE.
3 3
4 This is a work-in-progress, porting over parts of the whefs API into 4 This is a work-in-progress, porting over parts of the whefs API into
5 the whio API... 5 the whio API...
6 6
7 Author: Stephan Beal (http://wanderinghorse.net/home/stephan/) 7 Author: Stephan Beal (http://wanderinghorse.net/home/stephan/)
8 8
9 License: Public Domain 9 License: Public Domain
10 ************************************************************************/ 10 ************************************************************************/
> 11 #if 1
> 12 #define MARKER(X)
> 13 #else
> 14 #define MARKER(X) printf X
> 15 #define WHIO_DEBUG_ENABLED 1
> 16 #endif
11 17
12 #include <wh/whio/whio_devs.h> 18 #include <wh/whio/whio_devs.h>
13 #include <wh/whio/whio_encode.h> 19 #include <wh/whio/whio_encode.h>
14 #include <assert.h> 20 #include <assert.h>
15 #include <string.h> // memset() and friends 21 #include <string.h> // memset() and friends
> 22
16 #include "whio_epfs_internal.h" 23 #include "whio_epfs_internal.h"
17 24
18 #define MARKER WHIO_DEBUG <
19 25
20 const whio_epfs_block whio_epfs_block_empty = whio_epfs_block_empty_m; 26 const whio_epfs_block whio_epfs_block_empty = whio_epfs_block_empty_m;
21 const whio_epfs_block_list whio_epfs_block_list_empty = whio_epfs_block_list_empty_m; 27 const whio_epfs_block_list whio_epfs_block_list_empty = whio_epfs_block_list_empty_m;
22 28
23 int whio_epfs_block_list_reserve( whio_epfs * fs, whio_epfs_block_list *bl, whio_epfs_id_t n ) 29 int whio_epfs_block_list_reserve( whio_epfs * fs, whio_epfs_block_list *bl, whio_epfs_id_t n )
24 { 30 {
25 if( ! bl ) return whio_rc.ArgError; 31 if( ! bl ) return whio_rc.ArgError;
26 else if( 0 == n ) 32 else if( 0 == n )
27 { 33 {
28 //MARKER("Freeing block list of %"WHIO_EPFS_ID_T_PFMT" items @%p\n",n, (void const *)bl->list); | 34 //MARKER(("Freeing block list of %"WHIO_EPFS_ID_T_PFMT" items @%p\n",n, (void const *)bl->list);
29 //free( bl->list ); 35 //free( bl->list );
30 whio_epfs_mfree( fs, bl->list ); 36 whio_epfs_mfree( fs, bl->list );
31 //void * x; x = realloc( bl->list, 0 ); 37 //void * x; x = realloc( bl->list, 0 );
32 *bl = whio_epfs_block_list_empty; 38 *bl = whio_epfs_block_list_empty;
33 return whio_rc.OK; 39 return whio_rc.OK;
34 } 40 }
35 else if( bl->alloced >= n ) return whio_rc.OK; 41 else if( bl->alloced >= n ) return whio_rc.OK;
36 whio_epfs_block * li = (whio_epfs_block *) 42 whio_epfs_block * li = (whio_epfs_block *)
37 //realloc( bl->list, n * sizeof(whio_epfs_block) ); 43 //realloc( bl->list, n * sizeof(whio_epfs_block) );
38 whio_epfs_mrealloc( fs, bl->list, n * sizeof(whio_epfs_block) ); 44 whio_epfs_mrealloc( fs, bl->list, n * sizeof(whio_epfs_block) );
39 //MARKER("(Re)allocated block list of %"WHIO_EPFS_ID_T_PFMT" items @%p\n", n, (void const *)li); | 45 //MARKER(("(Re)allocated block list of %"WHIO_EPFS_ID_T_PFMT" items @%p\n", n, (void const *)li));
40 if( ! li ) 46 if( ! li )
41 { 47 {
42 return whio_rc.AllocError; 48 return whio_rc.AllocError;
43 } 49 }
44 bl->alloced = n; 50 bl->alloced = n;
73 hidden lines
118 bool whio_epfs_block_is_used( whio_epfs_block const * bl ) 124 bool whio_epfs_block_is_used( whio_epfs_block const * bl )
119 { 125 {
120 return bl && (bl->flags & WHIO_EPFS_FLAG_IS_USED); 126 return bl && (bl->flags & WHIO_EPFS_FLAG_IS_USED);
121 } 127 }
122 128
123 int whio_epfs_block_set_used( whio_epfs_block * bl, bool u ) | 129 int whio_epfs_block_set_used( whio_epfs * fs, whio_epfs_block * bl, bool u )
124 { 130 {
125 if( ! bl ) return whio_rc.ArgError; 131 if( ! bl ) return whio_rc.ArgError;
126 else 132 else
127 { 133 {
128 if(u) bl->flags |= WHIO_EPFS_FLAG_IS_USED; | 134 if(u)
| 135 {
| 136 if( !(bl->flags & WHIO_EPFS_FLAG_IS_USED) )
| 137 {
| 138 bl->flags |= WHIO_EPFS_FLAG_IS_USED;
| 139 if( fs->hints.freeBlockList == bl->id )
| 140 {
| 141 fs->hints.freeBlockList = bl->nextFree;
| 142 bl->nextFree = 0;
| 143 }
| 144 }
| 145 }
129 else 146 else
130 { 147 {
131 whio_epfs_id_t id = bl->id; | 148 if( bl->flags & WHIO_EPFS_FLAG_IS_USED )
132 if( bl->nextBlock ) |
133 { 149 {
134 WHIO_DEBUG("WARNING: un-using block %"WHIO_EPFS_ID_T_PFMT | 150 whio_epfs_id_t id = bl->id;
135 " while it still links to %"WHIO_EPFS_ID_T_PFMT"!\n", | 151 if( bl->nextBlock )
136 id, bl->nextBlock); | 152 {
| 153 WHIO_DEBUG("WARNING: un-using block %"WHIO_EPFS_ID_T_PFMT
| 154 " while it still links to %"WHIO_EPFS_ID_T_PFMT"!\n",
| 155 id, bl->nextBlock);
| 156 }
| 157 *bl = whio_epfs_block_empty;
| 158 bl->id = id;
| 159 bl->nextFree = fs->hints.freeBlockList;
| 160 fs->hints.freeBlockList = bl->id;
137 } 161 }
138 *bl = whio_epfs_block_empty; <
139 bl->id = id; <
140 } 162 }
141 return whio_rc.OK; 163 return whio_rc.OK;
142 } 164 }
143 } 165 }
144 166
2 hidden lines
147 { 169 {
148 if( ! bl || ! dest ) return 0; 170 if( ! bl || ! dest ) return 0;
149 *(dest++) = whio_epfs_block_tag_char; 171 *(dest++) = whio_epfs_block_tag_char;
150 dest += whio_epfs_encode_id( dest, bl->id ); 172 dest += whio_epfs_encode_id( dest, bl->id );
151 dest += whio_epfs_encode_id( dest, bl->nextBlock ); 173 dest += whio_epfs_encode_id( dest, bl->nextBlock );
> 174 dest += whio_epfs_encode_id( dest, bl->nextFree );
152 dest += whio_encode_uint8( dest, bl->flags ); 175 dest += whio_encode_uint8( dest, bl->flags );
153 return whio_epfs_sizeof_blockMeta; 176 return whio_epfs_sizeof_blockMeta;
154 } 177 }
155 int whio_epfs_block_decode( whio_epfs_block * bl, unsigned char const * src ) 178 int whio_epfs_block_decode( whio_epfs_block * bl, unsigned char const * src )
156 { 179 {
3 hidden lines
160 return whio_rc.ConsistencyError; 183 return whio_rc.ConsistencyError;
161 } 184 }
162 int rc = whio_epfs_decode_id( at, &bl->id ); 185 int rc = whio_epfs_decode_id( at, &bl->id );
163 if( rc ) return rc; 186 if( rc ) return rc;
164 at += whio_epfs_sizeof_id; 187 at += whio_epfs_sizeof_id;
> 188
165 rc = whio_epfs_decode_id( at, &bl->nextBlock ); 189 rc = whio_epfs_decode_id( at, &bl->nextBlock );
166 if( rc ) return rc; 190 if( rc ) return rc;
167 at += whio_epfs_sizeof_id; 191 at += whio_epfs_sizeof_id;
> 192
> 193 rc = whio_epfs_decode_id( at, &bl->nextFree );
> 194 if( rc ) return rc;
> 195 at += whio_epfs_sizeof_id;
> 196
168 rc = whio_decode_uint8( at, &bl->flags ); 197 rc = whio_decode_uint8( at, &bl->flags );
169 return rc; 198 return rc;
170 } 199 }
171 200
172 bool whio_epfs_block_id_in_bounds( whio_epfs const * fs, 201 bool whio_epfs_block_id_in_bounds( whio_epfs const * fs,
89 hidden lines
262 { 291 {
263 fs->hints.maxEverUsedBlock = bl->id; 292 fs->hints.maxEverUsedBlock = bl->id;
264 ++changes; 293 ++changes;
265 } 294 }
266 } 295 }
267 else if( fs->hints.nextFreeBlock > bl->id ) <
268 { <
269 fs->hints.nextFreeBlock = bl->id; <
270 ++changes; <
271 } <
272 #if WHIO_EPFS_CONFIG_AUTO_FLUSH_HINTS 296 #if WHIO_EPFS_CONFIG_AUTO_FLUSH_HINTS
273 if( changes ) 297 if( changes )
274 { 298 {
275 int rc = whio_epfs_hints_write( fs ); 299 int rc = whio_epfs_hints_write( fs );
276 if( rc ) return rc; 300 if( rc ) return rc;
45 hidden lines
322 wrc = whio_epfs_write( fs, buf, wsz); 346 wrc = whio_epfs_write( fs, buf, wsz);
323 if( ! wrc ) break; 347 if( ! wrc ) break;
324 if( wsz != wrc ) return whio_rc.IOError; 348 if( wsz != wrc ) return whio_rc.IOError;
325 total += wrc; 349 total += wrc;
326 } 350 }
327 //MARKER("Wrote %"WHIO_SIZE_T_PFMT" bytes to zero block #%"WHIO_EPFS_ID_T_PFMT". Range=[%"WHIO_SIZE_T_PFMT" .. %"WHIO_SIZE_T_PFMT")", total, bl->id, fpos, fpos+count ); | 351 //MARKER(("Wrote %"WHIO_SIZE_T_PFMT" bytes to zero block #%"WHIO_EPFS_ID_T_PFMT". Range=[%"WHIO_SIZE_T_PFMT" .. %"WHIO_SIZE_T_PFMT")", total, bl->id, fpos, fpos+count ));
328 } 352 }
329 return whio_rc.OK; 353 return whio_rc.OK;
330 354
331 } 355 }
332 356
33 hidden lines
366 //WHIO_DEBUG("Warning: we're cleaning up the metadata without cleaning up children! We're losing blocks!\n"); 390 //WHIO_DEBUG("Warning: we're cleaning up the metadata without cleaning up children! We're losing blocks!\n");
367 } 391 }
368 const whio_epfs_id_t oid = bl->id; 392 const whio_epfs_id_t oid = bl->id;
369 *bl = whio_epfs_block_empty; 393 *bl = whio_epfs_block_empty;
370 bl->id = oid; 394 bl->id = oid;
> 395 bl->nextFree = fs->hints.freeBlockList;
> 396 fs->hints.freeBlockList = bl->id;
> 397 if(1)
> 398 {
> 399 WHIO_DEBUG("Wiping block #%"WHIO_EPFS_ID_T_PFMT
> 400 ". freeBlockList=#%"WHIO_EPFS_ID_T_PFMT
> 401 "->#%"WHIO_EPFS_ID_T_PFMT"\n",
> 402 bl->id, fs->hints.freeBlockList, bl->nextFree);
> 403 }
371 rc = whio_epfs_block_flush( fs, bl ); 404 rc = whio_epfs_block_flush( fs, bl );
372 if( whio_rc.OK != rc ) | 405 if(!rc)
| 406 { /* FIXME? move this somewhere else? */
| 407 rc = whio_epfs_hints_write( fs );
| 408 }
| 409 if( whio_rc.OK != rc )
373 { 410 {
374 //WHIO_DEBUG("Wiping block #%"WHEFS_ID_TYPE_PFMT" failed: flush failed with error code #%d!\n", bl->id, rc); 411 //WHIO_DEBUG("Wiping block #%"WHEFS_ID_TYPE_PFMT" failed: flush failed with error code #%d!\n", bl->id, rc);
375 return rc; 412 return rc;
376 } <
377 if( oid < fs->hints.nextFreeBlock ) <
378 { <
379 fs->hints.nextFreeBlock = oid; <
380 } 413 }
381 } 414 }
382 if( wipeData ) 415 if( wipeData )
383 { 416 {
384 rc = whio_epfs_block_wipe_data( fs, bl, 0 ); 417 rc = whio_epfs_block_wipe_data( fs, bl, 0 );
42 hidden lines
427 { 460 {
428 fs->hints.maxEverUsedBlock = bl.id; 461 fs->hints.maxEverUsedBlock = bl.id;
429 ++changes; 462 ++changes;
430 } 463 }
431 } 464 }
432 else if( fs->hints.nextFreeBlock > bl.id ) <
433 { <
434 fs->hints.nextFreeBlock = bl.id; <
435 ++changes; <
436 } <
437 #if WHIO_EPFS_CONFIG_AUTO_FLUSH_HINTS 465 #if WHIO_EPFS_CONFIG_AUTO_FLUSH_HINTS
438 if( changes && whio_epfs_is_rw(fs) ) 466 if( changes && whio_epfs_is_rw(fs) )
439 { 467 {
440 rc = whio_epfs_hints_write( fs ); 468 rc = whio_epfs_hints_write( fs );
441 if( rc ) return rc; 469 if( rc ) return rc;
5 hidden lines
447 } 475 }
448 476
449 int whio_epfs_block_next_free( whio_epfs * fs, whio_epfs_block * dest, bool markAsUsed ) 477 int whio_epfs_block_next_free( whio_epfs * fs, whio_epfs_block * dest, bool markAsUsed )
450 { 478 {
451 if( ! fs || ! dest ) return whio_rc.ArgError; 479 if( ! fs || ! dest ) return whio_rc.ArgError;
452 whio_epfs_id_t id = fs->hints.nextFreeBlock; <
453 if( markAsUsed && ! whio_epfs_is_rw(fs) ) return whio_rc.AccessError; 480 if( markAsUsed && ! whio_epfs_is_rw(fs) ) return whio_rc.AccessError;
> 481 int rc = whio_rc.InternalError;
> 482 #if 1
> 483 whio_epfs_block bl = whio_epfs_block_empty;
> 484 whio_epfs_id_t id = fs->hints.freeBlockList;
> 485 if( ! id )
> 486 { /* assume we are full and try to add blocks */
> 487 if( ! markAsUsed ) return whio_rc.DeviceFullError;
> 488 do
> 489 {
> 490 id = fs->hints.maxEverUsedBlock+1;
> 491 rc = whio_epfs_block_read( fs, id, &bl );
> 492 if( 0 == rc )
> 493 { /* block exists */
> 494 }
> 495 else
> 496 {
> 497 /** Create the block... */
> 498 bl = whio_epfs_block_empty;
> 499 bl.id = id;
> 500 rc = whio_epfs_block_flush( fs, &bl );
> 501 if( rc ) return rc;
> 502 rc = whio_epfs_block_wipe_data( fs, &bl, 0 );
> 503 if( rc ) return rc;
> 504 }
> 505 break;
> 506 } while(true);
> 507 }
> 508 else
> 509 {
> 510 rc = whio_epfs_block_read( fs, id, &bl );
> 511 if( rc ) return rc;
> 512 }
> 513 if( !rc )
> 514 {
> 515 if( markAsUsed )
> 516 {
> 517 whio_epfs_block_set_used( fs, &bl, true );
> 518 rc = whio_epfs_block_flush( fs, &bl );
> 519 if(!rc) rc = whio_epfs_hints_write( fs );
> 520 }
> 521 if( ! rc )
> 522 {
> 523 *dest = bl;
> 524 }
> 525 }
> 526 return rc;
> 527 #else /* older, linear impl */
> 528 whio_epfs_id_t id = fs->hints.nextFreeBlock;
454 if( ! (id+1) ) 529 if( ! (id+1) )
455 { 530 {
456 WHIO_DEBUG("Search for next free inode would overflow counter!\n"); 531 WHIO_DEBUG("Search for next free inode would overflow counter!\n");
457 return whio_rc.RangeError; 532 return whio_rc.RangeError;
458 } 533 }
13 hidden lines
472 if( fs->fsopt.maxBlocks && (id > fs->fsopt.maxBlocks) ) 547 if( fs->fsopt.maxBlocks && (id > fs->fsopt.maxBlocks) )
473 { 548 {
474 return whio_rc.DeviceFullError; 549 return whio_rc.DeviceFullError;
475 } 550 }
476 //whio_epfs_id_t const origin = id; 551 //whio_epfs_id_t const origin = id;
477 int rc = whio_rc.RangeError; | 552 rc = whio_rc.RangeError;
478 whio_epfs_block bl = whio_epfs_block_empty; 553 whio_epfs_block bl = whio_epfs_block_empty;
479 for( ; ; ++id ) 554 for( ; ; ++id )
480 { 555 {
481 if( (fs->fsopt.maxBlocks && (id >fs->fsopt.maxBlocks)) 556 if( (fs->fsopt.maxBlocks && (id >fs->fsopt.maxBlocks))
482 || ((whio_epfs_id_t)-1 == id)) 557 || ((whio_epfs_id_t)-1 == id))
16 hidden lines
499 bl = whio_epfs_block_empty; 574 bl = whio_epfs_block_empty;
500 bl.id = id; 575 bl.id = id;
501 } 576 }
502 if( markAsUsed ) 577 if( markAsUsed )
503 { 578 {
504 whio_epfs_block_set_used( &bl, true ); | 579 whio_epfs_block_set_used( fs, &bl, true );
505 rc = whio_epfs_block_flush( fs, &bl ); 580 rc = whio_epfs_block_flush( fs, &bl );
506 if( rc ) return rc; 581 if( rc ) return rc;
507 /** We wipe the data area for two reasons: 582 /** We wipe the data area for two reasons:
508 583
509 1) to ensure that recycled blocks behave like 584 1) to ensure that recycled blocks behave like
33 hidden lines
543 #endif 618 #endif
544 } 619 }
545 *dest = bl; 620 *dest = bl;
546 return whio_rc.OK; 621 return whio_rc.OK;
547 } 622 }
> 623 #endif
548 return rc; 624 return rc;
549 } 625 }
550 626
551 int whio_epfs_block_read_next( whio_epfs * fs, 627 int whio_epfs_block_read_next( whio_epfs * fs,
552 whio_epfs_block const * left, 628 whio_epfs_block const * left,
20 hidden lines
573 { 649 {
574 return whio_rc.OK; 650 return whio_rc.OK;
575 } 651 }
576 if( (h_ == h) && h->blocks.count ) 652 if( (h_ == h) && h->blocks.count )
577 { 653 {
578 MARKER("WARNING: this function shouldn't be called when handle->blocks.count is !0. inode=#%"WHIO_EPFS_ID_T_PFMT".", | 654 MARKER(("WARNING: this function shouldn't be called when handle->blocks.count is !0. inode=#%"WHIO_EPFS_ID_T_PFMT".",
579 ino->id); | 655 ino->id));
580 return whio_rc.OK; 656 return whio_rc.OK;
581 } 657 }
582 else if( (h_ != h) && h->blocks.count ) 658 else if( (h_ != h) && h->blocks.count )
583 { 659 {
584 /* assume the list was loaded by the original handle. */ 660 /* assume the list was loaded by the original handle. */
114 hidden lines
699 if( whio_rc.OK == rc ) 775 if( whio_rc.OK == rc )
700 { 776 {
701 *tgt = *blP; 777 *tgt = *blP;
702 } 778 }
703 return rc; 779 return rc;
> 780 }
> 781
> 782 int whio_epfs_blocks_format( whio_epfs * fs, whio_epfs_id_t from, whio_epfs_id_t to )
> 783 {
> 784 if( ! fs || (from<to) ) return whio_rc.ArgError;
> 785 else
> 786 {
> 787 whio_epfs_id_t i = 0;
> 788 if( ! from ) from = 1;
> 789 if( ! to )
> 790 {
> 791 to = fs->fsopt.maxBlocks;
> 792 if( ! to ) return whio_rc.RangeError;
> 793 }
> 794 if( fs->fsopt.maxBlocks && (i > fs->fsopt.maxBlocks) )
> 795 {
> 796 return whio_rc.RangeError;
> 797 }
> 798 if( from < to )
> 799 {
> 800 /**
> 801 Reverse free-list link order so that we get
> 802 allocated low-ID's blocks first.
> 803 */
> 804 i = from;
> 805 from = to;
> 806 to = i;
> 807 }
> 808 i = from;
> 809 whio_epfs_block bl = whio_epfs_block_empty;
> 810 int rc = whio_rc.RangeError;
> 811 for( ; i >= to; --i )
> 812 {
> 813 bl.id = i;
> 814 bl.nextFree = (i > 1) ? (i-1) : 0;
> 815 rc = whio_epfs_block_wipe( fs, &bl, true, true, false );
> 816 if( rc )
> 817 {
> 818 //MARKER("Error writing block #%"WHIO_EPFS_ID_T_PFMT"!\n",i);
> 819 break;
> 820 }
> 821 }
> 822 return rc;
> 823 }
704 } 824 }
705 825
706 #undef MARKER 826 #undef MARKER

Changes to pfs/inode.c

Old (b77b809984b28ecc) New (ee3c237647709ee6)
1 /************************************************************************ 1 /************************************************************************
2 This file contains most of the inode-specific whio_epfs routines. 2 This file contains most of the inode-specific whio_epfs routines.
3 3
4 Author: Stephan Beal (http://wanderinghorse.net/home/stephan/) 4 Author: Stephan Beal (http://wanderinghorse.net/home/stephan/)
5 5
8 hidden lines
14 #include <wh/whio/whio_encode.h> 14 #include <wh/whio/whio_encode.h>
15 #include <assert.h> 15 #include <assert.h>
16 #include <time.h> // time(), gmtime(), mktime() 16 #include <time.h> // time(), gmtime(), mktime()
17 17
18 #include "whio_epfs_internal.h" 18 #include "whio_epfs_internal.h"
> 19 #define MARKER printf("MARKER: %s:%d:%s():\t",__FILE__,__LINE__,__func__); printf
19 20
20 bool whio_epfs_inode_is_used( whio_epfs_inode const * ino ) 21 bool whio_epfs_inode_is_used( whio_epfs_inode const * ino )
21 { 22 {
22 return ino && (ino->flags & WHIO_EPFS_FLAG_IS_USED); 23 return ino && (ino->flags & WHIO_EPFS_FLAG_IS_USED);
23 } 24 }
26 hidden lines
50 whio_size_t whio_epfs_inode_encode( whio_epfs_inode const * ino, unsigned char * dest ) 51 whio_size_t whio_epfs_inode_encode( whio_epfs_inode const * ino, unsigned char * dest )
51 { 52 {
52 if( ! ino || ! dest ) return 0; 53 if( ! ino || ! dest ) return 0;
53 *(dest++) = whio_epfs_inode_tag_char; 54 *(dest++) = whio_epfs_inode_tag_char;
54 dest += whio_epfs_encode_id( dest, ino->id ); 55 dest += whio_epfs_encode_id( dest, ino->id );
55 dest += whio_encode_uint32( dest, ino->cflags ); <
56 dest += whio_encode_uint8( dest, ino->flags ); 56 dest += whio_encode_uint8( dest, ino->flags );
57 dest += whio_encode_uint32( dest, ino->mtime ); <
58 dest += whio_epfs_encode_id( dest, ino->firstBlock ); 57 dest += whio_epfs_encode_id( dest, ino->firstBlock );
> 58 dest += whio_epfs_encode_id( dest, ino->nextFree );
> 59 dest += whio_encode_uint32( dest, ino->cflags );
59 dest += whio_encode_size_t( dest, ino->size ); 60 dest += whio_encode_size_t( dest, ino->size );
> 61 dest += whio_encode_uint32( dest, ino->mtime );
60 return whio_epfs_sizeof_inode; 62 return whio_epfs_sizeof_inode;
61 } 63 }
62 int whio_epfs_inode_decode( whio_epfs_inode * ino, unsigned char const * src ) 64 int whio_epfs_inode_decode( whio_epfs_inode * ino, unsigned char const * src )
63 { 65 {
64 unsigned char const * at = src; 66 unsigned char const * at = src;
65 if( *(at++) != whio_epfs_inode_tag_char ) 67 if( *(at++) != whio_epfs_inode_tag_char )
66 { 68 {
67 return whio_rc.ConsistencyError; 69 return whio_rc.ConsistencyError;
68 } 70 }
69 int rc = whio_epfs_decode_id( at, &ino->id ); | 71 else
70 if( rc ) return rc; | 72 {
71 at += whio_epfs_sizeof_id; | 73 int rc = 0;
72 | 74 rc = whio_epfs_decode_id( at, &ino->id );
73 rc = whio_decode_uint32( at, &ino->cflags ); | 75 if( rc ) return rc;
74 if( rc ) return rc; | 76 at += whio_epfs_sizeof_id;
75 at += whio_sizeof_encoded_uint32; | 77
76 | 78 rc = whio_decode_uint8( at, &ino->flags );
77 rc = whio_decode_uint8( at, &ino->flags ); | 79 if( rc ) return rc;
78 if( rc ) return rc; | 80 at += whio_sizeof_encoded_uint8;
79 at += whio_sizeof_encoded_uint8; | 81
80 | 82 rc = whio_epfs_decode_id( at, &ino->firstBlock );
81 rc = whio_decode_uint32( at, &ino->mtime ); | 83 if( rc ) return rc;
82 if( rc ) return rc; | 84 at += whio_epfs_sizeof_id;
83 at += whio_sizeof_encoded_uint32; | 85
84 | 86 rc = whio_epfs_decode_id( at, &ino->nextFree );
85 rc = whio_epfs_decode_id( at, &ino->firstBlock ); | 87 if( rc ) return rc;
86 if( rc ) return rc; | 88 at += whio_epfs_sizeof_id;
87 at += whio_epfs_sizeof_id; | 89
88 rc = whio_decode_size_t( at, &ino->size ); | 90 rc = whio_decode_uint32( at, &ino->cflags );
89 return rc; | 91 if( rc ) return rc;
| 92 at += whio_sizeof_encoded_uint32;
| 93
| 94 rc = whio_decode_size_t( at, &ino->size );
| 95 if( rc ) return rc;
| 96 at += whio_sizeof_encoded_size_t;
| 97
| 98 rc = whio_decode_uint32( at, &ino->mtime );
| 99 if( rc ) return rc;
| 100 at += whio_sizeof_encoded_uint32;
| 101
| 102 return rc;
| 103 }
90 } 104 }
91 105
92 bool whio_epfs_inode_id_in_bounds( whio_epfs const * fs, 106 bool whio_epfs_inode_id_in_bounds( whio_epfs const * fs,
93 whio_epfs_id_t ino ) 107 whio_epfs_id_t ino )
94 { 108 {
140 hidden lines
235 } 249 }
236 } 250 }
237 251
238 252
239 int whio_epfs_inode_read( whio_epfs * fs, 253 int whio_epfs_inode_read( whio_epfs * fs,
240 whio_epfs_id_t id, | 254 whio_epfs_id_t id,
241 whio_epfs_inode * dest ) | 255 whio_epfs_inode * dest )
242 { 256 {
243 if( ! fs || !dest ) return whio_rc.ArgError; 257 if( ! fs || !dest ) return whio_rc.ArgError;
244 whio_size_t pos = whio_epfs_inode_id_pos( fs, id ); 258 whio_size_t pos = whio_epfs_inode_id_pos( fs, id );
245 if( ! pos ) 259 if( ! pos )
246 { 260 {
183 hidden lines
430 rc = whio_epfs_inode_client_flags_get( ino, flags ); 444 rc = whio_epfs_inode_client_flags_get( ino, flags );
431 } 445 }
432 return rc; 446 return rc;
433 } 447 }
434 448
> 449 #undef MARKER

Changes to pfs/ls.c

Old (55ea713474af85bf) New (9bf1654b37254e30)
1 /************************************************************************ 1 /************************************************************************
2 An "ls"-like program for use with whio_epfs. 2 An "ls"-like program for use with whio_epfs.
3 3
4 Author: Stephan Beal (http://wanderinghorse.net/home/stephan/) 4 Author: Stephan Beal (http://wanderinghorse.net/home/stephan/)
5 5
200 hidden lines
206 whio_epfs_fsopt const * fopt = whio_epfs_options(EPFSApp.fs); 206 whio_epfs_fsopt const * fopt = whio_epfs_options(EPFSApp.fs);
207 ls_foreach_info info = ls_foreach_info_empty; 207 ls_foreach_info info = ls_foreach_info_empty;
208 if( ! AppLs.oneMode ) 208 if( ! AppLs.oneMode )
209 { 209 {
210 printf("whio_efps container file [%s]:\n" 210 printf("whio_efps container file [%s]:\n"
211 "\tLabel: [%s]\n" | 211 "Label:\t[%s]\n",
212 "\t[inodes=%"WHIO_EPFS_ID_T_PFMT"] [maxEverUsedInodeID==%"WHIO_EPFS_ID_T_PFMT"]\n" |
213 "\t[blockSize=%"WHIO_SIZE_T_PFMT"] [blocksInFS=%"WHIO_EPFS_ID_T_PFMT"] [maxBlocks=%"WHIO_EPFS_ID_T_PFMT"] [maxEverUsedBlockID==%"WHIO_EPFS_ID_T_PFMT"]" |
214 "\n", |
215 EPFSApp.fsName, 212 EPFSApp.fsName,
216 (AppLs.label && *AppLs.label) ? AppLs.label : "<empty>", | 213 (AppLs.label && *AppLs.label) ? AppLs.label : "<empty>"
217 fopt->inodeCount, EPFSApp.fs->hints.maxEverUsedInode, |
218 fopt->blockSize, EPFSApp.fs->hints.blockCount, fopt->maxBlocks, EPFSApp.fs->hints.maxEverUsedBlock |
219 ); 214 );
> 215 if( EPFSApp.verbose )
> 216 {
> 217 printf("\t[inodes=%"WHIO_EPFS_ID_T_PFMT"] [maxEverUsedInodeID==%"WHIO_EPFS_ID_T_PFMT"]\n"
> 218 "\t[blockSize=%"WHIO_SIZE_T_PFMT"] [blocksInFS=%"WHIO_EPFS_ID_T_PFMT"] [maxBlocks=%"WHIO_EPFS_ID_T_PFMT"] [maxEverUsedBlockID==%"WHIO_EPFS_ID_T_PFMT"]\n"
> 219 "\t[freeBlockList=%"WHIO_SIZE_T_PFMT"]"
> 220 "\n",
> 221 fopt->inodeCount, EPFSApp.fs->hints.maxEverUsedInode,
> 222 fopt->blockSize, EPFSApp.fs->hints.blockCount, fopt->maxBlocks, EPFSApp.fs->hints.maxEverUsedBlock,
> 223 EPFSApp.fs->hints.freeBlockList
> 224 );
> 225 }
220 226
221 //printf("Magic bytes: "); ls_dump_core_magic(); 227 //printf("Magic bytes: "); ls_dump_core_magic();
222 printf("Inode #\t Size\t "); 228 printf("Inode #\t Size\t ");
223 if( AppLs.showFlags ) 229 if( AppLs.showFlags )
224 { 230 {
8 hidden lines
233 puts(""); 239 puts("");
234 } 240 }
235 whio_epfs_fsopt const * o = whio_epfs_options(EPFSApp.fs); 241 whio_epfs_fsopt const * o = whio_epfs_options(EPFSApp.fs);
236 int rc = whio_epfs_foreach_inode( EPFSApp.fs, NULL, NULL, inode_foreach_ls, &info ); 242 int rc = whio_epfs_foreach_inode( EPFSApp.fs, NULL, NULL, inode_foreach_ls, &info );
237 243
> 244
238 if( ! AppLs.oneMode ) 245 if( ! AppLs.oneMode )
239 { 246 {
240 printf("\nTotal: %"WHIO_EPFS_ID_T_PFMT" of %"WHIO_EPFS_ID_T_PFMT" inodes take up " 247 printf("\nTotal: %"WHIO_EPFS_ID_T_PFMT" of %"WHIO_EPFS_ID_T_PFMT" inodes take up "
241 "%"WHIO_SIZE_T_PFMT" bytes", 248 "%"WHIO_SIZE_T_PFMT" bytes",
242 info.inodeCount, o->inodeCount, 249 info.inodeCount, o->inodeCount,
3 hidden lines
246 { 253 {
247 printf(" in %"WHIO_EPFS_ID_T_PFMT" blocks", 254 printf(" in %"WHIO_EPFS_ID_T_PFMT" blocks",
248 info.blockCount ); 255 info.blockCount );
249 } 256 }
250 puts("."); 257 puts(".");
> 258 }
> 259
> 260 if( EPFSApp.verbose && AppLs.showBlocks )
> 261 {
> 262 puts("\nData block free-list: ");
> 263 whio_epfs_id_t f = EPFSApp.fs->hints.freeBlockList;
> 264 if( !f )
> 265 {
> 266 puts("No explicit unused blocks.");
> 267 }
> 268 else
> 269 while( f )
> 270 {
> 271 whio_epfs_block bl = whio_epfs_block_empty;
> 272 rc = whio_epfs_block_read( EPFSApp.fs, f, &bl );
> 273 if( rc )
> 274 {
> 275 APPERR("Error reading block #%"WHIO_EPFS_ID_T_PFMT"!\n",f);
> 276 break;
> 277 }
> 278 printf("%"WHIO_EPFS_ID_T_PFMT"->%"WHIO_EPFS_ID_T_PFMT"%s",
> 279 bl.id, bl.nextFree,
> 280 (bl.nextFree ? ", " : "")
> 281 );
> 282 f = bl.nextFree;
> 283 }
> 284 putchar('\n');
251 } 285 }
252 if( rc ) 286 if( rc )
253 { 287 {
254 APPERR("Got error code %d while looping over inodes!\n", rc ); 288 APPERR("Got error code %d while looping over inodes!\n", rc );
255 } 289 }
160 hidden lines
416 } 450 }
417 } 451 }
418 EPFSApp_verbose_error_code( rc ); 452 EPFSApp_verbose_error_code( rc );
419 return rc; 453 return rc;
420 } 454 }

Changes to pfs/mkfs.c

Old (d2b0b5e426bec894) New (dba5fa1c0c1d8940)
1 /* 1 /*
2 Author: Stephan Beal (http://wanderinghorse.net/home/stephan/ 2 Author: Stephan Beal (http://wanderinghorse.net/home/stephan/
3 3
4 License: Public Domain 4 License: Public Domain
5 */ 5 */
80 hidden lines
86 } 86 }
87 if( fsopt->maxBlocks && AppMkfs.fillBlocks ) 87 if( fsopt->maxBlocks && AppMkfs.fillBlocks )
88 { 88 {
89 VERBOSE("Filling out blocks table with %"WHIO_EPFS_ID_T_PFMT" blocks...\n", 89 VERBOSE("Filling out blocks table with %"WHIO_EPFS_ID_T_PFMT" blocks...\n",
90 fsopt->maxBlocks); 90 fsopt->maxBlocks);
91 whio_epfs_id_t i = 1; | 91 rc = whio_epfs_blocks_format( EPFSApp.fs, 0, 0 );
92 whio_epfs_block bl = whio_epfs_block_empty; | 92 if( rc )
93 for( ; i <= fsopt->maxBlocks; ++i ) |
94 { 93 {
95 bl.id = i; | 94 APPERR("Block-filling failed with code %d!\n", rc );
96 rc = whio_epfs_block_wipe( EPFSApp.fs, &bl, true, true, false ); |
97 if( rc ) |
98 { |
99 APPERR("Error writing block #%"WHIO_EPFS_ID_T_PFMT"!\n",i); |
100 break; |
101 } |
102 } 95 }
103 } 96 }
104 if( !rc && AppMkfs.label ) do 97 if( !rc && AppMkfs.label ) do
105 { 98 {
106 whio_size_t len = (whio_size_t)strlen(AppMkfs.label); 99 whio_size_t len = (whio_size_t)strlen(AppMkfs.label);
80 hidden lines
187 const whio_size_t sz = whio_dev_size( EPFSApp.fs->dev ); 180 const whio_size_t sz = whio_dev_size( EPFSApp.fs->dev );
188 APPMSG("EFS container created (%"WHIO_SIZE_T_PFMT" bytes).\n",sz); 181 APPMSG("EFS container created (%"WHIO_SIZE_T_PFMT" bytes).\n",sz);
189 } 182 }
190 return rc; 183 return rc;
191 } 184 }

Changes to pfs/pfs.c

Old (5362e1b0afb6a286) New (f2648eead089b3f3)
1 /************************************************************************ 1 /************************************************************************
2 This is a work-in-progress, porting over parts of the whefs API into 2 This is a work-in-progress, porting over parts of the whefs API into
3 the whio API... 3 the whio API...
4 4
5 Author: Stephan Beal (http://wanderinghorse.net/home/stephan/) 5 Author: Stephan Beal (http://wanderinghorse.net/home/stephan/)
33 hidden lines
39 #define MARKER printf("MARKER: %s:%d:%s():\t",__FILE__,__LINE__,__func__); printf 39 #define MARKER printf("MARKER: %s:%d:%s():\t",__FILE__,__LINE__,__func__); printf
40 40
41 const uint16_t whio_epfs_magic_bytes[] = 41 const uint16_t whio_epfs_magic_bytes[] =
42 { 42 {
43 2010, 43 2010,
44 2, | 44 3,
45 21, | 45 10,
46 WHIO_SIZE_T_BITS, 46 WHIO_SIZE_T_BITS,
47 WHIO_EPFS_ID_T_BITS, 47 WHIO_EPFS_ID_T_BITS,
48 whio_epfs_sizeof_label_payload, 48 whio_epfs_sizeof_label_payload,
49 0 }; 49 0 };
50 50
529 hidden lines
580 580
581 rc = whio_epfs_encode_id( dest, fs->hints.maxEverUsedInode ); 581 rc = whio_epfs_encode_id( dest, fs->hints.maxEverUsedInode );
582 dest += rc; 582 dest += rc;
583 sz += rc; 583 sz += rc;
584 584
> 585 #if 0
585 rc = whio_epfs_encode_id( dest, fs->hints.nextFreeBlock ); 586 rc = whio_epfs_encode_id( dest, fs->hints.nextFreeBlock );
586 dest += rc; 587 dest += rc;
587 sz += rc; 588 sz += rc;
588 | 589 #endif
589 rc = whio_epfs_encode_id( dest, fs->hints.maxEverUsedBlock ); 590 rc = whio_epfs_encode_id( dest, fs->hints.maxEverUsedBlock );
> 591 dest += rc;
> 592 sz += rc;
> 593
> 594 rc = whio_epfs_encode_id( dest, fs->hints.freeBlockList );
590 dest += rc; 595 dest += rc;
591 sz += rc; 596 sz += rc;
592 597
593 rc = whio_epfs_encode_id( dest, fs->hints.blockCount ); 598 rc = whio_epfs_encode_id( dest, fs->hints.blockCount );
594 dest += rc; 599 dest += rc;
38 hidden lines
633 638
634 rc = whio_epfs_decode_id( at, &fs->hints.maxEverUsedInode ); 639 rc = whio_epfs_decode_id( at, &fs->hints.maxEverUsedInode );
635 at += whio_epfs_sizeof_id; 640 at += whio_epfs_sizeof_id;
636 if( rc ) return rc; 641 if( rc ) return rc;
637 642
> 643 #if 0
638 rc = whio_epfs_decode_id( at, &fs->hints.nextFreeBlock ); 644 rc = whio_epfs_decode_id( at, &fs->hints.nextFreeBlock );
639 at += whio_epfs_sizeof_id; 645 at += whio_epfs_sizeof_id;
640 if( rc ) return rc; 646 if( rc ) return rc;
> 647 #endif
641 648
642 rc = whio_epfs_decode_id( at, &fs->hints.maxEverUsedBlock ); 649 rc = whio_epfs_decode_id( at, &fs->hints.maxEverUsedBlock );
> 650 at += whio_epfs_sizeof_id;
> 651 if( rc ) return rc;
> 652
> 653 rc = whio_epfs_decode_id( at, &fs->hints.freeBlockList );
643 at += whio_epfs_sizeof_id; 654 at += whio_epfs_sizeof_id;
644 if( rc ) return rc; 655 if( rc ) return rc;
645 656
646 rc = whio_epfs_decode_id( at, &fs->hints.blockCount ); 657 rc = whio_epfs_decode_id( at, &fs->hints.blockCount );
647 at += whio_epfs_sizeof_id; 658 at += whio_epfs_sizeof_id;
7 hidden lines
655 int rc = 0; 666 int rc = 0;
656 whio_size_t i; 667 whio_size_t i;
657 for( i = 1; (!rc) && (i <= fs->fsopt.inodeCount); ++i ) 668 for( i = 1; (!rc) && (i <= fs->fsopt.inodeCount); ++i )
658 { 669 {
659 ino.id = i; 670 ino.id = i;
> 671 ino.nextFree = (i < fs->fsopt.inodeCount) ? (i+1) : 0;
660 rc = whio_epfs_inode_flush( fs, &ino ); 672 rc = whio_epfs_inode_flush( fs, &ino );
661 } 673 }
662 return rc; 674 return rc;
663 } 675 }
664 676
454 hidden lines
1119 return rc; 1131 return rc;
1120 } 1132 }
1121 1133
1122 1134
1123 #undef MARKER 1135 #undef MARKER

Changes to pfs/sanityCheck.sh

Old (775a49ae4372b635) New (43e4308f98c61145)
1 #!/bin/bash 1 #!/bin/bash
2 ######################################################################## 2 ########################################################################
3 # Some quite sanity tests for whio_epfs. 3 # Some quite sanity tests for whio_epfs.
4 # Should be run from the source dir. 4 # Should be run from the source dir.
5 WHIODIR=../src 5 WHIODIR=../src
18 hidden lines
24 exit 2 24 exit 2
25 } 25 }
26 26
27 fs=my.epfs 27 fs=my.epfs
28 blockSize=$((512*8)) 28 blockSize=$((512*8))
29 inodeCount=256 | 29 inodeCount=40
30 blockCount=512 | 30 blockCount=100
31 theDir=. 31 theDir=.
32 mkfs="${theDir}/whio-epfs-mkfs" 32 mkfs="${theDir}/whio-epfs-mkfs"
33 cp="${theDir}/whio-epfs-cp" 33 cp="${theDir}/whio-epfs-cp"
34 ls="${theDir}/whio-epfs-ls" 34 ls="${theDir}/whio-epfs-ls"
35 rm="${theDir}/whio-epfs-rm" 35 rm="${theDir}/whio-epfs-rm"
80 hidden lines
116 ecp -i ${fs} ${ino}=${testin} || die "cp import failed!" 116 ecp -i ${fs} ${ino}=${testin} || die "cp import failed!"
117 ecp -x ${fs} ${ino}=${testout} || die "cp export failed!" 117 ecp -x ${fs} ${ino}=${testout} || die "cp export failed!"
118 cmp ${testin} ${testout} || die "Compare of imported/exported data failed!" 118 cmp ${testin} ${testout} || die "Compare of imported/exported data failed!"
119 echo "Compare of imported/exported files suceeded." 119 echo "Compare of imported/exported files suceeded."
120 120
121 els ${fs} || die "ls failed!" | 121 els -b ${fs} || die "ls failed!"
122 122
123 line="********************************************************************************" 123 line="********************************************************************************"
124 echo "$line" 124 echo "$line"
125 echo "If you got this far, sanity checks appear to have worked." 125 echo "If you got this far, sanity checks appear to have worked."
126 echo "$line" 126 echo "$line"

Changes to pfs/test.c

Old (4650356b64ce008b) New (4afcd569975d14f4)
1 /************************************************************************ 1 /************************************************************************
2 FAR FROM COMPLETE. 2 FAR FROM COMPLETE.
3 3
4 This is a work-in-progress, porting over parts of the whefs API into 4 This is a work-in-progress, porting over parts of the whefs API into
5 the whio API... 5 the whio API...
49 hidden lines
55 55
56 The address 0x4000300020003 is apparently bogus, but i don't know where it's coming from. 56 The address 0x4000300020003 is apparently bogus, but i don't know where it's coming from.
57 */ 57 */
58 enum { AllocatorSize = 58 enum { AllocatorSize =
59 //5000 only a very large EFS with lots of opened records would need this much 59 //5000 only a very large EFS with lots of opened records would need this much
60 1000 | 60 //2000
61 //500 // works for small use cases on 32-bit, but not 64-bit. 61 //500 // works for small use cases on 32-bit, but not 64-bit.
62 //0 // uses stdlib allocators | 62 0 // uses stdlib allocators
63 }; 63 };
64 static struct Application 64 static struct Application
65 { 65 {
66 whio_stream * cout; 66 whio_stream * cout;
67 unsigned char buffer[AllocatorSize ? AllocatorSize : 1]; 67 unsigned char buffer[AllocatorSize ? AllocatorSize : 1];
192 hidden lines
260 dev = 0; 260 dev = 0;
261 rc = whio_epfs_dev_open( fs, &dev, 0, WHIO_EPFS_MODE_RW | WHIO_EPFS_MODE_FLAG_CREATE ); 261 rc = whio_epfs_dev_open( fs, &dev, 0, WHIO_EPFS_MODE_RW | WHIO_EPFS_MODE_FLAG_CREATE );
262 assert( !rc && "opendev failed!"); 262 assert( !rc && "opendev failed!");
263 MARKER("opendev got whio_dev@%p\n",(void const *)dev); 263 MARKER("opendev got whio_dev@%p\n",(void const *)dev);
264 sz = fs->fsopt.blockSize * 2.5; 264 sz = fs->fsopt.blockSize * 2.5;
> 265 MARKER("Truncating to %"WHIO_SIZE_T_PFMT" bytes.\n",sz);
265 rc = dev->api->truncate( dev, sz ); 266 rc = dev->api->truncate( dev, sz );
266 MARKER("Truncated to %"WHIO_SIZE_T_PFMT" bytes. rc=%d\n",sz,rc); 267 MARKER("Truncated to %"WHIO_SIZE_T_PFMT" bytes. rc=%d\n",sz,rc);
267 assert( !rc && "Truncate failed!" ); 268 assert( !rc && "Truncate failed!" );
268 inoID = whio_epfs_dev_inode_id( dev ); 269 inoID = whio_epfs_dev_inode_id( dev );
269 dump_fs_mem(fs); 270 dump_fs_mem(fs);
113 hidden lines
383 rc = whio_epfs_inode_next_free( fs, &ino, true ); 384 rc = whio_epfs_inode_next_free( fs, &ino, true );
384 assert( !rc && "next-free-inode failed!"); 385 assert( !rc && "next-free-inode failed!");
385 MARKER("Next free inode=%"WHIO_EPFS_ID_T_PFMT"\n",ino.id); 386 MARKER("Next free inode=%"WHIO_EPFS_ID_T_PFMT"\n",ino.id);
386 } 387 }
387 } 388 }
388 <
389 if(0 && fs->fsopt.maxBlocks) 389 if(0 && fs->fsopt.maxBlocks)
390 { 390 {
391 whio_epfs_block bl = whio_epfs_block_empty; 391 whio_epfs_block bl = whio_epfs_block_empty;
392 bl.id = 3; 392 bl.id = 3;
393 whio_epfs_block_set_used( &bl, true ); | 393 whio_epfs_block_set_used( fs, &bl, true );
394 rc = whio_epfs_block_flush( fs, &bl ); 394 rc = whio_epfs_block_flush( fs, &bl );
395 whio_epfs_id_t i; 395 whio_epfs_id_t i;
396 for( i = 1; (i<=(fs->fsopt.maxBlocks/2)) && !rc; ++i ) 396 for( i = 1; (i<=(fs->fsopt.maxBlocks/2)) && !rc; ++i )
397 { 397 {
398 MARKER("fs->hints.nextFreeBlock=%"WHIO_EPFS_ID_T_PFMT"\n",fs->hints.nextFreeBlock); | 398 MARKER("fs->hints.freeBlockList=%"WHIO_EPFS_ID_T_PFMT"\n",fs->hints.freeBlockList);
399 rc = whio_epfs_block_next_free( fs, &bl, true ); 399 rc = whio_epfs_block_next_free( fs, &bl, true );
400 //assert( !rc && "next-free-inode failed!"); 400 //assert( !rc && "next-free-inode failed!");
401 if( rc ) { break; } 401 if( rc ) { break; }
402 MARKER("Next free block rc=%d, id=%"WHIO_EPFS_ID_T_PFMT", " 402 MARKER("Next free block rc=%d, id=%"WHIO_EPFS_ID_T_PFMT", "
403 "fs->hints.nextFreeBlock=%"WHIO_EPFS_ID_T_PFMT"\n", | 403 "fs->hints.freeBlockList=%"WHIO_EPFS_ID_T_PFMT"\n",
404 rc, bl.id, fs->hints.nextFreeBlock); | 404 rc, bl.id, fs->hints.freeBlockList);
405 if(0) if( i && ! (i%3) ) 405 if(0) if( i && ! (i%3) )
406 { 406 {
407 bl.id -= 2; 407 bl.id -= 2;
408 MARKER("Un-using block #%"WHIO_EPFS_ID_T_PFMT".\n",bl.id); 408 MARKER("Un-using block #%"WHIO_EPFS_ID_T_PFMT".\n",bl.id);
409 whio_epfs_block_set_used( &bl, false ); | 409 whio_epfs_block_set_used( fs, &bl, false );
410 rc = whio_epfs_block_flush( fs, &bl ); 410 rc = whio_epfs_block_flush( fs, &bl );
411 MARKER("Un-used block #%"WHIO_EPFS_ID_T_PFMT", rc=%d.\n",bl.id,rc); 411 MARKER("Un-used block #%"WHIO_EPFS_ID_T_PFMT", rc=%d.\n",bl.id,rc);
412 } 412 }
413 413
414 } 414 }
102 hidden lines
517 SO(ThisApp.buffer); 517 SO(ThisApp.buffer);
518 #undef SO 518 #undef SO
519 MARKER("Done. rc=%d\n",rc); 519 MARKER("Done. rc=%d\n",rc);
520 return rc; 520 return rc;
521 } 521 }

Changes to pfs/whio_epfs_internal.h

Old (8c755f4f661c5bc4) New (43ec21d3d412a462)
1 #ifndef WANDERINGHORSE_NET_WHIO_EPFS_INTERNAL_H_INCLUDED 1 #ifndef WANDERINGHORSE_NET_WHIO_EPFS_INTERNAL_H_INCLUDED
2 #define WANDERINGHORSE_NET_WHIO_EPFS_INTERNAL_H_INCLUDED 2 #define WANDERINGHORSE_NET_WHIO_EPFS_INTERNAL_H_INCLUDED
3 3
4 /** @file whio_epfs_internal.h 4 /** @file whio_epfs_internal.h
5 5
215 hidden lines
221 but it can only fail if !bl. If !u then bl is zeroed out 221 but it can only fail if !bl. If !u then bl is zeroed out
222 except for its id. This means that any blocks which bl links 222 except for its id. This means that any blocks which bl links
223 to MUST be set to unused before bl is, or blocks may be 223 to MUST be set to unused before bl is, or blocks may be
224 orphaned. 224 orphaned.
225 225
226 Does not update storage. | 226 Does not update storage but may update fs->hints.freeBlockList
| 227 and bl->nextFree.
| 228
| 229 If bl already has the given use-state, this function has no
| 230 side-effects.
227 */ 231 */
228 int whio_epfs_block_set_used( whio_epfs_block * bl, bool u ); | 232 int whio_epfs_block_set_used( whio_epfs * fs, whio_epfs_block * bl, bool u );
229 233
230 /** @internal 234 /** @internal
231 235
232 Returns the on-storage position of the given block. This is 236 Returns the on-storage position of the given block. This is
233 where the metadata is stored - the client data follows that. 237 where the metadata is stored - the client data follows that.
30 hidden lines
264 Flushes the given block, which must be a properly populated 268 Flushes the given block, which must be a properly populated
265 object, to storage. This writes only the metadata part of the 269 object, to storage. This writes only the metadata part of the
266 block, not the client data. Returns 0 on success. 270 block, not the client data. Returns 0 on success.
267 */ 271 */
268 int whio_epfs_block_flush( whio_epfs * fs, whio_epfs_block const * bl ); 272 int whio_epfs_block_flush( whio_epfs * fs, whio_epfs_block const * bl );
> 273
> 274 /** @internal
> 275
> 276 "Formats" an inclusive range of blocks in fs, destroying their
> 277 contents and adding them to the free-block list. It pays NO
> 278 ATTENTION to whether or not those blocks are in use, and thus
> 279 corrupts any in-use inodes which use those blocks. Thus it
> 280 should only be called as part of the mkfs() process to pre-fill
> 281 any blocks.
> 282
> 283 If from is 0 then 1 is used. If to is 0 then
> 284 fs->fsopt.maxBlocks is used. If to and fs->fsopt.maxBlocks are
> 285 both 0, whio_rc.RangeError is returned. whio_rc.RangeError is also
> 286 returned if fs->fsopt.maxBlocks is not 0 and to is higher than
> 287 that value.
> 288
> 289 from must be 0 or less than to.
> 290
> 291 Returns 0 on success.
> 292 */
> 293 int whio_epfs_blocks_format( whio_epfs * fs, whio_epfs_id_t from, whio_epfs_id_t to );
269 294
270 /** @internal 295 /** @internal
271 296
272 Tries to read the given block ID and store it into dest. On 297 Tries to read the given block ID and store it into dest. On
273 success, 0 is returned. 298 success, 0 is returned.
739 hidden lines
1013 #ifdef __cplusplus 1038 #ifdef __cplusplus
1014 } /* extern "C" */ 1039 } /* extern "C" */
1015 #endif 1040 #endif
1016 1041
1017 #endif /* WANDERINGHORSE_NET_WHIO_EPFS_INTERNAL_H_INCLUDED */ 1042 #endif /* WANDERINGHORSE_NET_WHIO_EPFS_INTERNAL_H_INCLUDED */