Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 31 Jan 2010 19:07:17 -0500
From:      Scott Burns <scott@bqinternet.com>
To:        freebsd-fs@freebsd.org
Subject:   Inode number treated as signed int in ffs_nodealloccg
Message-ID:  <4B661B35.7050501@bqinternet.com>

next in thread | raw e-mail | index | archive | help
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 <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <ufs/ufs/dinode.h>
#include <ufs/ffs/fs.h>

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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?4B661B35.7050501>