Subject: 64-bit daddr_t problems with libsa
To: None <tech-kern@netbsd.org>
From: Simon Burge <simonb@wasabisystems.com>
List: tech-kern
Date: 01/29/2003 20:39:17
On a number of platforms the size of the bootblocks have reasonably
severe size constraints.

With the changes to make daddr_t a 64-bit type, the following bit of
code in libsa's ufs.c

	idx = file_block / fp->f_nindir[level - 1];
	file_block %= fp->f_nindir[level - 1];

ends up generating library calls to 64bit division and modulus library
functions, and at least on alpha, pmax and sbmips we blow our space
budget.

It turns out that the code above is only used if we hit the double
indirect block, so by conditionally leaving out support for the double-
and triple-indirect blocks we can trim out enough code to fit back in
the space restrictions on at least alpha (see patch below).  I have a
similar change for lfs.c too along the same lines.  Suggestions for a
better name would be appreciated.  :-)

On pmax however, we're still 40 bytes over...

To get back extra space, Matt Green came up with the following patch
for <sys/types.h> 

+#ifndef daddr_t
 typedef	int64_t		daddr_t;	/* disk address */
+#endif
+

and then adding

	CPPFLAGS+=      -Ddaddr_t='unsigned int'

to any Makefiles where you need a smaller ufs.o or lfs.o.


I'd like to add both of these changes, but not enable the
LIBSA_UFS_SMALL_FILE changes anywhere just yet.  The overriding of
daddr_t gets enough back for now, but the LIBSA_UFS_SMALL_FILE changes
may buy us space that we need down the track.

Comments?

Simon.
--
Simon Burge                                   <simonb@wasabisystems.com>
NetBSD Development, Support and Service:   http://www.wasabisystems.com/


Index: ufs.c
===================================================================
RCS file: /cvsroot/src/sys/lib/libsa/ufs.c,v
retrieving revision 1.31
diff -d -p -u -r1.31 ufs.c
--- ufs.c	2003/01/24 21:55:18	1.31
+++ ufs.c	2003/01/29 07:16:15
@@ -106,9 +106,11 @@ struct file {
 	off_t		f_seekp;	/* seek pointer */
 	struct fs	*f_fs;		/* pointer to super-block */
 	struct dinode	f_di;		/* copy of on-disk inode */
+#ifndef LIBSA_UFS_SMALL_FILE
 	unsigned int	f_nindir[NIADDR];
 					/* number of blocks mapped by
 					   indirect block at level i */
+#endif
 	char		*f_blk[NIADDR];	/* buffer for indirect block at
 					   level i */
 	size_t		f_blksize[NIADDR];
@@ -236,6 +238,7 @@ block_map(f, file_block, disk_block_p)
 	 * nindir[2] = NINDIR**3
 	 *	etc
 	 */
+#ifndef LIBSA_UFS_SMALL_FILE
 	for (level = 0; level < NIADDR; level++) {
 		if (file_block < fp->f_nindir[level])
 			break;
@@ -245,6 +248,9 @@ block_map(f, file_block, disk_block_p)
 		/* Block number too high */
 		return (EFBIG);
 	}
+#else
+	level = 0;	/* XXX - check NINDIR here and return EFBIG? */
+#endif
 
 	ind_block_num = fp->f_di.di_ib[level];
 
@@ -276,10 +282,12 @@ block_map(f, file_block, disk_block_p)
 		/* XXX ondisk32 */
 		ind_p = (int32_t *)fp->f_blk[level];
 
+#ifndef LIBSA_UFS_SMALL_FILE
 		if (level > 0) {
 			idx = file_block / fp->f_nindir[level - 1];
 			file_block %= fp->f_nindir[level - 1];
 		} else
+#endif
 			idx = file_block;
 
 		ind_block_num = ind_p[idx];
@@ -454,6 +462,7 @@ ufs_open(path, f)
 	ffs_oldfscompat(fs);
 #endif
 
+#ifndef LIBSA_UFS_SMALL_FILE
 	/*
 	 * Calculate indirect block levels.
 	 */
@@ -467,6 +476,7 @@ ufs_open(path, f)
 			fp->f_nindir[level] = mult;
 		}
 	}
+#endif
 
 	inumber = ROOTINO;
 	if ((rc = read_inode(inumber, f)) != 0)