Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs/ext2fs support arbitrary ext3/ext4 inode size, add a...
details: https://anonhg.NetBSD.org/src/rev/a6a079faa8f1
branches: trunk
changeset: 346799:a6a079faa8f1
user: jdolecek <jdolecek%NetBSD.org@localhost>
date: Wed Aug 03 21:53:02 2016 +0000
description:
support arbitrary ext3/ext4 inode size, add all the new ext4 fields ext2fs_dinode, and add support for loading the extra inode data
diffstat:
sys/ufs/ext2fs/ext2fs.h | 5 +-
sys/ufs/ext2fs/ext2fs_alloc.c | 6 +-
sys/ufs/ext2fs/ext2fs_bswap.c | 42 ++++++++++++--
sys/ufs/ext2fs/ext2fs_dinode.h | 36 ++++++++----
sys/ufs/ext2fs/ext2fs_inode.c | 6 +-
sys/ufs/ext2fs/ext2fs_vfsops.c | 120 +++++++++++++++++++++++++---------------
sys/ufs/ext2fs/ext2fs_vnops.c | 6 +-
7 files changed, 148 insertions(+), 73 deletions(-)
diffs (truncated from 453 to 300 lines):
diff -r 7b06fad8818b -r a6a079faa8f1 sys/ufs/ext2fs/ext2fs.h
--- a/sys/ufs/ext2fs/ext2fs.h Wed Aug 03 19:59:57 2016 +0000
+++ b/sys/ufs/ext2fs/ext2fs.h Wed Aug 03 21:53:02 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ext2fs.h,v 1.38 2016/06/24 17:21:30 christos Exp $ */
+/* $NetBSD: ext2fs.h,v 1.39 2016/08/03 21:53:02 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
@@ -327,7 +327,8 @@
#define EXT2F_COMPAT_SUPP 0x0000
#define EXT2F_ROCOMPAT_SUPP (EXT2F_ROCOMPAT_SPARSESUPER \
| EXT2F_ROCOMPAT_LARGEFILE \
- | EXT2F_ROCOMPAT_HUGE_FILE)
+ | EXT2F_ROCOMPAT_HUGE_FILE \
+ | EXT2F_ROCOMPAT_EXTRA_ISIZE)
#define EXT2F_INCOMPAT_SUPP (EXT2F_INCOMPAT_FTYPE \
| EXT2F_INCOMPAT_EXTENTS)
diff -r 7b06fad8818b -r a6a079faa8f1 sys/ufs/ext2fs/ext2fs_alloc.c
--- a/sys/ufs/ext2fs/ext2fs_alloc.c Wed Aug 03 19:59:57 2016 +0000
+++ b/sys/ufs/ext2fs/ext2fs_alloc.c Wed Aug 03 21:53:02 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ext2fs_alloc.c,v 1.46 2015/03/28 19:24:04 maxv Exp $ */
+/* $NetBSD: ext2fs_alloc.c,v 1.47 2016/08/03 21:53:02 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_alloc.c,v 1.46 2015/03/28 19:24:04 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_alloc.c,v 1.47 2016/08/03 21:53:02 jdolecek Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -198,7 +198,7 @@
panic("ext2fs_valloc: dup alloc");
}
- memset(ip->i_din.e2fs_din, 0, sizeof(struct ext2fs_dinode));
+ memset(ip->i_din.e2fs_din, 0, EXT2_DINODE_SIZE(fs));
/*
* Set up a new generation number for this inode.
diff -r 7b06fad8818b -r a6a079faa8f1 sys/ufs/ext2fs/ext2fs_bswap.c
--- a/sys/ufs/ext2fs/ext2fs_bswap.c Wed Aug 03 19:59:57 2016 +0000
+++ b/sys/ufs/ext2fs/ext2fs_bswap.c Wed Aug 03 21:53:02 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ext2fs_bswap.c,v 1.20 2016/08/02 17:24:24 jdolecek Exp $ */
+/* $NetBSD: ext2fs_bswap.c,v 1.21 2016/08/03 21:53:02 jdolecek Exp $ */
/*
* Copyright (c) 1997 Manuel Bouyer.
@@ -26,7 +26,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_bswap.c,v 1.20 2016/08/02 17:24:24 jdolecek Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_bswap.c,v 1.21 2016/08/03 21:53:02 jdolecek Exp $");
#include <sys/types.h>
#include <ufs/ext2fs/ext2fs.h>
@@ -81,7 +81,8 @@
new->e2fs_reserved_ngdb = bswap16(old->e2fs_reserved_ngdb);
}
-void e2fs_cg_bswap(struct ext2_gd *old, struct ext2_gd *new, int size)
+void
+e2fs_cg_bswap(struct ext2_gd *old, struct ext2_gd *new, int size)
{
int i;
@@ -95,9 +96,13 @@
}
}
-void e2fs_i_bswap(struct ext2fs_dinode *old, struct ext2fs_dinode *new)
+void
+e2fs_i_bswap(struct ext2fs_dinode *old, struct ext2fs_dinode *new, size_t isize)
{
+ /* preserve non-swapped and unused fields */
+ memcpy(new, old, isize);
+ /* swap what needs to be swapped */
new->e2di_mode = bswap16(old->e2di_mode);
new->e2di_uid = bswap16(old->e2di_uid);
new->e2di_gid = bswap16(old->e2di_gid);
@@ -117,7 +122,32 @@
new->e2di_facl_high = bswap16(old->e2di_facl_high);
new->e2di_uid_high = bswap16(old->e2di_uid_high);
new->e2di_gid_high = bswap16(old->e2di_gid_high);
- memcpy(&new->e2di_blocks[0], &old->e2di_blocks[0],
- (EXT2FS_NDADDR + EXT2FS_NIADDR) * sizeof(uint32_t));
+ new->e2di_checksum_low = bswap16(old->e2di_checksum_low);
+
+ /*
+ * Following fields are only supported for inode sizes bigger
+ * than the old ext2 one
+ */
+ if (isize == EXT2_REV0_DINODE_SIZE)
+ return;
+
+ new->e2di_extra_isize = bswap16(old->e2di_extra_isize);
+ new->e2di_checksum_high = bswap16(old->e2di_checksum_high);
+
+ /* Following fields are ext4, might not be actually present */
+ if (EXT2_DINODE_FITS(new, e2di_ctime_extra, isize))
+ new->e2di_ctime_extra = bswap32(old->e2di_ctime_extra);
+ if (EXT2_DINODE_FITS(new, e2di_mtime_extra, isize))
+ new->e2di_mtime_extra = bswap32(old->e2di_mtime_extra);
+ if (EXT2_DINODE_FITS(new, e2di_atime_extra, isize))
+ new->e2di_atime_extra = bswap32(old->e2di_atime_extra);
+ if (EXT2_DINODE_FITS(new, e2di_crtime, isize))
+ new->e2di_crtime = bswap32(old->e2di_crtime);
+ if (EXT2_DINODE_FITS(new, e2di_crtime_extra, isize))
+ new->e2di_crtime_extra = bswap32(old->e2di_crtime_extra);
+ if (EXT2_DINODE_FITS(new, e2di_version_high, isize))
+ new->e2di_version_high = bswap32(old->e2di_version_high);
+ if (EXT2_DINODE_FITS(new, e2di_projid, isize))
+ new->e2di_projid = bswap32(old->e2di_projid);
}
#endif
diff -r 7b06fad8818b -r a6a079faa8f1 sys/ufs/ext2fs/ext2fs_dinode.h
--- a/sys/ufs/ext2fs/ext2fs_dinode.h Wed Aug 03 19:59:57 2016 +0000
+++ b/sys/ufs/ext2fs/ext2fs_dinode.h Wed Aug 03 21:53:02 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ext2fs_dinode.h,v 1.27 2016/08/02 17:36:02 jdolecek Exp $ */
+/* $NetBSD: ext2fs_dinode.h,v 1.28 2016/08/03 21:53:02 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1989, 1993
@@ -125,11 +125,19 @@
uint16_t e2di_facl_high; /* 118: file ACL bits 47:32 (ext4) */
uint16_t e2di_uid_high; /* 120: Owner UID top 16 bits (ext4) */
uint16_t e2di_gid_high; /* 122: Owner GID top 16 bits (ext4) */
- uint16_t e2di_extra_isize; /* 124: inode extra size (over 128) actually used (ext4) */
- uint16_t e2di_checksum_high; /* 126: crc (not implemented) (ext4) */
+ uint16_t e2di_checksum_low; /* 124: crc LE (not implemented) (ext4) */
+ uint16_t e2di_reserved; /* 126: reserved */
+ uint16_t e2di_extra_isize; /* 128: inode extra size (over 128) actually used (ext4) */
+ uint16_t e2di_checksum_high; /* 130: crc BE (not implemented) (ext4) */
+ uint32_t e2di_ctime_extra; /* 132: ctime (nsec << 2 | high epoch) (ext4) */
+ uint32_t e2di_mtime_extra; /* 136: mtime (nsec << 2 | high epoch) (ext4) */
+ uint32_t e2di_atime_extra; /* 140: atime (nsec << 2 | high epoch) (ext4) */
+ uint32_t e2di_crtime; /* 144: creation time (epoch) (ext4) */
+ uint32_t e2di_crtime_extra; /* 148: creation time (nsec << 2 | high epoch) (ext4) */
+ uint32_t e2di_version_high; /* 152: version high (ext4) */
+ uint32_t e2di_projid; /* 156: project id (not implemented) (ext4) */
};
-
/* XXX how does this differ from EXT2_MAXSYMLINKLEN above? */
#define E2MAXSYMLINKLEN ((EXT2FS_NDADDR + EXT2FS_NIADDR) * sizeof(uint32_t))
@@ -171,10 +179,14 @@
#define EXT2_EOFBLOCKS 0x00400000 /* Blocks allocated beyond EOF */
/* Size of on-disk inode. */
-#define EXT2_REV0_DINODE_SIZE sizeof(struct ext2fs_dinode)
+#define EXT2_REV0_DINODE_SIZE 128
#define EXT2_DINODE_SIZE(fs) ((fs)->e2fs.e2fs_rev > E2FS_REV0 ? \
(fs)->e2fs.e2fs_inode_size : \
EXT2_REV0_DINODE_SIZE)
+#define EXT2_DINODE_FITS(dinode, field, isize) (\
+ (isize > EXT2_REV0_DINODE_SIZE) \
+ && ((EXT2_REV0_DINODE_SIZE + (dinode)->e2di_extra_isize) >= offsetof(struct ext2fs_dinode, field) + sizeof((dinode)->field)) \
+ )
/*
* The e2di_blocks fields may be overlaid with other information for
@@ -189,14 +201,14 @@
/* e2fs needs byte swapping on big-endian systems */
#if BYTE_ORDER == LITTLE_ENDIAN
-# define e2fs_iload(old, new) \
- memcpy((new),(old),sizeof(struct ext2fs_dinode))
-# define e2fs_isave(old, new) \
- memcpy((new),(old),sizeof(struct ext2fs_dinode))
+# define e2fs_iload(old, new, isize) \
+ memcpy((new),(old),(isize))
+# define e2fs_isave(old, new, isize) \
+ memcpy((new),(old),(isize))
#else
-void e2fs_i_bswap(struct ext2fs_dinode *, struct ext2fs_dinode *);
-# define e2fs_iload(old, new) e2fs_i_bswap((old), (new))
-# define e2fs_isave(old, new) e2fs_i_bswap((old), (new))
+void e2fs_i_bswap(struct ext2fs_dinode *, struct ext2fs_dinode *, size_t);
+# define e2fs_iload(old, new, isize) e2fs_i_bswap((old), (new))
+# define e2fs_isave(old, new, isize) e2fs_i_bswap((old), (new))
#endif
#endif /* !_UFS_EXT2FS_EXT2FS_DINODE_H_ */
diff -r 7b06fad8818b -r a6a079faa8f1 sys/ufs/ext2fs/ext2fs_inode.c
--- a/sys/ufs/ext2fs/ext2fs_inode.c Wed Aug 03 19:59:57 2016 +0000
+++ b/sys/ufs/ext2fs/ext2fs_inode.c Wed Aug 03 21:53:02 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ext2fs_inode.c,v 1.82 2015/03/28 19:24:04 maxv Exp $ */
+/* $NetBSD: ext2fs_inode.c,v 1.83 2016/08/03 21:53:02 jdolecek Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_inode.c,v 1.82 2015/03/28 19:24:04 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_inode.c,v 1.83 2016/08/03 21:53:02 jdolecek Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -269,7 +269,7 @@
ip->i_flag &= ~(IN_MODIFIED | IN_ACCESSED);
cp = (char *)bp->b_data +
(ino_to_fsbo(fs, ip->i_number) * EXT2_DINODE_SIZE(fs));
- e2fs_isave(ip->i_din.e2fs_din, (struct ext2fs_dinode *)cp);
+ e2fs_isave(ip->i_din.e2fs_din, (struct ext2fs_dinode *)cp, EXT2_DINODE_SIZE(fs));
if ((updflags & (UPDATE_WAIT|UPDATE_DIROP)) != 0 &&
(flags & IN_MODIFIED) != 0 &&
(vp->v_mount->mnt_flag & MNT_ASYNC) == 0)
diff -r 7b06fad8818b -r a6a079faa8f1 sys/ufs/ext2fs/ext2fs_vfsops.c
--- a/sys/ufs/ext2fs/ext2fs_vfsops.c Wed Aug 03 19:59:57 2016 +0000
+++ b/sys/ufs/ext2fs/ext2fs_vfsops.c Wed Aug 03 21:53:02 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ext2fs_vfsops.c,v 1.193 2015/03/28 19:24:04 maxv Exp $ */
+/* $NetBSD: ext2fs_vfsops.c,v 1.194 2016/08/03 21:53:02 jdolecek Exp $ */
/*
* Copyright (c) 1989, 1991, 1993, 1994
@@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.193 2015/03/28 19:24:04 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.194 2016/08/03 21:53:02 jdolecek Exp $");
#if defined(_KERNEL_OPT)
#include "opt_compat_netbsd.h"
@@ -213,7 +213,6 @@
* XXX Same structure as FFS inodes? Should we share a common pool?
*/
struct pool ext2fs_inode_pool;
-struct pool ext2fs_dinode_pool;
extern u_long ext2gennumber;
@@ -223,8 +222,6 @@
pool_init(&ext2fs_inode_pool, sizeof(struct inode), 0, 0, 0,
"ext2fsinopl", &pool_allocator_nointr, IPL_NONE);
- pool_init(&ext2fs_dinode_pool, sizeof(struct ext2fs_dinode), 0, 0, 0,
- "ext2dinopl", &pool_allocator_nointr, IPL_NONE);
ufs_init();
}
@@ -240,7 +237,6 @@
ufs_done();
pool_destroy(&ext2fs_inode_pool);
- pool_destroy(&ext2fs_dinode_pool);
}
/*
@@ -497,6 +493,43 @@
}
/*
+ *
+ */
+static int
+ext2fs_loadvnode_content(struct m_ext2fs *fs, ino_t ino, struct buf *bp, struct inode *ip)
+{
+ struct ext2fs_dinode *din;
+ void *cp;
+ int error = 0;
+
+ cp = (char *)bp->b_data + (ino_to_fsbo(fs, ino) * EXT2_DINODE_SIZE(fs));
+ din = kmem_alloc(EXT2_DINODE_SIZE(fs), KM_SLEEP);
+ e2fs_iload((struct ext2fs_dinode *)cp, din, EXT2_DINODE_SIZE(fs));
+
+ /* sanity checks */
+ if (EXT2_DINODE_FITS(din, e2di_extra_isize, EXT2_DINODE_SIZE(fs))
+ && (EXT2_DINODE_SIZE(fs) - EXT2_REV0_DINODE_SIZE) < din->e2di_extra_isize)
+ {
+ printf("ext2fs: inode %llu bad extra_isize %u",
+ ino, din->e2di_extra_isize);
+ error = EINVAL;
+ goto bad;
+ }
+
+ /* replace old dinode; assumes new dinode size is same as old one */
+ if (ip->i_din.e2fs_din)
+ kmem_free(ip->i_din.e2fs_din, EXT2_DINODE_SIZE(fs));
+ ip->i_din.e2fs_din = din;
+
+ ext2fs_set_inode_guid(ip);
+ return (error);
+
+ bad:
Home |
Main Index |
Thread Index |
Old Index