From 0471133b8de9e6654f7504bd03b6197441d0a247 Mon Sep 17 00:00:00 2001 From: jdolecek Date: Mon, 15 Aug 2016 18:29:34 +0000 Subject: [PATCH] adjust ext2fs_makeinode() so that the direnter is optional, use the function (with the direnter off) in ext2fs_mkdir() instead of the code copy; adjust ext2fs_makeinode() to initialize extra_isize and set creation time, if supported by the filesystem --- sys/ufs/ext2fs/ext2fs_bswap.c | 5 ++- sys/ufs/ext2fs/ext2fs_extern.h | 4 +- sys/ufs/ext2fs/ext2fs_vnops.c | 74 +++++++++++++++++----------------- 3 files changed, 43 insertions(+), 40 deletions(-) diff --git a/sys/ufs/ext2fs/ext2fs_bswap.c b/sys/ufs/ext2fs/ext2fs_bswap.c index 7e72940dadd8..81322506b8a7 100644 --- a/sys/ufs/ext2fs/ext2fs_bswap.c +++ b/sys/ufs/ext2fs/ext2fs_bswap.c @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_bswap.c,v 1.22 2016/08/04 17:43:48 jdolecek Exp $ */ +/* $NetBSD: ext2fs_bswap.c,v 1.23 2016/08/15 18:29:34 jdolecek Exp $ */ /* * Copyright (c) 1997 Manuel Bouyer. @@ -26,7 +26,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ext2fs_bswap.c,v 1.22 2016/08/04 17:43:48 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_bswap.c,v 1.23 2016/08/15 18:29:34 jdolecek Exp $"); #include #include @@ -79,6 +79,7 @@ e2fs_sb_bswap(struct ext2fs *old, struct ext2fs *new) new->e2fs_features_rocompat = bswap32(old->e2fs_features_rocompat); new->e2fs_algo = bswap32(old->e2fs_algo); new->e2fs_reserved_ngdb = bswap16(old->e2fs_reserved_ngdb); + new->e4fs_want_extra_isize = bswap16(old->e4fs_want_extra_isize); } void diff --git a/sys/ufs/ext2fs/ext2fs_extern.h b/sys/ufs/ext2fs/ext2fs_extern.h index 9a2adcc72913..6fe47aca378d 100644 --- a/sys/ufs/ext2fs/ext2fs_extern.h +++ b/sys/ufs/ext2fs/ext2fs_extern.h @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_extern.h,v 1.52 2016/08/09 21:08:02 kre Exp $ */ +/* $NetBSD: ext2fs_extern.h,v 1.53 2016/08/15 18:29:34 jdolecek Exp $ */ /*- * Copyright (c) 1991, 1993, 1994 @@ -176,7 +176,7 @@ int ext2fs_fsync(void *); int ext2fs_vinit(struct mount *, int (**specops)(void *), int (**fifoops)(void *), struct vnode **); int ext2fs_makeinode(int, struct vnode *, struct vnode **, - struct componentname *cnp); + struct componentname *cnp, int); int ext2fs_reclaim(void *); /* ext2fs_hash.c */ diff --git a/sys/ufs/ext2fs/ext2fs_vnops.c b/sys/ufs/ext2fs/ext2fs_vnops.c index 1c4cac46bd63..7c9731dd6f98 100644 --- a/sys/ufs/ext2fs/ext2fs_vnops.c +++ b/sys/ufs/ext2fs/ext2fs_vnops.c @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_vnops.c,v 1.123 2016/08/14 11:44:54 jdolecek Exp $ */ +/* $NetBSD: ext2fs_vnops.c,v 1.124 2016/08/15 18:29:34 jdolecek Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -65,7 +65,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.123 2016/08/14 11:44:54 jdolecek Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_vnops.c,v 1.124 2016/08/15 18:29:34 jdolecek Exp $"); #include #include @@ -136,7 +136,7 @@ ext2fs_create(void *v) error = ext2fs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode), - ap->a_dvp, ap->a_vpp, ap->a_cnp); + ap->a_dvp, ap->a_vpp, ap->a_cnp, 1); if (error) return error; @@ -166,7 +166,7 @@ ext2fs_mknod(void *v) ino_t ino; if ((error = ext2fs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode), - ap->a_dvp, vpp, ap->a_cnp)) != 0) + ap->a_dvp, vpp, ap->a_cnp, 1)) != 0) return error; VN_KNOTE(ap->a_dvp, NOTE_WRITE); ip = VTOI(*vpp); @@ -666,12 +666,11 @@ ext2fs_mkdir(void *v) struct vattr *a_vap; } */ *ap = v; struct vnode *dvp = ap->a_dvp; - struct vattr *vap = ap->a_vap; struct componentname *cnp = ap->a_cnp; struct inode *ip, *dp = VTOI(dvp); struct vnode *tvp; struct ext2fs_dirtemplate dirtemplate; - int error, dmode; + int error; struct ufs_lookup_results *ulr; /* XXX should handle this material another way */ @@ -682,30 +681,17 @@ ext2fs_mkdir(void *v) error = EMLINK; goto out; } - dmode = vap->va_mode & ACCESSPERMS; - dmode |= IFDIR; + /* - * Must simulate part of ext2fs_makeinode here to acquire the inode, - * but not have it entered in the parent directory. The entry is - * made later after writing "." and ".." entries. + * Acquire the inode, but don't sync/direnter it just yet */ - if ((error = ext2fs_valloc(dvp, dmode, cnp->cn_cred, &tvp)) != 0) + error = ext2fs_makeinode(IFDIR | ap->a_vap->va_mode, ap->a_dvp, + &tvp, ap->a_cnp, 0); + if (error) goto out; + + /* the link count is going to be 2 when all is done */ ip = VTOI(tvp); - ip->i_uid = kauth_cred_geteuid(cnp->cn_cred); - ip->i_e2fs_uid = ip->i_uid & 0xffff; - ip->i_e2fs_gid = dp->i_e2fs_gid; - if (ip->i_e2fs->e2fs.e2fs_rev > E2FS_REV0) { - ip->i_e2fs_uid_high = (ip->i_uid >> 16) & 0xffff; - ip->i_e2fs_gid_high = dp->i_e2fs_gid_high; - } else { - ip->i_e2fs_uid_high = 0; - ip->i_e2fs_gid_high = 0; - } - ip->i_gid = ip->i_e2fs_gid | (ip->i_e2fs_gid_high << 16); - ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; - ip->i_e2fs_mode = dmode; - tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */ ip->i_e2fs_nlink = 2; /* @@ -886,7 +872,7 @@ ext2fs_symlink(void *v) vpp = ap->a_vpp; error = ext2fs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp, - vpp, ap->a_cnp); + vpp, ap->a_cnp, 1); if (error) return error; VN_KNOTE(ap->a_dvp, NOTE_WRITE); @@ -1036,7 +1022,7 @@ ext2fs_vinit(struct mount *mntp, int (**specops)(void *), */ int ext2fs_makeinode(int mode, struct vnode *dvp, struct vnode **vpp, - struct componentname *cnp) + struct componentname *cnp, int do_direnter) { struct inode *ip, *pdir; struct vnode *tvp; @@ -1082,14 +1068,30 @@ ext2fs_makeinode(int mode, struct vnode *dvp, struct vnode **vpp, ip->i_e2fs_mode &= ~ISGID; } - /* - * Make sure inode goes to disk before directory entry. - */ - if ((error = ext2fs_update(tvp, NULL, NULL, UPDATE_WAIT)) != 0) - goto bad; - error = ext2fs_direnter(ip, dvp, ulr, cnp); - if (error != 0) - goto bad; + /* Initialize extra_isize according to what is set in superblock */ + if (EXT2F_HAS_ROCOMPAT_FEATURE(ip->i_e2fs, EXT2F_ROCOMPAT_EXTRA_ISIZE) + && EXT2_DINODE_SIZE(ip->i_e2fs) > EXT2_REV0_DINODE_SIZE) { + ip->i_din.e2fs_din->e2di_extra_isize = ip->i_e2fs->e2fs.e4fs_want_extra_isize; + } + + /* Set create time if possible */ + if (EXT2_DINODE_FITS(ip->i_din.e2fs_din, e2di_crtime, EXT2_DINODE_SIZE(ip->i_e2fs))) { + struct timespec now; + vfs_timestamp(&now); + EXT2_DINODE_TIME_SET(&now, ip->i_din.e2fs_din, e2di_crtime, EXT2_DINODE_SIZE(ip->i_e2fs)); + } + + if (do_direnter) { + /* + * Make sure inode goes to disk before directory entry. + */ + if ((error = ext2fs_update(tvp, NULL, NULL, UPDATE_WAIT)) != 0) + goto bad; + error = ext2fs_direnter(ip, dvp, ulr, cnp); + if (error != 0) + goto bad; + } + *vpp = tvp; return 0;