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)