jack@cadre.dsl.PITTSBURGH.EDU (Jack Nelson) (05/04/88)
Index: /usr/src/sys/pdpuba/xp.c 2.10BSD Index: /usr/src/sys/pdpuba/hk.c 2.10BSD Description: BADSECT handling is wrong in xp.c and hk.c of BSD2_10 Repeat-By: Do dd if=/dev/rxp0c of=/dev/null bs=10k on a partition that has badblocks and watch the system hang up or crash with "kernel red stack violation" panic. In some cases, the file system gets munged up, giving a spurious "file system full" message. Usually when trying to backup with tar in my experience. Put a printf in xpecc() code where calculations being done of "ndone" and "wc" on CONT return from revectoring; watch how the wrong numbers get generated: The main error is division by NBPW in line 857 of xp.c; since that is defined as sizeof(int), and sizeof is an unsigned operator, the division is promoted to unsigned, and the result is a nonsense number in the 32000's range, i.e. the unsigned value shifted right one bit as an unsigned number. Probably NBPW was "#define NBPW 2" at some time in the past, and was redefined "sizeof(int)" without considering this unsigned property of the sizeof operator. A simple C program will prove the point: printf("%d\n",-10/2); output: -5 printf("%d\n",-10/sizeof(int)); output: 32763 Fix: apply the patch below, which casts NBPG to (int) and does a bit of cosmetic rearrangement of the code to express its purpose better. "wc" is supposed to be the negative count of words to be read, as fed into the controller register. UUCP: { akgua | allegra | cmcl2 | idis | ihnp4 | mi-cec | pitt | psuvax1 | sun | sunrise | vax135 } ! cadre ! nelslab ! jack ARPA: jack@cadre.dsl.pittsburgh.edu John P. Nelson, M.D., 3811 O'Hara St, Pittsburgh, PA 15213, t:412-624-1769 Dept. of Psychiatry, U. of Pittsburgh Cut:---------- *** ../orgs/xp.c Sun Aug 30 22:47:05 1987 --- xp.c.badfix Sun Apr 24 20:57:20 1988 *************** *** 854,865 **** npx = bp->b_error; bp->b_error = 0; ndone = npx * NBPG; ! wc = ((int)(ndone - bp->b_bcount)) / NBPW; } else { #endif wc = xpaddr->hpwc; ! ndone = (wc * NBPW) + bp->b_bcount; npx = ndone / NBPG; #ifdef BADSECT } --- 854,865 ---- npx = bp->b_error; bp->b_error = 0; ndone = npx * NBPG; ! wc = -((short)(bp->b_bcount - ndone) / (short)NBPW); } else { #endif wc = xpaddr->hpwc; ! ndone = bp->b_bcount - ((unsigned)(-wc) * NBPW) ; npx = ndone / NBPG; #ifdef BADSECT } *************** *** 929,935 **** #ifdef DEBUG printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); #endif ! wc = -(512 / NBPW); break; case CONT: bp->b_flags &= ~B_BAD; --- 929,935 ---- #ifdef DEBUG printf("revector to cn %d tn %d sn %d\n", cn, tn, sn); #endif ! wc = -(512 / (short)NBPW); break; case CONT: bp->b_flags &= ~B_BAD; -- John P. Nelson, M.D., 3811 O'Hara St, Pittsburgh, PA 15213, t:412-624-1769 Dept. of Psychiatry, U. of Pittsburgh UUCP: { akgua | allegra | cmcl2 | idis | ihnp4 | mi-cec | pitt | psuvax1 | sun | sunrise | vax135 } ! cadre ! jack ARPA: jack@cadre.dsl.pittsburgh.edu