AmendHub

Download:

jcs

/

amend

/

amendments

/

53

bile: New code


jcs made amendment 53 over 2 years ago
--- bile.c Wed Jan 19 16:22:46 2022 +++ bile.c Fri Jan 21 17:59:46 2022 @@ -19,12 +19,16 @@ #include "util.h" /* for errors not specific to a bile */ -static short _bile_error; +static short _bile_error = 0; +static short _bile_open_ignore_primary_map = 0; + struct bile_object * bile_alloc(struct bile *bile, const OSType type, const unsigned long id, const size_t size); struct bile_object * bile_object_in_map(struct bile *bile, const OSType type, const unsigned long id); +short bile_read_map(struct bile *bile, + struct bile_object *map_ptr); short bile_write_map(struct bile *bile); void bile_sort_by_pos(struct bile *bile); size_t bile_xwriteat(struct bile *bile, const size_t pos, @@ -164,62 +168,17 @@ bile_open(const Str255 filename, short vrefnum) if (_bile_error) goto open_bail; -retry_map_check: - if (bile->map_ptr.pos + bile->map_ptr.size > file_size) { - if (old_map_tried) - panic("bile_open: map points to %lu + %lu, but file is only %lu", - bile->map_ptr.pos, bile->map_ptr.size, file_size); - goto load_old_map; + if (_bile_open_ignore_primary_map) { + if (!bile->old_map_ptr.size) + goto open_bail; + bile->map_ptr = bile->old_map_ptr; } - if (bile->map_ptr.size % BILE_OBJECT_SIZE != 0) { - if (old_map_tried) - panic("bile_open: map pointer size is not a multiple of object " - "size (%lu): %lu", BILE_OBJECT_SIZE, bile->map_ptr.size); - goto load_old_map; - } if (bile->map_ptr.size) { - /* read and verify map object header map_ptr points to */ - _bile_error = SetFPos(bile->frefnum, fsFromStart, - bile->map_ptr.pos); - if (_bile_error) { - if (old_map_tried) - goto open_bail; - goto load_old_map; + if (bile_read_map(bile, &bile->map_ptr) != 0) { + warn("bile_open: Failed reading map"); + goto open_bail; } - - size = sizeof(struct bile_object); - _bile_error = FSRead(bile->frefnum, &size, &map_obj); - if (_bile_error) { - if (old_map_tried) - goto open_bail; - goto load_old_map; - } - - if (map_obj.pos != bile->map_ptr.pos) { - if (old_map_tried) - panic("bile_open: map pointer points to %lu but object " - "there has position %lu", bile->map_ptr.pos, map_obj.pos); - goto load_old_map; - } - if (map_obj.size != bile->map_ptr.size) { - if (old_map_tried) - panic("bile_open: map is supposed to have size %lu but " - "object pointed to has size %lu", bile->map_ptr.size, - map_obj.size); - goto load_old_map; - } - - /* read entire map */ - size = map_obj.size; - bile->map = xmalloczero(size); - _bile_error = FSRead(bile->frefnum, &size, bile->map); - if (_bile_error) { - if (old_map_tried) - goto open_bail; - goto load_old_map; - } - bile->nobjects = map_obj.size / BILE_OBJECT_SIZE; } return bile; @@ -229,16 +188,54 @@ open_bail: if (bile != NULL) free(bile); return NULL; +} -load_old_map: - if (bile->old_map_ptr.pos == 0) - goto open_bail; - _bile_error = 0; - old_map_tried = 1; - bile->map_ptr = bile->old_map_ptr; - goto retry_map_check; +struct bile * +bile_open_recover_map(const Str255 filename, short vrefnum) +{ + struct bile *bile; + + _bile_open_ignore_primary_map = 1; + bile = bile_open(filename, vrefnum); + _bile_open_ignore_primary_map = 0; + + if (bile) { + bile->map_ptr = bile->old_map_ptr; + bile_write_map(bile); + } + + return bile; } +short +bile_autoflush(struct bile *bile, short val) +{ + bile->autoflush = val; +} + +short +bile_flush(struct bile *bile, short and_vol) +{ + IOParam pb; + short ret; + + memset(&pb, 0, sizeof(pb)); + pb.ioRefNum = bile->frefnum; + ret = PBFlushFile(&pb, false); + if (ret != noErr) + return ret; + + if (and_vol) { + memset(&pb, 0, sizeof(pb)); + /* XXX: this flushes default volume, maybe flush specific volume */ + ret = PBFlushVol(&pb, false); + if (ret != noErr) + return ret; + } + + return 0; +} + void bile_close(struct bile *bile) { @@ -399,30 +396,51 @@ bile_read_object(struct bile *bile, const struct bile_ _bile_error = bile->last_error = 0; - if (o->pos + BILE_OBJECT_SIZE + o->size > bile->file_size) - panic("bile_read_object: object %ld pos %ld size %ld > file size %ld", - o->id, o->pos, o->size, bile->file_size); + if (o->pos + BILE_OBJECT_SIZE + o->size > bile->file_size) { + warn("bile_read_object: object %s:%ld pos %ld size %ld > " + "file size %ld", OSTypeToString(o->type), o->id, o->pos, + o->size, bile->file_size); + _bile_error = bile->last_error = BILE_ERR_BOGUS_OBJECT; + return 0; + } - _bile_error = SetFPos(bile->frefnum, fsFromStart, o->pos); - if (_bile_error) - panic("bile_read_object: object %lu points to bogus position %lu", - o->id, o->pos); - + _bile_error = bile->last_error = SetFPos(bile->frefnum, fsFromStart, + o->pos); + if (_bile_error) { + warn("bile_read_object: object %s:%lu points to bogus position " + "%lu", OSTypeToString(o->type), o->id, o->pos); + _bile_error = bile->last_error = BILE_ERR_BOGUS_OBJECT; + return 0; + } + rsize = BILE_OBJECT_SIZE; - _bile_error = bile->last_error = FSRead(bile->frefnum, &rsize, &verify); + _bile_error = bile->last_error = FSRead(bile->frefnum, &rsize, + &verify); if (_bile_error) return 0; - if (verify.id != o->id) - panic("bile_read_object: object %ld pos %ld wrong id %ld, " - "expected %ld", o->id, o->pos, verify.id, o->id); - if (verify.type != o->type) - panic("bile_read_object: object %ld pos %ld wrong type %ld, " - "expected %ld", o->id, o->pos, verify.type, o->type); - if (verify.size != o->size) - panic("bile_read_object: object %ld pos %ld wrong size %ld, " - "expected %ld", o->id, o->pos, verify.size, o->size); - + if (verify.id != o->id) { + warn("bile_read_object: object %s:%ld pos %ld wrong id %ld, " + "expected %ld", OSTypeToString(o->type), o->id, o->pos, + verify.id, o->id); + _bile_error = bile->last_error = BILE_ERR_BOGUS_OBJECT; + return 0; + } + if (verify.type != o->type) { + warn("bile_read_object: object %s:%ld pos %ld wrong type %ld, " + "expected %ld", OSTypeToString(o->type), o->id, o->pos, + verify.type, o->type); + _bile_error = bile->last_error = BILE_ERR_BOGUS_OBJECT; + return 0; + } + if (verify.size != o->size) { + warn("bile_read_object: object %s:%ld pos %ld wrong size %ld, " + "expected %ld", OSTypeToString(o->type), o->id, o->pos, + verify.size, o->size); + _bile_error = bile->last_error = BILE_ERR_BOGUS_OBJECT; + return 0; + } + wantlen = len; if (wantlen > o->size) wantlen = o->size; @@ -432,9 +450,13 @@ bile_read_object(struct bile *bile, const struct bile_ if (_bile_error) return 0; - if (rsize != wantlen) - panic("bile_read: needed to read %ld, read %ld", wantlen, rsize); - + if (rsize != wantlen) { + warn("bile_read: %s:%lu: needed to read %ld, read %ld", + OSTypeToString(o->type), o->id, wantlen, rsize); + _bile_error = bile->last_error = BILE_ERR_BOGUS_OBJECT; + return 0; + } + return rsize; } @@ -531,12 +553,11 @@ bile_write(struct bile *bile, const OSType type, const return wrote; } - -void +short bile_verify(struct bile *bile) { struct bile_object o; - size_t n; + size_t n, size; char data; if (bile == NULL) @@ -544,8 +565,15 @@ bile_verify(struct bile *bile) _bile_error = bile->last_error = 0; - for (n = 0; n < bile->nobjects; n++) - bile_read_object(bile, &bile->map[n], &data, 1); + for (n = 0; n < bile->nobjects; n++) { + size = bile_read_object(bile, &bile->map[n], &data, 1); + if (bile_error(bile)) + return bile_error(bile); + else if (size == 0) + return -1; + } + + return 0; } /* Private API */ @@ -615,9 +643,63 @@ bile_alloc(struct bile *bile, const OSType type, const } short +bile_read_map(struct bile *bile, struct bile_object *map_ptr) +{ + size_t size; + struct bile_object map_obj, *map; + + if (map_ptr->pos + map_ptr->size > bile->file_size) { + warn("bile_read_map: map points to %lu + %lu, but file is only %lu", + map_ptr->pos, map_ptr->size, bile->file_size); + return -1; + } + + if (map_ptr->size % BILE_OBJECT_SIZE != 0) { + warn("bile_read_map: map pointer size is not a multiple of object " + "size (%lu): %lu", BILE_OBJECT_SIZE, map_ptr->size); + return -1; + } + + /* read and verify map object header map_ptr points to */ + _bile_error = SetFPos(bile->frefnum, fsFromStart, map_ptr->pos); + if (_bile_error) + return -1; + + size = sizeof(struct bile_object); + _bile_error = FSRead(bile->frefnum, &size, &map_obj); + if (_bile_error) + return -1; + + if (map_obj.pos != map_ptr->pos) { + warn("bile_read_map: map pointer points to %lu but object " + "there has position %lu", map_ptr->pos, map_obj.pos); + return -1; + } + + if (map_obj.size != map_ptr->size) { + warn("bile_read_map: map is supposed to have size %lu but " + "object pointed to has size %lu", map_ptr->size, map_obj.size); + return -1; + } + + /* read entire map */ + size = map_obj.size; + map = xmalloczero(size); + _bile_error = FSRead(bile->frefnum, &size, map); + if (_bile_error) { + free(map); + return -1; + } + + bile->map = map; + bile->nobjects = map_obj.size / BILE_OBJECT_SIZE; + + return 0; +} + +short bile_write_map(struct bile *bile) { - IOParam pb; struct bile_object *obj, *new_map_obj, *new_map, *new_map_obj_in_new_map = NULL; size_t new_map_size, new_nobjects, new_map_id; @@ -677,10 +759,13 @@ bile_write_map(struct bile *bile) SetFPos(bile->frefnum, fsFromLEOF, 0); GetFPos(bile->frefnum, &bile->file_size); - memset(&pb, 0, sizeof(pb)); - pb.ioRefNum = bile->frefnum; - PBFlushFile(&pb, false); - + if (bile->autoflush) { + if ((ret = bile_flush(bile, false)) != noErr) { + warn("bile_write_map: flush failed: %d", ret); + return -1; + } + } + /* successfully wrote new map, switch over */ free(bile->map); bile->nobjects = new_nobjects; @@ -702,9 +787,13 @@ bile_write_map(struct bile *bile) if (bile->last_error) return -1; - if ((ret = PBFlushFile(&pb, false)) != noErr) - panic("PBFlushFIle failed: %d", ret); - + if (bile->autoflush) { + if ((ret = bile_flush(bile, false)) != noErr) { + warn("bile_write_map: final flush failed: %d", ret); + return -1; + } + } + return 0; } --- bile.h Wed Jan 19 15:19:18 2022 +++ bile.h Fri Jan 21 17:58:40 2022 @@ -71,6 +71,7 @@ struct bile_object { #endif #define BILE_ERR_NEED_UPGRADE_1 -4000 +#define BILE_ERR_BOGUS_OBJECT -4001 struct bile { struct bile_object map_ptr; @@ -80,6 +81,7 @@ struct bile { size_t file_size; struct bile_object *map; /* array of bile_objects */ size_t nobjects; + short autoflush; }; short bile_error(struct bile *bile); @@ -87,6 +89,10 @@ short bile_error(struct bile *bile); struct bile * bile_create(const Str255 filename, short vrefnum, const OSType creator, const OSType type); struct bile * bile_open(const Str255 filename, short vrefnum); +struct bile * bile_open_recover_map(const Str255 filename, + short vrefnum); +short bile_flush(struct bile *bile, short and_vol); +short bile_autoflush(struct bile *bile, short val); void bile_close(struct bile *bile); struct bile_object * bile_find(struct bile *bile, const OSType type, @@ -110,6 +116,6 @@ size_t bile_read_alloc(struct bile *bile, size_t bile_write(struct bile *bile, OSType type, const unsigned long id, const void *data, const size_t len); -void bile_verify(struct bile *bile); +short bile_verify(struct bile *bile); #endif --- repo.c Thu Jan 20 10:34:17 2022 +++ repo.c Sat Jan 22 08:11:49 2022 @@ -369,10 +369,14 @@ repo_show_diff_text(struct repo *repo, struct repo_com short header_len, i, blen, height, trunc = 0; unsigned short warn_off; - bob = bile_find(repo->bile, REPO_DIFF_RTYPE, commit->id); - if (bob == NULL) - err(1, "failed finding DIFF %d", commit->id); + TESetText("", 0, te); + bob = bile_find(repo->bile, REPO_DIFF_RTYPE, commit->id); + if (bob == NULL) { + warn("Failed finding DIFF %d, corrupted repo?", commit->id); + return; + } + diff_len = bob->size; if (diff_len == 0) err(1, "diff zero bytes"); @@ -403,7 +407,6 @@ repo_show_diff_text(struct repo *repo, struct repo_com memcpy(dtext + MAX_TEXTEDIT_SIZE - blen, truncbuf, blen); } - TESetText("", 0, te); /* manually reset scroll without TESetSelect(0, 0, te) which redraws */ height = (*te)->destRect.bottom - (*te)->destRect.top; (*te)->destRect.top = (*te)->viewRect.top; @@ -1021,6 +1024,9 @@ repo_commit(struct repo *repo, short *files, short nfi repo_file_update(repo, file); } + + /* flush volume */ + bile_flush(repo->bile, 1); repo->next_commit_id = commit_id + 1;