From owner-freebsd-fs@FreeBSD.ORG Mon Feb 1 00:25:25 2010 Return-Path: Delivered-To: freebsd-fs@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id BFD841065670 for ; Mon, 1 Feb 2010 00:25:25 +0000 (UTC) (envelope-from scott@bqinternet.com) Received: from mail.bqinternet.com (mail.bqinternet.com [69.9.32.203]) by mx1.freebsd.org (Postfix) with ESMTP id 977098FC12 for ; Mon, 1 Feb 2010 00:25:25 +0000 (UTC) Received: from localhost (mail [69.9.32.203]) by mail.bqinternet.com (Postfix) with ESMTP id 0D8568405F6 for ; Mon, 1 Feb 2010 00:07:24 +0000 (GMT) Received: from mail.bqinternet.com ([69.9.32.203]) by localhost (mail.bqinternet.com [69.9.32.203]) (amavisd-new, port 10024) with ESMTP id X1I+VEAuGs6w for ; Mon, 1 Feb 2010 00:07:23 +0000 (GMT) Received: from scott-burnss-macbook-air.local (mail [69.9.32.203]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.bqinternet.com (Postfix) with ESMTP id 6CB9E8405D7 for ; Mon, 1 Feb 2010 00:07:23 +0000 (GMT) Message-ID: <4B661B35.7050501@bqinternet.com> Date: Sun, 31 Jan 2010 19:07:17 -0500 From: Scott Burns User-Agent: Thunderbird 2.0.0.23 (Macintosh/20090812) MIME-Version: 1.0 To: freebsd-fs@freebsd.org Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Inode number treated as signed int in ffs_nodealloccg X-BeenThere: freebsd-fs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Filesystems List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 01 Feb 2010 00:25:25 -0000 Hi guys, While working with a 17TB UFS2 filesystem, g_vfs_done() was reporting write errors with negative offsets. I modified bufwrite() to have it panic on a negative bp->b_blkno so that I could trace the source of the write. The traces showed ffs_nodealloccg() as the source of the problem. The negative number is coming from the ino_to_fsba(fs, x) macro used in ffs_nodealloccg(). In this case, the x is "cg * fs->fs_ipg + cgp->cg_initediblk". The problem goes away if I cast cg as (unsigned int)cg. I imagine that this hasn't been noticed up to now since most people are not exceeding the range of a signed int, even with multi-TB filesystems. Is this issue likely to exist in other FFS code? Should I just recreate the filesystem with less inodes for now? I made a crude example program to easily demonstrate the problem: #include #include #include #include #include int main() { struct fs *fs; struct cg *cgp; int cg; fs = malloc(sizeof(struct fs)); cgp = malloc(sizeof(struct cg)); fs->fs_magic = 424935705; fs->fs_fsbtodb = 2; fs->fs_inopb = 64; fs->fs_fragshift = 3; fs->fs_ipg = 23552; fs->fs_iblkno = 56; fs->fs_fpg = 94064; cg = 96868; cgp->cg_initediblk = 21696; printf("ino_to_fsba #1: %lld\n", ino_to_fsba(fs, cg * fs->fs_ipg + cgp->cg_initediblk)); printf("ino_to_fsba #2: %lld\n", ino_to_fsba(fs, (unsigned int)cg * fs->fs_ipg + cgp->cg_initediblk)); return 0; } /* Observed output: ino_to_fsba #1: -8041719792 ino_to_fsba #2: 9111794320 */ -- Scott Burns System Administrator BQ Internet Corporation