DMD *getdmd(int drv) { DMD *dm; #if DBGFSDRIVE kprintf("getdmd(%i)\n", drv); #endif if (!(drvtbl[drv] = dm = MGET(DMD))) return ( (DMD *) 0 ); if (!(dm->m_dtl = MGET(DND))) goto fredm; if (!(dm->m_dtl->d_ofd = MGET(OFD))) goto fredtl; if (!(dm->m_fatofd = MGET(OFD))) goto freofd; return(dm); freofd: xmfreblk (dm->m_dtl->d_ofd); fredtl: xmfreblk (dm->m_dtl); fredm: xmfreblk (dm); return ( (DMD *) 0 ); }
static void freednd(DND *dn) /* M01.01.1031.02 */ { DND **prev; if ( dn->d_ofd ) { /* free associated OFD if it's linked */ xmfreblk( (char *)(dn->d_ofd) ); } for ( prev = &(dn->d_parent->d_left); *prev != dn; prev = &((*prev)->d_right) ) ; /* find the predecessor to this DND */ *prev = dn->d_right; /* then cut this DND out of the list */ while ( dn->d_left ) { /* is this step really necessary? */ freednd( dn->d_left ); } xmfreblk( (char *)dn ); /* finally free this DND */ }
/* reserve a block, i.e. remove it from the allocated list */ static void reserve_block(void *addr, MPB *mpb) { MD *m,**q; for (m = *(q = &mpb->mp_mal); m ; m = *q) { if (m->m_own == run) { *q = m->m_link; /* pouf ! like magic */ xmfreblk(m); } else { q = &m->m_link; } } }
/* ** sftdel - delete an entry from the sft ** delete the entry from the sft. If no other entries in the sft ** have the same ofd, free up the OFD, also. */ static void sftdel(FTAB *sftp) { FTAB *s; OFD *ofd; /* clear out the entry */ ofd = (s=sftp)->f_ofd; s->f_ofd = 0; s->f_own = 0; s->f_use = 0; /* if no other sft entries with same OFD, delete ofd */ if (sftofdsrch(ofd) == NULL) xmfreblk((int *)ofd); }
/* * xmfremd - free an MD */ void xmfremd(MD *md) { MDBLOCK *mdb; MDEXT *entry; WORD i, avail; i = *(WORD *)(md+1); /* word following MD */ if ((i < 0) || (i >= MDS_PER_BLOCK)) { KDEBUG(("xmfremd(): MD at %p not freed, invalid index %d\n",md,i)); return; } entry = (MDEXT *)md - i; /* point to first entry */ mdb = (MDBLOCK *)((char *)entry - sizeof(MDBLOCK *)); mdb->entry[i].index = -1; /* mark as free */ KDEBUG(("xmfremd(): MD at %p freed\n",md)); for (i = 0, avail = 0; i < MDS_PER_BLOCK; i++) if (mdb->entry[i].index < 0) avail++; switch(avail) { case 3: /* remove from mdb chain & put on free chain */ KDEBUG(("xmfremd(): MDBLOCK at %p is now empty\n",mdb)); if (unlink_mdblock(mdb) == 0) { xmfreblk(mdb); /* move to free chain */ KDEBUG(("xmfremd(): MDBLOCK at %p moved to free chain\n",mdb)); } break; case 2: break; case 1: /* add to mdb chain */ mdb->mdb_next = mdbroot; mdbroot = mdb; KDEBUG(("xmfremd(): MDBLOCK at %p now has free entry, moved to mdb chain\n",mdb)); break; default: KDEBUG(("xmfremd(): MDBLOCK at %p is invalid, %d free entries\n",mdb,avail)); break; } }
long xrmdir(char *p) { register DND *d; DND *d1,**q; FCB *f; OFD *fd,*f2; /* M01.01.03 */ long pos; const char *s; register int i; if ((long)(d = findit(p,&s,1)) < 0) /* M01.01.1212.01 */ return( (long)d ); if (!d) /* M01.01.1214.01 */ return( EPTHNF ); /* M01.01.SCC.FS.09 */ if( ! d->d_parent ) /* Can't delete root */ return( EACCDN ) ; for( i = 1 ; i <= NCURDIR ; i++ ) /* Can't delete in use */ if( diruse[i] && dirtbl[i] == d ) return( EACCDN ) ; /* end M01.01.SCC.FS.09 */ if (!(fd = d->d_ofd)) if (!(fd = makofd(d))) return (ENSMEM); ixlseek(fd,0x40L); do { if (!(f = (FCB *) ixread(fd,32L,NULLPTR))) break; } while (f->f_name[0] == (char)0x0e5 || f->f_attrib == FA_LFN); if( f != (FCB*)NULLPTR && f->f_name[0] != 0 ) return(EACCDN); for(d1 = *(q = &d->d_parent->d_left); d1 != d; d1 = *(q = &d1->d_right)) ; /* follow sib-links */ if( d1 != d ) return(EINTRN); /* internal error */ if (d->d_files) return(EINTRN); /* open files ? - internal error */ if (d->d_left) return(EINTRN); /* subdir - internal error */ /* take him out ! */ *q = d->d_right; if (d->d_ofd) { xmfreblk((char *)d->d_ofd); } d1 = d->d_parent; xmfreblk((char *)d); ixlseek((f2 = fd->o_dirfil),(pos = fd->o_dirbyt)); f = (FCB *) ixread(f2,32L,NULLPTR); return(ixdel(d1,f,pos)); }
long xmkdir(char *s) { register OFD *f; register FCB *f2; OFD *fd,*f0; FCB *b; DND *dn; int h,cl,plen; long rc; if ((h = rc = ixcreat(s,FA_SUBDIR)) < 0) return(rc); f = getofd(h); /* build a DND in the tree */ fd = f->o_dirfil; ixlseek(fd,f->o_dirbyt); b = (FCB *) ixread(fd,32L,NULLPTR); /* is the total path length too long? */ /* M01.01.1107.01 */ plen = namlen( b->f_name ); for ( dn = f->o_dnode; dn; dn = dn->d_parent ) plen += namlen( dn->d_name ); if ( plen >= (LEN_ZPATH-3) ) { ixdel( f->o_dnode, b, f->o_dirbyt ); return ( EACCDN ); } if( (dn = makdnd(f->o_dnode,b)) == NULLPTR ) { ixdel( f->o_dnode, b, f->o_dirbyt ); /* M01.01.1103.01 */ return (ENSMEM); } if( (dn->d_ofd = f0 = makofd(dn)) == (OFD*)NULLPTR ) { ixdel( f->o_dnode, b, f->o_dirbyt ); /* M01.01.1103.01 */ f->o_dnode->d_left = NULLPTR; /* M01.01.1103.01 */ xmfreblk((char *)dn); return (ENSMEM); } /* initialize dir cluster */ if (nextcl(f0,1)) { ixdel( f->o_dnode, b, f->o_dirbyt ); /* M01.01.1103.01 */ f->o_dnode->d_left = NULLPTR; /* M01.01.1103.01 */ freednd(dn); /* M01.01.1031.02 */ return(EACCDN); } f2 = dirinit(dn); /* pointer to dirty dir block */ /* write identifier */ memcpy(f2, dots, 22); f2->f_attrib = FA_SUBDIR; f2->f_time = time; swpw( f2->f_time ) ; /* M01.01.SCC.FS.04 */ f2->f_date = date; swpw( f2->f_date ) ; /* M01.01.SCC.FS.04 */ cl = f0->o_strtcl; swpw(cl); f2->f_clust = cl; f2->f_fileln = 0; f2++; /* write parent entry .. */ memcpy(f2, dots, 22); f2->f_name[1] = '.'; /* This is .. */ f2->f_attrib = FA_SUBDIR; f2->f_time = time; swpw( f2->f_time ) ; /* M01.01.SCC.FS.06 */ f2->f_date = date; swpw( f2->f_date ) ; /* M01.01.SCC.FS.06 */ cl = f->o_dirfil->o_strtcl; if (!fd->o_dnode) /* if creating a folder in the root, the */ cl = 0; /* cluster# of the .. entry must be 0 */ swpw(cl); f2->f_clust = cl; f2->f_fileln = 0; memcpy(f, f0, sizeof(OFD)); f->o_flag |= O_DIRTY; ixclose(f,CL_DIR | CL_FULL); /* force flush and write */ xmfreblk((char*)f); sft[h-NUMSTD].f_own = 0; sft[h-NUMSTD].f_ofd = 0; return(E_OK); }
static DND *makdnd(DND *p, FCB *b) { register DND *p1; register DND **prev; OFD *fd; register int i; int in_use; fd = p->d_ofd; /* ** scavenge a DND at this level if we can find one that has not ** d_left */ for (prev = &p->d_left; (p1 = *prev) ; prev = &p1->d_right) { if (!p1->d_left) { /* check dirtbl[] to see if anyone is using this guy */ in_use = 0; for (i = 1; i < NCURDIR; i++) if (diruse[i] && dirtbl[i] == p1) { in_use = 1; break; } #if DBGFSDIR kprintf("\n makdnd check dirtbl (%d)", in_use); #endif if( !in_use && p1->d_files == NULLPTR ) { /* M01.01.KTB.SCC.02 */ /* clean out this DND for reuse */ p1->d_flag = 0; p1->d_scan = 0L; p1->d_files = (OFD *) 0; if (p1->d_ofd) { xmfreblk((char *)p1->d_ofd); } break; } } } /* we didn't find one that qualifies, so allocate a new one */ if (!p1) { #if DBGFSDIR kprintf("\n makdnd new"); #endif if (!(p1 = MGET(DND))) return ( (DND *) 0 ); /* ran out of system memory */ /* do this init only on a newly allocated DND */ p1->d_right = p->d_left; p->d_left = p1; p1->d_parent = p; } /* complete the initialization */ p1->d_ofd = (OFD *) 0; p1->d_strtcl = b->f_clust; swpw(p1->d_strtcl); p1->d_drv = p->d_drv; p1->d_dirfil = fd; p1->d_dirpos = fd->o_bytnum - 32; p1->d_time = b->f_time; p1->d_date = b->f_date; memcpy(p1->d_name, b->f_name, 11); #if DBGFSDIR kprintf("\n makdnd(%08lx)", (long)p1); #endif return(p1); }