Fix tar's handling of links. [rsc] --rw-rw-r-- M 23749 glenda sys 22453 Jan 31 07:50 sys/src/cmd/tar.c /n/sourcesdump/2006/0131/plan9/sys/src/cmd/tar.c:56,62 - /n/sourcesdump/2006/0201/plan9/sys/src/cmd/tar.c:56,62 LF_PLAIN2 = '0', LF_LINK = '1', LF_SYMLINK1 = '2', - LF_SYMLINK2 = 's', + LF_SYMLINK2 = 's', /* 4BSD used this */ LF_CHR = '3', LF_BLK = '4', LF_DIR = '5', /n/sourcesdump/2006/0131/plan9/sys/src/cmd/tar.c:459,470 - /n/sourcesdump/2006/0201/plan9/sys/src/cmd/tar.c:459,471 return name(hp)[0] == '\0'; } + /* return the size from the header block, or zero for links, dirs, etc. */ Off hdrsize(Hdr *hp) { Off bytes = strtoull(hp->size, nil, 8); - if(isdir(hp)) + if(isdir(hp) || islink(hp->linkflag)) bytes = 0; return bytes; } /n/sourcesdump/2006/0131/plan9/sys/src/cmd/tar.c:934,939 - /n/sourcesdump/2006/0201/plan9/sys/src/cmd/tar.c:935,942 } else print("%s\n", fname); + if (blksleft == 0) + bytes = 0; for (; blksleft > 0; blksleft -= blksread) { hbp = getblkrd(ar, (fd >= 0? Alldata: Justnxthdr)); if (hbp == nil) /n/sourcesdump/2006/0131/plan9/sys/src/cmd/tar.c:940,945 - /n/sourcesdump/2006/0201/plan9/sys/src/cmd/tar.c:943,951 sysfatal("unexpected EOF on archive extracting %s", fname); blksread = gothowmany(blksleft); + if (blksread <= 0) + fprint(2, "%s: got %ld blocks reading %s!\n", + argv0, blksread, fname); wrbytes = Tblock*blksread; if(wrbytes > bytes) wrbytes = bytes; /n/sourcesdump/2006/0131/plan9/sys/src/cmd/tar.c:948,953 - /n/sourcesdump/2006/0201/plan9/sys/src/cmd/tar.c:954,963 putreadblks(ar, blksread); bytes -= wrbytes; } + if (bytes > 0) + fprint(2, + "%s: %lld bytes uncopied at eof; %s not fully extracted\n", + argv0, bytes, fname); if (fd >= 0) { /* * directories should be wstated after we're done Remove debugging print. [jmk] --rw-rw-r-- M 23749 glenda sys 5589 Jan 31 11:12 sys/src/cmd/ip/ping.c /n/sourcesdump/2006/0131/plan9/sys/src/cmd/ip/ping.c:185,191 - /n/sourcesdump/2006/0201/plan9/sys/src/cmd/ip/ping.c:185,190 alarm(0); now = nsec(); if(n <= 0){ /* read interrupted - time to go */ - fprint(2, "clean\n"); clean(0, now+MINUTE, nil); continue; } Avoid holding locks too long in imagereclaim, and avoid rescheduling if it does happen. [rsc] --rw-rw-r-- M 23749 glenda sys 28702 Jan 31 18:16 sys/src/9/port/proc.c /n/sourcesdump/2006/0131/plan9/sys/src/9/port/proc.c:122,128 - /n/sourcesdump/2006/0201/plan9/sys/src/9/port/proc.c:122,146 getcallerpc(&p+2)); if(up){ - if(up->nlocks.ref && up->state != Moribund && up->delaysched < 20){ + /* + * Delay the sched until the process gives up the locks + * it is holding. This avoids dumb lock loops. + * Don't delay if the process is Moribund. + * It called sched to die. + * But do sched eventually. This avoids a missing unlock + * from hanging the entire kernel. + * But don't reschedule procs holding palloc or procalloc. + * Those are far too important to be holding while asleep. + * + * This test is not exact. There can still be a few instructions + * in the middle of taslock when a process holds a lock + * but Lock.p has not yet been initialized. + */ + if(up->nlocks.ref) + if(up->state != Moribund) + if(up->delaysched < 20 + || palloc.Lock.p == up + || procalloc.Lock.p == up){ up->delaysched++; delayedscheds++; return; [rsc] --rw-rw-r-- M 23749 glenda sys 13939 Jan 31 18:16 sys/src/9/port/segment.c /n/sourcesdump/2006/0131/plan9/sys/src/9/port/segment.c:320,325 - /n/sourcesdump/2006/0201/plan9/sys/src/9/port/segment.c:320,326 static void imagereclaim(void) { + int n; Page *p; uvlong ticks; /n/sourcesdump/2006/0131/plan9/sys/src/9/port/segment.c:330,339 - /n/sourcesdump/2006/0201/plan9/sys/src/9/port/segment.c:331,348 lock(&palloc); ticks = fastticks(nil); - for(p = palloc.head; p; p = p->next) { - if(p->ref == 0 && p->image && canlock(p)) { - if(p->ref == 0) + n = 0; + /* + * All the pages with images backing them are at the + * end of the list (see putpage) so start there and work + * backward. + */ + for(p = palloc.tail; p && p->image && n<1000; p = p->prev) { + if(p->ref == 0 && canlock(p)) { + if(p->ref == 0) { + n++; uncachepage(p); + } unlock(p); } }