Annotation of coherent/b/kernel/coh.386/seg.c, revision 1.1.1.1

1.1       root        1: /* $Header: /src386/kernel/coh.386/RCS/seg.c,v 1.6 93/06/14 13:35:09 bin Exp Locker: bin $ */
                      2: /* (lgl-
                      3:  *     The information contained herein is a trade secret of Mark Williams
                      4:  *     Company, and  is confidential information.  It is provided  under a
                      5:  *     license agreement,  and may be  copied or disclosed  only under the
                      6:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
                      7:  *     material without the express written authorization of Mark Williams
                      8:  *     Company or persuant to the license agreement is unlawful.
                      9:  *
                     10:  *     COHERENT Version 2.3.37
                     11:  *     Copyright (c) 1982, 1983, 1984.
                     12:  *     An unpublished work by Mark Williams Company, Chicago.
                     13:  *     All rights reserved.
                     14:  -lgl) */
                     15: /*
                     16:  * Coherent.
                     17:  * Segment manipulation.
                     18:  *
                     19:  */
                     20: #include <sys/coherent.h>
                     21: #include <sys/buf.h>
                     22: #include <errno.h>
                     23: #include <sys/ino.h>
                     24: #include <sys/inode.h>
                     25: #include <sys/proc.h>
                     26: #include <sys/sched.h>
                     27: #include <sys/seg.h>
                     28: #include <a.out.h>
                     29: 
                     30: 
                     31: #define        min(a, b)       ((a) < (b) ? (a) : (b))
                     32: 
                     33: /*
                     34:  * Initialisation code.
                     35:  */
                     36: seginit()
                     37: {
                     38:        /*
                     39:         * Create empty circular-list of memory segments.
                     40:         */
                     41:        segmq.s_forw = &segmq;
                     42:        segmq.s_back = &segmq;
                     43: 
                     44:        /*
                     45:         * Create empty circular-list of disk segments.
                     46:         */
                     47:        segdq.s_forw = &segdq;
                     48:        segdq.s_back = &segdq;
                     49: }
                     50: 
                     51: /*
                     52:  * Given an inode, `ip', and flags, `ff', describing a segment associated
                     53:  * with the inode, see if the segment already exists and if so, return a
                     54:  * copy.  If the segment does not exist, allocate the segment having size
                     55:  * `ss', and read the segment using the inode at seek offset `dq' with a
                     56:  * size of `ds'.
                     57:  */
                     58: SEG *
                     59: ssalloc(ip, ff, ss)
                     60: register INODE *ip;
                     61: {
                     62:        register SEG *sp;
                     63:        register int f;
                     64: 
                     65:        lock(seglink);
                     66:        f = ff & (SFSHRX|SFTEXT);
                     67: 
                     68:        /*
                     69:         * Look for the segment in the memory queue.
                     70:         */
                     71:        for (sp=segmq.s_forw; sp!=&segmq; sp=sp->s_forw) {
                     72:                if (sp->s_ip==ip && (sp->s_flags&(SFSHRX|SFTEXT))==f) {
                     73:                        unlock(seglink);
                     74:                        if (sp = segdupl(sp))
                     75:                                segfinm(sp);
                     76:                        return (sp);
                     77:                }
                     78:        }
                     79: 
                     80:        /*
                     81:         * Look for the segment on the disk queue.
                     82:         */
                     83:        for (sp=segdq.s_forw; sp!=&segdq; sp=sp->s_forw) {
                     84:                if (sp->s_ip==ip && (sp->s_flags&(SFSHRX|SFTEXT))==f) {
                     85:                        unlock(seglink);
                     86:                        if (sp = segdupl(sp))
                     87:                                segfinm(sp);
                     88:                        return (sp);
                     89:                }
                     90:        }
                     91:        unlock(seglink);
                     92: 
                     93:        /*
                     94:         * Allocate and create the segment.
                     95:         */
                     96:        return salloc(roundu(ss, NBPC), ff);
                     97: }
                     98: 
                     99: /*
                    100:  * Given a pointer to a newly created process, copy all of our segments
                    101:  * into the given process.
                    102:  *
                    103:  * Return nonzero if successful.
                    104:  */
                    105: int
                    106: segadup(cpp)
                    107: register PROC *cpp;
                    108: {
                    109:        register SEG *sp;
                    110:        register int n;
                    111:        register PROC *pp;
                    112: 
                    113:        pp = SELF;
                    114:        cpp->p_flags |= PFSWIO;
                    115:        for (n=0; n<NUSEG; n++) {
                    116:                if ((sp=pp->p_segp[n]) == NULL)
                    117:                        continue;
                    118:                if ((sp=segdupl(sp)) == NULL)
                    119:                        break;
                    120:                cpp->p_segp[n] = sp;
                    121:                if ((sp->s_flags&SFCORE) == 0)
                    122:                        cpp->p_flags &= ~PFCORE;
                    123:        }
                    124: 
                    125:        /*
                    126:         * One of the calls to segdupl() failed.
                    127:         * Undo any that succeeded.
                    128:         */
                    129:        if (n < NUSEG) {
                    130:                while (n > 0) {
                    131:                        if (sp=cpp->p_segp[--n]) {
                    132:                                cpp->p_segp[n] = NULL;
                    133:                                sfree(sp);
                    134:                        }
                    135:                }
                    136:        }
                    137:        cpp->p_flags &= ~PFSWIO;
                    138:        return n;
                    139: }
                    140: 
                    141: /*
                    142:  * Duplicate a segment.
                    143:  */
                    144: SEG *
                    145: segdupl(sp)
                    146: register SEG *sp;
                    147: {
                    148:        register SEG *sp1;
                    149: 
                    150:        if (sp->s_flags & SFSHRX) {
                    151:                sp->s_urefc++;
                    152:                sp->s_lrefc++;
                    153:                return (sp);
                    154:        }
                    155:        if ((sp->s_flags&SFCORE) == 0)
                    156:                panic("Cannot duplicate non shared swapped segment");
                    157:        if ((sp1=salloc(sp->s_size, sp->s_flags|SFNSWP|SFNCLR)) == NULL)
                    158:                sp1 = segdupd(sp);
                    159:        else {
                    160:                sp1->s_flags = sp->s_flags;
                    161:                dmacopy( btoc(sp->s_size), sp->s_vmem, sp1->s_vmem) ;
                    162:        }
                    163:        return sp1;
                    164: }
                    165: 
                    166: /*
                    167:  * Allocate a segment `bytes_wanted' bytes long.
                    168:  * `flags' contains some pseudo flags.
                    169:  */
                    170: SEG *
                    171: salloc(bytes_wanted, flags)
                    172: int bytes_wanted, flags;
                    173: {
                    174:        register SEG *sp;
                    175:        register int r;
                    176: 
                    177:        r = (flags & (SFSYST|SFTEXT|SFSHRX|SFDOWN)) | SFCORE;
                    178: 
                    179: /*
                    180: #ifdef _I386
                    181:        bytes_wanted += (sizeof(char *) - 1);
                    182:        bytes_wanted &= ~(sizeof(char *) - 1);
                    183: #else
                    184:        bytes_wanted += (BSIZE - 1);
                    185:        bytes_wanted &= ~(BSIZE - 1);
                    186: #endif
                    187: */
                    188: 
                    189:        lock(seglink);
                    190:        sp = smalloc(bytes_wanted);
                    191:        unlock(seglink);
                    192: 
                    193:        if (sp) {
                    194:                sp->s_flags = r;
                    195:        } else {
                    196: #if 0
                    197:                /* no room now - let the swapper try to grow it */
                    198:                if (flags & SFNSWP)
                    199:                        return 0;
                    200:                if ((sp=kalloc(sizeof(SEG))) == NULL)
                    201:                        return 0;
                    202:                sp->s_forw = sp;
                    203:                sp->s_back = sp;
                    204:                sp->s_flags = r;
                    205:                sp->s_urefc = 1;
                    206:                sp->s_lrefc = 1;
                    207:                if (segsext(sp, bytes_wanted) == NULL) {
                    208:                        kfree(sp);
                    209:                        return 0;
                    210:                }
                    211: #else
                    212:                return 0;
                    213: #endif
                    214:        }
                    215:        if ((flags&SFNCLR) == 0)
                    216:                dmaclear(sp->s_size, MAPIO(sp->s_vmem, 0), 0L);
                    217:        return sp;
                    218: }
                    219: 
                    220: /*
                    221:  * Free the given segment pointer.
                    222:  */
                    223: sfree(sp)
                    224: register SEG *sp;
                    225: {
                    226:        register INODE *ip;
                    227: 
                    228:        if ( sp->s_urefc != 1 ) {
                    229:                sp->s_urefc--;
                    230:                sp->s_lrefc--;
                    231:                return;
                    232:        }
                    233: 
                    234:        lock(seglink);
                    235: 
                    236:        --sp->s_lrefc;
                    237: 
                    238:        sp->s_back->s_forw = sp->s_forw;
                    239:        sp->s_forw->s_back = sp->s_back;
                    240: 
                    241:        c_free(sp->s_vmem, btoc(sp->s_size));
                    242: 
                    243:        unlock(seglink);
                    244:        if (sp->s_lrefc)
                    245:                panic("Bad segment count");
                    246: 
                    247:        /*
                    248:         * Check if inode is ilocked, in order to allow the process
                    249:         * to exec itself (file with the same inode as parent). Vlad.
                    250:         */
                    251:        if ((ip=sp->s_ip) && !ilocked(ip)) {
                    252:                ldetach(ip);
                    253:        }
                    254:        kfree(sp);
                    255: }
                    256: 
                    257: /*
                    258:  * Grow or shrink the segment `sp' so that it has size `new_bytes' bytes.
                    259:  * 
                    260:  * downward growing segments not done yet!
                    261:  */
                    262: seggrow(sp, new_bytes)
                    263: register SEG *sp;
                    264: unsigned int new_bytes;
                    265: {
                    266:        register SEG *sp1;
                    267:        register int dowflag;
                    268:        unsigned int    old_bytes, common_clicks;
                    269: 
                    270:        dowflag = sp->s_flags & SFDOWN;
                    271:        old_bytes = sp->s_size;
                    272: 
                    273:        /*
                    274:         * If we want a larger segment AND c_grow() succeeds
                    275:         *      boost segment size to new_bytes
                    276:         */
                    277:        if (new_bytes >= old_bytes && c_grow(sp, new_bytes)==0) {
                    278:                T_HAL(0x100, printf("c_grow(%d) ", new_bytes));
                    279:                sp->s_size = new_bytes;
                    280:                dmaclear(new_bytes - old_bytes,
                    281:                  MAPIO(sp->s_vmem, old_bytes), 0);
                    282:                return 1;
                    283:        }
                    284: dont_c_grow:
                    285: 
                    286:        if (sp1 = salloc(new_bytes, (sp->s_flags|SFNSWP|SFNCLR))) {
                    287:                T_HAL(0x100, printf("salloc(%d) ", new_bytes));
                    288:                if (dowflag == 0) {
                    289:                        common_clicks = btoc(min(new_bytes, old_bytes));
                    290:                        dmacopy(common_clicks, sp->s_vmem, sp1->s_vmem);
                    291:                        if (new_bytes > old_bytes) {
                    292:                                dmaclear(new_bytes - old_bytes,
                    293:                                  MAPIO(sp1->s_vmem, old_bytes), 0);
                    294:                        }
                    295:                } else
                    296:                        panic("downflag");
                    297:                lock(seglink);
                    298:                c_free(sp->s_vmem, btoc(old_bytes));
                    299:                satcopy(sp, sp1);
                    300:                unlock(seglink);
                    301: 
                    302:                return 1;
                    303:        }
                    304: 
                    305: #if 1
                    306:        return 0;
                    307: #else
                    308:        /*
                    309:         * Last chance.  Extend the segment by swapping it.
                    310:         */
                    311:        if (!segsext(sp, new_bytes))
                    312:                return 0;
                    313: 
                    314:        if (dowflag == 0) {
                    315:                if (new_bytes > old_bytes)
                    316:                        dmaclear(new_bytes - old_bytes, MAPIO(sp->s_vmem,old_bytes), 0);
                    317:        } else
                    318:                panic("downflag");
                    319: 
                    320:        return (1);
                    321: #endif
                    322: }
                    323: 
                    324: /*
                    325:  * Given a segment pointer, `sp' and a segment size, grow the given segment
                    326:  * to the given size.
                    327:  */
                    328: segsize(sp, s2)
                    329: register SEG *sp;
                    330: caddr_t s2;
                    331: {
                    332:        register caddr_t s1;
                    333: 
                    334:        s1 = (caddr_t) sp->s_size;
                    335:        if (s2 == 0 || seggrow(sp, (off_t)s2) == 0) {
                    336:                SET_U_ERROR( ENOMEM, "can not grow segment" );
                    337:                return;
                    338:        }
                    339:        if (sproto(0) == 0) {
                    340:                if (seggrow(sp, (off_t)s1)==0 || sproto(0)==0) {
                    341:                        T_PIGGY( 0x2000000, printf("auto SEGV\n"); );
                    342:                        sendsig(SIGSEGV, SELF);
                    343:                }
                    344:        }
                    345:        segload();
                    346: }
                    347: 
                    348: /*
                    349:  * Grow the segment `sp1' to the size `s' in bytes by swapping it out
                    350:  * and back in.  The segment may not be locked.
                    351:  */
                    352: SEG *
                    353: segsext(sp1, s)
                    354: register SEG *sp1;
                    355: register off_t s;
                    356: {
                    357: #if 0
                    358:        register SEG *sp2;
                    359: 
                    360: #if    MONITOR
                    361:        if (swmflag)
                    362:                printf("Segsext(%p, %u)\n", SELF, SELF->p_pid);
                    363: #endif
                    364:        if (sexflag == 0) {
                    365:                SET_U_ERROR( ENOMEM, "can not extend, swapping is off" );
                    366:                return (NULL);
                    367:        }
                    368:        lock(seglink);
                    369:        if ((sp2=sdalloc(s)) == NULL) {
                    370:                unlock(seglink);
                    371:                return (NULL);
                    372:        }
                    373:        unlock(seglink);
                    374:        sp1->s_lrefc++;
                    375:        if (sp1->s_size != 0)
                    376:                swapio(1, MAPIO(sp1->s_vmem, 0), sp2->s_daddr, sp1->s_size);
                    377:        lock(seglink);
                    378:        satcopy(sp1, sp2);
                    379:        unlock(seglink);
                    380:        sp1->s_flags &= ~SFCORE;
                    381:        sp1->s_lrefc--;
                    382:        segfinm(sp1);
                    383:        return (sp1);
                    384: #else
                    385:        return 0;
                    386: #endif
                    387: }
                    388: 
                    389: /*
                    390:  * Force the given segment to be in memory.  One can only force
                    391:  * one segment to be in memory at a time.
                    392:  */
                    393: segfinm(sp)
                    394: register SEG *sp;
                    395: {
                    396:        register PROC *pp;
                    397:        register int s;
                    398: 
                    399:        if (sp->s_flags&SFCORE)
                    400:                return;
                    401:        pp = SELF;
                    402:        sp->s_urefc++;
                    403:        sp->s_lrefc++;
                    404:        pp->p_segp[SIAUXIL] = sp;
                    405:        pp->p_flags &= ~PFCORE;
                    406: #ifndef QWAKEUP
                    407:        s = sphi();
                    408: #endif
                    409:        setrun(pp);
                    410:        dispatch();
                    411: #ifndef QWAKEUP
                    412:        spl(s);
                    413: #endif
                    414:        pp->p_segp[SIAUXIL] = NULL;
                    415:        sfree(sp);
                    416: }
                    417: 
                    418: /*
                    419:  * Make a copy of the segment `sp1' which is in memory by writing
                    420:  * it out to disk.
                    421:  */
                    422: SEG *
                    423: segdupd(sp1)
                    424: register SEG *sp1;
                    425: {
                    426:        register SEG *sp2;
                    427: 
                    428:        if (sexflag == 0)
                    429:                return (NULL);
                    430:        lock(seglink);
                    431:        if ((sp2=sdalloc(sp1->s_size)) == NULL) {
                    432:                unlock(seglink);
                    433:                return (NULL);
                    434:        }
                    435:        sp1->s_lrefc++;
                    436:        unlock(seglink);
                    437:        swapio(1, MAPIO(sp1->s_vmem, 0), sp2->s_daddr, sp1->s_size);
                    438:        sp1->s_lrefc--;
                    439:        sp2->s_flags = sp1->s_flags & ~SFCORE;
                    440:        sp2->s_size  = sp1->s_size;
                    441:        return (sp2);
                    442: }
                    443: 
                    444: /*
                    445:  * Given a flag, a physical core address, a disk address and a count in
                    446:  * bytes, perform an I/O operation between core and disk.  If `flag' is
                    447:  * set, the transfer is to the disk otherwise it is to memory.  As you may
                    448:  * have guessed, this is used by the swapper.
                    449:  *
                    450:  */
                    451: swapio(f, p, d, n)
                    452: paddr_t p;
                    453: daddr_t d;
                    454: off_t  n;
                    455: {
                    456:        register BUF * bp;
                    457:        register SEG * sp;
                    458:        register int s;
                    459:        register int nb;
                    460: 
                    461: #if    MONITOR
                    462:        if (swmflag > 1)
                    463:                printf("swapio(%s,%x,%x,%x)\n",f?"out":"in",(int)p,(int)d,n);
                    464: #endif
                    465:        if (d < swapbot || d+(n/BSIZE) > swaptop)
                    466:                panic("Swapio bad parameter");
                    467: 
                    468:        bp = &swapbuf;
                    469:        lock(bp->b_gate);
                    470:        SELF->p_flags |= PFSWIO;
                    471:        bp->b_paddr = p;
                    472: 
                    473:        while (n) {
                    474:                nb = (n > SCHUNK) ? SCHUNK : n;
                    475:                /*
                    476:                 * Prevent I/O transfer from crossing 64 Kbyte boundary.
                    477:                 */
                    478:                if ( (p & 0xFFFF0000L) != ((p+nb) & 0xFFFF0000L) )
                    479:                        nb = 0x10000L - (p & 0x0000FFFFL);
                    480:                bp->b_flag  = BFNTP;
                    481:                bp->b_req   = f ? BWRITE : BREAD;
                    482:                bp->b_dev   = swapdev;
                    483:                bp->b_bno   = d;
                    484:                bp->b_paddr = p;
                    485:                bp->b_count = nb;
                    486:                s = sphi();
                    487:                dblock(swapdev, bp);
                    488:                while ((bp->b_flag&BFNTP) != 0) {
                    489:                        x_sleep((char *)bp, pridisk, slpriNoSig, "swap");
                    490:                        /* Sleeping in the swapper.  */
                    491:                }
                    492:                spl(s);
                    493:                if ((bp->b_flag&BFERR) != 0)
                    494:                        panic("Swapio error");
                    495:                bp->b_vaddr += nb;
                    496:                p += nb;
                    497:                d += nb / BSIZE;
                    498:                n -= nb;
                    499:        }
                    500:        unlock(bp->b_gate);
                    501:        SELF->p_flags &= ~PFSWIO;
                    502: }
                    503: 
                    504: /*
                    505:  * Make the segment descriptor pointed to by `sp1' have the attributes
                    506:  * of `sp2' including it's position in the segment queue and release
                    507:  * `sp2'.  `seglink' must be locked when this routine is called.
                    508:  */
                    509: satcopy(sp1, sp2)
                    510: register SEG *sp1;
                    511: register SEG *sp2;
                    512: {
                    513:        sp1->s_back->s_forw = sp1->s_forw;
                    514:        sp1->s_forw->s_back = sp1->s_back;
                    515:        sp2->s_back->s_forw = sp1;
                    516:        sp1->s_back = sp2->s_back;
                    517:        sp2->s_forw->s_back = sp1;
                    518:        sp1->s_forw  = sp2->s_forw;
                    519:        sp1->s_daddr = sp2->s_daddr;
                    520:        sp1->s_size = sp2->s_size;
                    521:        sp1->s_vmem = sp2->s_vmem;
                    522:        kfree(sp2);
                    523: }
                    524: 
                    525: /*
                    526:  * Allocate a segment on disk that is `n' bytes long.
                    527:  * The `seglink' gate should be locked before this routine is called.
                    528:  */
                    529: SEG *
                    530: sdalloc( s )
                    531: off_t s;
                    532: {
                    533:        register SEG *sp1;
                    534:        register SEG *sp2;
                    535:        register daddr_t d;
                    536:        register daddr_t d1;
                    537:        register daddr_t d2;
                    538: 
                    539:        d  = s / BSIZE;
                    540:        d1 = swapbot;
                    541:        sp1 = &segdq;
                    542:        do {
                    543:                if (d1 >= swaptop)
                    544:                        return (NULL);
                    545:                if ((sp1=sp1->s_forw) != &segdq)
                    546:                        d2 = sp1->s_daddr;
                    547:                else
                    548:                        d2 = swaptop;
                    549:                if (d2-d1 >= d) {
                    550:                        if ((sp2=kalloc(sizeof(SEG))) == NULL)
                    551:                                return (NULL);
                    552:                        sp1->s_back->s_forw = sp2;
                    553:                        sp2->s_back = sp1->s_back;
                    554:                        sp1->s_back = sp2;
                    555:                        sp2->s_forw = sp1;
                    556:                        sp2->s_urefc = 1;
                    557:                        sp2->s_lrefc = 1;
                    558:                        sp2->s_size  = s;
                    559:                        sp2->s_daddr = d1;
                    560:                        return (sp2);
                    561:                }
                    562:                d1 = sp1->s_daddr + (sp1->s_size / BSIZE);
                    563:        } while (sp1 != &segdq);
                    564:        return (NULL);
                    565: }
                    566: 
                    567: /*
                    568:  * Allocate a segment in memory that is `bytes_wanted' bytes long.
                    569:  * The `seglink' gate should be locked before this routine is called.
                    570:  *
                    571:  * if successful, return allocated SEG *
                    572:  * else, return 0
                    573:  */
                    574: SEG *
                    575: smalloc(bytes_wanted)
                    576: off_t bytes_wanted;
                    577: {
                    578:        register SEG *sp1;
                    579:        register SEG *new_seg;
                    580:        unsigned        clicks_wanted;
                    581: 
                    582:        clicks_wanted = btoc(bytes_wanted);
                    583: 
                    584:        /*
                    585:         * Estimate space needed for new segment and its overhead.
                    586:         * Fail if not enough free RAM available.
                    587:         */
                    588:        if (countsize(clicks_wanted) > allocno())
                    589:                return 0;
                    590:        /*
                    591:         * Allocate a new SEG struct to keep track of the segment, if possible.
                    592:         */
                    593:        if ((new_seg = kalloc(sizeof (SEG))) == NULL)
                    594:                return 0;
                    595: 
                    596:        if ((new_seg->s_vmem = c_alloc(clicks_wanted)) == 0) {
                    597:                kfree(new_seg);
                    598:                return 0;
                    599:        }
                    600: 
                    601:        /* link new_seg in at start of segmq */
                    602:        sp1 = segmq.s_forw;
                    603:        sp1->s_back->s_forw = new_seg;
                    604:        new_seg->s_back = sp1->s_back;
                    605:        sp1->s_back = new_seg;
                    606:        new_seg->s_forw = sp1;
                    607: 
                    608:        new_seg->s_urefc = 1;
                    609:        new_seg->s_lrefc = 1;
                    610:        new_seg->s_size  = bytes_wanted;
                    611: 
                    612:        return new_seg;
                    613: }
                    614: 
                    615: /*
                    616:  * Set up `SR' structure in user area from segments descriptors in
                    617:  * process structure.  Also set up the user segmentation registers.
                    618:  */
                    619: sproto(xhp)
                    620: struct xechdr *xhp;
                    621: {
                    622:        register int n;
                    623:        register SEG *sp;
                    624: 
                    625:        for (n=0; n<NUSEG; n++) {
                    626:                u.u_segl[n].sr_flag = u.u_segl[n].sr_size = 0;
                    627:                u.u_segl[n].sr_segp = 0;
                    628:                if ((sp=SELF->p_segp[n]) == NULL)
                    629:                        continue;
                    630:                if (n == SIUSERP)
                    631:                        u.u_segl[n].sr_base = &u;
                    632:                else {
                    633:                        if (xhp)
                    634:                                u.u_segl[n].sr_base = xhp->segs[n].mbase;
                    635:                        u.u_segl[n].sr_flag |= SRFPMAP;
                    636:                }
                    637:                if (n!=SISTEXT)
                    638:                        u.u_segl[n].sr_flag |= SRFDUMP;
                    639:                if (n!=SIUSERP && n!=SISTEXT)
                    640:                        u.u_segl[n].sr_flag |= SRFDATA;
                    641:                u.u_segl[n].sr_size = sp->s_size;
                    642:                u.u_segl[n].sr_segp = sp;
                    643:        }
                    644:        return (mproto());
                    645: }
                    646: 
                    647: /*
                    648:  * Search for a busy text inode.
                    649:  */
                    650: sbusy(ip)
                    651: register INODE *ip;
                    652: {
                    653:        register SEG *sp;
                    654: 
                    655:        lock(seglink);
                    656:        /*
                    657:         * Look for the segment in the memory queue.
                    658:         */
                    659:        for (sp=segmq.s_forw; sp!=&segmq; sp=sp->s_forw) {
                    660:                if (sp->s_ip==ip
                    661:                 && (sp->s_flags&(SFSHRX|SFTEXT))==(SFSHRX|SFTEXT)) {
                    662:                        unlock(seglink);
                    663:                        return (1);
                    664:                }
                    665:        }
                    666: 
                    667:        /*
                    668:         * Look for the segment on the disk queue.
                    669:         */
                    670:        for (sp=segdq.s_forw; sp!=&segdq; sp=sp->s_forw) {
                    671:                if (sp->s_ip==ip
                    672:                 && (sp->s_flags&(SFSHRX|SFTEXT))==(SFSHRX|SFTEXT)) {
                    673:                        unlock(seglink);
                    674:                        return (1);
                    675:                }
                    676:        }
                    677:        unlock(seglink);
                    678:        return 0;
                    679: }
                    680: 
                    681: /*
                    682:  * Segment consistency checks for the paranoid.
                    683: segchk()
                    684: {
                    685:        register SEG *sp;
                    686:        register int nbad;
                    687:        off_t s;
                    688:        daddr_t d;
                    689: 
                    690:        nbad = 0;
                    691:        sp = &segdq;
                    692:        d = swapbot;
                    693:        while ((sp=sp->s_forw) != &segdq) {
                    694:                if (sp->s_daddr < d)
                    695:                        nbad += badseg("disk", (int)sp->s_daddr, 0);
                    696:                d = sp->s_daddr + (sp->s_size / BSIZE);
                    697:        }
                    698:        if (swaptop < d)
                    699:                nbad += badseg("disk", sp->s_back->s_daddr, sp->s_back->s_size);
                    700: }
                    701: 
                    702: badseg(t, b, s)
                    703: char *t;
                    704: daddr_t b;
                    705: off_t s;
                    706: {
                    707:        printf( "Bad %s segment at %X of len %X\n", t, b, s );
                    708:        return (1);
                    709: }
                    710: */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.