--- uae/src/filesys.c 2018/04/24 17:07:29 1.1.1.16 +++ uae/src/filesys.c 2018/04/24 17:14:30 1.1.1.20 @@ -37,14 +37,13 @@ #include "newcpu.h" #include "filesys.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 +#define TRACING_ENABLED 0 +#if TRACING_ENABLED #define TRACE(x) do { write_log x; } while(0) #define DUMPLOCK(u,x) dumplock(u,x) #else @@ -120,7 +119,7 @@ typedef struct { char *rootdir; /* root unix directory */ int readonly; /* disallow write access? */ int devno; - + struct hardfiledata hf; /* Threading stuff */ @@ -184,7 +183,7 @@ char *get_filesys_unit (struct uaedev_mo if (nr >= mountinfo->num_units) return "No slot allocated for this unit"; - + *volname = uip->volname ? my_strdup (uip->volname) : 0; *rootdir = uip->rootdir ? my_strdup (uip->rootdir) : 0; *readonly = uip->readonly; @@ -354,7 +353,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); } @@ -601,7 +601,7 @@ find_unit (uaecptr port) return u; } - + static void prepare_for_open (char *name) { #if 0 @@ -663,7 +663,7 @@ static void recycle_aino (Unit *unit, a_ a_inode **aip; aip = &parent->child; - if (! parent->locked_children) + if (! parent->locked_children) { for (;;) { a_inode *aino = *aip; if (aino == 0) @@ -672,9 +672,9 @@ static void recycle_aino (Unit *unit, a_ /* Not recyclable if next == 0 (i.e., not chained into recyclable list), or if parent directory is being ExNext()ed. */ - if (aino->next == 0) + if (aino->next == 0) { aip = &aino->sibling; - else { + } else { if (aino->shlock > 0 || aino->elock) write_log ("panic: freeing locked a_inode!\n"); @@ -683,6 +683,7 @@ static void recycle_aino (Unit *unit, a_ 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. */ @@ -719,7 +720,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) { @@ -748,7 +749,6 @@ 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)); @@ -759,13 +759,17 @@ static void delete_aino (Unit *unit, a_i /* 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) { - if (k->curr_file == aino) + TRACE(("Same parent found for %d\n", i)); + if (k->curr_file == aino) { k->curr_file = aino->sibling; + TRACE(("Advancing curr_file\n")); + } } } } @@ -803,9 +807,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; } @@ -854,7 +863,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 @@ -887,7 +896,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)) { @@ -980,7 +989,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; } @@ -1258,7 +1267,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 ()); @@ -1746,6 +1755,8 @@ static void populate_directory (Unit *un 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; @@ -1767,13 +1778,13 @@ static void populate_directory (Unit *un static void do_examine (Unit *unit, dpacket packet, ExamineKey *ek, uaecptr info) { - a_inode *aino; - 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: @@ -1806,14 +1817,19 @@ static void action_examine_next (Unit *u } 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; - } else + 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"); goto no_more_entries; @@ -1964,9 +1980,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. */ @@ -2174,6 +2190,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) { @@ -2283,7 +2315,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); @@ -3020,6 +3052,14 @@ static int get_new_device (char **devnam 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; @@ -3028,7 +3068,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; @@ -3068,11 +3108,10 @@ void filesys_reset (void) 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); + a_inode *a; + while (a = parent->child) { + free_all_ainos (u, a); + dispose_aino (u, &parent->child, a); } } @@ -3115,10 +3154,7 @@ static uae_u32 filesys_diagentry (void) 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) { @@ -3135,7 +3171,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.