diff options
Diffstat (limited to 'sys/ufs')
-rw-r--r-- | sys/ufs/ext2fs/ext2fs_alloc.c | 4 | ||||
-rw-r--r-- | sys/ufs/ext2fs/ext2fs_extern.h | 5 | ||||
-rw-r--r-- | sys/ufs/ext2fs/ext2fs_inode.c | 6 | ||||
-rw-r--r-- | sys/ufs/ext2fs/ext2fs_subr.c | 92 | ||||
-rw-r--r-- | sys/ufs/ext2fs/ext2fs_vfsops.c | 22 | ||||
-rw-r--r-- | sys/ufs/ext2fs/ext2fs_vnops.c | 32 | ||||
-rw-r--r-- | sys/ufs/ufs/inode.h | 48 |
7 files changed, 149 insertions, 60 deletions
diff --git a/sys/ufs/ext2fs/ext2fs_alloc.c b/sys/ufs/ext2fs/ext2fs_alloc.c index fa2fcb611a7..7992ff86ca2 100644 --- a/sys/ufs/ext2fs/ext2fs_alloc.c +++ b/sys/ufs/ext2fs/ext2fs_alloc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ext2fs_alloc.c,v 1.19 2005/07/03 20:14:01 drahn Exp $ */ +/* $OpenBSD: ext2fs_alloc.c,v 1.20 2005/12/11 20:46:28 pedro Exp $ */ /* $NetBSD: ext2fs_alloc.c,v 1.10 2001/07/05 08:38:27 toshii Exp $ */ /* @@ -170,7 +170,7 @@ ext2fs_inode_alloc(struct inode *pip, mode_t mode, struct ucred *cred, panic("ext2fs_valloc: dup alloc"); } - bzero(&(ip->i_e2din), sizeof(struct ext2fs_dinode)); + bzero(ip->i_e2din, sizeof(struct ext2fs_dinode)); /* * Set up a new generation number for this inode. diff --git a/sys/ufs/ext2fs/ext2fs_extern.h b/sys/ufs/ext2fs/ext2fs_extern.h index 411d4b3e6b9..42b8cdfbb81 100644 --- a/sys/ufs/ext2fs/ext2fs_extern.h +++ b/sys/ufs/ext2fs/ext2fs_extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ext2fs_extern.h,v 1.22 2005/07/28 23:11:25 pedro Exp $ */ +/* $OpenBSD: ext2fs_extern.h,v 1.23 2005/12/11 20:46:28 pedro Exp $ */ /* $NetBSD: ext2fs_extern.h,v 1.1 1997/06/11 09:33:55 bouyer Exp $ */ /*- @@ -52,6 +52,7 @@ struct mbuf; struct componentname; /* extern struct pool ext2fs_inode_pool; */ /* memory pool for inodes */ +extern struct pool ext2fs_dinode_pool; /* memory pool for dinodes */ __BEGIN_DECLS @@ -96,6 +97,8 @@ int ext2fs_checkpath(struct inode *, struct inode *, struct ucred *); /* ext2fs_subr.c */ int ext2fs_bufatoff(struct inode *, off_t, char **, struct buf **); +int ext2fs_vinit(struct mount *, int (**)(void *), int (**)(void *), + struct vnode **); void ext2fs_fragacct(struct m_ext2fs *, int, int32_t[], int); #ifdef DIAGNOSTIC void ext2fs_checkoverlap(struct buf *, struct inode *); diff --git a/sys/ufs/ext2fs/ext2fs_inode.c b/sys/ufs/ext2fs/ext2fs_inode.c index c969759606b..859a2179c9b 100644 --- a/sys/ufs/ext2fs/ext2fs_inode.c +++ b/sys/ufs/ext2fs/ext2fs_inode.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ext2fs_inode.c,v 1.29 2005/10/06 17:43:14 pedro Exp $ */ +/* $OpenBSD: ext2fs_inode.c,v 1.30 2005/12/11 20:46:28 pedro Exp $ */ /* $NetBSD: ext2fs_inode.c,v 1.24 2001/06/19 12:59:18 wiz Exp $ */ /* @@ -200,7 +200,7 @@ ext2fs_update(struct inode *ip, struct timespec *atime, struct timespec *mtime, ip->i_e2fs_uid_high = ip->i_e2fs_uid >> 16; ip->i_e2fs_gid_high = ip->i_e2fs_gid >> 16; - e2fs_isave(&ip->i_e2din, (struct ext2fs_dinode *)cp); + e2fs_isave(ip->i_e2din, (struct ext2fs_dinode *)cp); if (waitfor) return (bwrite(bp)); else { @@ -247,7 +247,7 @@ ext2fs_truncate(struct inode *oip, off_t length, int flags, struct ucred *cred) if (length != 0) panic("ext2fs_truncate: partial truncate of symlink"); #endif - bzero((char *)&oip->i_e2din.e2di_shortlink, + bzero((char *)&oip->i_e2din->e2di_shortlink, (u_int)ext2fs_size(oip)); (void)ext2fs_setsize(oip, 0); oip->i_flag |= IN_CHANGE | IN_UPDATE; diff --git a/sys/ufs/ext2fs/ext2fs_subr.c b/sys/ufs/ext2fs/ext2fs_subr.c index 555b963e3f5..ec7f4f90c5d 100644 --- a/sys/ufs/ext2fs/ext2fs_subr.c +++ b/sys/ufs/ext2fs/ext2fs_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ext2fs_subr.c,v 1.12 2005/07/03 20:14:01 drahn Exp $ */ +/* $OpenBSD: ext2fs_subr.c,v 1.13 2005/12/11 20:46:28 pedro Exp $ */ /* $NetBSD: ext2fs_subr.c,v 1.1 1997/06/11 09:34:03 bouyer Exp $ */ /* @@ -47,6 +47,28 @@ #include <ufs/ext2fs/ext2fs.h> #include <ufs/ext2fs/ext2fs_extern.h> +#include <miscfs/specfs/specdev.h> +#include <miscfs/fifofs/fifo.h> + +union _qcvt { + int64_t qcvt; + int32_t val[2]; +}; + +#define SETHIGH(q, h) { \ + union _qcvt tmp; \ + tmp.qcvt = (q); \ + tmp.val[_QUAD_HIGHWORD] = (h); \ + (q) = tmp.qcvt; \ +} + +#define SETLOW(q, l) { \ + union _qcvt tmp; \ + tmp.qcvt = (q); \ + tmp.val[_QUAD_LOWWORD] = (l); \ + (q) = tmp.qcvt; \ +} + #ifdef _KERNEL /* @@ -112,3 +134,71 @@ ext2fs_checkoverlap(bp, ip) } } #endif /* DIAGNOSTIC */ + +/* + * Initialize the vnode associated with a new inode, handle aliased vnodes. + */ +int +ext2fs_vinit(struct mount *mp, int (**specops)(void *), + int (**fifoops)(void *), struct vnode **vpp) +{ + struct inode *ip; + struct vnode *vp, *nvp; + struct timeval tv; + + vp = *vpp; + ip = VTOI(vp); + vp->v_type = IFTOVT(ip->i_e2fs_mode); + + switch(vp->v_type) { + case VCHR: + case VBLK: + vp->v_op = specops; + + nvp = checkalias(vp, ip->i_e2din->e2di_rdev, mp); + if (nvp != NULL) { + /* + * Discard unneeded vnode, but save its inode. Note + * that the lock is carried over in the inode to the + * replacement vnode. + */ + nvp->v_data = vp->v_data; + vp->v_data = NULL; + vp->v_op = spec_vnodeop_p; +#ifdef VFSDEBUG + vp->v_flag &= ~VLOCKSWORK; +#endif + vrele(vp); + vgone(vp); + /* Reinitialize aliased vnode. */ + vp = nvp; + ip->i_vnode = vp; + } + + break; + + case VFIFO: +#ifdef FIFO + vp->v_op = fifoops; + break; +#else + return (EOPNOTSUPP); +#endif /* FIFO */ + + default: + + break; + } + + if (ip->i_number == EXT2_ROOTINO) + vp->v_flag |= VROOT; + + /* Initialize modrev times */ + getmicrouptime(&tv); + SETHIGH(ip->i_modrev, tv.tv_sec); + SETLOW(ip->i_modrev, tv.tv_usec * 4294); + + *vpp = vp; + + return (0); +} diff --git a/sys/ufs/ext2fs/ext2fs_vfsops.c b/sys/ufs/ext2fs/ext2fs_vfsops.c index e279efcda54..52a8e53b363 100644 --- a/sys/ufs/ext2fs/ext2fs_vfsops.c +++ b/sys/ufs/ext2fs/ext2fs_vfsops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ext2fs_vfsops.c,v 1.41 2005/11/30 10:35:08 pedro Exp $ */ +/* $OpenBSD: ext2fs_vfsops.c,v 1.42 2005/12/11 20:46:28 pedro Exp $ */ /* $NetBSD: ext2fs_vfsops.c,v 1.1 1997/06/11 09:34:07 bouyer Exp $ */ /* @@ -101,6 +101,7 @@ const struct vfsops ext2fs_vfsops = { }; /* struct pool ext2fs_inode_pool; */ +struct pool ext2fs_dinode_pool; extern u_long ext2gennumber; @@ -108,6 +109,9 @@ int ext2fs_init(vfsp) struct vfsconf *vfsp; { + pool_init(&ext2fs_dinode_pool, sizeof(struct ext2fs_dinode), 0, 0, 0, + "ext2dinopl", &pool_allocator_nointr); + return (ufs_init(vfsp)); } @@ -363,7 +367,7 @@ ext2fs_reload_vnode(struct vnode *vp, void *args) { } cp = (caddr_t)bp->b_data + (ino_to_fsbo(era->fs, ip->i_number) * EXT2_DINODE_SIZE); - e2fs_iload((struct ext2fs_dinode *)cp, &ip->i_e2din); + e2fs_iload((struct ext2fs_dinode *)cp, ip->i_e2din); brelse(bp); vput(vp); return (0); @@ -831,6 +835,7 @@ ext2fs_vget(mp, ino, vpp) { register struct m_ext2fs *fs; register struct inode *ip; + struct ext2fs_dinode *dp; struct ufsmount *ump; struct buf *bp; struct vnode *vp; @@ -893,8 +898,12 @@ ext2fs_vget(mp, ino, vpp) *vpp = NULL; return (error); } - bcopy(((struct ext2fs_dinode*)bp->b_data + ino_to_fsbo(fs, ino)), - &ip->i_e2din, sizeof(struct ext2fs_dinode)); + + dp = (struct ext2fs_dinode *) bp->b_data + ino_to_fsbo(fs, ino); + ip->i_e2din = pool_get(&ext2fs_dinode_pool, PR_WAITOK); + e2fs_iload(dp, ip->i_e2din); + brelse(bp); + ip->i_effnlink = ip->i_e2fs_nlink; /* @@ -908,8 +917,6 @@ ext2fs_vget(mp, ino, vpp) ip->i_e2fs_uid = ip->i_e2fs_uid_low | (ip->i_e2fs_uid_high << 16); ip->i_e2fs_gid = ip->i_e2fs_gid_low | (ip->i_e2fs_gid_high << 16); - brelse(bp); - /* If the inode was deleted, reset all fields */ if (ip->i_e2fs_dtime != 0) { ip->i_e2fs_mode = ip->i_e2fs_nblock = 0; @@ -920,12 +927,13 @@ ext2fs_vget(mp, ino, vpp) * Initialize the vnode from the inode, check for aliases. * Note that the underlying vnode may have changed. */ - error = ufs_vinit(mp, ext2fs_specop_p, EXT2FS_FIFOOPS, &vp); + error = ext2fs_vinit(mp, ext2fs_specop_p, EXT2FS_FIFOOPS, &vp); if (error) { vput(vp); *vpp = NULL; return (error); } + /* * Finish inode initialization now that aliasing has been resolved. */ diff --git a/sys/ufs/ext2fs/ext2fs_vnops.c b/sys/ufs/ext2fs/ext2fs_vnops.c index 818c56126b1..c4faaf63dec 100644 --- a/sys/ufs/ext2fs/ext2fs_vnops.c +++ b/sys/ufs/ext2fs/ext2fs_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ext2fs_vnops.c,v 1.41 2005/08/14 12:41:44 pedro Exp $ */ +/* $OpenBSD: ext2fs_vnops.c,v 1.42 2005/12/11 20:46:28 pedro Exp $ */ /* $NetBSD: ext2fs_vnops.c,v 1.1 1997/06/11 09:34:09 bouyer Exp $ */ /* @@ -70,27 +70,9 @@ #include <ufs/ext2fs/ext2fs_extern.h> #include <ufs/ext2fs/ext2fs_dir.h> - static int ext2fs_chmod(struct vnode *, mode_t, struct ucred *, struct proc *); static int ext2fs_chown(struct vnode *, uid_t, gid_t, struct ucred *, struct proc *); -union _qcvt { - int64_t qcvt; - int32_t val[2]; -}; -#define SETHIGH(q, h) { \ - union _qcvt tmp; \ - tmp.qcvt = (q); \ - tmp.val[_QUAD_HIGHWORD] = (h); \ - (q) = tmp.qcvt; \ -} -#define SETLOW(q, l) { \ - union _qcvt tmp; \ - tmp.qcvt = (q); \ - tmp.val[_QUAD_LOWWORD] = (l); \ - (q) = tmp.qcvt; \ -} - /* * Create a regular file */ @@ -139,7 +121,7 @@ ext2fs_mknod(v) * Want to be able to use this to make badblock * inodes, so don't truncate the dev number. */ - ip->i_e2din.e2di_rdev = h2fs32(vap->va_rdev); + ip->i_e2din->e2di_rdev = h2fs32(vap->va_rdev); } /* * Remove inode so that it will be reloaded by VFS_VGET and @@ -228,7 +210,7 @@ ext2fs_getattr(v) vap->va_nlink = ip->i_e2fs_nlink; vap->va_uid = ip->i_e2fs_uid; vap->va_gid = ip->i_e2fs_gid; - vap->va_rdev = (dev_t)fs2h32(ip->i_e2din.e2di_rdev); + vap->va_rdev = (dev_t)fs2h32(ip->i_e2din->e2di_rdev); vap->va_size = ext2fs_size(ip); vap->va_atime.tv_sec = ip->i_e2fs_atime; vap->va_atime.tv_nsec = 0; @@ -1184,7 +1166,7 @@ ext2fs_symlink(v) len = strlen(ap->a_target); if (len < vp->v_mount->mnt_maxsymlinklen) { ip = VTOI(vp); - bcopy(ap->a_target, (char *)ip->i_e2din.e2di_shortlink, len); + bcopy(ap->a_target, (char *)ip->i_e2din->e2di_shortlink, len); error = ext2fs_setsize(ip, len); if (error) goto bad; @@ -1217,7 +1199,7 @@ ext2fs_readlink(v) isize = ext2fs_size(ip); if (isize < vp->v_mount->mnt_maxsymlinklen || (vp->v_mount->mnt_maxsymlinklen == 0 && ip->i_e2fs_nblock == 0)) { - uiomove((char *)ip->i_e2din.e2di_shortlink, isize, ap->a_uio); + uiomove((char *)ip->i_e2din->e2di_shortlink, isize, ap->a_uio); return (0); } return (VOP_READ(vp, ap->a_uio, 0, ap->a_cred)); @@ -1363,7 +1345,11 @@ ext2fs_reclaim(v) if (ip->i_devvp) vrele(ip->i_devvp); + if (ip->i_e2din != NULL) + pool_put(&ext2fs_dinode_pool, ip->i_e2din); + FREE(vp->v_data, M_EXT2FSNODE); + vp->v_data = NULL; return (0); diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h index 70e09eea1d4..fead61b28ce 100644 --- a/sys/ufs/ufs/inode.h +++ b/sys/ufs/ufs/inode.h @@ -1,4 +1,4 @@ -/* $OpenBSD: inode.h,v 1.28 2005/10/06 17:43:14 pedro Exp $ */ +/* $OpenBSD: inode.h,v 1.29 2005/12/11 20:46:28 pedro Exp $ */ /* $NetBSD: inode.h,v 1.8 1995/06/15 23:22:50 cgd Exp $ */ /* @@ -102,6 +102,7 @@ struct inode { struct ext2fs_inode_ext e2fs; struct dirhash *dirhash; } inode_ext; + #define i_e2fs_last_lblk inode_ext.e2fs.ext2fs_last_lblk #define i_e2fs_last_blk inode_ext.e2fs.ext2fs_last_blk #define i_e2fs_uid inode_ext.e2fs.ext2fs_effective_uid @@ -112,9 +113,10 @@ struct inode { * The on-disk dinode itself. */ union { - struct ufs1_dinode ffs1_din; - struct ext2fs_dinode e2fs_din; + struct ufs1_dinode ffs1_din; + struct ext2fs_dinode *e2fs_din; } dinode_u; + #define i_din1 dinode_u.ffs1_din #define i_e2din dinode_u.e2fs_din @@ -204,26 +206,26 @@ struct inode_vtbl { #define i_uid i_din1.di_uid #endif /* _KERNEL */ -#define i_e2fs_mode i_e2din.e2di_mode -#define i_e2fs_size i_e2din.e2di_size -#define i_e2fs_atime i_e2din.e2di_atime -#define i_e2fs_ctime i_e2din.e2di_ctime -#define i_e2fs_mtime i_e2din.e2di_mtime -#define i_e2fs_dtime i_e2din.e2di_dtime -#define i_e2fs_nlink i_e2din.e2di_nlink -#define i_e2fs_nblock i_e2din.e2di_nblock -#define i_e2fs_flags i_e2din.e2di_flags -#define i_e2fs_blocks i_e2din.e2di_blocks -#define i_e2fs_gen i_e2din.e2di_gen -#define i_e2fs_facl i_e2din.e2di_facl -#define i_e2fs_dacl i_e2din.e2di_dacl -#define i_e2fs_faddr i_e2din.e2di_faddr -#define i_e2fs_nfrag i_e2din.e2di_nfrag -#define i_e2fs_fsize i_e2din.e2di_fsize -#define i_e2fs_uid_low i_e2din.e2di_uid_low -#define i_e2fs_gid_low i_e2din.e2di_gid_low -#define i_e2fs_uid_high i_e2din.e2di_uid_high -#define i_e2fs_gid_high i_e2din.e2di_gid_high +#define i_e2fs_mode i_e2din->e2di_mode +#define i_e2fs_size i_e2din->e2di_size +#define i_e2fs_atime i_e2din->e2di_atime +#define i_e2fs_ctime i_e2din->e2di_ctime +#define i_e2fs_mtime i_e2din->e2di_mtime +#define i_e2fs_dtime i_e2din->e2di_dtime +#define i_e2fs_nlink i_e2din->e2di_nlink +#define i_e2fs_nblock i_e2din->e2di_nblock +#define i_e2fs_flags i_e2din->e2di_flags +#define i_e2fs_blocks i_e2din->e2di_blocks +#define i_e2fs_gen i_e2din->e2di_gen +#define i_e2fs_facl i_e2din->e2di_facl +#define i_e2fs_dacl i_e2din->e2di_dacl +#define i_e2fs_faddr i_e2din->e2di_faddr +#define i_e2fs_nfrag i_e2din->e2di_nfrag +#define i_e2fs_fsize i_e2din->e2di_fsize +#define i_e2fs_uid_low i_e2din->e2di_uid_low +#define i_e2fs_gid_low i_e2din->e2di_gid_low +#define i_e2fs_uid_high i_e2din->e2di_uid_high +#define i_e2fs_gid_high i_e2din->e2di_gid_high /* These flags are kept in i_flag. */ #define IN_ACCESS 0x0001 /* Access time update request. */ |