--- uae/src/filesys.c 2018/04/24 17:02:12 1.1.1.13 +++ uae/src/filesys.c 2018/04/24 17:18:36 1.1.1.22 @@ -27,7 +27,6 @@ #include "sysconfig.h" #include "sysdeps.h" -#include "config.h" #include "threaddep/thread.h" #include "options.h" #include "uae.h" @@ -36,15 +35,20 @@ #include "events.h" #include "newcpu.h" #include "filesys.h" +#include "traps.h" #include "autoconf.h" -#include "compiler.h" #include "fsusage.h" #include "native2amiga.h" #include "scsidev.h" #include "fsdb.h" -/* #define TRACING_ENABLED */ -#ifdef TRACING_ENABLED +/* Count the number of FS packets waiting to be serviced, for the benefit + * of the idle on STOP code. */ +int active_fs_packets; +uae_sem_t packet_counter_sem; + +#define TRACING_ENABLED 0 +#if TRACING_ENABLED #define TRACE(x) do { write_log x; } while(0) #define DUMPLOCK(u,x) dumplock(u,x) #else @@ -119,8 +123,9 @@ typedef struct { char *volname; /* volume name, e.g. CDROM, WORK, etc. */ char *rootdir; /* root unix directory */ int readonly; /* disallow write access? */ + int bootpri; int devno; - + struct hardfiledata hf; /* Threading stuff */ @@ -176,16 +181,17 @@ static void close_filesys_unit (UnitInfo } char *get_filesys_unit (struct uaedev_mount_info *mountinfo, int nr, - char **volname, char **rootdir, int *readonly, - int *secspertrack, int *surfaces, int *reserved, - int *cylinders, int *size, int *blocksize) + char **devname, char **volname, char **rootdir, + int *readonly, int *secspertrack, int *surfaces, int *reserved, + int *cylinders, int *size, int *blocksize, int *bootpri) { UnitInfo *uip = mountinfo->ui + nr; if (nr >= mountinfo->num_units) return "No slot allocated for this unit"; - + *volname = uip->volname ? my_strdup (uip->volname) : 0; + *devname = uip->devname ? my_strdup (uip->devname) : 0; *rootdir = uip->rootdir ? my_strdup (uip->rootdir) : 0; *readonly = uip->readonly; *secspertrack = uip->hf.secspertrack; @@ -194,13 +200,14 @@ char *get_filesys_unit (struct uaedev_mo *size = uip->hf.size; *cylinders = uip->hf.nrcyls; *blocksize = uip->hf.blocksize; + *bootpri = uip->bootpri; return 0; } static char *set_filesys_unit_1 (struct uaedev_mount_info *mountinfo, int nr, - char *volname, char *rootdir, int readonly, - int secspertrack, int surfaces, int reserved, - int blocksize) + const char *devname, const char *volname, const char *rootdir, + int readonly, int secspertrack, int surfaces, int reserved, + int blocksize, int bootpri) { UnitInfo *ui = mountinfo->ui + nr; @@ -245,19 +252,27 @@ static char *set_filesys_unit_1 (struct ui->self = 0; ui->reset_state = FS_STARTUP; ui->rootdir = my_strdup (rootdir); + if (devname != 0 && strlen (devname) != 0) + ui->devname = my_strdup (devname); ui->readonly = readonly; + if (bootpri < -128) + bootpri = -128; + if (bootpri > 127) + bootpri = 127; + ui->bootpri = bootpri; return 0; } char *set_filesys_unit (struct uaedev_mount_info *mountinfo, int nr, - char *volname, char *rootdir, int readonly, - int secspertrack, int surfaces, int reserved, - int blocksize) + const char *devname, const char *volname, const char *rootdir, + int readonly, int secspertrack, int surfaces, int reserved, + int blocksize, int bootpri) { UnitInfo ui = mountinfo->ui[nr]; - char *result = set_filesys_unit_1 (mountinfo, nr, volname, rootdir, readonly, - secspertrack, surfaces, reserved, blocksize); + char *result = set_filesys_unit_1 (mountinfo, nr, devname, volname, rootdir, + readonly, secspertrack, surfaces, reserved, + blocksize, bootpri); if (result) mountinfo->ui[nr] = ui; else @@ -267,9 +282,9 @@ char *set_filesys_unit (struct uaedev_mo } char *add_filesys_unit (struct uaedev_mount_info *mountinfo, - char *volname, char *rootdir, int readonly, - int secspertrack, int surfaces, int reserved, - int blocksize) + const char *devname, const char *volname, const char *rootdir, + int readonly, int secspertrack, int surfaces, int reserved, + int blocksize, int bootpri) { char *retval; int nr = mountinfo->num_units; @@ -279,8 +294,9 @@ char *add_filesys_unit (struct uaedev_mo return "Maximum number of file systems mounted"; mountinfo->num_units++; - retval = set_filesys_unit_1 (mountinfo, nr, volname, rootdir, readonly, - secspertrack, surfaces, reserved, blocksize); + retval = set_filesys_unit_1 (mountinfo, nr, devname, volname, rootdir, readonly, + secspertrack, surfaces, reserved, blocksize, + bootpri); if (retval) mountinfo->num_units--; return retval; @@ -354,7 +370,8 @@ void write_filesys_config (struct uaedev } else { fprintf (f, "hardfile=%s,%d,%d,%d,%d,%s\n", uip[i].readonly ? "ro" : "rw", uip[i].hf.secspertrack, - uip[i].hf.surfaces, uip[i].hf.reservedblocks, 512, str); + uip[i].hf.surfaces, uip[i].hf.reservedblocks, + uip[i].hf.blocksize, str); } free (str); } @@ -475,8 +492,10 @@ struct hardfiledata *get_hardfile_data ( typedef struct { uae_u32 uniq; + /* The directory we're going through. */ a_inode *aino; - DIR* dir; + /* The file we're going to look up next. */ + a_inode *curr_file; } ExamineKey; typedef struct key { @@ -517,8 +536,9 @@ typedef struct _unit { volatile unsigned int cmds_acked; /* ExKeys */ - ExamineKey examine_keys[EXKEYS]; + ExamineKey examine_keys[EXKEYS]; int next_exkey; + unsigned long total_locked_ainos; /* Keys */ struct key *keys; @@ -547,11 +567,11 @@ static char *bstr1 (uaecptr addr) { static char buf[256]; int i; - int n = get_byte(addr); + int n = get_byte (addr); addr++; for (i = 0; i < n; i++, addr++) - buf[i] = get_byte(addr); + buf[i] = get_byte (addr); buf[i] = 0; return buf; } @@ -559,11 +579,11 @@ static char *bstr1 (uaecptr addr) static char *bstr (Unit *unit, uaecptr addr) { int i; - int n = get_byte(addr); + int n = get_byte (addr); addr++; for (i = 0; i < n; i++, addr++) - unit->tmpbuf3[i] = get_byte(addr); + unit->tmpbuf3[i] = get_byte (addr); unit->tmpbuf3[i] = 0; return unit->tmpbuf3; } @@ -576,7 +596,7 @@ static char *bstr_cut (Unit *unit, uaecp addr++; for (i = 0; i < n; i++, addr++) { - uae_u8 c = get_byte(addr); + uae_u8 c = get_byte (addr); unit->tmpbuf3[i] = c; if (c == '/' || (c == ':' && colon_seen++ == 0)) p = unit->tmpbuf3 + i + 1; @@ -598,7 +618,7 @@ find_unit (uaecptr port) return u; } - + static void prepare_for_open (char *name) { #if 0 @@ -650,34 +670,55 @@ static void recycle_aino (Unit *unit, a_ /* Still in use */ return; - if (unit->aino_cache_size > 500) { + TRACE (("Recycling; cache size %d, total_locked %d\n", + unit->aino_cache_size, unit->total_locked_ainos)); + if (unit->aino_cache_size > 500 + unit->total_locked_ainos) { /* Reap a few. */ int i = 0; while (i < 50) { - a_inode **aip; - aip = &unit->rootnode.prev->parent->child; - for (;;) { - a_inode *aino = *aip; - if (aino == 0) - break; - - if (aino->next == 0) - aip = &aino->sibling; - else { - if (aino->shlock > 0 || aino->elock) - write_log ("panic: freeing locked a_inode!\n"); - - de_recycle_aino (unit, aino); - dispose_aino (unit, aip, aino); - i++; + a_inode *parent = unit->rootnode.prev->parent; + a_inode **aip, *old_prev; + aip = &parent->child; + + if (! parent->locked_children) { + for (;;) { + a_inode *aino = *aip; + if (aino == 0) + break; + + /* Not recyclable if next == 0 (i.e., not chained into + recyclable list), or if parent directory is being + ExNext()ed. */ + if (aino->next == 0) { + aip = &aino->sibling; + } else { + if (aino->shlock > 0 || aino->elock) + write_log ("panic: freeing locked a_inode!\n"); + + de_recycle_aino (unit, aino); + dispose_aino (unit, aip, aino); + i++; + } } } + /* In the previous loop, we went through all children of one + parent. Re-arrange the recycled list so that we'll find a + different parent the next time around. */ + old_prev = unit->rootnode.prev; + do { + unit->rootnode.next->prev = unit->rootnode.prev; + unit->rootnode.prev->next = unit->rootnode.next; + unit->rootnode.next = unit->rootnode.prev; + unit->rootnode.prev = unit->rootnode.prev->prev; + unit->rootnode.prev->next = unit->rootnode.next->prev = &unit->rootnode; + } while (unit->rootnode.prev != old_prev + && unit->rootnode.prev->parent == parent); } #if 0 { char buffer[40]; sprintf (buffer, "%d ainos reaped.\n", i); - write_log (buffer); + TRACE ((buffer)); } #endif } @@ -698,7 +739,7 @@ static void update_child_names (Unit *un char *name_start; char *new_name; char dirsep[2] = { FSDB_DIR_SEPARATOR, '\0' }; - + a->parent = parent; name_start = strrchr (a->nname, FSDB_DIR_SEPARATOR); if (name_start == 0) { @@ -727,13 +768,31 @@ static void move_aino_children (Unit *un static void delete_aino (Unit *unit, a_inode *aino) { a_inode **aip; - int hash; TRACE(("deleting aino %x\n", aino->uniq)); aino->dirty = 1; aino->deleted = 1; de_recycle_aino (unit, aino); + + /* If any ExKeys are currently pointing at us, advance them. */ + if (aino->parent->exnext_count > 0) { + int i; + TRACE(("entering exkey validation\n")); + for (i = 0; i < EXKEYS; i++) { + ExamineKey *k = unit->examine_keys + i; + if (k->uniq == 0) + continue; + if (k->aino == aino->parent) { + TRACE(("Same parent found for %d\n", i)); + if (k->curr_file == aino) { + k->curr_file = aino->sibling; + TRACE(("Advancing curr_file\n")); + } + } + } + } + aip = &aino->parent->child; while (*aip != aino && *aip != 0) aip = &(*aip)->sibling; @@ -767,9 +826,14 @@ static a_inode *lookup_sub (a_inode *dir } cp = &c->sibling; } - *cp = c->sibling; - c->sibling = dir->child; - dir->child = c; + if (! dir->locked_children) { + /* Move to the front to speed up repeated lookups. Don't do this if + an ExNext is going on in this directory, or we'll terminally + confuse it. */ + *cp = c->sibling; + c->sibling = dir->child; + dir->child = c; + } return retval; } @@ -818,7 +882,7 @@ static char *get_nname (Unit *unit, a_in char *p = 0; *modified_rel = 0; - + /* If we have a mapping of some other aname to "rel", we must pretend * it does not exist. * This can happen for example if an Amiga program creates a @@ -851,7 +915,7 @@ static char *create_nname (Unit *unit, a char *p; /* We are trying to create a file called REL. */ - + /* If the name is used otherwise in the directory (or globally), we * need a new unique nname. */ if (fsdb_name_invalid (rel) || fsdb_used_as_nname (base, rel)) { @@ -898,6 +962,14 @@ static void init_child_aino (Unit *unit, aino->dirty = 0; aino->deleted = 0; + /* For directories - this one isn't being ExNext()ed yet. */ + aino->locked_children = 0; + aino->exnext_count = 0; + /* But the parent might be. */ + if (base->exnext_count) { + unit->total_locked_ainos++; + base->locked_children++; + } /* Update tree structure */ aino->parent = base; aino->child = 0; @@ -936,7 +1008,7 @@ static a_inode *new_child_aino (Unit *un init_child_aino (unit, base, aino); recycle_aino (unit, aino); - TRACE(("created aino %x, lookup\n", aino->uniq)); + TRACE(("created aino %x, lookup, amigaos_mode %d\n", aino->uniq, aino->amigaos_mode)); return aino; } @@ -1081,7 +1153,7 @@ static a_inode *get_aino (Unit *unit, a_ return curr; } -static uae_u32 startup_handler (void) +static uae_u32 startup_handler (TrapContext *dummy) { /* Just got the startup packet. It's in A4. DosBase is in A2, * our allocated volume structure is in D6, A5 is a pointer to @@ -1133,6 +1205,7 @@ static uae_u32 startup_handler (void) unit->ui.volname = my_strdup (uinfo->volname); /* might free later for rename */ unit->ui.rootdir = uinfo->rootdir; unit->ui.readonly = uinfo->readonly; + unit->ui.bootpri = uinfo->bootpri; unit->ui.unit_pipe = uinfo->unit_pipe; unit->ui.back_pipe = uinfo->back_pipe; unit->cmds_complete = 0; @@ -1140,9 +1213,10 @@ static uae_u32 startup_handler (void) unit->cmds_acked = 0; for (i = 0; i < EXKEYS; i++) { unit->examine_keys[i].aino = 0; - unit->examine_keys[i].dir = 0; + unit->examine_keys[i].curr_file = 0; unit->examine_keys[i].uniq = 0; } + unit->total_locked_ainos = 0; unit->next_exkey = 1; unit->keys = 0; unit->a_uniq = unit->key_uniq = 0; @@ -1213,7 +1287,7 @@ static void do_info (Unit *unit, dpacket packet, uaecptr info) { struct fs_usage fsu; - + if (get_fs_usage (unit->ui.rootdir, 0, &fsu) != 0) { PUT_PCK_RES1 (packet, DOS_FALSE); PUT_PCK_RES2 (packet, dos_errno ()); @@ -1512,12 +1586,16 @@ put_time (long days, long mins, long tic return t; } -static void free_exkey (ExamineKey *ek) +static void free_exkey (Unit *unit, ExamineKey *ek) { + if (--ek->aino->exnext_count == 0) { + TRACE (("Freeing ExKey and reducing total_locked from %d by %d\n", + unit->total_locked_ainos, ek->aino->locked_children)); + unit->total_locked_ainos -= ek->aino->locked_children; + ek->aino->locked_children = 0; + } ek->aino = 0; ek->uniq = 0; - if (ek->dir) - closedir (ek->dir); } static ExamineKey *lookup_exkey (Unit *unit, uae_u32 uniq) @@ -1539,7 +1617,7 @@ static ExamineKey *lookup_exkey (Unit *u static ExamineKey *new_exkey (Unit *unit, a_inode *aino) { uae_u32 uniq; - uae_u32 oldest = 0xFFFFFFFF; + uae_u32 oldest = 0xFFFFFFFE; ExamineKey *ek, *oldest_ek = 0; int i; @@ -1559,23 +1637,44 @@ static ExamineKey *new_exkey (Unit *unit } /* This message should usually be harmless. */ write_log ("Houston, we have a problem.\n"); - free_exkey (oldest_ek); + free_exkey (unit, oldest_ek); ek = oldest_ek; found: uniq = unit->next_exkey; - if (uniq == 0xFFFFFFFF) { + if (uniq >= 0xFFFFFFFE) { /* Things will probably go wrong, but most likely the Amiga will crash * before this happens because of something else. */ uniq = 1; } unit->next_exkey = uniq+1; ek->aino = aino; - ek->dir = 0; + ek->curr_file = 0; ek->uniq = uniq; return ek; } +static void move_exkeys (Unit *unit, a_inode *from, a_inode *to) +{ + int i; + unsigned long tmp = 0; + for (i = 0; i < EXKEYS; i++) { + ExamineKey *k = unit->examine_keys + i; + if (k->uniq == 0) + continue; + if (k->aino == from) { + k->aino = to; + tmp++; + } + } + if (tmp != from->exnext_count) + write_log ("filesys.c: Bug in ExNext bookkeeping. BAD.\n"); + to->exnext_count = from->exnext_count; + to->locked_children = from->locked_children; + from->exnext_count = 0; + from->locked_children = 0; +} + static void get_fileinfo (Unit *unit, dpacket packet, uaecptr info, a_inode *aino) { @@ -1624,7 +1723,10 @@ get_fileinfo (Unit *unit, dpacket packet else { TRACE(("comment=\"%s\"\n", aino->comment)); i = 144; - n = strlen (x = aino->comment); + x = aino->comment; + if (! x) + x = ""; + n = strlen (x); if (n > 78) n = 78; put_byte (info + i, n); i++; @@ -1636,47 +1738,6 @@ get_fileinfo (Unit *unit, dpacket packet PUT_PCK_RES1 (packet, DOS_TRUE); } -static void do_examine (Unit *unit, dpacket packet, ExamineKey *ek, uaecptr info) -{ - struct dirent de_space; - struct dirent* de; - a_inode *aino; - uae_u32 err; - - if (!ek->dir) { - ek->dir = opendir (ek->aino->nname); - } - if (!ek->dir) { - free_exkey (ek); - PUT_PCK_RES1 (packet, DOS_FALSE); - PUT_PCK_RES2 (packet, ERROR_NO_MORE_ENTRIES); - return; - } - - do { - de = my_readdir (ek->dir, &de_space); - } while (de && fsdb_name_invalid (de->d_name)); - - if (!de) { - TRACE(("no more entries\n")); - free_exkey (ek); - PUT_PCK_RES1 (packet, DOS_FALSE); - PUT_PCK_RES2 (packet, ERROR_NO_MORE_ENTRIES); - return; - } - - TRACE(("entry=\"%s\"\n", de->d_name)); - aino = lookup_child_aino_for_exnext (unit, ek->aino, de->d_name, &err); - if (err != 0) { - write_log ("Severe problem in ExNext.\n"); - free_exkey (ek); - PUT_PCK_RES1 (packet, DOS_FALSE); - PUT_PCK_RES2 (packet, err); - return; - } - get_fileinfo (unit, packet, info, aino); -} - static void action_examine_object (Unit *unit, dpacket packet) { uaecptr lock = GET_PCK_ARG1 (packet) << 2; @@ -1698,6 +1759,61 @@ static void action_examine_object (Unit put_long (info, 0); } +/* Read a directory's contents, create a_inodes for each file, and + mark them as locked in memory so that recycle_aino will not reap + them. + We do this to avoid problems with the host OS: we don't want to + leave the directory open on the host side until all ExNext()s have + finished - they may never finish! */ + +static void populate_directory (Unit *unit, a_inode *base) +{ + DIR *d = opendir (base->nname); + a_inode *aino; + + for (aino = base->child; aino; aino = aino->sibling) { + base->locked_children++; + unit->total_locked_ainos++; + } + TRACE(("Populating directory, child %p, locked_children %d\n", + base->child, base->locked_children)); + for (;;) { + struct dirent de_space; + struct dirent *de; + uae_u32 err; + + /* Find next file that belongs to the Amiga fs (skipping things + like "..", "." etc. */ + do { + de = my_readdir (d, &de_space); + } while (de && fsdb_name_invalid (de->d_name)); + if (! de) + break; + /* This calls init_child_aino, which will notice that the parent is + being ExNext()ed, and it will increment the locked counts. */ + aino = lookup_child_aino_for_exnext (unit, base, de->d_name, &err); + } + closedir (d); +} + +static void do_examine (Unit *unit, dpacket packet, ExamineKey *ek, uaecptr info) +{ + if (ek->curr_file == 0) + goto no_more_entries; + + get_fileinfo (unit, packet, info, ek->curr_file); + ek->curr_file = ek->curr_file->sibling; + TRACE (("curr_file set to %p %s\n", ek->curr_file, + ek->curr_file ? ek->curr_file->aname : "NULL")); + return; + + no_more_entries: + TRACE(("no more entries\n")); + free_exkey (unit, ek); + PUT_PCK_RES1 (packet, DOS_FALSE); + PUT_PCK_RES2 (packet, ERROR_NO_MORE_ENTRIES); +} + static void action_examine_next (Unit *unit, dpacket packet) { uaecptr lock = GET_PCK_ARG1 (packet) << 2; @@ -1717,21 +1833,34 @@ static void action_examine_next (Unit *u uniq = get_long (info); if (uniq == 0) { write_log ("ExNext called for a file! (Houston?)\n"); - PUT_PCK_RES1 (packet, DOS_FALSE); - PUT_PCK_RES2 (packet, ERROR_NO_MORE_ENTRIES); - return; - } else if (uniq == 0xFFFFFFFF) { - ek = new_exkey(unit, aino); - } else + goto no_more_entries; + } else if (uniq == 0xFFFFFFFE) + goto no_more_entries; + else if (uniq == 0xFFFFFFFF) { + TRACE(("Creating new ExKey\n")); + ek = new_exkey (unit, aino); + if (ek) { + if (aino->exnext_count++ == 0) + populate_directory (unit, aino); + } + ek->curr_file = aino->child; + TRACE(("Initial curr_file: %p %s\n", ek->curr_file, + ek->curr_file ? ek->curr_file->aname : "NULL")); + } else { + TRACE(("Looking up ExKey\n")); ek = lookup_exkey (unit, get_long (info)); + } if (ek == 0) { write_log ("Couldn't find a matching ExKey. Prepare for trouble.\n"); - PUT_PCK_RES1 (packet, DOS_FALSE); - PUT_PCK_RES2 (packet, ERROR_NO_MORE_ENTRIES); - return; + goto no_more_entries; } put_long (info, ek->uniq); do_examine (unit, packet, ek, info); + return; + + no_more_entries: + PUT_PCK_RES1 (packet, DOS_FALSE); + PUT_PCK_RES2 (packet, ERROR_NO_MORE_ENTRIES); } static void do_find (Unit *unit, dpacket packet, int mode, int create, int fallback) @@ -1871,9 +2000,9 @@ action_fh_from_lock (Unit *unit, dpacket mode = aino->amigaos_mode; /* Use same mode for opened filehandle as existing Lock() */ prepare_for_open (aino->nname); - - openmode = (((mode & A_FIBF_READ) == 0 ? O_WRONLY - : (mode & A_FIBF_WRITE) == 0 ? O_RDONLY + TRACE ((" mode is %d\n", mode)); + openmode = (((mode & A_FIBF_READ) ? O_WRONLY + : (mode & A_FIBF_WRITE) ? O_RDONLY : O_RDWR)); /* the files on CD really can have the write-bit set. */ @@ -2009,7 +2138,7 @@ action_read (Unit *unit, dpacket packet) int i; PUT_PCK_RES1 (packet, actual); for (i = 0; i < actual; i++) - put_byte(addr + i, buf[i]); + put_byte (addr + i, buf[i]); k->file_pos += actual; } free (buf); @@ -2048,7 +2177,7 @@ action_write (Unit *unit, dpacket packet } for (i = 0; i < size; i++) - buf[i] = get_byte(addr + i); + buf[i] = get_byte (addr + i); PUT_PCK_RES1 (packet, write(k->fd, buf, size)); if (GET_PCK_RES1 (packet) != size) @@ -2081,6 +2210,22 @@ action_seek (Unit *unit, dpacket packet) TRACE(("ACTION_SEEK(%s,%d,%d)\n", k->aino->nname, pos, mode)); old = lseek (k->fd, 0, SEEK_CUR); + { + uae_s32 temppos; + long filesize = lseek (k->fd, 0, SEEK_END); + lseek (k->fd, old, SEEK_SET); + + if (whence == SEEK_CUR) temppos = old + pos; + if (whence == SEEK_SET) temppos = pos; + if (whence == SEEK_END) temppos = filesize + pos; + if (filesize < temppos) { + res = -1; + PUT_PCK_RES1 (packet,res); + PUT_PCK_RES2 (packet, ERROR_SEEK_ERROR); + return; + } + } + res = lseek (k->fd, pos, whence); if (-1 == res) { @@ -2190,7 +2335,7 @@ action_change_mode (Unit *unit, dpacket /* will be CHANGE_FH or CHANGE_LOCK value */ long type = GET_PCK_ARG1 (packet); /* either a file-handle or lock */ - uaecptr object = GET_PCK_ARG2 (packet) << 2; + uaecptr object = GET_PCK_ARG2 (packet) << 2; /* will be EXCLUSIVE_LOCK/SHARED_LOCK if CHANGE_LOCK, * or MODE_OLDFILE/MODE_NEWFILE/MODE_READWRITE if CHANGE_FH */ long mode = GET_PCK_ARG3 (packet); @@ -2569,6 +2714,8 @@ action_rename_object (Unit *unit, dpacke a2->comment = a1->comment; a1->comment = 0; a2->amigaos_mode = a1->amigaos_mode; + a2->uniq = a1->uniq; + move_exkeys (unit, a1, a2); move_aino_children (unit, a1, a2); delete_aino (unit, a1); PUT_PCK_RES1 (packet, DOS_TRUE); @@ -2627,7 +2774,7 @@ action_flush (Unit *unit, dpacket packet * know whether AmigaOS takes care of that, but this does. */ static uae_sem_t singlethread_int_sem; -static uae_u32 exter_int_helper (void) +static uae_u32 exter_int_helper (TrapContext *dummy) { UnitInfo *uip = current_mountinfo->ui; uaecptr port; @@ -2834,6 +2981,11 @@ static void *filesys_thread (void *unit_ /* The message is sent by our interrupt handler, so make sure an interrupt * happens. */ uae_int_requested = 1; + + uae_sem_wait (&packet_counter_sem); + active_fs_packets--; + uae_sem_post (&packet_counter_sem); + /* Send back the locks. */ if (get_long (ui->self->locklist) != 0) write_comm_pipe_int (ui->back_pipe, (int)(get_long (ui->self->locklist)), 0); @@ -2844,7 +2996,7 @@ static void *filesys_thread (void *unit_ #endif /* Talk about spaghetti code... */ -static uae_u32 filesys_handler (void) +static uae_u32 filesys_handler (TrapContext *dummy) { Unit *unit = find_unit (m68k_areg (regs, 5)); uaecptr packet_addr = m68k_dreg (regs, 3); @@ -2877,6 +3029,10 @@ static uae_u32 filesys_handler (void) put_long (m68k_areg (regs, 3), get_long (get_long (morelocks))); put_long (get_long (morelocks), 0); + uae_sem_wait (&packet_counter_sem); + active_fs_packets++; + uae_sem_post (&packet_counter_sem); + /* The packet wasn't processed yet. */ do_put_mem_long ((uae_u32 *)(msg + 4), 0); write_comm_pipe_pvoid (unit->ui.unit_pipe, (void *)pck, 0); @@ -2921,10 +3077,20 @@ static int get_new_device (char **devnam result = current_deviceno++; } - *devname_amiga = ds (*devname = my_strdup (buffer)); + if (*devname == NULL) + *devname = my_strdup (buffer); + *devname_amiga = ds (*devname); return result; } +static void init_filesys_diagentry (void) +{ + do_put_mem_long ((uae_u32 *)(filesysory + 0x2100), EXPANSION_explibname); + do_put_mem_long ((uae_u32 *)(filesysory + 0x2104), filesys_configdev); + do_put_mem_long ((uae_u32 *)(filesysory + 0x2108), EXPANSION_doslibname); + do_put_mem_long ((uae_u32 *)(filesysory + 0x210c), current_mountinfo->num_units); +} + void filesys_start_threads (void) { UnitInfo *uip; @@ -2933,7 +3099,7 @@ void filesys_start_threads (void) current_mountinfo = dup_mountinfo (currprefs.mountinfo); reset_uaedevices (); - + uip = current_mountinfo->ui; for (i = 0; i < current_mountinfo->num_units; i++) { uip[i].unit_pipe = 0; @@ -2971,6 +3137,16 @@ void filesys_reset (void) current_mountinfo = 0; } +static void free_all_ainos (Unit *u, a_inode *parent) +{ + a_inode *a; + while (a = parent->child) { + free_all_ainos (u, a); + dispose_aino (u, &parent->child, a); + } +} + + void filesys_prepare_reset (void) { UnitInfo *uip = current_mountinfo->ui; @@ -2992,18 +3168,14 @@ void filesys_prepare_reset (void) #endif u = units; while (u != 0) { - while (u->rootnode.next != &u->rootnode) { - a_inode *b; - a_inode *a = u->rootnode.next; - u->rootnode.next = a->next; - de_recycle_aino (u, a); - dispose_aino (u, &b, a); - } + free_all_ainos (u, &u->rootnode); + u->rootnode.next = u->rootnode.prev = &u->rootnode; + u->aino_cache_size = 0; u = u->next; } } -static uae_u32 filesys_diagentry (void) +static uae_u32 filesys_diagentry (TrapContext *dummy) { uaecptr resaddr = m68k_areg (regs, 2) + 0x10; uaecptr start = resaddr; @@ -3012,11 +3184,7 @@ static uae_u32 filesys_diagentry (void) TRACE (("filesystem: diagentry called\n")); filesys_configdev = m68k_areg (regs, 3); - - do_put_mem_long ((uae_u32 *)(filesysory + 0x2100), EXPANSION_explibname); - do_put_mem_long ((uae_u32 *)(filesysory + 0x2104), filesys_configdev); - do_put_mem_long ((uae_u32 *)(filesysory + 0x2108), EXPANSION_doslibname); - do_put_mem_long ((uae_u32 *)(filesysory + 0x210c), current_mountinfo->num_units); + init_filesys_diagentry (); uae_sem_init (&singlethread_int_sem, 0, 1); if (ROM_hardfile_resid != 0) { @@ -3033,7 +3201,7 @@ static uae_u32 filesys_diagentry (void) } resaddr += 0x1A; tmp = resaddr; - + /* The good thing about this function is that it always gets called * when we boot. So we could put all sorts of stuff that wants to be done * here. @@ -3060,8 +3228,14 @@ static uae_u32 filesys_diagentry (void) tmp++; } } - put_word (resaddr, 0x7001); /* moveq.l #1,d0 */ - put_word (resaddr + 2, RTS); + /* call setup_exter */ + put_word (resaddr + 0, 0x2079); + put_long (resaddr + 2, RTAREA_BASE + 28 + 4); /* move.l RTAREA_BASE+32,a0 */ + put_word (resaddr + 6, 0xd1fc); + put_long (resaddr + 8, RTAREA_BASE + 8 + 4); /* add.l #RTAREA_BASE+12,a0 */ + put_word (resaddr + 12, 0x4e90); /* jsr (a0) */ + put_word (resaddr + 14, 0x7001); /* moveq.l #1,d0 */ + put_word (resaddr + 16, RTS); m68k_areg (regs, 0) = residents; return 1; @@ -3069,23 +3243,24 @@ static uae_u32 filesys_diagentry (void) /* Remember a pointer AmigaOS gave us so we can later use it to identify * which unit a given startup message belongs to. */ -static uae_u32 filesys_dev_remember (void) +static uae_u32 filesys_dev_remember (TrapContext *dummy) { int unit_no = m68k_dreg (regs, 6); + UnitInfo *uip = ¤t_mountinfo->ui[unit_no]; uaecptr devicenode = m68k_areg (regs, 3); - current_mountinfo->ui[unit_no].startup = get_long (devicenode + 28); + uip->startup = get_long (devicenode + 28); return devicenode; } /* Fill in per-unit fields of a parampacket */ -static uae_u32 filesys_dev_storeinfo (void) +static uae_u32 filesys_dev_storeinfo (TrapContext *dummy) { UnitInfo *uip = current_mountinfo->ui; int unit_no = m68k_dreg (regs, 6); uaecptr parmpacket = m68k_areg (regs, 0); - put_long (parmpacket, current_mountinfo->ui[unit_no].devname_amiga); + put_long (parmpacket, uip[unit_no].devname_amiga); put_long (parmpacket + 4, is_hardfile (current_mountinfo, unit_no) ? ROM_hardfile_resname : fsdevname); put_long (parmpacket + 8, uip[unit_no].devno); put_long (parmpacket + 12, 0); /* Device flags */ @@ -3093,7 +3268,7 @@ static uae_u32 filesys_dev_storeinfo (vo put_long (parmpacket + 20, uip[unit_no].hf.blocksize >> 2); /* longwords per block */ put_long (parmpacket + 24, 0); /* unused */ put_long (parmpacket + 28, uip[unit_no].hf.surfaces); /* heads */ - put_long (parmpacket + 32, 0); /* unused */ + put_long (parmpacket + 32, 1); /* sectors per block */ put_long (parmpacket + 36, uip[unit_no].hf.secspertrack); /* sectors per track */ put_long (parmpacket + 40, uip[unit_no].hf.reservedblocks); /* reserved blocks */ put_long (parmpacket + 44, 0); /* unused */ @@ -3104,7 +3279,7 @@ static uae_u32 filesys_dev_storeinfo (vo put_long (parmpacket + 64, 0); /* Buffer mem type */ put_long (parmpacket + 68, 0x7FFFFFFF); /* largest transfer */ put_long (parmpacket + 72, ~1); /* addMask (?) */ - put_long (parmpacket + 76, (uae_u32)-1); /* bootPri */ + put_long (parmpacket + 76, uip[unit_no].bootpri); /* bootPri */ put_long (parmpacket + 80, 0x444f5300); /* DOS\0 */ put_long (parmpacket + 84, 0); /* pad */ @@ -3118,38 +3293,40 @@ void filesys_install (void) TRACE (("Installing filesystem\n")); - ROM_filesys_resname = ds("UAEunixfs.resource"); - ROM_filesys_resid = ds("UAE unixfs 0.4"); + ROM_filesys_resname = ds ("UAEunixfs.resource"); + ROM_filesys_resid = ds ("UAE unixfs 0.4"); fsdevname = ds ("uae.device"); /* does not really exist */ ROM_filesys_diagentry = here(); calltrap (deftrap(filesys_diagentry)); - dw(0x4ED0); /* JMP (a0) - jump to code that inits Residents */ + dw (0x4ED0); /* JMP (a0) - jump to code that inits Residents */ loop = here (); /* Special trap for the assembly make_dev routine */ - org (0xF0FF20); + org (RTAREA_BASE + 0xFF20); calltrap (deftrap (filesys_dev_remember)); dw (RTS); - org (0xF0FF28); + org (RTAREA_BASE + 0xFF28); calltrap (deftrap (filesys_dev_storeinfo)); dw (RTS); - org (0xF0FF30); + org (RTAREA_BASE + 0xFF30); calltrap (deftrap (filesys_handler)); dw (RTS); - org (0xF0FF40); + org (RTAREA_BASE + 0xFF40); calltrap (deftrap (startup_handler)); dw (RTS); - org (0xF0FF50); + org (RTAREA_BASE + 0xFF50); calltrap (deftrap (exter_int_helper)); dw (RTS); org (loop); + + uae_sem_init (&packet_counter_sem, 0, 0); } void filesys_install_code (void) @@ -3157,114 +3334,9 @@ void filesys_install_code (void) align(4); /* The last offset comes from the code itself, look for it near the top. */ - EXPANSION_bootcode = here () + 8 + 0x14; + EXPANSION_bootcode = here () + 8 + 0x1c + 4; /* Ouch. Make sure this is _always_ a multiple of two bytes. */ - filesys_initcode = here() + 8 + 0x28; - db(0x00); db(0x00); db(0x00); db(0x10); db(0x00); db(0x00); db(0x00); db(0x00); - db(0x60); db(0x00); db(0x01); db(0xd4); db(0x00); db(0x00); db(0x01); db(0x3e); - db(0x00); db(0x00); db(0x00); db(0x28); db(0x00); db(0x00); db(0x00); db(0xbc); - db(0x00); db(0x00); db(0x00); db(0x14); db(0x43); db(0xfa); db(0x03); db(0x11); - db(0x4e); db(0xae); db(0xff); db(0xa0); db(0x20); db(0x40); db(0x20); db(0x28); - db(0x00); db(0x16); db(0x20); db(0x40); db(0x4e); db(0x90); db(0x4e); db(0x75); - db(0x48); db(0xe7); db(0xff); db(0xfe); db(0x2c); db(0x78); db(0x00); db(0x04); - db(0x2a); db(0x79); db(0x00); db(0xf0); db(0xff); db(0xfc); db(0x43); db(0xfa); - db(0x02); db(0xfb); db(0x70); db(0x24); db(0x7a); db(0x00); db(0x4e); db(0xae); - db(0xfd); db(0xd8); db(0x4a); db(0x80); db(0x66); db(0x0c); db(0x43); db(0xfa); - db(0x02); db(0xeb); db(0x70); db(0x00); db(0x7a); db(0x01); db(0x4e); db(0xae); - db(0xfd); db(0xd8); db(0x28); db(0x40); db(0x70); db(0x58); db(0x72); db(0x01); - db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x26); db(0x40); db(0x7e); db(0x54); - db(0x27); db(0xb5); db(0x78); db(0x00); db(0x78); db(0x00); db(0x59); db(0x87); - db(0x64); db(0xf6); db(0x7c); db(0x00); db(0xbc); db(0xad); db(0x01); db(0x0c); - db(0x64); db(0x14); db(0x20); db(0x4b); db(0x48); db(0xe7); db(0x02); db(0x10); - db(0x7e); db(0x01); db(0x61); db(0x00); db(0x00); db(0xc2); db(0x4c); db(0xdf); - db(0x08); db(0x40); db(0x52); db(0x86); db(0x60); db(0xe6); db(0x2c); db(0x78); - db(0x00); db(0x04); db(0x22); db(0x4c); db(0x4e); db(0xae); db(0xfe); db(0x62); - db(0x61); db(0x00); db(0x00); db(0x7c); db(0x2c); db(0x78); db(0x00); db(0x04); - db(0x4e); db(0xb9); db(0x00); db(0xf0); db(0xff); db(0x80); db(0x72); db(0x03); - db(0x74); db(0xf6); db(0x20); db(0x7c); db(0x00); db(0x20); db(0x00); db(0x00); - db(0x90); db(0x88); db(0x65); db(0x0a); db(0x67); db(0x08); db(0x78); db(0x00); - db(0x22); db(0x44); db(0x4e); db(0xae); db(0xfd); db(0x96); db(0x4c); db(0xdf); - db(0x7f); db(0xff); db(0x4e); db(0x75); db(0x48); db(0xe7); db(0x00); db(0x20); - db(0x70); db(0x00); db(0x4e); db(0xb9); db(0x00); db(0xf0); db(0xff); db(0x50); - db(0x4a); db(0x80); db(0x67); db(0x3c); db(0x2c); db(0x78); db(0x00); db(0x04); - db(0x70); db(0x02); db(0x4e); db(0xb9); db(0x00); db(0xf0); db(0xff); db(0x50); - db(0x0c); db(0x80); db(0x00); db(0x00); db(0x00); db(0x01); db(0x6d); db(0x1e); - db(0x6e); db(0x06); db(0x4e); db(0xae); db(0xfe); db(0x92); db(0x60); db(0xe8); - db(0x0c); db(0x80); db(0x00); db(0x00); db(0x00); db(0x02); db(0x6e); db(0x08); - db(0x20); db(0x01); db(0x4e); db(0xae); db(0xfe); db(0xbc); db(0x60); db(0xd8); - db(0x4e); db(0xae); db(0xfe); db(0x86); db(0x60); db(0xd2); db(0x70); db(0x04); - db(0x4e); db(0xb9); db(0x00); db(0xf0); db(0xff); db(0x50); db(0x70); db(0x01); - db(0x4c); db(0xdf); db(0x04); db(0x00); db(0x4e); db(0x75); db(0x2c); db(0x78); - db(0x00); db(0x04); db(0x70); db(0x1a); db(0x22); db(0x3c); db(0x00); db(0x01); - db(0x00); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x22); db(0x40); - db(0x41); db(0xfa); db(0x01); db(0xf6); db(0x23); db(0x48); db(0x00); db(0x0a); - db(0x41); db(0xfa); db(0xff); db(0x92); db(0x23); db(0x48); db(0x00); db(0x0e); - db(0x41); db(0xfa); db(0xff); db(0x8a); db(0x23); db(0x48); db(0x00); db(0x12); - db(0x70); db(0x0d); db(0x4e); db(0xee); db(0xff); db(0x58); db(0x2a); db(0x79); - db(0x00); db(0xf0); db(0xff); db(0xfc); db(0x4e); db(0xb9); db(0x00); db(0xf0); - db(0xff); db(0x28); db(0x26); db(0x00); db(0xc0); db(0x85); db(0x66); db(0x00); - db(0xff); db(0x6a); db(0x2c); db(0x4c); db(0x4e); db(0xae); db(0xff); db(0x70); - db(0x26); db(0x40); db(0x4e); db(0xb9); db(0x00); db(0xf0); db(0xff); db(0x20); - db(0x70); db(0x00); db(0x27); db(0x40); db(0x00); db(0x08); db(0x27); db(0x40); - db(0x00); db(0x10); db(0x27); db(0x40); db(0x00); db(0x20); db(0x4a); db(0x83); - db(0x66); db(0x1c); db(0x27); db(0x7c); db(0x00); db(0x00); db(0x0f); db(0xa0); - db(0x00); db(0x14); db(0x43); db(0xfa); db(0xfe); db(0x80); db(0x20); db(0x09); - db(0xe4); db(0x88); db(0x27); db(0x40); db(0x00); db(0x20); db(0x27); db(0x7c); - db(0xff); db(0xff); db(0xff); db(0xff); db(0x00); db(0x24); db(0x4a); db(0x87); - db(0x67); db(0x36); db(0x2c); db(0x78); db(0x00); db(0x04); db(0x70); db(0x14); - db(0x72); db(0x00); db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x22); db(0x40); - db(0x70); db(0x00); db(0x22); db(0x80); db(0x23); db(0x40); db(0x00); db(0x04); - db(0x33); db(0x40); db(0x00); db(0x0e); db(0x30); db(0x3c); db(0x10); db(0xff); - db(0x90); db(0x06); db(0x33); db(0x40); db(0x00); db(0x08); db(0x23); db(0x6d); - db(0x01); db(0x04); db(0x00); db(0x0a); db(0x23); db(0x4b); db(0x00); db(0x10); - db(0x41); db(0xec); db(0x00); db(0x4a); db(0x4e); db(0xee); db(0xfe); db(0xf2); - db(0x20); db(0x4b); db(0x72); db(0x00); db(0x22); db(0x41); db(0x70); db(0xff); - db(0x2c); db(0x4c); db(0x4e); db(0xee); db(0xff); db(0x6a); db(0x2c); db(0x78); - db(0x00); db(0x04); db(0x70); db(0x00); db(0x22); db(0x40); db(0x4e); db(0xae); - db(0xfe); db(0xda); db(0x20); db(0x40); db(0x4b); db(0xe8); db(0x00); db(0x5c); - db(0x43); db(0xfa); db(0x01); db(0x3d); db(0x70); db(0x00); db(0x4e); db(0xae); - db(0xfd); db(0xd8); db(0x24); db(0x40); db(0x20); db(0x3c); db(0x00); db(0x00); - db(0x00); db(0x9d); db(0x22); db(0x3c); db(0x00); db(0x01); db(0x00); db(0x01); - db(0x4e); db(0xae); db(0xff); db(0x3a); db(0x26); db(0x40); db(0x7c); db(0x00); - db(0x26); db(0x86); db(0x27); db(0x46); db(0x00); db(0x04); db(0x27); db(0x46); - db(0x00); db(0x08); db(0x7a); db(0x00); db(0x20); db(0x4d); db(0x4e); db(0xae); - db(0xfe); db(0x80); db(0x20); db(0x4d); db(0x4e); db(0xae); db(0xfe); db(0x8c); - db(0x28); db(0x40); db(0x26); db(0x2c); db(0x00); db(0x0a); db(0x70); db(0x00); - db(0x4e); db(0xb9); db(0x00); db(0xf0); db(0xff); db(0x40); db(0x60); db(0x76); - db(0x20); db(0x4d); db(0x4e); db(0xae); db(0xfe); db(0x80); db(0x20); db(0x4d); - db(0x4e); db(0xae); db(0xfe); db(0x8c); db(0x28); db(0x40); db(0x26); db(0x2c); - db(0x00); db(0x0a); db(0x66); db(0x38); db(0x70); db(0x01); db(0x4e); db(0xb9); - db(0x00); db(0xf0); db(0xff); db(0x50); db(0x45); db(0xeb); db(0x00); db(0x04); - db(0x20); db(0x52); db(0x20); db(0x08); db(0x67); db(0xda); db(0x22); db(0x50); - db(0x20); db(0x40); db(0x20); db(0x28); db(0x00); db(0x04); db(0x6a); db(0x16); - db(0x48); db(0xe7); db(0x00); db(0xc0); db(0x28); db(0x68); db(0x00); db(0x0a); - db(0x61); db(0x42); db(0x53); db(0x85); db(0x4c); db(0xdf); db(0x03); db(0x00); - db(0x24); db(0x89); db(0x20); db(0x49); db(0x60); db(0xdc); db(0x24); db(0x48); - db(0x20); db(0x49); db(0x60); db(0xd6); db(0x0c); db(0x85); db(0x00); db(0x00); - db(0x00); db(0x14); db(0x65); db(0x00); db(0x00); db(0x0a); db(0x70); db(0x01); - db(0x29); db(0x40); db(0x00); db(0x04); db(0x60); db(0x0e); db(0x61); db(0x2a); - db(0x4e); db(0xb9); db(0x00); db(0xf0); db(0xff); db(0x30); db(0x4a); db(0x80); - db(0x67); db(0x0c); db(0x52); db(0x85); db(0x28); db(0xab); db(0x00); db(0x04); - db(0x27); db(0x4c); db(0x00); db(0x04); db(0x60); db(0x8a); db(0x28); db(0x43); - db(0x61); db(0x02); db(0x60); db(0x84); db(0x22); db(0x54); db(0x20); db(0x6c); - db(0x00); db(0x04); db(0x29); db(0x4d); db(0x00); db(0x04); db(0x4e); db(0xee); - db(0xfe); db(0x92); db(0x2f); db(0x05); db(0x7a); db(0xfc); db(0x24); db(0x53); - db(0x2e); db(0x0a); db(0x22); db(0x0a); db(0x67); db(0x00); db(0x00); db(0x0c); - db(0x52); db(0x85); db(0x67); db(0x1e); db(0x22); db(0x4a); db(0x24); db(0x52); - db(0x60); db(0xf0); db(0x52); db(0x85); db(0x67); db(0x3c); db(0x24); db(0x47); - db(0x70); db(0x18); db(0x72); db(0x01); db(0x4e); db(0xae); db(0xff); db(0x3a); - db(0x52); db(0x46); db(0x24); db(0x40); db(0x24); db(0x87); db(0x2e); db(0x0a); - db(0x60); db(0xe8); db(0x20); db(0x12); db(0x67); db(0x24); db(0x20); db(0x40); - db(0x20); db(0x10); db(0x67); db(0x1e); db(0x20); db(0x40); db(0x20); db(0x10); - db(0x67); db(0x18); db(0x70); db(0x00); db(0x22); db(0x80); db(0x22); db(0x4a); - db(0x24); db(0x51); db(0x70); db(0x18); db(0x4e); db(0xae); db(0xff); db(0x2e); - db(0x06); db(0x86); db(0x00); db(0x01); db(0x00); db(0x00); db(0x20); db(0x0a); - db(0x66); db(0xec); db(0x26); db(0x87); db(0x2a); db(0x1f); db(0x4e); db(0x75); - db(0x55); db(0x41); db(0x45); db(0x20); db(0x66); db(0x69); db(0x6c); db(0x65); - db(0x73); db(0x79); db(0x73); db(0x74); db(0x65); db(0x6d); db(0x00); db(0x64); - db(0x6f); db(0x73); db(0x2e); db(0x6c); db(0x69); db(0x62); db(0x72); db(0x61); - db(0x72); db(0x79); db(0x00); db(0x65); db(0x78); db(0x70); db(0x61); db(0x6e); - db(0x73); db(0x69); db(0x6f); db(0x6e); db(0x2e); db(0x6c); db(0x69); db(0x62); - db(0x72); db(0x61); db(0x72); db(0x79); db(0x00); db(0x00); db(0x00); db(0x00); - db(0x00); db(0x00); db(0x03); db(0xf2); + filesys_initcode = here() + 8 + 0x30 + 4; + + #include "filesys_bootrom.c" }