Subject: bin/9890: dumplfs doesn't work with >2G partitions
To: None <gnats-bugs@gnats.netbsd.org>
From: IWAMOTO Toshihiro <iwamoto@sat.t.u-tokyo.ac.jp>
List: netbsd-bugs
Date: 04/15/2000 01:24:12
>Number:         9890
>Category:       bin
>Synopsis:       dumplfs doesn't work with >2G partitions
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Apr 15 01:25:00 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     IWAMOTO Toshihiro
>Release:        today's -current
>Organization:
	
>Environment:
	
System: NetBSD miyuki.my.domain 1.4X NetBSD 1.4X (MASH) #26: Mon Apr 10 01:23:11 JST 2000 toshii@miyuki.my.domain:/usr/src/syssrc/sys/arch/i386/compile/MASH i386


>Description:
	dumplfs(8) doesn't work with >2G partitions
	This is because byte offsets in a device file is calculated
	using int.
>How-To-Repeat:
	# dumplfs <LFS device file>
>Fix:
	Cast to 64bit type before bitshift.
Index: dumplfs.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/dumplfs/dumplfs.c,v
retrieving revision 1.13
diff -u -r1.13 dumplfs.c
--- dumplfs.c   1999/05/02 00:26:01     1.13
+++ dumplfs.c   2000/04/15 08:15:47
@@ -115,6 +115,8 @@
                (void)printf("%d\tINUSE\t%d\t%8X    \n", \
                    i, ip->if_version, ip->if_daddr)

+#define datobyte(da) (((off_t)(da)) << daddr_shift)
+
 int
 main(argc, argv)
        int argc;
@@ -159,7 +161,7 @@
         * most up to date.
         */
        get(fd,
-           lfs_sb1.lfs_sboffs[1] << daddr_shift, &(lfs_sb2.lfs_dlfs), sizeof(struct dlfs));
+           datobyte(lfs_sb1.lfs_sboffs[1]), &(lfs_sb2.lfs_dlfs), sizeof(struct dlfs));

        lfs_master = &lfs_sb1;
        if (lfs_sb1.lfs_tstamp > lfs_sb2.lfs_tstamp) {
@@ -210,7 +212,7 @@

        if (!(dpage = malloc(psize)))
                err(1, "malloc");
-       get(fd, addr << daddr_shift, dpage, psize);
+       get(fd, datobyte(addr), dpage, psize);

        for (dip = dpage + INOPB(lfsp) - 1; dip >= dpage; --dip)
                if (dip->di_inumber == LFS_IFILE_INUM)
@@ -231,7 +233,7 @@
                err(1, "malloc");
        for (inum = 0, addrp = dip->di_db, i = 0; i < block_limit;
            i++, addrp++) {
-               get(fd, *addrp << daddr_shift, ipage, psize);
+               get(fd, datobyte(*addrp), ipage, psize);
                if (i < lfsp->lfs_cleansz) {
                        dump_cleaner_info(lfsp, ipage);
                        print_suheader;
@@ -258,12 +260,12 @@
        /* Dump out blocks off of single indirect block */
        if (!(indir = malloc(psize)))
                err(1, "malloc");
-       get(fd, dip->di_ib[0] << daddr_shift, indir, psize);
+       get(fd, datobyte(dip->di_ib[0]), indir, psize);
        block_limit = MIN(i + lfsp->lfs_nindir, nblocks);
        for (addrp = indir; i < block_limit; i++, addrp++) {
                if (*addrp == LFS_UNUSED_DADDR)
                        break;
-               get(fd, *addrp << daddr_shift,ipage, psize);
+               get(fd, datobyte(*addrp), ipage, psize);
                if (i < lfsp->lfs_cleansz) {
                        dump_cleaner_info(lfsp, ipage);
                        continue;
@@ -289,16 +291,16 @@
        /* Get the double indirect block */
        if (!(dindir = malloc(psize)))
                err(1, "malloc");
-       get(fd, dip->di_ib[1] << daddr_shift, dindir, psize);
+       get(fd, datobyte(dip->di_ib[1]), dindir, psize);
        for (iaddrp = dindir, j = 0; j < lfsp->lfs_nindir; j++, iaddrp++) {
                if (*iaddrp == LFS_UNUSED_DADDR)
                        break;
-               get(fd, *iaddrp << daddr_shift, indir, psize);
+               get(fd, datobyte(*iaddrp), indir, psize);
                block_limit = MIN(i + lfsp->lfs_nindir, nblocks);
                for (addrp = indir; i < block_limit; i++, addrp++) {
                        if (*addrp == LFS_UNUSED_DADDR)
                                break;
-                       get(fd, *addrp << daddr_shift, ipage, psize);
+                       get(fd, datobyte(*addrp), ipage, psize);
                        if (i < lfsp->lfs_cleansz) {
                                dump_cleaner_info(lfsp, ipage);
                                continue;
@@ -434,8 +436,7 @@
        for (dp--, i = 0; i < sp->ss_ninos; dp--) {
                numbytes += lfsp->lfs_bsize;    /* add bytes for inode block */
                printf("\t0x%X {", *dp);
-               get(fd, *dp << (lfsp->lfs_bshift - lfsp->lfs_fsbtodb), inop,
-                   (1 << lfsp->lfs_bshift));
+               get(fd, datobyte(*dp), inop, (1 << lfsp->lfs_bshift));
                for (j = 0; i < sp->ss_ninos && j < INOPB(lfsp); j++, i++) {
                        if (j > 0)
                                (void)printf(", ");
@@ -484,7 +485,7 @@

        (void)printf("\nSEGMENT %d (Disk Address 0x%X)\n",
            addr >> (lfsp->lfs_segshift - daddr_shift), addr);
-       sum_offset = (addr << (lfsp->lfs_bshift - lfsp->lfs_fsbtodb));
+       sum_offset = datobyte(addr);

        sb = 0;
        did_one = 0;
>Release-Note:
>Audit-Trail:
>Unformatted: