Force near fnode use to use either fnode[0] or fnode[1] instead of the

allocation scheme. This eliminates the checks done in inthndlr.c because
the f_count field is no longer checked.


git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@1389 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2009-05-20 18:13:37 +00:00
parent 24b9d0e61e
commit 2092745236
6 changed files with 58 additions and 128 deletions

View File

@ -56,14 +56,13 @@ VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart)
fnp->f_cluster = fnp->f_dirstart = dirstart;
}
f_node_ptr dir_open(register const char *dirname)
f_node_ptr dir_open(register const char *dirname, f_node_ptr fnp)
{
f_node_ptr fnp;
int i;
char fcbname[FNAME_SIZE + FEXT_SIZE];
/* Allocate an fnode if possible - error return (0) if not. */
if ((fnp = get_f_node()) == (f_node_ptr) 0)
if ((fnp = get_f_node(fnp)) == (f_node_ptr) 0)
{
return (f_node_ptr) 0;
}
@ -399,7 +398,7 @@ COUNT dos_findfirst(UCOUNT attr, BYTE * name)
{
char tmp = name[i];
name[i] = '\0';
if ((fnp = dir_open(name)) == NULL)
if ((fnp = dir_open(name, &fnode[0])) == NULL)
return DE_PATHNOTFND;
name[i] = tmp;
}
@ -462,7 +461,7 @@ COUNT dos_findnext(void)
REG dmatch *dmp = &sda_tmp_dm;
/* Allocate an fnode if possible - error return (0) if not. */
if ((fnp = get_f_node()) == (f_node_ptr) 0)
if ((fnp = get_f_node(&fnode[0])) == (f_node_ptr) 0)
{
return DE_NFILES;
}

View File

@ -40,8 +40,7 @@ BYTE *RcsId = "$Id$";
f_node_ptr xlt_fd(COUNT);
COUNT xlt_fnp(f_node_ptr);
STATIC void save_far_f_node(f_node_ptr fnp);
STATIC f_node_ptr get_near_f_node(void);
STATIC f_node_ptr split_path(char *, char *);
STATIC f_node_ptr split_path(char *, char *, f_node_ptr fnp);
STATIC BOOL find_fname(f_node_ptr, char *, int);
/* /// Added - Ron Cemer */
STATIC void merge_file_changes(f_node_ptr fnp, int collect);
@ -149,7 +148,7 @@ long dos_open(char *path, unsigned flags, unsigned attrib)
/* next split the passed dir into comopnents (i.e. - path to */
/* new directory and name of new directory. */
if ((fnp = split_path(path, fcbname)) == NULL)
if ((fnp = split_path(path, fcbname, &fnode[0])) == NULL)
return DE_PATHNOTFND;
/* Check that we don't have a duplicate name, so if we */
@ -296,10 +295,9 @@ COUNT dos_commit(COUNT fd)
/* note: an invalid fd is indicated by a 0 return */
if (fnp == (f_node_ptr) 0)
return DE_INVLDHNDL;
fnp2 = get_f_node();
fnp2 = get_f_node(&fnode[1]);
if (fnp2 == (f_node_ptr) 0)
{
release_near_f_node(fnp);
return DE_INVLDHNDL;
}
@ -307,17 +305,14 @@ COUNT dos_commit(COUNT fd)
is updated etc, but we keep our old info */
memcpy(fnp2, fnp, sizeof(*fnp));
save_far_f_node(fnp2);
release_near_f_node(fnp);
return dos_close(xlt_fnp(fnp2));
}
/* */
/* split a path into it's component directory and file name */
/* */
f_node_ptr split_path(char * path, char * fcbname)
f_node_ptr split_path(char * path, char * fcbname, f_node_ptr fnp)
{
REG f_node_ptr fnp;
/* Start off by parsing out the components. */
int dirlength = ParseDosName(path, fcbname, FALSE);
@ -348,7 +343,7 @@ f_node_ptr split_path(char * path, char * fcbname)
{
char tmp = path[dirlength];
path[dirlength] = '\0';
fnp = dir_open(path);
fnp = dir_open(path, fnp);
path[dirlength] = tmp;
}
@ -370,7 +365,7 @@ BOOL dir_exists(char * path)
REG f_node_ptr fnp;
char fcbname[FNAME_SIZE + FEXT_SIZE];
if ((fnp = split_path(path, fcbname)) == NULL)
if ((fnp = split_path(path, fcbname, &fnode[0])) == NULL)
return FALSE;
dir_close(fnp);
@ -451,7 +446,7 @@ STATIC void merge_file_changes(f_node_ptr fnp, int collect)
return;
fd = xlt_fnp(fnp);
fnp2 = get_near_f_node();
fnp2 = &fnode[1];
for (i = 0; i < f_nodes_cnt; i++)
{
fmemcpy(fnp2, &f_nodes[i], sizeof(*fnp2));
@ -479,7 +474,6 @@ STATIC void merge_file_changes(f_node_ptr fnp, int collect)
}
}
}
release_near_f_node(fnp2);
}
/* /// Added - Ron Cemer */
@ -538,7 +532,7 @@ COUNT dos_delete(BYTE * path, int attrib)
/* first split the passed dir into components (i.e. - */
/* path to new directory and name of new directory */
if ((fnp = split_path(path, fcbname)) == NULL)
if ((fnp = split_path(path, fcbname, &fnode[0])) == NULL)
{
return DE_PATHNOTFND;
}
@ -581,7 +575,7 @@ COUNT dos_rmdir(BYTE * path)
/* next, split the passed dir into components (i.e. - */
/* path to new directory and name of new directory */
if ((fnp = split_path(path, fcbname)) == NULL)
if ((fnp = split_path(path, fcbname, &fnode[0])) == NULL)
{
return DE_PATHNOTFND;
}
@ -611,7 +605,7 @@ COUNT dos_rmdir(BYTE * path)
/* Check that the directory is empty. Only the */
/* "." and ".." are permissable. */
fnp->f_flags &= ~F_DMOD;
fnp1 = dir_open(path);
fnp1 = dir_open(path, &fnode[1]);
if (fnp1 == NULL)
{
dir_close(fnp);
@ -683,7 +677,7 @@ COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib)
/* first split the passed target into compnents (i.e. - path to */
/* new file name and name of new file name */
if ((fnp2 = split_path(path2, fcbname)) == NULL)
if ((fnp2 = split_path(path2, fcbname, &fnode[1])) == NULL)
{
return DE_PATHNOTFND;
}
@ -698,7 +692,7 @@ COUNT dos_rename(BYTE * path1, BYTE * path2, int attrib)
/* next split the passed source into compnents (i.e. - path to */
/* old file name and name of old file name */
if ((fnp1 = split_path(path1, fcbname)) == NULL)
if ((fnp1 = split_path(path1, fcbname, &fnode[0])) == NULL)
{
dir_close(fnp2);
return DE_PATHNOTFND;
@ -816,7 +810,7 @@ STATIC int alloc_find_free(f_node_ptr fnp, char *path, char *fcbname)
{
fnp->f_flags &= ~F_DMOD;
dir_close(fnp);
fnp = split_path(path, fcbname);
fnp = split_path(path, fcbname, fnp);
/* Get a free f_node pointer so that we can use */
/* it in building the new file. */
@ -891,7 +885,6 @@ COUNT dos_getftime(COUNT fd, date FAR * dp, time FAR * tp)
*dp = fnp->f_dir.dir_date;
*tp = fnp->f_dir.dir_time;
release_near_f_node(fnp);
return SUCCESS;
}
@ -940,7 +933,6 @@ ULONG dos_getfsize(COUNT fd)
return (ULONG)-1l;
/* Return the file size */
release_near_f_node(fnp);
return fnp->f_dir.dir_size;
}
@ -1053,7 +1045,7 @@ COUNT dos_mkdir(BYTE * dir)
/* first split the passed dir into components (i.e. - */
/* path to new directory and name of new directory */
if ((fnp = split_path(dir, fcbname)) == NULL)
if ((fnp = split_path(dir, fcbname, &fnode[0])) == NULL)
{
return DE_PATHNOTFND;
}
@ -1824,7 +1816,6 @@ LONG dos_lseek(COUNT fd, LONG foffset, COUNT origin)
/* default to an invalid function */
default:
release_near_f_node(fnp);
return (LONG) DE_INVLDFUNC;
}
save_far_f_node(fnp);
@ -1883,7 +1874,7 @@ int dos_cd(char * PathName)
return DE_INVLDDRV;
/* now test for its existance. If it doesn't, return an error. */
if ((fnp = dir_open(PathName)) == NULL)
if ((fnp = dir_open(PathName, &fnode[0])) == NULL)
return DE_PATHNOTFND;
/* problem: RBIL table 01643 does not give a FAT32 field for the
@ -1894,48 +1885,21 @@ int dos_cd(char * PathName)
}
#endif
/* try to allocate a near f_node */
/* (there are just two of them, in the SDA) */
f_node_ptr get_near_f_node(void)
{
f_node_ptr fnp = fnode;
if (fnp->f_count == 0)
fnp->f_count++;
else
{
fnp++;
if (fnp->f_count == 0)
fnp->f_count++;
else
{
fnp = (f_node_ptr) 0;
panic("more than two near fnodes requested at the same time!\n");
}
}
return fnp;
}
/* Try to allocate an f_node from the available files array */
f_node_ptr get_f_node(void)
f_node_ptr get_f_node(f_node_ptr fnp)
{
REG int i;
f_node_ptr fnp = get_near_f_node();
if (fnp != (f_node_ptr)0)
for (i = 0; i < f_nodes_cnt; i++)
{
for (i = 0; i < f_nodes_cnt; i++)
if (f_nodes[i].f_count == 0)
{
if (f_nodes[i].f_count == 0)
{
++f_nodes[i].f_count;
fnode_fd[fnp - fnode] = i;
return fnp;
}
++f_nodes[i].f_count;
fnp->f_count = 1;
fnode_fd[fnp - fnode] = i;
return fnp;
}
release_near_f_node(fnp);
}
return (f_node_ptr) 0;
}
@ -1948,7 +1912,6 @@ VOID release_f_node(f_node_ptr fnp)
--fp->f_count;
else
fp->f_count = 0;
release_near_f_node(fnp);
}
#ifndef IPL
@ -1962,7 +1925,6 @@ COUNT dos_getfattr_fd(COUNT fd)
if (fnp == (f_node_ptr) 0)
return DE_TOOMANY;
release_near_f_node(fnp);
return fnp->f_dir.dir_attrib;
}
@ -2191,36 +2153,28 @@ COUNT xlt_fnp(f_node_ptr fnp)
return fnode_fd[fnp - fnode];
}
/* allocate a near fnode and copy the far fd fnode to it */
/* copy the far fnode fd into the first near fnode */
f_node_ptr xlt_fd(int fd)
{
f_node_ptr fnp = (f_node_ptr) 0;
/* If the fd was invalid because it was out of range or the */
/* requested file was not open, tell the caller and exit */
/* note: an invalid fd is indicated by a 0 return */
if (fd < f_nodes_cnt)
{
fnp = get_near_f_node();
if (fnp != (f_node_ptr)0)
fmemcpy(&fnode[0], &f_nodes[fd], sizeof(fnode[0]));
if (fnode[0].f_count > 0)
{
fmemcpy(fnp, &f_nodes[fd], sizeof(*fnp));
if (fnp->f_count == 0)
{
release_near_f_node(fnp);
fnp = (f_node_ptr) 0;
} else
fnode_fd[fnp - fnode] = fd;
fnode_fd[0] = fd;
return &fnode[0];
}
}
return fnp;
return NULL;
}
/* copy a near fnode to the corresponding far one and release it */
/* copy a near fnode to the corresponding far one */
STATIC void save_far_f_node(f_node_ptr fnp)
{
fmemcpy(&f_nodes[xlt_fnp(fnp)], fnp, sizeof(*fnp));
release_near_f_node(fnp);
}
/* TE

View File

@ -425,5 +425,13 @@ void ASMCFUNC DosIdle_hlt(void); /* dosidle.asm */
GLOBAL BYTE ReturnAnyDosVersionExpected;
GLOBAL BYTE ASM HaltCpuWhileIdle;
/* near fnodes:
* fnode[0] is used internally for almost all cases.
* fnode[1] is only used for:
* 1) rename (target)
* 2) rmdir (checks if the directory to remove is empty)
* 3) commit (copies, than closes fnode[0])
* 3) merge_file_changes (for SHARE)
*/
GLOBAL struct f_node fnode[2];
GLOBAL int fnode_fd[2];

View File

@ -426,28 +426,23 @@ dispatch:
}
/* Clear carry by default for these functions */
/* We force clear the near fnodes,
On a normal int21h entry these are unused, so should already
be clear, thus this code is effectively redundant.
However when re-entering int21h, such as a device driver
(e.g. shsufdrv), the fnodes may contain the values of the
in progress call; as long as the driver/tsr causing the
reentrancey saves and restores the SDA across the call then
any changes we do (ie clearing these) should go unnoticed
and if the cause of the reentrancy does not save/restore the
SDA then the caller should expected the unexpected.
Failure to do this will at a minimal result in the extra
output indicating fnodes not 0 (and possibly clearing at end
of call) when the re-entered int21h call completes, but could
result in the re-entered call to fail with no free near fnodes
if both are already in use by the original int21h call (?bug 1879?).
See also PATCH TE 5 jul 04 explanation at end
*/
/*
what happened:
Application does FindFirst("I:\*.*");
this fails, and causes Int24
this sets ErrorMode, and calls Int24
Application decides NOT to return to DOS,
but instead pop the stack and return to itself
(this is legal; see RBIL/INT 24 description
*) errormode NEVER gets set back to 0 until exit()
I have NO idea how real DOS handles this;
the appended patch cures the worst symptoms
*/
if (/*ErrorMode && */lr.AH > 0x0c && lr.AH != 0x30 && lr.AH != 0x59)
{
/*if (ErrorMode)*/ ErrorMode = 0;
fnode[0].f_count = 0; /* don't panic - THEY ARE unused !! */
fnode[1].f_count = 0;
}
/* Check for Ctrl-Break */
if (break_ena || (lr.AH >= 1 && lr.AH <= 5) || (lr.AH >= 8 && lr.AH <= 0x0b))
@ -1573,31 +1568,6 @@ exit_dispatch:
r->ES = lr.ES;
real_exit:;
/* PATCH !! TE 5 JUL 04
what happened:
Application does FindFirst("I:\*.*");
this fails, and causes Int24
this sets ErrorMode, and calls Int24
Application decides NOT to return to DOS,
but instead pop the stack and return to itself
(this is legal; see RBIL/INT 24 description
a) now the alloc()'ed fnode[0] never gets free()'ed
b) errormode NEVER gets set back to 0 unyil exit()
I have NO idea how real DOS handles this;
the appended patch cures the worst symptoms
*/
if (fnode[0].f_count != 0 ||
fnode[1].f_count != 0 )
{
if (ErrorMode == 0)
put_string("near_fnodes not 0"); /* panic ?? */
fnode[0].f_count = 0; /* don't panic - THEY ARE unused !! */
fnode[1].f_count = 0;
}
/* PATCH !! END TE 5 JUL 04 */
#ifdef DEBUG
if (bDumpRegs)
{

View File

@ -50,7 +50,7 @@ VOID unicode_to_lfn(UNICODE FAR **name, struct lfn_entry FAR *lep);
*/
COUNT lfn_allocate_inode(VOID)
{
f_node_ptr fnp = get_f_node();
f_node_ptr fnp = get_f_node(&fnode[0]);
struct dpb FAR *dpbp;
COUNT handle;
if (fnp == 0) return LHE_NOFREEHNDL;

View File

@ -138,7 +138,7 @@ VOID fatal(BYTE * err_msg);
/* fatdir.c */
VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart);
f_node_ptr dir_open(const char *dirname);
f_node_ptr dir_open(const char *dirname, f_node_ptr fnp);
COUNT dir_read(REG f_node_ptr fnp);
BOOL dir_write(REG f_node_ptr fnp);
VOID dir_close(REG f_node_ptr fnp);
@ -180,9 +180,8 @@ VOID trim_path(BYTE FAR * s);
int dos_cd(char * PathName);
f_node_ptr get_f_node(void);
f_node_ptr get_f_node(f_node_ptr fnp);
VOID release_f_node(f_node_ptr fnp);
#define release_near_f_node(fnp) ((fnp)->f_count = 0)
COUNT dos_getfattr_fd(COUNT fd);
COUNT dos_getfattr(BYTE * name);
COUNT dos_setfattr(BYTE * name, UWORD attrp);