Exemplo n.º 1
0
/*
 *  ckdrv - check the drive, see if it needs to be logged in.
 *
 *  Arguments:
 *    d - has this drive been accessed, or had a media change
 *
 *
 *      returns:
 *          ERR     if getbpb() failed
 *          ENSMEM  if log() failed
 *          EINTRN  if no room in dirtbl
 *          drive nbr if success.
 */
long ckdrv(int d)
{
    int curdir;
    LONG mask;
    BPB *b;

    KDEBUG(("ckdrv(%i)\n",d));

    mask = 1L << d;

    if (!(mask & drvsel))
    {       /*  drive has not been selected yet  */
        b = (BPB *) Getbpb(d);

        if (!b)
            return (mask&drvrem) ? EPTHNF : EDRIVE;

        if ((long)b < 0)
            return (long)b;

        if (log_media(b,d))
            return ENSMEM;

        drvsel |= mask;
    }
    else if (mask & drvrem)     /* handle removable media */
    {
        if (Mediach(d))
        {
            errdrv = d;
            rwerr = E_CHNG;         /* signal media change */
            errcode = rwerr;
            longjmp(errbuf,1);
        }
    }

    /*
     * ensure that current process has a valid default directory
     * on this drive
     */
    curdir = run->p_curdir[d];
    if (curdir >= NCURDIR)      /* validate */
        curdir = 0;             /* if invalid, say none */
    if (!curdir                 /* no current dir for this drive */
     || !dirtbl[curdir].dnd)    /* or current dir is invalid  */
    {
        curdir = incr_curdir_usage(drvtbl[d]->m_dtl);   /* add root DND */
        if (curdir < 0)
            return ENSMEM;
        run->p_curdir[d] = curdir;  /* link to process  */
    }

    return d;
}
Exemplo n.º 2
0
/*
 * getbcb - called by getrec() to get the BCB for the desired record
 *
 * buftype is BT_FAT, BT_ROOT, or BT_DATA
 */
BCB *getbcb(DMD *dmd,WORD buftype,RECNO recnum)
{
    BCB *b;
    BCB *p, *mtbuf, **q, **phdr;
    int err;

    mtbuf = 0;
    phdr = &bufl[buftype==BT_FAT ? BI_FAT : BI_DATA];

    /*
     * See if the desired record for the desired drive is in memory.
     * If it is, we will use it.  Otherwise we will use
     *          the last invalid (available) buffer,  or
     *          the last (least recently) used buffer.
     */

    for (b = *(q = phdr); b; b = *(q = &b->b_link))
    {
        if ((b->b_bufdrv == dmd->m_drvnum) && (b->b_buftyp == buftype) && (b->b_bufrec == recnum))
            break;
        /*
         * keep track of the last invalid buffer
         */
        if (b->b_bufdrv == -1)  /*  if buffer not valid */
            mtbuf = b;          /*    then it's 'empty' */
    }

    if (!b)
    {
        /*
         * not in memory.  If there was an 'empty' buffer, use it.
         */
        if (mtbuf)
            b = mtbuf;

        /*
         * find predecessor of mtbuf, or last guy in list, which
         * is the least recently used.
         */

doio:   for (p = *(q = phdr); p->b_link; p = *(q = &p->b_link))
            if (b == p)
                break;
        b = p;

        /*
         * flush the current contents of the buffer, and read in the
         * new record.
         */

        flush(b);
        longjmp_rwabs(0, (long)b->b_bufr, 1, recnum+dmd->m_recoff[buftype], dmd->m_drvnum);

        /*
         * make the new buffer current
         */

        b->b_bufrec = recnum;
        b->b_dirty = 0;
        b->b_buftyp = buftype;
        b->b_bufdrv = dmd->m_drvnum;
        b->b_dm = dmd;
    }
    else
    {   /* use a buffer, but first validate media */
        err = Mediach(b->b_bufdrv);
        if (err != 0) {
            if (err == 1) {
                goto doio; /* media may be changed */
            } else if (err == 2) {
                /* media definitely changed */
                errdrv = b->b_bufdrv;
                rwerr = E_CHNG; /* media change */
                errcode = rwerr;
                longjmp(errbuf,1);
            }
        }
    }

    /*
     *  now put the current buffer at the head of the list
     */

    *q = b->b_link;
    b->b_link = *phdr;
    *phdr = b;

    return b;
}
Exemplo n.º 3
0
char *getrec(RECNO recn, OFD *of, int wrtflg)
{
    DMD *dm = of->o_dmd;
    register BCB *b;
    BCB *p,*mtbuf,**q,**phdr;
    int n,err;

#if DBGFSBUF
    kprintf("getrec 0x%lx, %p, 0x%x\n", (long)recn, dm, wrtflg);
#endif

    /* put bcb management here */
    if (of->o_dmd->m_fatofd == of)  /* is this the OFD for the 'FAT file'? */
        n = BT_FAT;                 /* yes, must be FAT access             */
    else if (!of->o_dnode)          /* no - do we have a dir node?         */
        n = BT_ROOT;                /* no, must be root                    */
    else n = BT_DATA;               /* yes, must be normal dir/file        */

#if DBGFSBUF
    kprintf("n=%i , dm->m_recoff[n] = 0x%lx\n", n, dm->m_recoff[n]);
#endif

    mtbuf = 0;
    phdr = &bufl[n==BT_FAT ? BI_FAT : BI_DATA];

    /*
     * See, if the desired record for the desired drive is in memory.
     * If it is, we will use it.  Otherwise we will use
     *          the last invalid (available) buffer,  or
     *          the last (least recently) used buffer.
     */

    for (b = *(q = phdr); b; b = *(q = &b->b_link))
    {
        if ((b->b_bufdrv == dm->m_drvnum) && (b->b_buftyp == n) && (b->b_bufrec == recn))
            break;
        /*
         * keep track of the last invalid buffer
         */
        if (b->b_bufdrv == -1)          /*  if buffer not valid */
            mtbuf = b;          /*    then it's 'empty' */
    }

    if (!b)
    {
        /*
         * not in memory.  If there was an 'empty' buffer, use it.
         */
        if (mtbuf)
            b = mtbuf;

        /*
         * find predecessor of mtbuf, or last guy in list, which
         * is the least recently used.
         */

doio:   for (p = *(q = phdr); p->b_link; p = *(q = &p->b_link))
            if (b == p)
                break;
        b = p;

        /*
         * flush the current contents of the buffer, and read in the
         * new record.
         */

        flush(b);
        longjmp_rwabs(0, (long)b->b_bufr, 1, recn+dm->m_recoff[n], dm->m_drvnum);

        /*
         * make the new buffer current
         */

        b->b_bufrec = recn;
        b->b_dirty = 0;
        b->b_buftyp = n;
        b->b_bufdrv = dm->m_drvnum;
        b->b_dm = dm;
    }
    else
    {   /* use a buffer, but first validate media */
        err = Mediach(b->b_bufdrv);
        if (err != 0) {
            if (err == 1) {
                goto doio; /* media may be changed */
            } else if (err == 2) {
                /* media definitely changed */
                errdrv = b->b_bufdrv;
                rwerr = E_CHNG; /* media change */
                errcode = rwerr;
                longjmp(errbuf,1);
            }
        }
    }

    /*
     *  now put the current buffer at the head of the list
     */

    *q = b->b_link;
    b->b_link = *phdr;
    *phdr = b;

    /*
     *  if we are writing to the buffer, dirty it.
     */

    if (wrtflg) {
        b->b_dirty = 1;
    }

    return(b->b_bufr);
}