From owner-freebsd-hackers Thu Mar 11 8: 2:58 1999 Delivered-To: freebsd-hackers@freebsd.org Received: from gateway.cybernet.com (gateway.cybernet.com [192.245.33.1]) by hub.freebsd.org (Postfix) with ESMTP id 39E88153AE; Thu, 11 Mar 1999 08:02:55 -0800 (PST) (envelope-from mtaylor@cybernet.com) Received: from spiffy.cybernet.com (spiffy.cybernet.com [192.245.33.55]) by gateway.cybernet.com (8.8.8/8.8.8) with ESMTP id LAA25156; Thu, 11 Mar 1999 11:02:05 -0500 (EST) (envelope-from mtaylor@cybernet.com) Message-ID: X-Mailer: XFMail 1.3 [p0] on FreeBSD X-Priority: 3 (Normal) Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 8bit MIME-Version: 1.0 In-Reply-To: <199903110751.XAA62027@apollo.backplane.com> Date: Thu, 11 Mar 1999 11:03:04 -0500 (EST) Reply-To: mtaylor@cybernet.com Organization: Cybernet Systems From: "Mark J. Taylor" To: Matthew Dillon Subject: Re: ccd driver problems with > 2GB segments, +fix Cc: jkh@FreeBSD.ORG, msmith@FreeBSD.ORG, freebsd-hackers@FreeBSD.ORG Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG The fixes actually came at two separate times: one to fix the panic, and another to fix the filesystem. 1) Changing the long to u_long makes the ccd not panic the system when it is configured. The corrected problem, specifically, was that the "<< 9" of a 32 bit (signed) word and subsequent store into a 32 bit (signed) word was causing negative transfer sizes. 2) Using an off_f in read/write size comparisons corrected the problem of putting a 64 bit value into a 32 bit word. The second fix (the off_t) is really the only fix needed. The first patch (the u_long) is not necessary: it hid the real problem under most cases (32 bit << 9 being put into a 32 bit value ends up being negative much of the time!), until the math worked out "badly". Here's the final and complete patch (for -current): (this is exactly what NetBSD does, BTW) *** ccd.c.orig Wed Mar 10 11:22:41 1999 --- ccd.c Thu Mar 11 10:53:13 1999 *************** *** 841,846 **** --- 841,847 ---- register struct ccdcinfo *ci, *ci2 = NULL; /* XXX */ register struct ccdbuf *cbp; register daddr_t cbn, cboff; + register off_t cbc; #ifdef DEBUG if (ccddebug & CCDB_IO) *************** *** 919,929 **** LIST_INIT(&cbp->cb_buf.b_dep); cbp->cb_buf.b_resid = 0; if (cs->sc_ileave == 0) ! cbp->cb_buf.b_bcount = dbtob(ci->ci_size - cbn); else ! cbp->cb_buf.b_bcount = dbtob(cs->sc_ileave - cboff); ! if (cbp->cb_buf.b_bcount > bcount) ! cbp->cb_buf.b_bcount = bcount; cbp->cb_buf.b_bufsize = cbp->cb_buf.b_bcount; --- 920,929 ---- LIST_INIT(&cbp->cb_buf.b_dep); cbp->cb_buf.b_resid = 0; if (cs->sc_ileave == 0) ! cbc = dbtob((off_t)(ci->ci_size - cbn)); else ! cbc = dbtob((off_t)(cs->sc_ileave - cboff)); ! cbp->cb_buf.b_bcount = (cbc < bcount) ? cbc : bcount; cbp->cb_buf.b_bufsize = cbp->cb_buf.b_bcount; On 11-Mar-99 Matthew Dillon wrote: > Interesting. What if each disk is 8GB and we set the stripe > size to 8GB? Won't that break the u_long ( i.e. was broken > before, and is still broken now ). Perhaps these variables > should be 64 bit quantities throughout except for the > bp->b_count? > > -Matt > Matthew Dillon > > >:Fix: >:The ccd driver has a variable "bcount" that is a long: it needs >:to be a u_long. And, a 64 bit int is shifted into a 32 bit int >:in ccdbuffer(): the 32 bit int must changed to be a 64 bit int. >: >:This second change has already been made in NetBSD (somebody else >:figured it out), where the ccd driver originated from. It was >:rather tricky to find: the math involving block numbers and ccd >:... -------------------------------------------------------------------- Mark J. Taylor Networking Research Cybernet Systems mtaylor@cybernet.com 727 Airport Blvd. PHONE (734) 668-2567 Ann Arbor, MI 48108 FAX (734) 668-8780 http://www.cybernet.com/ http://www.netmax.com/ -------------------------------------------------------------------- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message