summaryrefslogtreecommitdiffstats
path: root/sys/gnu/ext2fs/ext2_vfsops.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/gnu/ext2fs/ext2_vfsops.c')
-rw-r--r--sys/gnu/ext2fs/ext2_vfsops.c193
1 files changed, 101 insertions, 92 deletions
diff --git a/sys/gnu/ext2fs/ext2_vfsops.c b/sys/gnu/ext2fs/ext2_vfsops.c
index 54c4305..b9afe91 100644
--- a/sys/gnu/ext2fs/ext2_vfsops.c
+++ b/sys/gnu/ext2fs/ext2_vfsops.c
@@ -40,8 +40,6 @@
* $FreeBSD$
*/
-#include "opt_quota.h"
-
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/namei.h>
@@ -57,12 +55,8 @@
#include <sys/stat.h>
#include <sys/mutex.h>
-#include <ufs/ufs/extattr.h>
-#include <ufs/ufs/quota.h>
-#include <ufs/ufs/ufsmount.h>
-#include <ufs/ufs/inode.h>
-#include <ufs/ufs/ufs_extern.h>
-
+#include <gnu/ext2fs/ext2_mount.h>
+#include <gnu/ext2fs/inode.h>
#include <gnu/ext2fs/fs.h>
#include <gnu/ext2fs/ext2_extern.h>
@@ -71,26 +65,29 @@
static int ext2_fhtovp(struct mount *, struct fid *, struct vnode **);
static int ext2_flushfiles(struct mount *mp, int flags, struct thread *td);
+static int ext2_init(struct vfsconf *);
static int ext2_mount(struct mount *,
char *, caddr_t, struct nameidata *, struct thread *);
static int ext2_mountfs(struct vnode *, struct mount *, struct thread *);
static int ext2_reload(struct mount *mountp, struct ucred *cred,
struct thread *td);
-static int ext2_sbupdate(struct ufsmount *, int);
+static int ext2_root(struct mount *, struct vnode **vpp);
+static int ext2_sbupdate(struct ext2mount *, int);
static int ext2_statfs(struct mount *, struct statfs *, struct thread *);
static int ext2_sync(struct mount *, int, struct ucred *, struct thread *);
static int ext2_unmount(struct mount *, int, struct thread *);
static int ext2_vget(struct mount *, ino_t, int, struct vnode **);
static int ext2_vptofh(struct vnode *, struct fid *);
-static MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part");
+MALLOC_DEFINE(M_EXT2NODE, "EXT2 node", "EXT2 vnode private part");
+static MALLOC_DEFINE(M_EXT2MNT, "EXT2 mount", "EXT2 mount structure");
static struct vfsops ext2fs_vfsops = {
ext2_mount,
- ufs_start, /* empty function */
+ vfs_stdstart,
ext2_unmount,
- ufs_root, /* root inode via vget */
- ufs_quotactl, /* does operations associated with quotas */
+ ext2_root, /* root inode via vget */
+ vfs_stdquotactl,
ext2_statfs,
ext2_sync,
ext2_vget,
@@ -129,7 +126,7 @@ ext2_mountroot()
register struct ext2_sb_info *fs;
register struct mount *mp;
struct thread *td = curthread;
- struct ufsmount *ump;
+ struct ext2mount *ump;
u_int size;
int error;
@@ -155,7 +152,7 @@ ext2_mountroot()
TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list);
mp->mnt_flag |= MNT_ROOTFS;
mp->mnt_vnodecovered = NULLVP;
- ump = VFSTOUFS(mp);
+ ump = VFSTOEXT2(mp);
fs = ump->um_e2fs;
bzero(fs->fs_fsmnt, sizeof(fs->fs_fsmnt));
fs->fs_fsmnt[0] = '/';
@@ -180,13 +177,13 @@ static int
ext2_mount(mp, path, data, ndp, td)
register struct mount *mp;
char *path;
- caddr_t data; /* this is actually a (struct ufs_args *) */
+ caddr_t data; /* this is actually a (struct ext2_args *) */
struct nameidata *ndp;
struct thread *td;
{
struct vnode *devvp;
- struct ufs_args args;
- struct ufsmount *ump = 0;
+ struct ext2_args args;
+ struct ext2mount *ump = 0;
register struct ext2_sb_info *fs;
size_t size;
int error, flags;
@@ -195,7 +192,7 @@ ext2_mount(mp, path, data, ndp, td)
/* Double-check the length of path.. */
if (strlen(path) >= MAXMNTLEN - 1)
return (ENAMETOOLONG);
- error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args));
+ error = copyin(data, (caddr_t)&args, sizeof (struct ext2_args));
if (error != 0)
return (error);
/*
@@ -203,7 +200,7 @@ ext2_mount(mp, path, data, ndp, td)
* read/write; if there is no device name, that's all we do.
*/
if (mp->mnt_flag & MNT_UPDATE) {
- ump = VFSTOUFS(mp);
+ ump = VFSTOEXT2(mp);
fs = ump->um_e2fs;
error = 0;
if (fs->s_rd_only == 0 && (mp->mnt_flag & MNT_RDONLY)) {
@@ -310,7 +307,7 @@ ext2_mount(mp, path, data, ndp, td)
vrele(devvp);
return (error);
}
- ump = VFSTOUFS(mp);
+ ump = VFSTOEXT2(mp);
fs = ump->um_e2fs;
/*
* Note that this strncpy() is ok because of a check at the start
@@ -466,7 +463,7 @@ static int compute_sb_data(devvp, es, fs)
V(s_db_per_group)
fs->s_group_desc = bsd_malloc(db_count * sizeof (struct buf *),
- M_UFSMNT, M_WAITOK);
+ M_EXT2MNT, M_WAITOK);
/* adjust logic_sb_block */
if(fs->s_blocksize > SBSIZE)
@@ -481,7 +478,7 @@ static int compute_sb_data(devvp, es, fs)
if(error) {
for (j = 0; j < i; j++)
brelse(fs->s_group_desc[j]);
- bsd_free(fs->s_group_desc, M_UFSMNT);
+ bsd_free(fs->s_group_desc, M_EXT2MNT);
printf("EXT2-fs: unable to read group descriptors (%d)\n", error);
return EIO;
}
@@ -491,7 +488,7 @@ static int compute_sb_data(devvp, es, fs)
if(!ext2_check_descriptors(fs)) {
for (j = 0; j < db_count; j++)
ULCK_BUF(fs->s_group_desc[j])
- bsd_free(fs->s_group_desc, M_UFSMNT);
+ bsd_free(fs->s_group_desc, M_EXT2MNT);
printf("EXT2-fs: (ext2_check_descriptors failure) "
"unable to read group descriptors\n");
return EIO;
@@ -539,7 +536,7 @@ ext2_reload(mountp, cred, td)
/*
* Step 1: invalidate all cached meta-data.
*/
- devvp = VFSTOUFS(mountp)->um_devvp;
+ devvp = VFSTOEXT2(mountp)->um_devvp;
if (vinvalbuf(devvp, 0, cred, td, 0, 0))
panic("ext2_reload: dirty1");
/*
@@ -553,7 +550,7 @@ ext2_reload(mountp, cred, td)
brelse(bp);
return (EIO); /* XXX needs translation */
}
- fs = VFSTOUFS(mountp)->um_e2fs;
+ fs = VFSTOEXT2(mountp)->um_e2fs;
bcopy(bp->b_data, fs->s_es, sizeof(struct ext2_super_block));
if((error = compute_sb_data(devvp, es, fs)) != 0) {
@@ -600,9 +597,8 @@ loop:
vput(vp);
return (error);
}
- ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data +
- EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)),
- &ip->i_din);
+ ext2_ei2i((struct ext2_inode *) ((char *)bp->b_data +
+ EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)), ip);
brelse(bp);
vput(vp);
mtx_lock(&mntvnode_mtx);
@@ -620,12 +616,12 @@ ext2_mountfs(devvp, mp, td)
struct mount *mp;
struct thread *td;
{
- register struct ufsmount *ump;
+ register struct ext2mount *ump;
struct buf *bp;
register struct ext2_sb_info *fs;
struct ext2_super_block * es;
dev_t dev = devvp->v_rdev;
- int error, i;
+ int error;
int ronly;
/*
@@ -677,22 +673,16 @@ ext2_mountfs(devvp, mp, td)
goto out;
}
}
- ump = bsd_malloc(sizeof *ump, M_UFSMNT, M_WAITOK);
+ ump = bsd_malloc(sizeof *ump, M_EXT2MNT, M_WAITOK);
bzero((caddr_t)ump, sizeof *ump);
- ump->um_malloctype = M_EXT2NODE;
- ump->um_blkatoff = ext2_blkatoff;
- ump->um_truncate = ext2_truncate;
- ump->um_update = ext2_update;
- ump->um_valloc = ext2_valloc;
- ump->um_vfree = ext2_vfree;
/* I don't know whether this is the right strategy. Note that
we dynamically allocate both a ext2_sb_info and a ext2_super_block
while Linux keeps the super block in a locked buffer
*/
ump->um_e2fs = bsd_malloc(sizeof(struct ext2_sb_info),
- M_UFSMNT, M_WAITOK);
+ M_EXT2MNT, M_WAITOK);
ump->um_e2fs->s_es = bsd_malloc(sizeof(struct ext2_super_block),
- M_UFSMNT, M_WAITOK);
+ M_EXT2MNT, M_WAITOK);
bcopy(es, ump->um_e2fs->s_es, (u_int)sizeof(struct ext2_super_block));
if ((error = compute_sb_data(devvp, ump->um_e2fs->s_es, ump->um_e2fs)))
goto out;
@@ -720,14 +710,12 @@ ext2_mountfs(devvp, mp, td)
ump->um_mountp = mp;
ump->um_dev = dev;
ump->um_devvp = devvp;
- /* setting those two parameters allows us to use
+ /* setting those two parameters allowed us to use
ufs_bmap w/o changse !
*/
ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs);
ump->um_bptrtodb = fs->s_es->s_log_block_size + 1;
ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs);
- for (i = 0; i < MAXQUOTAS; i++)
- ump->um_quotas[i] = NULLVP;
devvp->v_rdev->si_mountpoint = mp;
if (ronly == 0)
ext2_sbupdate(ump, MNT_WAIT);
@@ -737,9 +725,9 @@ out:
brelse(bp);
(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, td);
if (ump) {
- bsd_free(ump->um_e2fs->s_es, M_UFSMNT);
- bsd_free(ump->um_e2fs, M_UFSMNT);
- bsd_free(ump, M_UFSMNT);
+ bsd_free(ump->um_e2fs->s_es, M_EXT2MNT);
+ bsd_free(ump->um_e2fs, M_EXT2MNT);
+ bsd_free(ump, M_EXT2MNT);
mp->mnt_data = (qaddr_t)0;
}
return (error);
@@ -754,7 +742,7 @@ ext2_unmount(mp, mntflags, td)
int mntflags;
struct thread *td;
{
- register struct ufsmount *ump;
+ register struct ext2mount *ump;
register struct ext2_sb_info *fs;
int error, flags, ronly, i;
@@ -766,7 +754,7 @@ ext2_unmount(mp, mntflags, td)
}
if ((error = ext2_flushfiles(mp, flags, td)) != 0)
return (error);
- ump = VFSTOUFS(mp);
+ ump = VFSTOEXT2(mp);
fs = ump->um_e2fs;
ronly = fs->s_rd_only;
if (ronly == 0) {
@@ -778,7 +766,7 @@ ext2_unmount(mp, mntflags, td)
/* release buffers containing group descriptors */
for(i = 0; i < fs->s_db_per_group; i++)
ULCK_BUF(fs->s_group_desc[i])
- bsd_free(fs->s_group_desc, M_UFSMNT);
+ bsd_free(fs->s_group_desc, M_EXT2MNT);
/* release cached inode/block bitmaps */
for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++)
@@ -793,9 +781,9 @@ ext2_unmount(mp, mntflags, td)
error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE,
NOCRED, td);
vrele(ump->um_devvp);
- bsd_free(fs->s_es, M_UFSMNT);
- bsd_free(fs, M_UFSMNT);
- bsd_free(ump, M_UFSMNT);
+ bsd_free(fs->s_es, M_EXT2MNT);
+ bsd_free(fs, M_EXT2MNT);
+ bsd_free(ump, M_EXT2MNT);
mp->mnt_data = (qaddr_t)0;
mp->mnt_flag &= ~MNT_LOCAL;
return (error);
@@ -810,28 +798,8 @@ ext2_flushfiles(mp, flags, td)
int flags;
struct thread *td;
{
- register struct ufsmount *ump;
int error;
-#if QUOTA
- int i;
-#endif
- ump = VFSTOUFS(mp);
-#if QUOTA
- if (mp->mnt_flag & MNT_QUOTA) {
- if ((error = vflush(mp, 0, SKIPSYSTEM|flags)) != 0)
- return (error);
- for (i = 0; i < MAXQUOTAS; i++) {
- if (ump->um_quotas[i] == NULLVP)
- continue;
- quotaoff(td, mp, i);
- }
- /*
- * Here we fall through to vflush again to ensure
- * that we have gotten rid of all the system vnodes.
- */
- }
-#endif
error = vflush(mp, 0, flags);
return (error);
}
@@ -847,12 +815,12 @@ ext2_statfs(mp, sbp, td)
struct thread *td;
{
unsigned long overhead;
- register struct ufsmount *ump;
+ register struct ext2mount *ump;
register struct ext2_sb_info *fs;
register struct ext2_super_block *es;
int i, nsb;
- ump = VFSTOUFS(mp);
+ ump = VFSTOEXT2(mp);
fs = ump->um_e2fs;
es = fs->s_es;
@@ -908,7 +876,7 @@ ext2_sync(mp, waitfor, cred, td)
{
struct vnode *nvp, *vp;
struct inode *ip;
- struct ufsmount *ump = VFSTOUFS(mp);
+ struct ext2mount *ump = VFSTOEXT2(mp);
struct ext2_sb_info *fs;
int error, allerror = 0;
@@ -964,9 +932,6 @@ loop:
allerror = error;
VOP_UNLOCK(ump->um_devvp, 0, td);
}
-#if QUOTA
- qsync(mp);
-#endif
/*
* Write back modified superblock.
*/
@@ -994,17 +959,17 @@ ext2_vget(mp, ino, flags, vpp)
{
register struct ext2_sb_info *fs;
register struct inode *ip;
- struct ufsmount *ump;
+ struct ext2mount *ump;
struct buf *bp;
struct vnode *vp;
dev_t dev;
int i, error;
int used_blocks;
- ump = VFSTOUFS(mp);
+ ump = VFSTOEXT2(mp);
dev = ump->um_dev;
restart:
- if ((error = ufs_ihashget(dev, ino, flags, vpp)) != 0)
+ if ((error = ext2_ihashget(dev, ino, flags, vpp)) != 0)
return (error);
if (*vpp != NULL)
return (0);
@@ -1048,17 +1013,13 @@ restart:
ip->i_e2fs = fs = ump->um_e2fs;
ip->i_dev = dev;
ip->i_number = ino;
-#if QUOTA
- for (i = 0; i < MAXQUOTAS; i++)
- ip->i_dquot[i] = NODQUOT;
-#endif
/*
* Put it onto its hash chain and lock it so that other requests for
* this inode will block if they arrive while we are sleeping waiting
* for old data structures to be purged or for the contents of the
* disk portion of this inode to be read.
*/
- ufs_ihashins(ip);
+ ext2_ihashins(ip);
if (ext2fs_inode_hash_lock < 0)
wakeup(&ext2fs_inode_hash_lock);
@@ -1082,8 +1043,8 @@ printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
return (error);
}
/* convert ext2 inode to dinode */
- ext2_ei2di((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE *
- ino_to_fsbo(fs, ino)), &ip->i_din);
+ ext2_ei2i((struct ext2_inode *) ((char *)bp->b_data + EXT2_INODE_SIZE *
+ ino_to_fsbo(fs, ino)), ip);
ip->i_block_group = ino_to_cg(fs, ino);
ip->i_next_alloc_block = 0;
ip->i_next_alloc_goal = 0;
@@ -1107,7 +1068,7 @@ printf("ext2_vget(%d) dbn= %d ", ino, fsbtodb(fs, ino_to_fsba(fs, ino)));
* Initialize the vnode from the inode, check for aliases.
* Note that the underlying vnode may have changed.
*/
- if ((error = ufs_vinit(mp, ext2_specop_p, ext2_fifoop_p, &vp)) != 0) {
+ if ((error = ext2_vinit(mp, ext2_specop_p, ext2_fifoop_p, &vp)) != 0) {
vput(vp);
*vpp = NULL;
return (error);
@@ -1146,15 +1107,32 @@ ext2_fhtovp(mp, fhp, vpp)
struct fid *fhp;
struct vnode **vpp;
{
+ struct inode *ip;
register struct ufid *ufhp;
+ struct vnode *nvp;
struct ext2_sb_info *fs;
+ int error;
ufhp = (struct ufid *)fhp;
- fs = VFSTOUFS(mp)->um_e2fs;
+ fs = VFSTOEXT2(mp)->um_e2fs;
if (ufhp->ufid_ino < ROOTINO ||
ufhp->ufid_ino >= fs->s_groups_count * fs->s_es->s_inodes_per_group)
return (ESTALE);
- return (ufs_fhtovp(mp, ufhp, vpp));
+
+ error = VFS_VGET(mp, ufhp->ufid_ino, LK_EXCLUSIVE, &nvp);
+ if (error) {
+ *vpp = NULLVP;
+ return (error);
+ }
+ ip = VTOI(nvp);
+ if (ip->i_mode == 0 ||
+ ip->i_gen != ufhp->ufid_gen || ip->i_nlink <= 0) {
+ vput(nvp);
+ *vpp = NULLVP;
+ return (ESTALE);
+ }
+ *vpp = nvp;
+ return (0);
}
/*
@@ -1182,7 +1160,7 @@ ext2_vptofh(vp, fhp)
*/
static int
ext2_sbupdate(mp, waitfor)
- struct ufsmount *mp;
+ struct ext2mount *mp;
int waitfor;
{
register struct ext2_sb_info *fs = mp->um_e2fs;
@@ -1207,3 +1185,34 @@ printf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no");
return (error);
}
+
+/*
+ * Return the root of a filesystem.
+ */
+static int
+ext2_root(mp, vpp)
+ struct mount *mp;
+ struct vnode **vpp;
+{
+ struct vnode *nvp;
+ int error;
+
+ error = VFS_VGET(mp, (ino_t)ROOTINO, LK_EXCLUSIVE, &nvp);
+ if (error)
+ return (error);
+ *vpp = nvp;
+ return (0);
+}
+
+static int
+ext2_init(struct vfsconf *vfsp)
+{
+ static int done;
+
+ if (done)
+ return (0);
+ done = 1;
+ ext2_ihashinit();
+
+ return (0);
+}
OpenPOWER on IntegriCloud