Make merge_file_changes more direct dealing with SFTs and merge the

"close open files setfattr wants to change" functionality there.


git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@1408 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2009-05-28 18:33:22 +00:00
parent 896908d6f7
commit 7b89e44274

View File

@ -42,10 +42,7 @@ STATIC void fnode_to_sft(f_node_ptr fnp);
STATIC f_node_ptr split_path(char *, char *, f_node_ptr fnp); STATIC f_node_ptr split_path(char *, char *, f_node_ptr fnp);
STATIC BOOL find_fname(f_node_ptr, char *, int); STATIC BOOL find_fname(f_node_ptr, char *, int);
/* /// Added - Ron Cemer */ /* /// Added - Ron Cemer */
STATIC void merge_file_changes(f_node_ptr fnp, int collect); STATIC int merge_file_changes(f_node_ptr fnp, int collect);
/* /// Added - Ron Cemer */
STATIC int is_same_file(f_node_ptr fnp, sft FAR *sftp);
/* /// Added - Ron Cemer */
STATIC BOOL find_free(f_node_ptr); STATIC BOOL find_free(f_node_ptr);
STATIC int alloc_find_free(f_node_ptr fnp, char *path, char *fcbname); STATIC int alloc_find_free(f_node_ptr fnp, char *path, char *fcbname);
STATIC VOID wipe_out(f_node_ptr); STATIC VOID wipe_out(f_node_ptr);
@ -377,16 +374,6 @@ COUNT remove_lfn_entries(f_node_ptr fnp)
return SUCCESS; return SUCCESS;
} }
STATIC unsigned get_f_nodes_cnt(void)
{
sfttbl FAR *sp;
unsigned f_nodes_cnt = 0;
for (sp = sfthead; sp != (sfttbl FAR *) - 1; sp = sp->sftt_next)
f_nodes_cnt += sp->sftt_count;
return f_nodes_cnt;
}
/* /// Added - Ron Cemer */ /* /// Added - Ron Cemer */
/* If more than one SFT has a file open, and a write /* If more than one SFT has a file open, and a write
occurs, this function must be called to propagate the occurs, this function must be called to propagate the
@ -396,46 +383,62 @@ STATIC unsigned get_f_nodes_cnt(void)
reasons, since DOS without SHARE does not share changes reasons, since DOS without SHARE does not share changes
between two or more open instances of the same file between two or more open instances of the same file
unless these instances were generated by dup() or dup2(). */ unless these instances were generated by dup() or dup2(). */
STATIC void merge_file_changes(f_node_ptr fnp, int collect) STATIC int merge_file_changes(f_node_ptr fnp, int collect)
{ {
int i, fd; int i, j;
unsigned f_nodes_cnt; sft FAR *sftp;
sfttbl FAR *sp;
if (!IsShareInstalled(FALSE)) if (!IsShareInstalled(FALSE))
return; return SUCCESS;
fd = fnp->f_sft_idx; i = 0;
f_nodes_cnt = get_f_nodes_cnt(); for (sp = sfthead; sp != (sfttbl FAR *) - 1; sp = sp->sftt_next)
for (i = 0; i < f_nodes_cnt; i++)
{ {
sft FAR *sftp = idx_to_sft(i); for(j = sp->sftt_count, sftp = sp->sftt_table; --j >= 0; sftp++, i++)
if (i != fd && FP_OFF(sftp) != (size_t)-1 && is_same_file(fnp, sftp))
{ {
if (collect) if (i != fnp->f_sft_idx && sftp->sft_count != 0
&& fnp->f_dpb == sftp->sft_dcb
&& (fnp->f_dir.dir_attrib & D_VOLID) == 0
&& (sftp->sft_attrib & D_VOLID) == 0
&& fnp->f_diridx == sftp->sft_diridx
&& fnp->f_dirsector == sftp->sft_dirsector
) /* same file, but different FD */
{ {
/* We're collecting file changes from any other if (collect == -1)
SFT which refers to this file. */
if ((sftp->sft_mode & O_ACCMODE) != RDONLY)
{ {
setdstart(fnp->f_dpb, &fnp->f_dir, sftp->sft_stclust); /* set attrib: close open files */
fnp->f_dir.dir_size = sftp->sft_size; int rc = DosCloseSft(i, FALSE);
fnp->f_dir.dir_date = sftp->sft_date; if (rc != SUCCESS)
fnp->f_dir.dir_time = sftp->sft_time; return rc;
break; }
else if (collect)
{
/* We're collecting file changes from any other
SFT which refers to this file. */
if ((sftp->sft_mode & O_ACCMODE) != RDONLY)
{
setdstart(fnp->f_dpb, &fnp->f_dir, sftp->sft_stclust);
fnp->f_dir.dir_size = sftp->sft_size;
fnp->f_dir.dir_date = sftp->sft_date;
fnp->f_dir.dir_time = sftp->sft_time;
return SUCCESS;
}
}
else
{
/* We just made changes to this file, so we are
distributing these changes to the other f_nodes
which refer to this file. */
sftp->sft_stclust = getdstart(fnp->f_dpb, &fnp->f_dir);
sftp->sft_size = fnp->f_dir.dir_size;
sftp->sft_date = fnp->f_dir.dir_date;
sftp->sft_time = fnp->f_dir.dir_time;
} }
}
else
{
/* We just made changes to this file, so we are
distributing these changes to the other f_nodes
which refer to this file. */
sftp->sft_stclust = getdstart(fnp->f_dpb, &fnp->f_dir);
sftp->sft_size = fnp->f_dir.dir_size;
sftp->sft_date = fnp->f_dir.dir_date;
sftp->sft_time = fnp->f_dir.dir_time;
} }
} }
} }
return SUCCESS;
} }
void dos_merge_file_changes(int fd) void dos_merge_file_changes(int fd)
@ -443,16 +446,6 @@ void dos_merge_file_changes(int fd)
merge_file_changes(sft_to_fnode(fd), FALSE); merge_file_changes(sft_to_fnode(fd), FALSE);
} }
/* /// Added - Ron Cemer */
STATIC int is_same_file(f_node_ptr fnp, sft FAR *sftp)
{
return fnp->f_dpb == sftp->sft_dcb
&& (fnp->f_dir.dir_attrib & D_VOLID) == 0
&& (sftp->sft_attrib & D_VOLID) == 0
&& fnp->f_diridx == sftp->sft_diridx
&& fnp->f_dirsector == sftp->sft_dirsector;
}
STATIC COUNT delete_dir_entry(f_node_ptr fnp) STATIC COUNT delete_dir_entry(f_node_ptr fnp)
{ {
COUNT rc; COUNT rc;
@ -1712,6 +1705,7 @@ COUNT dos_setfattr(BYTE * name, UWORD attrp)
{ {
f_node_ptr fnp; f_node_ptr fnp;
char fcbname[FNAME_SIZE + FEXT_SIZE]; char fcbname[FNAME_SIZE + FEXT_SIZE];
int rc;
/* JPP-If user tries to set VOLID or RESERVED bits, return error. /* JPP-If user tries to set VOLID or RESERVED bits, return error.
We used to also check for D_DIR here, but causes issues with deltree We used to also check for D_DIR here, but causes issues with deltree
@ -1748,23 +1742,12 @@ COUNT dos_setfattr(BYTE * name, UWORD attrp)
fnp->f_flags |= F_DMOD | F_DDATE; fnp->f_flags |= F_DMOD | F_DDATE;
/* close open files in compat mode, otherwise there was a critical error */ /* close open files in compat mode, otherwise there was a critical error */
if (IsShareInstalled(FALSE)) { fnp->f_sft_idx = -1;
int f_nodes_cnt = get_f_nodes_cnt(); rc = merge_file_changes(fnp, -1);
int i; if (rc == SUCCESS)
for (i = 0; i < f_nodes_cnt; i++) dir_write(fnp);
{
sft FAR *sftp = idx_to_sft(i);
if (FP_OFF(sftp) != (size_t)-1 && is_same_file(fnp, sftp)) {
int rc = DosCloseSft(i, FALSE);
if (rc != SUCCESS)
return rc;
}
}
}
dir_write(fnp);
dir_close(fnp); dir_close(fnp);
return SUCCESS; return rc;
} }
#endif #endif