From ce290a033f174a6363fe5e990550b1f856dc035f Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Mon, 22 Mar 2004 22:33:05 +0000 Subject: [PATCH] Eliminate f_back field. extend() now uses f_cluster instead of f_back, while map_cluster makes sure it's not set to LONG_LAST_CLUSTER (but to the cluster before it) when calling extend(). extend() and first_fat() now return the new cluster number or LONG_LAST_CLUSTER, just like find_fat_free() Hopefully I didn't break anything... Initial testing was successful. git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@816 6ac86273-5f31-0410-b378-82cca8765d1b --- hdr/fnode.h | 1 - kernel/fatdir.c | 1 - kernel/fatfs.c | 89 +++++++++++++++++++++++++------------------------ 3 files changed, 45 insertions(+), 46 deletions(-) diff --git a/hdr/fnode.h b/hdr/fnode.h index f155118..36be857 100644 --- a/hdr/fnode.h +++ b/hdr/fnode.h @@ -55,7 +55,6 @@ struct f_node { struct dpb FAR *f_dpb; /* the block device for file */ ULONG f_offset; /* byte offset for next op */ - CLUSTER f_back; /* the cluster we were at */ CLUSTER f_cluster_offset; /* relative cluster number within file */ CLUSTER f_cluster; /* the cluster we are at */ }; diff --git a/kernel/fatdir.c b/kernel/fatdir.c index 71b9def..7a741b6 100644 --- a/kernel/fatdir.c +++ b/kernel/fatdir.c @@ -332,7 +332,6 @@ BOOL dir_write(REG f_node_ptr fnp) /* Do a "seek" to the directory position */ /* and convert the fnode to a directory fnode. */ fnp->f_offset = fnp->f_diroff * (ULONG)DIRENT_SIZE; - fnp->f_back = LONG_LAST_CLUSTER; fnp->f_cluster = fnp->f_dirstart; fnp->f_cluster_offset = 0; diff --git a/kernel/fatfs.c b/kernel/fatfs.c index b37dbb6..2670006 100644 --- a/kernel/fatfs.c +++ b/kernel/fatfs.c @@ -50,10 +50,9 @@ STATIC void copy_file_changes(f_node_ptr src, f_node_ptr dst); BOOL find_free(f_node_ptr); CLUSTER find_fat_free(f_node_ptr); VOID wipe_out(f_node_ptr); -BOOL last_link(f_node_ptr); -BOOL extend(f_node_ptr); +CLUSTER extend(f_node_ptr); COUNT extend_dir(f_node_ptr); -BOOL first_fat(f_node_ptr); +CLUSTER first_fat(f_node_ptr); COUNT map_cluster(f_node_ptr, COUNT); STATIC VOID shrink_file(f_node_ptr fnp); @@ -261,8 +260,7 @@ long dos_open(char *path, unsigned flags, unsigned attrib) /* Now change to file */ fnp->f_offset = 0l; - - fnp->f_back = LONG_LAST_CLUSTER; + if (status != S_OPENED) { fnp->f_cluster = FREE; @@ -1141,7 +1139,6 @@ COUNT dos_mkdir(BYTE * dir) /* Set the fnode to the desired mode */ fnp->f_mode = WRONLY; - fnp->f_back = LONG_LAST_CLUSTER; init_direntry(&fnp->f_dir, D_DIR, free_fat); @@ -1152,7 +1149,6 @@ COUNT dos_mkdir(BYTE * dir) fnp->f_offset = 0l; /* Mark the cluster in the FAT as used */ - fnp->f_cluster = free_fat; dpbp = fnp->f_dpb; link_fat(dpbp, free_fat, LONG_LAST_CLUSTER); @@ -1227,12 +1223,7 @@ COUNT dos_mkdir(BYTE * dir) return SUCCESS; } -BOOL last_link(f_node_ptr fnp) -{ - return (fnp->f_cluster == LONG_LAST_CLUSTER); -} - -STATIC BOOL extend(f_node_ptr fnp) +STATIC CLUSTER extend(f_node_ptr fnp) { CLUSTER free_fat; @@ -1245,24 +1236,24 @@ STATIC BOOL extend(f_node_ptr fnp) /* No empty clusters, disk is FULL! Translate into a useful */ /* error message. */ if (free_fat == LONG_LAST_CLUSTER) - return FALSE; + return free_fat; /* Now that we've found a free FAT entry, mark it as the last */ /* entry and save. */ - link_fat(fnp->f_dpb, fnp->f_back, free_fat); - fnp->f_cluster = free_fat; + link_fat(fnp->f_dpb, fnp->f_cluster, free_fat); link_fat(fnp->f_dpb, free_fat, LONG_LAST_CLUSTER); /* Mark the directory so that the entry is updated */ fnp->f_flags.f_dmod = TRUE; - return TRUE; + return free_fat; } STATIC COUNT extend_dir(f_node_ptr fnp) { REG COUNT idx; - if (!extend(fnp)) + CLUSTER cluster = extend(fnp); + if (cluster == LONG_LAST_CLUSTER) { dir_close(fnp); return DE_HNDLDSKFULL; @@ -1274,7 +1265,7 @@ STATIC COUNT extend_dir(f_node_ptr fnp) REG struct buffer FAR *bp; /* as we are overwriting it completely, don't read first */ - bp = getblockOver(clus2phys(fnp->f_cluster, fnp->f_dpb) + idx, + bp = getblockOver(clus2phys(cluster, fnp->f_dpb) + idx, fnp->f_dpb->dpb_unit); #ifdef DISPLAY_GETBLOCK printf("DIR (extend_dir)\n"); @@ -1306,7 +1297,7 @@ STATIC COUNT extend_dir(f_node_ptr fnp) } /* JPP: finds the next free cluster in the FAT */ -STATIC BOOL first_fat(f_node_ptr fnp) +STATIC CLUSTER first_fat(f_node_ptr fnp) { CLUSTER free_fat; @@ -1316,19 +1307,18 @@ STATIC BOOL first_fat(f_node_ptr fnp) /* No empty clusters, disk is FULL! Translate into a useful */ /* error message. */ if (free_fat == LONG_LAST_CLUSTER) - return FALSE; + return free_fat; /* Now that we've found a free FAT entry, mark it as the last */ /* entry and save it. */ /* BUG!! this caused wrong allocation, if file was created, then seeked, then written */ - fnp->f_cluster = free_fat; setdstart(fnp->f_dpb, &fnp->f_dir, free_fat); link_fat(fnp->f_dpb, free_fat, LONG_LAST_CLUSTER); /* Mark the directory so that the entry is updated */ fnp->f_flags.f_dmod = TRUE; - return TRUE; + return free_fat; } /* Description. @@ -1352,8 +1342,7 @@ STATIC BOOL first_fat(f_node_ptr fnp) COUNT map_cluster(REG f_node_ptr fnp, COUNT mode) { - CLUSTER relcluster = (CLUSTER)((fnp->f_offset / fnp->f_dpb->dpb_secsize) >> - fnp->f_dpb->dpb_shftcnt); + CLUSTER relcluster, cluster; #ifdef DISPLAY_GETBLOCK printf("map_cluster: current %lu, offset %lu, diff=%lu ", @@ -1366,12 +1355,21 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode) if ((mode == XFR_WRITE) && checkdstart(fnp->f_dpb, &fnp->f_dir, FREE)) { /* If there are no more free fat entries, then we are full! */ - if (!first_fat(fnp)) + cluster = first_fat(fnp); + if (cluster == LONG_LAST_CLUSTER) { return DE_HNDLDSKFULL; } + fnp->f_cluster = cluster; } + /* If this is a read but the file still has zero bytes return */ + /* immediately.... */ + if ((mode == XFR_READ) && (fnp->f_cluster == FREE)) + return DE_SEEK; + + relcluster = (CLUSTER)((fnp->f_offset / fnp->f_dpb->dpb_secsize) >> + fnp->f_dpb->dpb_shftcnt); if (relcluster < fnp->f_cluster_offset) { /* Set internal index and cluster size. */ @@ -1387,27 +1385,30 @@ COUNT map_cluster(REG f_node_ptr fnp, COUNT mode) /* up to the relative cluster position where the index falls */ /* within the cluster. */ - FOREVER + while (fnp->f_cluster_offset != relcluster) { - /* If this is a read and the next is a LAST_CLUSTER, */ - /* then we are going to read past EOF, return zero read */ - if ((mode == XFR_READ) && (last_link(fnp) || fnp->f_cluster == FREE)) - return DE_SEEK; - /* expand the list if we're going to write and have run into */ - /* the last cluster marker. */ - if ((mode == XFR_WRITE) && last_link(fnp) && !extend(fnp)) - return DE_HNDLDSKFULL; - - if (fnp->f_cluster_offset == relcluster) - break; - - fnp->f_back = fnp->f_cluster; - /* get next cluster in the chain */ - fnp->f_cluster = next_cluster(fnp->f_dpb, fnp->f_cluster); - fnp->f_cluster_offset++; - if (fnp->f_cluster == 1) + cluster = next_cluster(fnp->f_dpb, fnp->f_cluster); + if (cluster == 1) return DE_SEEK; + + /* If this is a read and the next is a LAST_CLUSTER, */ + /* then we are going to read past EOF, return zero read */ + /* or expand the list if we're going to write and have run into */ + /* the last cluster marker. */ + if (cluster == LONG_LAST_CLUSTER) + { + if (mode == XFR_READ) + return DE_SEEK; + + /* mode == XFR_WRITE */ + cluster = extend(fnp); + if (cluster == LONG_LAST_CLUSTER) + return DE_HNDLDSKFULL; + } + + fnp->f_cluster = cluster; + fnp->f_cluster_offset++; } #ifdef DISPLAY_GETBLOCK