mirror of https://github.com/FDOS/kernel.git
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
This commit is contained in:
parent
7e91d9cf9d
commit
ce290a033f
|
@ -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 */
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue