From 7b89e44274f1e66297345c00e1385c0df82f844f Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Thu, 28 May 2009 18:33:22 +0000 Subject: [PATCH] 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 --- kernel/fatfs.c | 119 +++++++++++++++++++++---------------------------- 1 file changed, 51 insertions(+), 68 deletions(-) diff --git a/kernel/fatfs.c b/kernel/fatfs.c index b19fcd6..8d6f1f7 100644 --- a/kernel/fatfs.c +++ b/kernel/fatfs.c @@ -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 BOOL find_fname(f_node_ptr, char *, int); /* /// Added - Ron Cemer */ -STATIC void 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 int merge_file_changes(f_node_ptr fnp, int collect); STATIC BOOL find_free(f_node_ptr); STATIC int alloc_find_free(f_node_ptr fnp, char *path, char *fcbname); STATIC VOID wipe_out(f_node_ptr); @@ -377,16 +374,6 @@ COUNT remove_lfn_entries(f_node_ptr fnp) 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 */ /* If more than one SFT has a file open, and a write 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 between two or more open instances of the same file 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; - unsigned f_nodes_cnt; + int i, j; + sft FAR *sftp; + sfttbl FAR *sp; if (!IsShareInstalled(FALSE)) - return; + return SUCCESS; - fd = fnp->f_sft_idx; - f_nodes_cnt = get_f_nodes_cnt(); - for (i = 0; i < f_nodes_cnt; i++) + i = 0; + for (sp = sfthead; sp != (sfttbl FAR *) - 1; sp = sp->sftt_next) { - sft FAR *sftp = idx_to_sft(i); - if (i != fd && FP_OFF(sftp) != (size_t)-1 && is_same_file(fnp, sftp)) + for(j = sp->sftt_count, sftp = sp->sftt_table; --j >= 0; sftp++, i++) { - 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 - SFT which refers to this file. */ - if ((sftp->sft_mode & O_ACCMODE) != RDONLY) + if (collect == -1) { - 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; - break; + /* set attrib: close open files */ + int rc = DosCloseSft(i, FALSE); + if (rc != SUCCESS) + return rc; + } + 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) @@ -443,16 +446,6 @@ void dos_merge_file_changes(int fd) 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) { COUNT rc; @@ -1712,6 +1705,7 @@ COUNT dos_setfattr(BYTE * name, UWORD attrp) { f_node_ptr fnp; char fcbname[FNAME_SIZE + FEXT_SIZE]; + int rc; /* 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 @@ -1748,23 +1742,12 @@ COUNT dos_setfattr(BYTE * name, UWORD attrp) fnp->f_flags |= F_DMOD | F_DDATE; /* close open files in compat mode, otherwise there was a critical error */ - if (IsShareInstalled(FALSE)) { - int f_nodes_cnt = get_f_nodes_cnt(); - int i; - for (i = 0; i < f_nodes_cnt; i++) - { - 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); + fnp->f_sft_idx = -1; + rc = merge_file_changes(fnp, -1); + if (rc == SUCCESS) + dir_write(fnp); dir_close(fnp); - return SUCCESS; + return rc; } #endif