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