--- uae/src/filesys.c 2018/04/24 16:53:07 1.1.1.9 +++ uae/src/filesys.c 2018/04/24 17:02:12 1.1.1.13 @@ -28,12 +28,12 @@ #include "sysdeps.h" #include "config.h" -#include "threaddep/penguin.h" +#include "threaddep/thread.h" #include "options.h" #include "uae.h" #include "memory.h" #include "custom.h" -#include "readcpu.h" +#include "events.h" #include "newcpu.h" #include "filesys.h" #include "autoconf.h" @@ -60,7 +60,7 @@ static long dos_errno(void) case ENOMEM: return ERROR_NO_FREE_STORE; case EEXIST: return ERROR_OBJECT_EXISTS; case EACCES: return ERROR_WRITE_PROTECTED; - case ENOENT: return ERROR_OBJECT_NOT_FOUND; + case ENOENT: return ERROR_OBJECT_NOT_AROUND; case ENOTDIR: return ERROR_OBJECT_WRONG_TYPE; case ENOSPC: return ERROR_DISK_IS_FULL; case EBUSY: return ERROR_OBJECT_IN_USE; @@ -125,7 +125,7 @@ typedef struct { /* Threading stuff */ smp_comm_pipe *unit_pipe, *back_pipe; - penguin_id tid; + uae_thread_id tid; struct _unit *volatile self; /* Reset handling */ uae_sem_t reset_sync_sem; @@ -352,7 +352,8 @@ void write_filesys_config (struct uaedev fprintf (f, "filesystem=%s,%s:%s\n", uip[i].readonly ? "ro" : "rw", uip[i].volname, str); } else { - fprintf (f, "hardfile=%s,%d,%d,%d,%d,%s\n", uip[i].hf.secspertrack, + 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); } free (str); @@ -418,6 +419,12 @@ struct hardfiledata *get_hardfile_data ( #define DOS_TRUE ((unsigned long)-1L) #define DOS_FALSE (0L) +/* Passed as type to Lock() */ +#define SHARED_LOCK -2 /* File is readable by others */ +#define ACCESS_READ -2 /* Synonym */ +#define EXCLUSIVE_LOCK -1 /* No other access allowed */ +#define ACCESS_WRITE -1 /* Synonym */ + /* packet types */ #define ACTION_CURRENT_VOLUME 7 #define ACTION_LOCATE_OBJECT 8 @@ -690,16 +697,17 @@ static void update_child_names (Unit *un while (a != 0) { char *name_start; char *new_name; - + char dirsep[2] = { FSDB_DIR_SEPARATOR, '\0' }; + a->parent = parent; - name_start = strrchr (a->nname, '/'); + name_start = strrchr (a->nname, FSDB_DIR_SEPARATOR); if (name_start == 0) { write_log ("malformed file name"); } name_start++; new_name = (char *)xmalloc (strlen (name_start) + l0); strcpy (new_name, parent->nname); - strcat (new_name, "/"); + strcat (new_name, dirsep); strcat (new_name, name_start); free (a->nname); a->nname = new_name; @@ -912,7 +920,7 @@ static a_inode *new_child_aino (Unit *un if (nn == 0) return 0; - aino = (a_inode *) xmalloc (sizeof (a_inode)); + aino = (a_inode *) xcalloc (sizeof (a_inode), 1); if (aino == 0) return 0; aino->aname = modified_rel ? modified_rel : my_strdup (rel); @@ -934,7 +942,7 @@ static a_inode *new_child_aino (Unit *un static a_inode *create_child_aino (Unit *unit, a_inode *base, char *rel, int isdir) { - a_inode *aino = (a_inode *) xmalloc (sizeof (a_inode)); + a_inode *aino = (a_inode *) xcalloc (sizeof (a_inode), 1); if (aino == 0) return 0; @@ -975,7 +983,7 @@ static a_inode *lookup_child_aino (Unit return c; c = new_child_aino (unit, base, rel); if (c == 0) - *err = ERROR_OBJECT_NOT_FOUND; + *err = ERROR_OBJECT_NOT_AROUND; return c; } @@ -1056,7 +1064,7 @@ static a_inode *get_aino (Unit *unit, a_ next = lookup_child_aino (unit, curr, p, err); if (next == 0) { /* if only last component not found, return parent dir. */ - if (*err != ERROR_OBJECT_NOT_FOUND || component_end != 0) + if (*err != ERROR_OBJECT_NOT_AROUND || component_end != 0) curr = 0; /* ? what error is appropriate? */ break; @@ -1112,7 +1120,7 @@ static uae_u32 startup_handler (void) } uinfo = current_mountinfo->ui + i; - unit = (Unit *) xmalloc (sizeof (Unit)); + unit = (Unit *) xcalloc (sizeof (Unit), 1); unit->next = units; units = unit; uinfo->self = unit; @@ -1150,6 +1158,8 @@ static uae_u32 startup_handler (void) unit->rootnode.amigaos_mode = 0; unit->rootnode.shlock = 0; unit->rootnode.elock = 0; + unit->rootnode.comment = 0; + unit->rootnode.has_dbentry = 0; unit->aino_cache_size = 0; for (i = 0; i < MAX_AINO_HASH; i++) unit->aino_hash[i] = 0; @@ -1254,7 +1264,7 @@ static void free_key (Unit *unit, Key *k } if (k->fd >= 0) - close(k->fd); + close (k->fd); free(k); } @@ -1390,16 +1400,16 @@ action_lock (Unit *unit, dpacket packet) a_inode *a; uae_u32 err; - if (mode != -2 && mode != -1) { + if (mode != SHARED_LOCK && mode != EXCLUSIVE_LOCK) { TRACE(("Bad mode.\n")); - mode = -2; + mode = SHARED_LOCK; } TRACE(("ACTION_LOCK(0x%lx, \"%s\", %d)\n", lock, bstr (unit, name), mode)); DUMPLOCK(unit, lock); a = find_aino (unit, lock, bstr (unit, name), &err); - if (err == 0 && (a->elock || (mode != -2 && a->shlock > 0))) { + if (err == 0 && (a->elock || (mode != SHARED_LOCK && a->shlock > 0))) { err = ERROR_OBJECT_IN_USE; } /* Lock() doesn't do access checks. */ @@ -1408,7 +1418,7 @@ action_lock (Unit *unit, dpacket packet) PUT_PCK_RES2 (packet, err); return; } - if (mode == -2) + if (mode == SHARED_LOCK) a->shlock++; else a->elock = 1; @@ -1426,7 +1436,7 @@ static void action_free_lock (Unit *unit a = lookup_aino (unit, get_long (lock + 4)); if (a == 0) { PUT_PCK_RES1 (packet, DOS_FALSE); - PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_FOUND); + PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_AROUND); return; } if (a->elock) @@ -1454,7 +1464,7 @@ action_dup_lock (Unit *unit, dpacket pac a = lookup_aino (unit, get_long (lock + 4)); if (a == 0) { PUT_PCK_RES1 (packet, DOS_FALSE); - PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_FOUND); + PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_AROUND); return; } /* DupLock()ing exclusive locks isn't possible, says the Autodoc, but @@ -1510,6 +1520,21 @@ static void free_exkey (ExamineKey *ek) closedir (ek->dir); } +static ExamineKey *lookup_exkey (Unit *unit, uae_u32 uniq) +{ + ExamineKey *ek; + int i; + + ek = unit->examine_keys; + for (i = 0; i < EXKEYS; i++, ek++) { + /* Did we find a free one? */ + if (ek->uniq == uniq) + return ek; + } + write_log ("Houston, we have a BIG problem.\n"); + return 0; +} + /* This is so sick... who invented ACTION_EXAMINE_NEXT? What did he THINK??? */ static ExamineKey *new_exkey (Unit *unit, a_inode *aino) { @@ -1551,21 +1576,6 @@ static ExamineKey *new_exkey (Unit *unit return ek; } -static ExamineKey *lookup_exkey (Unit *unit, uae_u32 uniq) -{ - ExamineKey *ek; - int i; - - ek = unit->examine_keys; - for (i = 0; i < EXKEYS; i++, ek++) { - /* Did we find a free one? */ - if (ek->uniq == uniq) - return ek; - } - write_log ("Houston, we have a BIG problem.\n"); - return 0; -} - static void get_fileinfo (Unit *unit, dpacket packet, uaecptr info, a_inode *aino) { @@ -1741,7 +1751,7 @@ static void do_find (Unit *unit, dpacket aino = find_aino (unit, lock, bstr (unit, name), &err); - if (aino == 0 || (err != 0 && err != ERROR_OBJECT_NOT_FOUND)) { + if (aino == 0 || (err != 0 && err != ERROR_OBJECT_NOT_AROUND)) { /* Whatever it is, we can't handle it. */ PUT_PCK_RES1 (packet, DOS_FALSE); PUT_PCK_RES2 (packet, err); @@ -2188,7 +2198,7 @@ action_change_mode (Unit *unit, dpacket a_inode *a = NULL, *olda = NULL; uae_u32 err = 0; TRACE(("ACTION_CHANGE_MODE(0x%lx,%d,%d)\n",object,type,mode)); - + if (! object || (type != CHANGE_FH && type != CHANGE_LOCK)) { @@ -2203,15 +2213,15 @@ action_change_mode (Unit *unit, dpacket mode = (mode == 1006 ? -1 : -2); if (type == CHANGE_LOCK) - uniq = get_long (object + 4); + uniq = get_long (object + 4); else { Key *k = lookup_key (unit, object); if (!k) { PUT_PCK_RES1 (packet, DOS_FALSE); - PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_FOUND); + PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_AROUND); return; } - uniq = k->aino->uniq; + uniq = k->aino->uniq; } a = lookup_aino (unit, uniq); @@ -2229,7 +2239,7 @@ action_change_mode (Unit *unit, dpacket a->elock = 0; a->shlock++; } - } + } if (err) { PUT_PCK_RES1 (packet, DOS_FALSE); @@ -2272,7 +2282,7 @@ action_parent_fh (Unit *unit, dpacket pa Key *k = lookup_key (unit, GET_PCK_ARG1 (packet)); if (!k) { PUT_PCK_RES1 (packet, DOS_FALSE); - PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_FOUND); + PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_AROUND); return; } action_parent_common (unit, packet, k->aino->uniq); @@ -2310,7 +2320,7 @@ action_create_dir (Unit *unit, dpacket p } aino = find_aino (unit, lock, bstr (unit, name), &err); - if (aino == 0 || (err != 0 && err != ERROR_OBJECT_NOT_FOUND)) { + if (aino == 0 || (err != 0 && err != ERROR_OBJECT_NOT_AROUND)) { PUT_PCK_RES1 (packet, DOS_FALSE); PUT_PCK_RES2 (packet, err); return; @@ -2373,7 +2383,7 @@ action_set_file_size (Unit *unit, dpacke off_t offset = GET_PCK_ARG2 (packet); long mode = (uae_s32)GET_PCK_ARG3 (packet); int whence = SEEK_CUR; - + if (mode > 0) whence = SEEK_END; if (mode < 0) whence = SEEK_SET; @@ -2382,7 +2392,7 @@ action_set_file_size (Unit *unit, dpacke k = lookup_key (unit, GET_PCK_ARG1 (packet)); if (k == 0) { PUT_PCK_RES1 (packet, DOS_TRUE); - PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_FOUND); + PUT_PCK_RES2 (packet, ERROR_OBJECT_NOT_AROUND); return; } @@ -2450,6 +2460,8 @@ action_delete_object (Unit *unit, dpacke return; } if (a->dir) { + /* This should take care of removing the fsdb if no files remain. */ + fsdb_dir_writeback (a); if (rmdir (a->nname) == -1) { PUT_PCK_RES1 (packet, DOS_FALSE); PUT_PCK_RES2 (packet, dos_errno()); @@ -2535,7 +2547,7 @@ action_rename_object (Unit *unit, dpacke return; } a2 = a2->parent; - } else if (a2 == 0 || err2 != ERROR_OBJECT_NOT_FOUND) { + } else if (a2 == 0 || err2 != ERROR_OBJECT_NOT_AROUND) { PUT_PCK_RES1 (packet, DOS_FALSE); PUT_PCK_RES2 (packet, err2 == 0 ? ERROR_OBJECT_EXISTS : err2); return; @@ -2786,7 +2798,7 @@ static int handle_packet (Unit *unit, dp } #ifdef UAE_FILESYS_THREADS -static void *filesys_penguin (void *unit_v) +static void *filesys_thread (void *unit_v) { UnitInfo *ui = (UnitInfo *)unit_v; for (;;) { @@ -2887,6 +2899,32 @@ static uae_u32 filesys_handler (void) return 0; } +static int current_deviceno = 0; +static int current_cdrom = 0; + +static void reset_uaedevices (void) +{ + current_deviceno = 0; + current_cdrom = 0; +} + +static int get_new_device (char **devname, uaecptr *devname_amiga, int cdrom) +{ + int result; + char buffer[80]; + + if (cdrom) { + sprintf (buffer, "CD%d", current_cdrom); + result = current_cdrom++; + } else { + sprintf (buffer, "DH%d", current_deviceno); + result = current_deviceno++; + } + + *devname_amiga = ds (*devname = my_strdup (buffer)); + return result; +} + void filesys_start_threads (void) { UnitInfo *uip; @@ -2899,7 +2937,7 @@ void filesys_start_threads (void) uip = current_mountinfo->ui; for (i = 0; i < current_mountinfo->num_units; i++) { uip[i].unit_pipe = 0; - uip[i].devno = get_new_device (&uip[i].devname, &uip[i].devname_amiga); + uip[i].devno = get_new_device (&uip[i].devname, &uip[i].devname_amiga, 0); #ifdef UAE_FILESYS_THREADS if (! is_hardfile (current_mountinfo, i)) { @@ -2907,7 +2945,7 @@ void filesys_start_threads (void) uip[i].back_pipe = (smp_comm_pipe *)xmalloc (sizeof (smp_comm_pipe)); init_comm_pipe (uip[i].unit_pipe, 50, 3); init_comm_pipe (uip[i].back_pipe, 50, 1); - start_penguin (filesys_penguin, (void *)(uip + i), &uip[i].tid); + uae_start_thread (filesys_thread, (void *)(uip + i), &uip[i].tid); } #endif } @@ -2916,7 +2954,6 @@ void filesys_start_threads (void) void filesys_reset (void) { Unit *u, *u1; - int i; /* We get called once from customreset at the beginning of the program * before filesys_start_threads has been called. Survive that. */ @@ -2956,13 +2993,11 @@ void filesys_prepare_reset (void) 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; - if (a->dirty && a->parent) - fsdb_dir_writeback (a->parent); - free (a->nname); - free (a->aname); - free (a); + de_recycle_aino (u, a); + dispose_aino (u, &b, a); } u = u->next; }