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);
 	}

Reply via email to