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