From owner-freebsd-fs Sun Jun 22 04:22:18 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.5/8.8.5) id EAA27569 for fs-outgoing; Sun, 22 Jun 1997 04:22:18 -0700 (PDT) Received: from ns1.netcologne.de (ns1.netcologne.de [194.8.194.70]) by hub.freebsd.org (8.8.5/8.8.5) with SMTP id EAA27395; Sun, 22 Jun 1997 04:21:47 -0700 (PDT) Received: from theseus.mediaconsult.de by ns1.netcologne.de (8.6.12/NetCologne/marvin/netsafe-a0020) id ; Sun, 22 Jun 1997 12:58:25 +0200 with ESMTP X-Ncc-Regid: de.netcologne Message-ID: <33AD0A8E.ED1452A0@netcologne.de> Date: Sun, 22 Jun 1997 13:20:46 +0200 From: Richard Cochius Reply-To: richard.cochius@netcologne.de Organization: Media Connect Cologne X-Mailer: Mozilla 4.0b5 [en] (Win95; I) MIME-Version: 1.0 To: FREEBSD-ADMIN@freebsd.org, FREEBSD-ANNOUNCE@freebsd.org, FREEBSD-ARCH@freebsd.org, FREEBSD-BUGS@freebsd.org, FREEBSD-CORE@freebsd.org, FREEBSD-CURRENT@freebsd.org, FREEBSD-CURRENT-DIGEST@freebsd.org, FREEBSD-STABLE@freebsd.org, FREEBSD-DOC@freebsd.org, FREEBSD-FS@freebsd.org, FREEBSD-HACKERS@freebsd.org, FREEBSD-HACKERS-DIGEST@freebsd.org, FREEBSD-HARDWARE@freebsd.org, FREEBSD-INSTALL@freebsd.org, FREEBSD-ISP@freebsd.org, FREEBSD-MULTIMEDIA@freebsd.org, FREEBSD-PLATFORMS@freebsd.org, FREEBSD-PORTS@freebsd.org, FREEBSD-QUESTIONS@freebsd.org, FREEBSD-QUESTIONS-DIGEST@freebsd.org, FREEBSD-SCSI@freebsd.org, FREEBSD-SECURITY@freebsd.org, FREEBSD-SECURITY-NOTIFICATIONS@freebsd.org, FREEBSD-USER-GROUPS@freebsd.org Subject: subscribe X-Priority: 3 (Normal) Content-Type: text/plain; charset=iso-8859-1 Sender: owner-fs@freebsd.org X-Loop: FreeBSD.org Precedence: bulk From owner-freebsd-fs Sat Jun 28 16:02:17 1997 Return-Path: Received: (from root@localhost) by hub.freebsd.org (8.8.5/8.8.5) id QAA07741 for fs-outgoing; Sat, 28 Jun 1997 16:02:17 -0700 (PDT) Received: from godzilla.zeta.org.au (godzilla.zeta.org.au [203.2.228.19]) by hub.freebsd.org (8.8.5/8.8.5) with ESMTP id QAA07724 for ; Sat, 28 Jun 1997 16:02:13 -0700 (PDT) Received: (from bde@localhost) by godzilla.zeta.org.au (8.8.5/8.6.9) id IAA13203 for fs@freebsd.org; Sun, 29 Jun 1997 08:59:25 +1000 Date: Sun, 29 Jun 1997 08:59:25 +1000 From: Bruce Evans Message-Id: <199706282259.IAA13203@godzilla.zeta.org.au> To: fs@freebsd.org Subject: fix for triple indirect block allocation Sender: owner-fs@freebsd.org X-Loop: FreeBSD.org Precedence: bulk For ufs on systems with 32-bit ints, triple indirect blocks only worked for block sizes of 4K, since MNINDIR(ump)^3 overflows for larger block sizes ( (8192/4)^3 = 2^33 ). This fix is large mainly because it rearranges the code to avoid doing unnecessary 64-bit caclulations. Please review it. There are some abitrary limits that prevent creation of files larger than a measly 512GB: - in newfs/mkfs.c, rev.1.6 hacks fs_maxfilesize down to 512GB. Lite2 fixed this in another way. - in ffs_vfsops.c, ffs_oldcompatfs() also reduces fs_maxfilesize to 512GB for the pre-4.4 filesystem case. I think it should reduce it to 2GB-1 instead, since old filesystems may need to be run under old or foreign systems that don't support 64 bit offsets. - in ffs_vfsops.c, ffs_mountfs reduces fs_maxfilesize to 0x40000000ULL * fs_bsize - 1. This is the Lite2 way. I think it has an off by one error and the correct limit is 0x80000000ULL * fs_bsize - 1. This still leaves negative block numbers free for metadata. For the default fs_bsize of 8K, this gives a limit of 16TB-1. This is not arbitrary. It is fundamental that ufs block numbers are 32 bits. The code is XXX'ed, but I think that is because the limit should be set properly in newfs and checked by fsck. Note that the magic numbers here are only indirectly related to the filesystem size and i/o offset limit of 1TB-1. Filesystem blocks are 16 times larger than DEV_BSIZE by default, and this gives a limit of about times larger. Sparse files can be much larger than the filesystems containing them. It takes only 512 real blocks for a sparse file of size 16TB-1 with 1 nonzero block at the end. Bruce diff -c2 ufs_bmap.c~ ufs_bmap.c *** ufs_bmap.c~ Tue Mar 11 05:18:32 1997 --- ufs_bmap.c Sun Jun 29 07:33:10 1997 *************** *** 251,257 **** int *nump; { ! long metalbn, realbn; struct ufsmount *ump; ! int blockcnt, i, numlevels, off; ump = VFSTOUFS(vp->v_mount); --- 249,256 ---- int *nump; { ! long blockcnt, metalbn, realbn; struct ufsmount *ump; ! int i, numlevels, off; ! int64_t qblockcnt; ump = VFSTOUFS(vp->v_mount); *************** *** 270,274 **** * Determine the number of levels of indirection. After this loop * is done, blockcnt indicates the number of data blocks possible ! * at the given level of indirection, and NIADDR - i is the number * of levels of indirection needed to locate the requested block. */ --- 269,273 ---- * Determine the number of levels of indirection. After this loop * is done, blockcnt indicates the number of data blocks possible ! * at the previous level of indirection, and NIADDR - i is the number * of levels of indirection needed to locate the requested block. */ *************** *** 276,282 **** if (i == 0) return (EFBIG); ! blockcnt *= MNINDIR(ump); ! if (bn < blockcnt) break; } --- 275,287 ---- if (i == 0) return (EFBIG); ! /* ! * Use int64_t's here to avoid overflow for triple indirect ! * blocks when longs have 32 bits and the block size is more ! * than 4K. ! */ ! qblockcnt = (int64_t)blockcnt * MNINDIR(ump); ! if (bn < qblockcnt) break; + blockcnt = qblockcnt; } *************** *** 302,306 **** break; - blockcnt /= MNINDIR(ump); off = (bn / blockcnt) % MNINDIR(ump); --- 307,310 ---- *************** *** 312,315 **** --- 316,320 ---- metalbn -= -1 + off * blockcnt; + blockcnt /= MNINDIR(ump); } if (nump)