summaryrefslogtreecommitdiff
path: root/sys/ufs
diff options
context:
space:
mode:
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ext2fs/ext2fs_alloc.c4
-rw-r--r--sys/ufs/ext2fs/ext2fs_extern.h5
-rw-r--r--sys/ufs/ext2fs/ext2fs_inode.c6
-rw-r--r--sys/ufs/ext2fs/ext2fs_subr.c92
-rw-r--r--sys/ufs/ext2fs/ext2fs_vfsops.c22
-rw-r--r--sys/ufs/ext2fs/ext2fs_vnops.c32
-rw-r--r--sys/ufs/ufs/inode.h48
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. */