Module Name: src Committed By: jakllsch Date: Wed Nov 21 23:11:24 UTC 2012
Modified Files: src/sys/ufs/ext2fs: ext2fs.h ext2fs_alloc.c ext2fs_balloc.c ext2fs_extern.h ext2fs_inode.c ext2fs_readwrite.c ext2fs_vfsops.c ext2fs_vnops.c Log Message: Write support for the Ext4 Read-only Compatible Feature "huge_file". Primarily, this feature extends the inode block count field to 48 bits. Additionally, this feature allows this field to be represented in file system block size units rather than DEV_BSIZE units. To generate a diff of this commit: cvs rdiff -u -r1.32 -r1.33 src/sys/ufs/ext2fs/ext2fs.h cvs rdiff -u -r1.42 -r1.43 src/sys/ufs/ext2fs/ext2fs_alloc.c cvs rdiff -u -r1.34 -r1.35 src/sys/ufs/ext2fs/ext2fs_balloc.c cvs rdiff -u -r1.45 -r1.46 src/sys/ufs/ext2fs/ext2fs_extern.h cvs rdiff -u -r1.75 -r1.76 src/sys/ufs/ext2fs/ext2fs_inode.c cvs rdiff -u -r1.61 -r1.62 src/sys/ufs/ext2fs/ext2fs_readwrite.c cvs rdiff -u -r1.166 -r1.167 src/sys/ufs/ext2fs/ext2fs_vfsops.c cvs rdiff -u -r1.104 -r1.105 src/sys/ufs/ext2fs/ext2fs_vnops.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/ufs/ext2fs/ext2fs.h diff -u src/sys/ufs/ext2fs/ext2fs.h:1.32 src/sys/ufs/ext2fs/ext2fs.h:1.33 --- src/sys/ufs/ext2fs/ext2fs.h:1.32 Wed Nov 21 20:45:35 2012 +++ src/sys/ufs/ext2fs/ext2fs.h Wed Nov 21 23:11:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs.h,v 1.32 2012/11/21 20:45:35 jakllsch Exp $ */ +/* $NetBSD: ext2fs.h,v 1.33 2012/11/21 23:11:23 jakllsch Exp $ */ /* * Copyright (c) 1982, 1986, 1993 @@ -265,7 +265,8 @@ struct m_ext2fs { */ #define EXT2F_COMPAT_SUPP 0x0000 #define EXT2F_ROCOMPAT_SUPP (EXT2F_ROCOMPAT_SPARSESUPER \ - | EXT2F_ROCOMPAT_LARGEFILE) + | EXT2F_ROCOMPAT_LARGEFILE \ + | EXT2F_ROCOMPAT_HUGE_FILE) #define EXT2F_INCOMPAT_SUPP EXT2F_INCOMPAT_FTYPE /* Index: src/sys/ufs/ext2fs/ext2fs_alloc.c diff -u src/sys/ufs/ext2fs/ext2fs_alloc.c:1.42 src/sys/ufs/ext2fs/ext2fs_alloc.c:1.43 --- src/sys/ufs/ext2fs/ext2fs_alloc.c:1.42 Sun Mar 6 04:46:26 2011 +++ src/sys/ufs/ext2fs/ext2fs_alloc.c Wed Nov 21 23:11:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_alloc.c,v 1.42 2011/03/06 04:46:26 rmind Exp $ */ +/* $NetBSD: ext2fs_alloc.c,v 1.43 2012/11/21 23:11:23 jakllsch Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ext2fs_alloc.c,v 1.42 2011/03/06 04:46:26 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_alloc.c,v 1.43 2012/11/21 23:11:23 jakllsch Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -135,7 +135,7 @@ ext2fs_alloc(struct inode *ip, daddr_t l bno = (daddr_t)ext2fs_hashalloc(ip, cg, bpref, fs->e2fs_bsize, ext2fs_alloccg); if (bno > 0) { - ip->i_e2fs_nblock += btodb(fs->e2fs_bsize); + ext2fs_setnblock(ip, ext2fs_nblock(ip) + btodb(fs->e2fs_bsize)); ip->i_flag |= IN_CHANGE | IN_UPDATE; *bnp = bno; return (0); Index: src/sys/ufs/ext2fs/ext2fs_balloc.c diff -u src/sys/ufs/ext2fs/ext2fs_balloc.c:1.34 src/sys/ufs/ext2fs/ext2fs_balloc.c:1.35 --- src/sys/ufs/ext2fs/ext2fs_balloc.c:1.34 Mon Oct 19 18:41:17 2009 +++ src/sys/ufs/ext2fs/ext2fs_balloc.c Wed Nov 21 23:11:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_balloc.c,v 1.34 2009/10/19 18:41:17 bouyer Exp $ */ +/* $NetBSD: ext2fs_balloc.c,v 1.35 2012/11/21 23:11:23 jakllsch Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ext2fs_balloc.c,v 1.34 2009/10/19 18:41:17 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_balloc.c,v 1.35 2012/11/21 23:11:23 jakllsch Exp $"); #if defined(_KERNEL_OPT) #include "opt_uvmhist.h" @@ -343,7 +343,7 @@ fail: } } if (deallocated) { - ip->i_e2fs_nblock -= btodb(deallocated); + ext2fs_setnblock(ip, ext2fs_nblock(ip) - btodb(deallocated)); ip->i_e2fs_flags |= IN_CHANGE | IN_UPDATE; } return error; Index: src/sys/ufs/ext2fs/ext2fs_extern.h diff -u src/sys/ufs/ext2fs/ext2fs_extern.h:1.45 src/sys/ufs/ext2fs/ext2fs_extern.h:1.46 --- src/sys/ufs/ext2fs/ext2fs_extern.h:1.45 Sat Nov 17 16:03:48 2012 +++ src/sys/ufs/ext2fs/ext2fs_extern.h Wed Nov 21 23:11:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_extern.h,v 1.45 2012/11/17 16:03:48 jakllsch Exp $ */ +/* $NetBSD: ext2fs_extern.h,v 1.46 2012/11/21 23:11:23 jakllsch Exp $ */ /*- * Copyright (c) 1991, 1993, 1994 @@ -110,6 +110,8 @@ int ext2fs_bmap(void *); /* ext2fs_inode.c */ uint64_t ext2fs_size(struct inode *); int ext2fs_setsize(struct inode *, uint64_t); +uint64_t ext2fs_nblock(struct inode *); +int ext2fs_setnblock(struct inode *, uint64_t); int ext2fs_update(struct vnode *, const struct timespec *, const struct timespec *, int); int ext2fs_truncate(struct vnode *, off_t, int, kauth_cred_t); Index: src/sys/ufs/ext2fs/ext2fs_inode.c diff -u src/sys/ufs/ext2fs/ext2fs_inode.c:1.75 src/sys/ufs/ext2fs/ext2fs_inode.c:1.76 --- src/sys/ufs/ext2fs/ext2fs_inode.c:1.75 Fri Jan 27 19:22:48 2012 +++ src/sys/ufs/ext2fs/ext2fs_inode.c Wed Nov 21 23:11:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_inode.c,v 1.75 2012/01/27 19:22:48 para Exp $ */ +/* $NetBSD: ext2fs_inode.c,v 1.76 2012/11/21 23:11:23 jakllsch Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ext2fs_inode.c,v 1.75 2012/01/27 19:22:48 para Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_inode.c,v 1.76 2012/11/21 23:11:23 jakllsch Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -128,6 +128,54 @@ ext2fs_setsize(struct inode *ip, uint64_ return 0; } +uint64_t +ext2fs_nblock(struct inode *ip) +{ + uint64_t nblock = ip->i_e2fs_nblock; + struct m_ext2fs * const fs = ip->i_e2fs; + + if (fs->e2fs.e2fs_features_rocompat & EXT2F_ROCOMPAT_HUGE_FILE) { + nblock |= (uint64_t)ip->i_e2fs_nblock_high << 32; + + if ((ip->i_e2fs_flags & EXT2_HUGE_FILE)) { + nblock = fsbtodb(fs, nblock); + } + } + + return nblock; +} + +int +ext2fs_setnblock(struct inode *ip, uint64_t nblock) +{ + struct m_ext2fs * const fs = ip->i_e2fs; + + if (nblock <= 0xffffffffULL) { + CLR(ip->i_e2fs_flags, EXT2_HUGE_FILE); + ip->i_e2fs_nblock = nblock; + return 0; + } + + if (!ISSET(fs->e2fs.e2fs_features_rocompat, EXT2F_ROCOMPAT_HUGE_FILE)) + return EFBIG; + + if (nblock <= 0xffffffffffffULL) { + CLR(ip->i_e2fs_flags, EXT2_HUGE_FILE); + ip->i_e2fs_nblock = nblock & 0xffffffff; + ip->i_e2fs_nblock_high = (nblock >> 32) & 0xffff; + return 0; + } + + if (dbtofsb(fs, nblock) <= 0xffffffffffffULL) { + SET(ip->i_e2fs_flags, EXT2_HUGE_FILE); + ip->i_e2fs_nblock = dbtofsb(fs, nblock) & 0xffffffff; + ip->i_e2fs_nblock_high = (dbtofsb(fs, nblock) >> 32) & 0xffff; + return 0; + } + + return EFBIG; +} + /* * Last reference to an inode. If necessary, write or delete it. */ @@ -260,7 +308,7 @@ ext2fs_truncate(struct vnode *ovp, off_t if (ovp->v_type == VLNK && (ext2fs_size(oip) < ump->um_maxsymlinklen || - (ump->um_maxsymlinklen == 0 && oip->i_e2fs_nblock == 0))) { + (ump->um_maxsymlinklen == 0 && ext2fs_nblock(oip) == 0))) { KDASSERT(length == 0); memset((char *)&oip->i_din.e2fs_din->e2di_shortlink, 0, (u_int)ext2fs_size(oip)); @@ -425,7 +473,9 @@ done: * Put back the real size. */ (void)ext2fs_setsize(oip, length); - oip->i_e2fs_nblock -= blocksreleased; + error = ext2fs_setnblock(oip, ext2fs_nblock(oip) - blocksreleased); + if (error != 0) + allerror = error; oip->i_flag |= IN_CHANGE; KASSERT(ovp->v_type != VREG || ovp->v_size == ext2fs_size(oip)); return (allerror); Index: src/sys/ufs/ext2fs/ext2fs_readwrite.c diff -u src/sys/ufs/ext2fs/ext2fs_readwrite.c:1.61 src/sys/ufs/ext2fs/ext2fs_readwrite.c:1.62 --- src/sys/ufs/ext2fs/ext2fs_readwrite.c:1.61 Sun Apr 29 22:54:00 2012 +++ src/sys/ufs/ext2fs/ext2fs_readwrite.c Wed Nov 21 23:11:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_readwrite.c,v 1.61 2012/04/29 22:54:00 chs Exp $ */ +/* $NetBSD: ext2fs_readwrite.c,v 1.62 2012/11/21 23:11:23 jakllsch Exp $ */ /*- * Copyright (c) 1993 @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ext2fs_readwrite.c,v 1.61 2012/04/29 22:54:00 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_readwrite.c,v 1.62 2012/11/21 23:11:23 jakllsch Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -123,7 +123,7 @@ ext2fs_read(void *v) if (vp->v_type == VLNK) { if (ext2fs_size(ip) < ump->um_maxsymlinklen || - (ump->um_maxsymlinklen == 0 && ip->i_e2fs_nblock == 0)) + (ump->um_maxsymlinklen == 0 && ext2fs_nblock(ip) == 0)) panic("%s: short symlink", "ext2fs_read"); } else if (vp->v_type != VREG && vp->v_type != VDIR) panic("%s: type %d", "ext2fs_read", vp->v_type); Index: src/sys/ufs/ext2fs/ext2fs_vfsops.c diff -u src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.166 src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.167 --- src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.166 Sat Sep 1 17:01:24 2012 +++ src/sys/ufs/ext2fs/ext2fs_vfsops.c Wed Nov 21 23:11:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_vfsops.c,v 1.166 2012/09/01 17:01:24 christos Exp $ */ +/* $NetBSD: ext2fs_vfsops.c,v 1.167 2012/11/21 23:11:23 jakllsch Exp $ */ /* * Copyright (c) 1989, 1991, 1993, 1994 @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.166 2012/09/01 17:01:24 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.167 2012/11/21 23:11:23 jakllsch Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -1075,8 +1075,9 @@ retry: /* If the inode was deleted, reset all fields */ if (ip->i_e2fs_dtime != 0) { - ip->i_e2fs_mode = ip->i_e2fs_nblock = 0; + ip->i_e2fs_mode = 0; (void)ext2fs_setsize(ip, 0); + (void)ext2fs_setnblock(ip, 0); memset(ip->i_e2fs_blocks, 0, sizeof(ip->i_e2fs_blocks)); } Index: src/sys/ufs/ext2fs/ext2fs_vnops.c diff -u src/sys/ufs/ext2fs/ext2fs_vnops.c:1.104 src/sys/ufs/ext2fs/ext2fs_vnops.c:1.105 --- src/sys/ufs/ext2fs/ext2fs_vnops.c:1.104 Wed May 9 00:21:18 2012 +++ src/sys/ufs/ext2fs/ext2fs_vnops.c Wed Nov 21 23:11:23 2012 @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_vnops.c,v 1.104 2012/05/09 00:21:18 riastradh Exp $ */ +/* $NetBSD: ext2fs_vnops.c,v 1.105 2012/11/21 23:11:23 jakllsch Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -65,7 +65,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.104 2012/05/09 00:21:18 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.105 2012/11/21 23:11:23 jakllsch Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -326,7 +326,7 @@ ext2fs_getattr(void *v) vap->va_blocksize = MAXBSIZE; else vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize; - vap->va_bytes = dbtob((u_quad_t)ip->i_e2fs_nblock); + vap->va_bytes = dbtob(ext2fs_nblock(ip)); vap->va_type = vp->v_type; vap->va_filerev = ip->i_modrev; return (0); @@ -922,7 +922,7 @@ ext2fs_readlink(void *v) isize = ext2fs_size(ip); if (isize < ump->um_maxsymlinklen || - (ump->um_maxsymlinklen == 0 && ip->i_e2fs_nblock == 0)) { + (ump->um_maxsymlinklen == 0 && ext2fs_nblock(ip) == 0)) { uiomove((char *)ip->i_din.e2fs_din->e2di_shortlink, isize, ap->a_uio); return (0); }