Esempio n. 1
0
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 );
}
Esempio n. 2
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 */
}
Esempio n. 3
0
/* 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;
        }
    }
}
Esempio n. 4
0
/*
**  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);
}
Esempio n. 5
0
/*
 *  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;
    }
}
Esempio n. 6
0
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));
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
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);
}