Add f_dirsector (sector containing dentry) and f_diridx (index within

sector) fields to the fnode, to make fnodes more compatible with SFTs.
Use them to simplify dir_read() and dir_write().


git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@1390 6ac86273-5f31-0410-b378-82cca8765d1b
This commit is contained in:
Bart Oldeman 2009-05-21 12:57:37 +00:00
parent 2092745236
commit d39420dc11
2 changed files with 25 additions and 73 deletions

View File

@ -43,6 +43,8 @@ struct f_node {
struct dirent f_dir; /* this file's dir entry image */ struct dirent f_dir; /* this file's dir entry image */
ULONG f_dirsector; /* the sector containing dir entry*/
UBYTE f_diridx; /* offset/32 of dir entry in sec*/
UWORD f_diroff; /* offset/32 of the dir entry */ UWORD f_diroff; /* offset/32 of the dir entry */
CLUSTER f_dirstart; /* the starting cluster of dir */ CLUSTER f_dirstart; /* the starting cluster of dir */
/* when dir is not root */ /* when dir is not root */

View File

@ -155,19 +155,6 @@ STATIC void swap_deleted(char *name)
name[0] ^= EXT_DELETED - DELETED; /* 0xe0 */ name[0] ^= EXT_DELETED - DELETED; /* 0xe0 */
} }
STATIC struct buffer FAR *getblock_from_off(f_node_ptr fnp, unsigned secsize)
{
/* Compute the block within the cluster and the */
/* offset within the block. */
unsigned sector;
sector = (UBYTE)(fnp->f_offset / secsize) & fnp->f_dpb->dpb_clsmask;
/* Get the block we need from cache */
return getblock(clus2phys(fnp->f_cluster, fnp->f_dpb) + sector,
fnp->f_dpb->dpb_unit);
}
/* Description. /* Description.
* Read next consequitive directory entry, pointed by fnp. * Read next consequitive directory entry, pointed by fnp.
* If some error occures the other critical * If some error occures the other critical
@ -184,6 +171,7 @@ COUNT dir_read(REG f_node_ptr fnp)
{ {
struct buffer FAR *bp; struct buffer FAR *bp;
REG UWORD secsize = fnp->f_dpb->dpb_secsize; REG UWORD secsize = fnp->f_dpb->dpb_secsize;
unsigned sector;
/* can't have more than 65535 directory entries */ /* can't have more than 65535 directory entries */
if (fnp->f_diroff >= 65535U) if (fnp->f_diroff >= 65535U)
@ -199,11 +187,8 @@ COUNT dir_read(REG f_node_ptr fnp)
if (fnp->f_diroff >= fnp->f_dpb->dpb_dirents) if (fnp->f_diroff >= fnp->f_dpb->dpb_dirents)
return DE_SEEK; return DE_SEEK;
bp = getblock(fnp->f_diroff / (secsize / DIRENT_SIZE) fnp->f_dirsector = fnp->f_diroff / (secsize / DIRENT_SIZE) +
+ fnp->f_dpb->dpb_dirstrt, fnp->f_dpb->dpb_unit); fnp->f_dpb->dpb_dirstrt;
#ifdef DISPLAY_GETBLOCK
printf("DIR (dir_read)\n");
#endif
} }
else else
{ {
@ -212,18 +197,23 @@ COUNT dir_read(REG f_node_ptr fnp)
/* Search through the FAT to find the block */ /* Search through the FAT to find the block */
/* that this entry is in. */ /* that this entry is in. */
#ifdef DISPLAY_GETBLOCK
printf("dir_read: ");
#endif
if (map_cluster(fnp, XFR_READ) != SUCCESS) if (map_cluster(fnp, XFR_READ) != SUCCESS)
return DE_SEEK; return DE_SEEK;
bp = getblock_from_off(fnp, secsize); /* Compute the block within the cluster and the */
#ifdef DISPLAY_GETBLOCK /* offset within the block. */
printf("DIR (dir_read)\n"); sector = (UBYTE)(fnp->f_offset / secsize) & fnp->f_dpb->dpb_clsmask;
#endif
fnp->f_dirsector = clus2phys(fnp->f_cluster, fnp->f_dpb) + sector;
/* Get the block we need from cache */
} }
bp = getblock(fnp->f_dirsector, fnp->f_dpb->dpb_unit);
#ifdef DISPLAY_GETBLOCK
printf("DIR (dir_read)\n");
#endif
/* Now that we have the block for our entry, get the */ /* Now that we have the block for our entry, get the */
/* directory entry. */ /* directory entry. */
if (bp == NULL) if (bp == NULL)
@ -232,9 +222,8 @@ COUNT dir_read(REG f_node_ptr fnp)
bp->b_flag &= ~(BFR_DATA | BFR_FAT); bp->b_flag &= ~(BFR_DATA | BFR_FAT);
bp->b_flag |= BFR_DIR | BFR_VALID; bp->b_flag |= BFR_DIR | BFR_VALID;
getdirent((BYTE FAR *) & bp-> fnp->f_diridx = fnp->f_diroff % (secsize / DIRENT_SIZE);
b_buffer[(fnp->f_diroff * DIRENT_SIZE) % fnp->f_dpb->dpb_secsize], getdirent(&bp->b_buffer[fnp->f_diridx * DIRENT_SIZE], &fnp->f_dir);
&fnp->f_dir);
swap_deleted(fnp->f_dir.dir_name); swap_deleted(fnp->f_dir.dir_name);
@ -260,7 +249,6 @@ COUNT dir_read(REG f_node_ptr fnp)
BOOL dir_write(REG f_node_ptr fnp) BOOL dir_write(REG f_node_ptr fnp)
{ {
struct buffer FAR *bp; struct buffer FAR *bp;
REG UWORD secsize = fnp->f_dpb->dpb_secsize;
if (!(fnp->f_flags & F_DDIR)) if (!(fnp->f_flags & F_DDIR))
return FALSE; return FALSE;
@ -268,48 +256,7 @@ BOOL dir_write(REG f_node_ptr fnp)
/* Update the entry if it was modified by a write or create... */ /* Update the entry if it was modified by a write or create... */
if (fnp->f_flags & F_DMOD) if (fnp->f_flags & F_DMOD)
{ {
/* Root is a consecutive set of blocks, so handling is */ bp = getblock(fnp->f_dirsector, fnp->f_dpb->dpb_unit);
/* simple. */
if (fnp->f_dirstart == 0)
{
bp = getblock(fnp->f_diroff / (secsize / DIRENT_SIZE)
+ fnp->f_dpb->dpb_dirstrt,
fnp->f_dpb->dpb_unit);
#ifdef DISPLAY_GETBLOCK
printf("DIR (dir_write)\n");
#endif
}
/* All other directories are just files. The only */
/* special handling is resetting the offset so that we */
/* can continually update the same directory entry. */
else
{
/* 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_cluster = fnp->f_dirstart;
fnp->f_cluster_offset = 0;
/* Search through the FAT to find the block */
/* that this entry is in. */
#ifdef DISPLAY_GETBLOCK
printf("dir_write: ");
#endif
if (map_cluster(fnp, XFR_READ) != SUCCESS)
{
release_f_node(fnp);
return FALSE;
}
bp = getblock_from_off(fnp, secsize);
bp->b_flag &= ~(BFR_DATA | BFR_FAT);
bp->b_flag |= BFR_DIR | BFR_VALID;
#ifdef DISPLAY_GETBLOCK
printf("DIR (dir_write)\n");
#endif
}
/* Now that we have a block, transfer the directory */ /* Now that we have a block, transfer the directory */
/* entry into the block. */ /* entry into the block. */
@ -319,10 +266,13 @@ BOOL dir_write(REG f_node_ptr fnp)
return FALSE; return FALSE;
} }
#ifdef DISPLAY_GETBLOCK
printf("DIR (dir_write)\n");
#endif
swap_deleted(fnp->f_dir.dir_name); swap_deleted(fnp->f_dir.dir_name);
putdirent(&fnp->f_dir, &bp->b_buffer[(fnp->f_diroff * DIRENT_SIZE) % putdirent(&fnp->f_dir, &bp->b_buffer[fnp->f_diridx * DIRENT_SIZE]);
fnp->f_dpb->dpb_secsize]);
swap_deleted(fnp->f_dir.dir_name); swap_deleted(fnp->f_dir.dir_name);