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.
This commit is contained in:
parent
cde2f36932
commit
4ca1f26828
|
@ -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
|
||||
|
||||
/*
|
||||
|
|
|
@ -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 lbn, daddr_t bpref,
|
|||
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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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_t size)
|
|||
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 length, int ioflag,
|
|||
|
||||
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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue