summaryrefslogtreecommitdiff
path: root/sys/ufs
diff options
context:
space:
mode:
authorJason Downs <downsj@cvs.openbsd.org>1996-06-24 03:35:06 +0000
committerJason Downs <downsj@cvs.openbsd.org>1996-06-24 03:35:06 +0000
commit3dd058744292725ea73c1c76b15e1bd7f2e9fd6b (patch)
tree3e7b8d92fb269421a7073e97583d1422fec7dff1 /sys/ufs
parent4fd419c58bfe70b818aa4e53892254bc7f46212e (diff)
ufs changes: add the notion of directory operators.
gnu/ext2fs: add the second extended filesystem. Note that I'm commiting this now for the sake of the ufs changes; ext2fs is not yet fully integrated into the system.
Diffstat (limited to 'sys/ufs')
-rw-r--r--sys/ufs/ffs/ffs_vfsops.c12
-rw-r--r--sys/ufs/lfs/lfs_vfsops.c11
-rw-r--r--sys/ufs/ufs/dir.h22
-rw-r--r--sys/ufs/ufs/inode.h11
-rw-r--r--sys/ufs/ufs/ufs_readwrite.c35
-rw-r--r--sys/ufs/ufs/ufs_vnops.c65
-rw-r--r--sys/ufs/ufs/ufsmount.h6
7 files changed, 142 insertions, 20 deletions
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index eecb3c01d98..4cba7974dd2 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ffs_vfsops.c,v 1.4 1996/02/27 07:27:39 niklas Exp $ */
+/* $OpenBSD: ffs_vfsops.c,v 1.5 1996/06/24 03:35:01 downsj Exp $ */
/* $NetBSD: ffs_vfsops.c,v 1.19 1996/02/09 22:22:26 christos Exp $ */
/*
@@ -57,6 +57,7 @@
#include <ufs/ufs/quota.h>
#include <ufs/ufs/ufsmount.h>
#include <ufs/ufs/inode.h>
+#include <ufs/ufs/dir.h>
#include <ufs/ufs/ufs_extern.h>
#include <ufs/ffs/fs.h>
@@ -79,6 +80,14 @@ struct vfsops ffs_vfsops = {
ffs_init,
};
+static struct ufs_dirops ffs_dirops = {
+ ufs_dirremove,
+ ufs_direnter,
+ ufs_dirempty,
+ ufs_dirrewrite,
+ ufs_checkpath,
+};
+
extern u_long nextgennumber;
/*
@@ -794,6 +803,7 @@ ffs_vget(mp, ino, vpp)
ip->i_fs = fs = ump->um_fs;
ip->i_dev = dev;
ip->i_number = ino;
+ ip->i_dirops = &ffs_dirops;
#ifdef QUOTA
{
int i;
diff --git a/sys/ufs/lfs/lfs_vfsops.c b/sys/ufs/lfs/lfs_vfsops.c
index b0cd531d1a0..b000bd4b019 100644
--- a/sys/ufs/lfs/lfs_vfsops.c
+++ b/sys/ufs/lfs/lfs_vfsops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: lfs_vfsops.c,v 1.3 1996/04/21 22:32:45 deraadt Exp $ */
+/* $OpenBSD: lfs_vfsops.c,v 1.4 1996/06/24 03:35:02 downsj Exp $ */
/* $NetBSD: lfs_vfsops.c,v 1.11 1996/03/25 12:53:35 pk Exp $ */
/*
@@ -79,6 +79,14 @@ struct vfsops lfs_vfsops = {
lfs_init,
};
+static struct ufs_dirops lfs_dirops = {
+ ufs_dirremove,
+ ufs_direnter,
+ ufs_dirempty,
+ ufs_dirrewrite,
+ ufs_checkpath,
+};
+
int
lfs_mountroot()
{
@@ -515,6 +523,7 @@ lfs_vget(mp, ino, vpp)
* Ask Kirk.
*/
ip->i_lfs = ump->um_lfs;
+ ip->i_dirops = &lfs_dirops;
/* Read in the disk contents for the inode, copy into the inode. */
error = bread(ump->um_devvp, daddr, (int)fs->lfs_bsize, NOCRED, &bp);
diff --git a/sys/ufs/ufs/dir.h b/sys/ufs/ufs/dir.h
index c4c15041009..6d1178474ce 100644
--- a/sys/ufs/ufs/dir.h
+++ b/sys/ufs/ufs/dir.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: dir.h,v 1.2 1996/04/19 16:10:44 niklas Exp $ */
+/* $OpenBSD: dir.h,v 1.3 1996/06/24 03:35:03 downsj Exp $ */
/* $NetBSD: dir.h,v 1.8 1996/03/09 19:42:41 scottr Exp $ */
/*
@@ -155,4 +155,24 @@ struct odirtemplate {
u_int16_t dotdot_namlen;
char dotdot_name[4]; /* ditto */
};
+
+/*
+ * For lack of a better place...
+ *
+ * This structure defines a set of function pointers, for managing rouge
+ * ufs-like filesystems in vnop code. Most have to do with directories.
+ */
+
+struct inode;
+struct ufs_dirops {
+ int (*dirremove) __P((struct vnode *, struct componentname *));
+ int (*direnter) __P((struct inode *, struct vnode *,
+ struct componentname *));
+ int (*dirempty) __P((struct inode *, ino_t, struct ucred *));
+ int (*dirrewrite) __P((struct inode *, struct inode *,
+ struct componentname *));
+ int (*checkpath) __P((struct inode *, struct inode *,
+ struct ucred *));
+};
+
#endif /* !_DIR_H_ */
diff --git a/sys/ufs/ufs/inode.h b/sys/ufs/ufs/inode.h
index b9e298d9250..121f045925a 100644
--- a/sys/ufs/ufs/inode.h
+++ b/sys/ufs/ufs/inode.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: inode.h,v 1.2 1996/06/24 03:35:03 downsj Exp $ */
/* $NetBSD: inode.h,v 1.8 1995/06/15 23:22:50 cgd Exp $ */
/*
@@ -62,11 +63,13 @@ struct inode {
ino_t i_number; /* The identity of the inode. */
union { /* Associated filesystem. */
- struct fs *fs; /* FFS */
- struct lfs *lfs; /* LFS */
+ struct fs *fs; /* FFS */
+ struct lfs *lfs; /* LFS */
+ struct ext2_sb_info *e2fs; /* EXT2FS */
} inode_u;
#define i_fs inode_u.fs
#define i_lfs inode_u.lfs
+#define i_e2fs inode_u.e2fs
struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
u_quad_t i_modrev; /* Revision level for NFS lease. */
@@ -83,6 +86,10 @@ struct inode {
ino_t i_ino; /* Inode number of found directory. */
u_int32_t i_reclen; /* Size of found directory entry. */
/*
+ * Directory operations pointers.
+ */
+ struct ufs_dirops *i_dirops;
+ /*
* The on-disk dinode itself.
*/
struct dinode i_din; /* 128 bytes of the on-disk dinode. */
diff --git a/sys/ufs/ufs/ufs_readwrite.c b/sys/ufs/ufs/ufs_readwrite.c
index 04795457609..bf65f80974b 100644
--- a/sys/ufs/ufs/ufs_readwrite.c
+++ b/sys/ufs/ufs/ufs_readwrite.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ufs_readwrite.c,v 1.3 1996/05/22 11:47:21 deraadt Exp $ */
+/* $OpenBSD: ufs_readwrite.c,v 1.4 1996/06/24 03:35:04 downsj Exp $ */
/* $NetBSD: ufs_readwrite.c,v 1.9 1996/05/11 18:27:57 mycroft Exp $ */
/*-
@@ -36,6 +36,11 @@
* @(#)ufs_readwrite.c 8.8 (Berkeley) 8/4/94
*/
+/*
+ * ext2fs support added to this module by Jason Downs, based on Godmar Back's
+ * original ext2_readwrite.c.
+ */
+
#ifdef LFS_READWRITE
#define BLKSIZE(a, b, c) blksize(a)
#define FS struct lfs
@@ -47,6 +52,17 @@
#define fs_bsize lfs_bsize
#define fs_maxfilesize lfs_maxfilesize
#else
+#ifdef EXT2_READWRITE
+#define BLKSIZE(a, b, c) blksize(a, b, c)
+#define FS struct ext2_sb_info
+#define I_FS i_e2fs
+#define READ ext2_read
+#define READ_S "ext2_read"
+#define WRITE ext2_write
+#define WRITE_S "ext2_write"
+#define fs_bsize s_frag_size
+#define MAXFILESIZE ((u_int64_t)0x80000000 * fs->s_frag_size - 1)
+#else
#define BLKSIZE(a, b, c) blksize(a, b, c)
#define FS struct fs
#define I_FS i_fs
@@ -55,6 +71,7 @@
#define WRITE ffs_write
#define WRITE_S "ffs_write"
#endif
+#endif
/*
* Vnode op for reading.
@@ -99,7 +116,11 @@ READ(v)
panic("%s: type %d", READ_S, vp->v_type);
#endif
fs = ip->I_FS;
+#ifdef EXT2_READWRITE
+ if ((u_int64_t)uio->uio_offset > MAXFILESIZE)
+#else
if ((u_int64_t)uio->uio_offset > fs->fs_maxfilesize)
+#endif
return (EFBIG);
for (error = 0, bp = NULL; uio->uio_resid > 0; bp = NULL) {
@@ -119,7 +140,11 @@ READ(v)
(void)lfs_check(vp, lbn);
error = cluster_read(vp, ip->i_size, lbn, size, NOCRED, &bp);
#else
+#ifdef EXT2_READWRITE
+ if (lblktosize(fs, nextlbn) > ip->i_size)
+#else
if (lblktosize(fs, nextlbn) >= ip->i_size)
+#endif
error = bread(vp, lbn, size, NOCRED, &bp);
else if (doclusterread)
error = cluster_read(vp,
@@ -213,7 +238,11 @@ WRITE(v)
fs = ip->I_FS;
if (uio->uio_offset < 0 ||
+#ifdef EXT2_READWRITE
+ (u_int64_t)uio->uio_offset + uio->uio_resid > MAXFILESIZE)
+#else
(u_int64_t)uio->uio_offset + uio->uio_resid > fs->fs_maxfilesize)
+#endif
return (EFBIG);
/*
* Maybe this should be above the vnode op call, but so long as
@@ -246,7 +275,11 @@ WRITE(v)
else
flags &= ~B_CLRBUF;
+#ifdef EXT2_READWRITE
+ error = ext2_balloc(ip,
+#else
error = ffs_balloc(ip,
+#endif
lbn, blkoffset + xfersize, ap->a_cred, &bp, flags);
#endif
if (error)
diff --git a/sys/ufs/ufs/ufs_vnops.c b/sys/ufs/ufs/ufs_vnops.c
index f78258249fa..80bc2beac92 100644
--- a/sys/ufs/ufs/ufs_vnops.c
+++ b/sys/ufs/ufs/ufs_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ufs_vnops.c,v 1.4 1996/05/22 11:47:22 deraadt Exp $ */
+/* $OpenBSD: ufs_vnops.c,v 1.5 1996/06/24 03:35:04 downsj Exp $ */
/* $NetBSD: ufs_vnops.c,v 1.18 1996/05/11 18:28:04 mycroft Exp $ */
/*
@@ -72,6 +72,12 @@ static int ufs_chmod __P((struct vnode *, int, struct ucred *, struct proc *));
static int ufs_chown
__P((struct vnode *, uid_t, gid_t, struct ucred *, struct proc *));
+#ifdef EXT2FS
+#include <gnu/ext2fs/ext2_extern.h>
+#include <gnu/ext2fs/ext2_fs.h>
+#include <gnu/ext2fs/ext2_fs_sb.h>
+#endif /* EXT2FS */
+
union _qcvt {
int64_t qcvt;
int32_t val[2];
@@ -627,7 +633,8 @@ ufs_remove(v)
error = EPERM;
goto out;
}
- if ((error = ufs_dirremove(dvp, ap->a_cnp)) == 0) {
+ error = VTOI(dvp)->i_dirops->dirremove(dvp, ap->a_cnp);
+ if (error == 0) {
ip->i_nlink--;
ip->i_flag |= IN_CHANGE;
}
@@ -693,7 +700,8 @@ ufs_link(v)
TIMEVAL_TO_TIMESPEC(&time, &ts);
error = VOP_UPDATE(vp, &ts, &ts, 1);
if (!error)
- error = ufs_direnter(ip, dvp, cnp);
+ error = VTOI(dvp)->i_dirops->direnter(ip, dvp, cnp);
+
if (error) {
ip->i_nlink--;
ip->i_flag |= IN_CHANGE;
@@ -938,7 +946,8 @@ abortit:
goto bad;
if (xp != NULL)
vput(tvp);
- if ((error = ufs_checkpath(ip, dp, tcnp->cn_cred)) != 0)
+ error = VTOI(tdvp)->i_dirops->checkpath(ip, dp, tcnp->cn_cred);
+ if (error != 0)
goto out;
if ((tcnp->cn_flags & SAVESTART) == 0)
panic("ufs_rename: lost to startdir");
@@ -974,7 +983,8 @@ abortit:
if ((error = VOP_UPDATE(tdvp, &ts, &ts, 1)) != 0)
goto bad;
}
- if ((error = ufs_direnter(ip, tdvp, tcnp)) != 0) {
+ error = VTOI(tdvp)->i_dirops->direnter(ip, tdvp, tcnp);
+ if (error != 0) {
if (doingdirectory && newparent) {
dp->i_nlink--;
dp->i_flag |= IN_CHANGE;
@@ -1009,7 +1019,8 @@ abortit:
* (both directories, or both not directories).
*/
if ((xp->i_mode&IFMT) == IFDIR) {
- if (!ufs_dirempty(xp, dp->i_number, tcnp->cn_cred) ||
+ if (! xp->i_dirops->dirempty
+ (xp, dp->i_number, tcnp->cn_cred) ||
xp->i_nlink > 2) {
error = ENOTEMPTY;
goto bad;
@@ -1023,7 +1034,8 @@ abortit:
error = EISDIR;
goto bad;
}
- if ((error = ufs_dirrewrite(dp, ip, tcnp)) != 0)
+ error = dp->i_dirops->dirrewrite(dp, ip, tcnp);
+ if (error != 0)
goto bad;
/*
* If the target directory is in the same
@@ -1114,6 +1126,11 @@ abortit:
# else
namlen = dirbuf.dotdot_namlen;
# endif
+#ifdef EXT2FS
+ if(IS_EXT2_VNODE(fvp))
+ namlen = ((struct odirtemplate *)
+ &dirbuf)->dotdot_namlen;
+#endif /* EXT2FS */
if (namlen != 2 ||
dirbuf.dotdot_name[0] != '.' ||
dirbuf.dotdot_name[1] != '.') {
@@ -1132,7 +1149,7 @@ abortit:
}
}
}
- error = ufs_dirremove(fdvp, fcnp);
+ error = VTOI(fdvp)->i_dirops->dirremove(fdvp, fcnp);
if (!error) {
xp->i_nlink--;
xp->i_flag |= IN_CHANGE;
@@ -1248,13 +1265,28 @@ ufs_mkdir(v)
goto bad;
/* Initialize directory with "." and ".." from static template. */
- if (dvp->v_mount->mnt_maxsymlinklen > 0)
+ if (dvp->v_mount->mnt_maxsymlinklen > 0
+#ifdef EXT2FS
+ /* omastertemplate is want we want for EXT2 */
+ && !IS_EXT2_VNODE(dvp)
+#endif /* EXT2FS */
+ )
dtp = &mastertemplate;
else
dtp = (struct dirtemplate *)&omastertemplate;
dirtemplate = *dtp;
dirtemplate.dot_ino = ip->i_number;
dirtemplate.dotdot_ino = dp->i_number;
+#ifdef EXT2FS
+ /* note that in ext2 DIRBLKSIZ == blocksize, not DEV_BSIZE
+ * so let's just redefine it - for this function only
+ */
+#undef DIRBLKSIZ
+#define DIRBLKSIZ (IS_EXT2_VNODE(dvp) ? \
+ VTOI(dvp)->i_e2fs->s_blocksize : DEV_BSIZE)
+ if(IS_EXT2_VNODE(dvp))
+ dirtemplate.dotdot_reclen = DIRBLKSIZ - 12;
+#endif /* EXT2FS */
error = vn_rdwr(UIO_WRITE, tvp, (caddr_t)&dirtemplate,
sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE,
IO_NODELOCKED|IO_SYNC, cnp->cn_cred, (int *)0, (struct proc *)0);
@@ -1271,7 +1303,8 @@ ufs_mkdir(v)
}
/* Directory set up, now install it's entry in the parent directory. */
- if ((error = ufs_direnter(ip, dvp, cnp)) != 0) {
+ error = VTOI(dvp)->i_dirops->direnter(ip, dvp, cnp);
+ if (error != 0) {
dp->i_nlink--;
dp->i_flag |= IN_CHANGE;
}
@@ -1290,6 +1323,10 @@ out:
FREE(cnp->cn_pnbuf, M_NAMEI);
vput(dvp);
return (error);
+#ifdef EXT2FS
+#undef DIRBLKSIZ
+#define DIRBLKSIZ DEV_BSIZE
+#endif /* EXT2FS */
}
/*
@@ -1329,7 +1366,7 @@ ufs_rmdir(v)
*/
error = 0;
if (ip->i_nlink != 2 ||
- !ufs_dirempty(ip, dp->i_number, cnp->cn_cred)) {
+ !ip->i_dirops->dirempty(ip, dp->i_number, cnp->cn_cred)) {
error = ENOTEMPTY;
goto out;
}
@@ -1342,7 +1379,8 @@ ufs_rmdir(v)
* inode. If we crash in between, the directory
* will be reattached to lost+found,
*/
- if ((error = ufs_dirremove(dvp, cnp)) != 0)
+ error = VTOI(dvp)->i_dirops->dirremove(dvp, cnp);
+ if (error != 0)
goto out;
dp->i_nlink--;
dp->i_flag |= IN_CHANGE;
@@ -2044,7 +2082,8 @@ ufs_makeinode(mode, dvp, vpp, cnp)
TIMEVAL_TO_TIMESPEC(&time, &ts);
if ((error = VOP_UPDATE(tvp, &ts, &ts, 1)) != 0)
goto bad;
- if ((error = ufs_direnter(ip, dvp, cnp)) != 0)
+ error = VTOI(dvp)->i_dirops->direnter(ip, dvp, cnp);
+ if (error != 0)
goto bad;
if ((cnp->cn_flags & SAVESTART) == 0)
FREE(cnp->cn_pnbuf, M_NAMEI);
diff --git a/sys/ufs/ufs/ufsmount.h b/sys/ufs/ufs/ufsmount.h
index 5a605812971..1c7c0c6f192 100644
--- a/sys/ufs/ufs/ufsmount.h
+++ b/sys/ufs/ufs/ufsmount.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: ufsmount.h,v 1.2 1996/06/24 03:35:05 downsj Exp $ */
/* $NetBSD: ufsmount.h,v 1.4 1994/12/21 20:00:23 mycroft Exp $ */
/*
@@ -51,11 +52,14 @@ struct ufsmount {
struct vnode *um_devvp; /* block device mounted vnode */
union { /* pointer to superblock */
- struct lfs *lfs; /* LFS */
struct fs *fs; /* FFS */
+ struct lfs *lfs; /* LFS */
+ struct ext2_sb_info *e2fs; /* EXT2FS */
} ufsmount_u;
#define um_fs ufsmount_u.fs
#define um_lfs ufsmount_u.lfs
+#define um_e2fs ufsmount_u.e2fs
+#define um_e2fsb ufsmount_u.e2fs->s_es
struct vnode *um_quotas[MAXQUOTAS]; /* pointer to quota files */
struct ucred *um_cred[MAXQUOTAS]; /* quota file access cred */