From d39420dc11a35dad8307bccd44dd8b36ee7f36fa Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Thu, 21 May 2009 12:57:37 +0000 Subject: [PATCH] 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 --- hdr/fnode.h | 2 ++ kernel/fatdir.c | 96 ++++++++++++------------------------------------- 2 files changed, 25 insertions(+), 73 deletions(-) diff --git a/hdr/fnode.h b/hdr/fnode.h index 5803d4f..9437d35 100644 --- a/hdr/fnode.h +++ b/hdr/fnode.h @@ -43,6 +43,8 @@ struct f_node { 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 */ CLUSTER f_dirstart; /* the starting cluster of dir */ /* when dir is not root */ diff --git a/kernel/fatdir.c b/kernel/fatdir.c index eff4a26..fa624ee 100644 --- a/kernel/fatdir.c +++ b/kernel/fatdir.c @@ -155,19 +155,6 @@ STATIC void swap_deleted(char *name) 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. * Read next consequitive directory entry, pointed by fnp. * If some error occures the other critical @@ -184,6 +171,7 @@ COUNT dir_read(REG f_node_ptr fnp) { struct buffer FAR *bp; REG UWORD secsize = fnp->f_dpb->dpb_secsize; + unsigned sector; /* can't have more than 65535 directory entries */ 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) return DE_SEEK; - bp = getblock(fnp->f_diroff / (secsize / DIRENT_SIZE) - + fnp->f_dpb->dpb_dirstrt, fnp->f_dpb->dpb_unit); -#ifdef DISPLAY_GETBLOCK - printf("DIR (dir_read)\n"); -#endif + fnp->f_dirsector = fnp->f_diroff / (secsize / DIRENT_SIZE) + + fnp->f_dpb->dpb_dirstrt; } else { @@ -212,18 +197,23 @@ COUNT dir_read(REG f_node_ptr fnp) /* Search through the FAT to find the block */ /* that this entry is in. */ -#ifdef DISPLAY_GETBLOCK - printf("dir_read: "); -#endif if (map_cluster(fnp, XFR_READ) != SUCCESS) return DE_SEEK; - bp = getblock_from_off(fnp, secsize); -#ifdef DISPLAY_GETBLOCK - printf("DIR (dir_read)\n"); -#endif + /* Compute the block within the cluster and the */ + /* offset within the block. */ + sector = (UBYTE)(fnp->f_offset / secsize) & fnp->f_dpb->dpb_clsmask; + + 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 */ /* directory entry. */ 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_DIR | BFR_VALID; - getdirent((BYTE FAR *) & bp-> - b_buffer[(fnp->f_diroff * DIRENT_SIZE) % fnp->f_dpb->dpb_secsize], - &fnp->f_dir); + fnp->f_diridx = fnp->f_diroff % (secsize / DIRENT_SIZE); + getdirent(&bp->b_buffer[fnp->f_diridx * DIRENT_SIZE], &fnp->f_dir); 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) { struct buffer FAR *bp; - REG UWORD secsize = fnp->f_dpb->dpb_secsize; if (!(fnp->f_flags & F_DDIR)) 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... */ if (fnp->f_flags & F_DMOD) { - /* Root is a consecutive set of blocks, so handling is */ - /* 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 - } + bp = getblock(fnp->f_dirsector, fnp->f_dpb->dpb_unit); /* Now that we have a block, transfer the directory */ /* entry into the block. */ @@ -319,10 +266,13 @@ BOOL dir_write(REG f_node_ptr fnp) return FALSE; } +#ifdef DISPLAY_GETBLOCK + printf("DIR (dir_write)\n"); +#endif + swap_deleted(fnp->f_dir.dir_name); - putdirent(&fnp->f_dir, &bp->b_buffer[(fnp->f_diroff * DIRENT_SIZE) % - fnp->f_dpb->dpb_secsize]); + putdirent(&fnp->f_dir, &bp->b_buffer[fnp->f_diridx * DIRENT_SIZE]); swap_deleted(fnp->f_dir.dir_name);