AmendHub

Download (as of this amendment):

jcs

/

amend

/

amendments

/

192

bile: Add bile_begin and bile_commit to do things in transactions

Rather than writing the new map on every change, one can enter a
transaction and defer writing the new map until bile_commit. This
way if a crash happens during changes, the map won't be left
pointing at partial progress.

jcs made amendment 192 18 days ago
--- bile.c Sat Oct 3 22:24:32 2026 +++ bile.c Sun Oct 4 00:41:47 2026 @@ -264,6 +264,33 @@ bile_close(struct bile *bile) xfree(&bile->map); } +void +bile_begin(struct bile *bile) +{ + bile_check_sanity(bile); + + if (bile->in_transaction) + panic("bile_begin: transaction already in progress"); + + bile->in_transaction = true; +} + +short +bile_commit(struct bile *bile) +{ + bile_check_sanity(bile); + + if (!bile->in_transaction) + panic("bile_commit: no transaction in progress"); + + bile->in_transaction = false; + + if (bile_write_map(bile) != 0) + return -1; + + return bile_flush(bile, true); +} + struct bile_object * bile_find(struct bile *bile, const OSType type, const unsigned long id) { @@ -413,21 +440,23 @@ bile_delete(struct bile *bile, const OSType type, cons pos = o->pos; size = o->size + BILE_OBJECT_SIZE; - _bile_error = bile->last_error = SetFPos(bile->frefnum, fsFromStart, - pos); - if (_bile_error) - return -1; - - while (size > 0) { - wsize = MIN(128, size); - size -= wsize; - - _bile_error = bile->last_error = FSWrite(bile->frefnum, &wsize, - zero); + if (!bile->in_transaction) { + _bile_error = bile->last_error = SetFPos(bile->frefnum, + fsFromStart, pos); if (_bile_error) return -1; - } + while (size > 0) { + wsize = MIN(128, size); + size -= wsize; + + _bile_error = bile->last_error = FSWrite(bile->frefnum, + &wsize, zero); + if (_bile_error) + return -1; + } + } + /* * If this is the highest id of this type, store it so it won't get * handed out again from bile_next_id @@ -447,7 +476,7 @@ bile_delete(struct bile *bile, const OSType type, cons sizeof(unsigned long)); /* bile_write wrote a new map for us */ - } else { + } else if (!bile->in_transaction) { bile_write_map(bile); if (_bile_error) return -1; @@ -620,10 +649,12 @@ bile_write(struct bile *bile, const OSType type, const SetFPos(bile->frefnum, fsFromLEOF, 0); GetFPos(bile->frefnum, &bile->file_size); - bile_write_map(bile); - if (bile->last_error) - return 0; - + if (!bile->in_transaction) { + bile_write_map(bile); + if (bile->last_error) + return 0; + } + return wrote; } --- bile.h Sat Mar 4 22:39:38 2023 +++ bile.h Sun Oct 4 00:36:47 2026 @@ -91,6 +91,7 @@ struct bile { struct bile_object *map; /* array of bile_objects */ size_t nobjects; char magic[5]; + bool in_transaction; }; struct bile_object_field { @@ -108,6 +109,8 @@ struct bile * bile_open_recover_map(const Str255 fil short vrefnum); short bile_flush(struct bile *bile, bool and_vol); void bile_close(struct bile *bile); +void bile_begin(struct bile *bile); +short bile_commit(struct bile *bile); struct bile_object * bile_find(struct bile *bile, const OSType type, const unsigned long id);