From 11a7b69e5c002bea0c831d34378195165670cf26 Mon Sep 17 00:00:00 2001 From: Bart Oldeman Date: Mon, 22 Mar 2004 10:29:26 +0000 Subject: [PATCH] Make f_diroff an entry offset so it can be 16bits. Enforce the 65536 entry limit in dir_read(). Saves 80 bytes or so + 2 bytes in every f_node. git-svn-id: https://svn.code.sf.net/p/freedos/svn/kernel/trunk@811 6ac86273-5f31-0410-b378-82cca8765d1b --- hdr/fnode.h | 2 +- kernel/fatdir.c | 37 ++++++++++++++++++++----------------- kernel/fatfs.c | 8 ++++---- kernel/lfnapi.c | 16 ++++++++-------- 4 files changed, 33 insertions(+), 30 deletions(-) diff --git a/hdr/fnode.h b/hdr/fnode.h index 9d1e1cc..17e343c 100644 --- a/hdr/fnode.h +++ b/hdr/fnode.h @@ -49,7 +49,7 @@ struct f_node { struct dirent f_dir; /* this file's dir entry image */ - ULONG f_diroff; /* offset of the dir entry */ + UWORD f_diroff; /* offset/32 of the dir entry */ CLUSTER f_dirstart; /* the starting cluster of dir */ /* when dir is not root */ struct dpb FAR *f_dpb; /* the block device for file */ diff --git a/kernel/fatdir.c b/kernel/fatdir.c index 5f2b5c5..56b345b 100644 --- a/kernel/fatdir.c +++ b/kernel/fatdir.c @@ -46,7 +46,8 @@ VOID dir_init_fnode(f_node_ptr fnp, CLUSTER dirstart) fnp->f_flags.f_droot = FALSE; fnp->f_flags.f_ddir = TRUE; fnp->f_flags.f_dnew = TRUE; - fnp->f_diroff = fnp->f_offset = 0l; + fnp->f_diroff = 0; + fnp->f_offset = 0l; fnp->f_cluster_offset = 0; /* root directory */ @@ -209,7 +210,11 @@ COUNT dir_read(REG f_node_ptr fnp) { struct buffer FAR *bp; REG UWORD secsize = fnp->f_dpb->dpb_secsize; - ULONG new_diroff = fnp->f_diroff; + unsigned new_diroff = fnp->f_diroff; + + /* can't have more than 65535 directory entries */ + if (new_diroff == 65535) + return DE_SEEK; /* Directories need to point to their current offset, not for */ /* next op. Therefore, if it is anything other than the first */ @@ -217,7 +222,7 @@ COUNT dir_read(REG f_node_ptr fnp) /* than wait until exit. If it was new, clear the special new */ /* flag. */ if (!fnp->f_flags.f_dnew) - new_diroff += DIRENT_SIZE; + new_diroff++; /* Determine if we hit the end of the directory. If we have, */ /* bump the offset back to the end and exit. If not, fill the */ @@ -226,12 +231,11 @@ COUNT dir_read(REG f_node_ptr fnp) if (fnp->f_flags.f_droot) { - if (new_diroff >= DIRENT_SIZE * (ULONG) fnp->f_dpb->dpb_dirents) + if (new_diroff >= fnp->f_dpb->dpb_dirents) return DE_SEEK; - bp = getblock((ULONG) (new_diroff / secsize - + fnp->f_dpb->dpb_dirstrt), - fnp->f_dpb->dpb_unit); + bp = getblock(new_diroff / (secsize / DIRENT_SIZE) + + fnp->f_dpb->dpb_dirstrt, fnp->f_dpb->dpb_unit); #ifdef DISPLAY_GETBLOCK printf("DIR (dir_read)\n"); #endif @@ -239,7 +243,7 @@ COUNT dir_read(REG f_node_ptr fnp) else { /* Do a "seek" to the directory position */ - fnp->f_offset = new_diroff; + fnp->f_offset = new_diroff * (ULONG)DIRENT_SIZE; /* Search through the FAT to find the block */ /* that this entry is in. */ @@ -264,8 +268,8 @@ COUNT dir_read(REG f_node_ptr fnp) bp->b_flag |= BFR_DIR | BFR_VALID; getdirent((BYTE FAR *) & bp-> - b_buffer[((UWORD) new_diroff) % fnp->f_dpb->dpb_secsize], - (struct dirent FAR *)&fnp->f_dir); + b_buffer[(new_diroff * DIRENT_SIZE) % fnp->f_dpb->dpb_secsize], + &fnp->f_dir); swap_deleted(fnp->f_dir.dir_name); @@ -308,8 +312,8 @@ BOOL dir_write(REG f_node_ptr fnp) /* simple. */ if (fnp->f_flags.f_droot) { - bp = getblock((ULONG) ((UWORD) fnp->f_diroff / secsize - + fnp->f_dpb->dpb_dirstrt), + 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"); @@ -324,7 +328,7 @@ 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; + 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; @@ -361,9 +365,8 @@ BOOL dir_write(REG f_node_ptr fnp) swap_deleted(fnp->f_dir.dir_name); - putdirent((struct dirent FAR *)&fnp->f_dir, - (VOID FAR *) & bp->b_buffer[(UWORD) fnp->f_diroff % - fnp->f_dpb->dpb_secsize]); + putdirent(&fnp->f_dir, &bp->b_buffer[(fnp->f_diroff * DIRENT_SIZE) % + fnp->f_dpb->dpb_secsize]); swap_deleted(fnp->f_dir.dir_name); @@ -524,7 +527,7 @@ COUNT dos_findnext(void) fnp->f_flags.f_dnew = TRUE; if (dmp->dm_entry > 0) { - fnp->f_diroff = (ULONG) (dmp->dm_entry - 1) * DIRENT_SIZE; + fnp->f_diroff = dmp->dm_entry - 1; fnp->f_flags.f_dnew = FALSE; } diff --git a/kernel/fatfs.c b/kernel/fatfs.c index dfe34b3..e4110c6 100644 --- a/kernel/fatfs.c +++ b/kernel/fatfs.c @@ -444,13 +444,13 @@ STATIC BOOL find_fname(f_node_ptr fnp, char *fcbname, int attr) */ COUNT remove_lfn_entries(f_node_ptr fnp) { - ULONG original_diroff = fnp->f_diroff; + unsigned original_diroff = fnp->f_diroff; while (TRUE) { if (fnp->f_diroff == 0) break; - fnp->f_diroff -= 2 * DIRENT_SIZE; + fnp->f_diroff -= 2; /* it cannot / should not get below 0 because of '.' and '..' */ if (dir_read(fnp) <= 0) { dir_close(fnp); @@ -462,7 +462,7 @@ COUNT remove_lfn_entries(f_node_ptr fnp) fnp->f_flags.f_dmod = TRUE; if (!dir_write(fnp)) return DE_BLKINVLD; } - fnp->f_diroff = original_diroff - DIRENT_SIZE; + fnp->f_diroff = original_diroff - 1; if (dir_read(fnp) <= 0) { dir_close(fnp); return DE_BLKINVLD; @@ -1748,7 +1748,7 @@ long rwblock(COUNT fd, VOID FAR * buffer, UCOUNT count, int mode) normal_xfer: #ifdef DSK_DEBUG - printf("r/w %d links; dir offset %ld, cluster %d, mode %x\n", + printf("r/w %d links; dir offset %d, cluster %d, mode %x\n", fnp->f_count, fnp->f_diroff, fnp->f_cluster, mode); #endif diff --git a/kernel/lfnapi.c b/kernel/lfnapi.c index 89a5fbd..b56fc05 100644 --- a/kernel/lfnapi.c +++ b/kernel/lfnapi.c @@ -100,12 +100,12 @@ COUNT lfn_free_inode(COUNT handle) /* Description. * Initialize internal fnode, so that it'll point to the directory entry - * at "diroff" byte offset from the start of the directory with the "dirstart" + * at "diroff" entry offset from the start of the directory with the "dirstart" * starting cluster. * Return value. * SUCCESS, LHE_INVLDHNDL */ -COUNT lfn_setup_inode(COUNT handle, ULONG dirstart, ULONG diroff) +COUNT lfn_setup_inode(COUNT handle, ULONG dirstart, UWORD diroff) { f_node_ptr fnp = xlt_fd(handle); if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL; @@ -131,7 +131,7 @@ COUNT lfn_create_entries(COUNT handle, lfn_inode_ptr lip) COUNT entries_needed, free_entries, i, rc; UNICODE FAR *lfn_name = lip->l_name; UBYTE id = 1, sfn_checksum = lfn_checksum(lip->l_dir.dir_name); - ULONG sfn_offset; + unsigned sfn_offset; if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL; entries_needed = (ufstrlen(lfn_name) + CHARS_IN_LFN_ENTRY - 1) @@ -160,7 +160,7 @@ COUNT lfn_create_entries(COUNT handle, lfn_inode_ptr lip) if (extend_dir(fnp) != SUCCESS) return LHE_NOSPACE; /* fnp points to the first free dir entry on return from extend_dir, * so we go to previous entry to read this free entry on next cycle */ - fnp->f_diroff -= DIRENT_SIZE; + fnp->f_diroff--; } else free_entries = 0; /* rc == 1 here => we've read some sfn entry */ } @@ -171,7 +171,7 @@ COUNT lfn_create_entries(COUNT handle, lfn_inode_ptr lip) fmemcpy(&fnp->f_dir, &lip->l_dir, sizeof(struct dirent)); dir_write(fnp); - fnp->f_diroff -= DIRENT_SIZE; + fnp->f_diroff--; /* Go in the reverse direction and create LFN entries */ for (i = 0; i < entries_needed - 1; i++, id++) { @@ -183,7 +183,7 @@ COUNT lfn_create_entries(COUNT handle, lfn_inode_ptr lip) lfn(fnp)->lfn_id = id; fnp->f_dir.dir_attrib = D_LFN; if (!dir_write(fnp)) return LHE_IOERROR; - fnp->f_diroff -= DIRENT_SIZE; + fnp->f_diroff--; } fnp->f_flags.f_dmod = FALSE; @@ -206,7 +206,7 @@ COUNT lfn_dir_read(COUNT handle, lfn_inode_ptr lip) COUNT rc; UBYTE id = 1, real_id; UNICODE FAR *lfn_name = lip->l_name; - ULONG sfn_diroff; + UWORD sfn_diroff; BOOL name_tail; f_node_ptr fnp = xlt_fd(handle); if (fnp == 0 || fnp->f_count <= 0) return LHE_INVLDHNDL; @@ -230,7 +230,7 @@ COUNT lfn_dir_read(COUNT handle, lfn_inode_ptr lip) while (TRUE) { if (fnp->f_diroff == 0) break; - fnp->f_diroff -= 2*DIRENT_SIZE; + fnp->f_diroff -= 2; rc = dir_read(fnp); if (rc == DE_BLKINVLD) return LHE_IOERROR; if (fnp->f_dir.dir_name[0] == DELETED