Index: src/sys/conf/files =================================================================== --- src/sys/conf/files (revision 177) +++ src/sys/conf/files (working copy) @@ -1767,17 +1767,33 @@ security/mac_stub/mac_stub.c optional mac_stub security/mac_test/mac_test.c optional mac_test ufs/ffs/ffs_alloc.c optional ffs +ufs/ffs/ffs_alloc.c optional ifs ufs/ffs/ffs_balloc.c optional ffs +ufs/ffs/ffs_balloc.c optional ifs ufs/ffs/ffs_inode.c optional ffs +ufs/ffs/ffs_inode.c optional ifs ufs/ffs/ffs_snapshot.c optional ffs +ufs/ffs/ffs_snapshot.c optional ifs ufs/ffs/ffs_softdep.c optional ffs +ufs/ffs/ffs_softdep.c optional ifs ufs/ffs/ffs_subr.c optional ffs +ufs/ffs/ffs_subr.c optional ifs ufs/ffs/ffs_tables.c optional ffs +ufs/ffs/ffs_tables.c optional ifs ufs/ffs/ffs_vfsops.c optional ffs +ufs/ffs/ffs_vfsops.c optional ifs ufs/ffs/ffs_vnops.c optional ffs +ufs/ffs/ffs_vnops.c optional ifs ufs/ffs/ffs_rawread.c optional directio ufs/ufs/ufs_acl.c optional ffs +ufs/ufs/ufs_acl.c optional ifs ufs/ufs/ufs_bmap.c optional ffs +ufs/ufs/ufs_bmap.c optional ifs +ufs/ufs/ufs_vnops.c optional ifs +ufs/ifs/ifs_lookup.c optional ifs +ufs/ifs/ifs_vfsops.c optional ifs +ufs/ifs/ifs_vnops.c optional ifs +ufs/ifs/ifs_subr.c optional ifs ufs/ufs/ufs_dirhash.c optional ffs ufs/ufs/ufs_extattr.c optional ffs ufs/ufs/ufs_inode.c optional ffs Index: src/sys/conf/options =================================================================== --- src/sys/conf/options (revision 177) +++ src/sys/conf/options (working copy) @@ -186,6 +186,7 @@ # Broken - ffs_snapshot() dependency from ufs_lookup() :-( FFS opt_ffs_broken_fixme.h +IFS opt_ffs_broken_fixme.h # These static filesystems have one slightly bogus static dependency in # sys/i386/i386/autoconf.c. If any of these filesystems are Index: src/sys/ufs/ifs/ifs_vfsops.c =================================================================== --- src/sys/ufs/ifs/ifs_vfsops.c (revision 0) +++ src/sys/ufs/ifs/ifs_vfsops.c (revision 0) @@ -0,0 +1,320 @@ +/* + * Copyright (c) 2005 Suleiman Souhlal + * Copyright (c) 1999, 2000 + * Adrian Chadd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ffs_vfsops.c 8.31 (Berkeley) 5/20/95 + * $FreeBSD: /repoman/r/ncvs/src/sys/ufs/ifs/ifs_vfsops.c,v 1.10 2002/04/04 21:03:33 jhb Exp $ + */ + + +#include "opt_ffs.h" +#include "opt_quota.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +extern uma_zone_t uma_inode, uma_ufs1, uma_ufs2; + +static int ifs_init (struct vfsconf *); +static int ifs_mount (struct mount *, struct thread *); +extern int ifs_vget (struct mount *, ino_t, int, struct vnode **); + +static struct vfsops ifs_vfsops = { + .vfs_mount = ifs_mount, + .vfs_unmount = ffs_unmount, + .vfs_root = ufs_root, + .vfs_quotactl = ufs_quotactl, + .vfs_statfs = ffs_statfs, + .vfs_sync = ffs_sync, + .vfs_vget = ifs_vget, + .vfs_fhtovp = ffs_fhtovp, + .vfs_vptofh = ffs_vptofh, + .vfs_init = ifs_init, +}; + +VFS_SET(ifs_vfsops, ifs, 0); + +/* + * ifs_mount + * + * A simple wrapper around ffs_mount - IFS filesystems right now can't + * deal with softupdates so we make sure the user isn't trying to use it. + */ +static int +ifs_mount(struct mount *mp, struct thread *td) +{ + /* Clear the softdep flag */ + mp->mnt_flag &= ~MNT_SOFTDEP; + return (ffs_mount(mp, td)); +} + + + +/* + * Look up a IFS dinode number to find its incore vnode, otherwise read it + * in from disk. If it is in core, wait for the lock bit to clear, then + * return the inode locked. Detection and handling of mount points must be + * done by the calling routine. + */ +static int ifs_inode_hash_lock; +/* + * ifs_inode_hash_lock is a variable to manage mutual exclusion + * of vnode allocation and intertion to the hash, especially to + * avoid holding more than one vnodes for the same inode in the + * hash table. ifs_inode_hash_lock must hence be tested-and-set + * or cleared atomically, accomplished by ifs_inode_hash_mtx. + * + * As vnode allocation may block during MALLOC() and zone + * allocation, we should also do msleep() to give away the CPU + * if anyone else is allocating a vnode. lockmgr is not suitable + * here because someone else may insert to the hash table the + * vnode we are trying to allocate during our sleep, in which + * case the hash table needs to be examined once again after + * waking up. + */ +static struct mtx ifs_inode_hash_mtx; + +/* + * Initialize the filesystem; just use ufs_init. + */ +static int +ifs_init(vfsp) + struct vfsconf *vfsp; +{ + mtx_init(&ifs_inode_hash_mtx, "ifsvgt", NULL, MTX_DEF); + /* return (ufs_init(vfsp)); */ + return (0); +} + +int +ifs_vget(mp, ino, flags, vpp) + struct mount *mp; + ino_t ino; + int flags; + struct vnode **vpp; +{ + struct fs *fs; + struct inode *ip; + struct ufsmount *ump; + struct buf *bp; + struct vnode *vp; + struct cdev *dev; + int error, want_wakeup; + +restart: + error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL); + if (error || *vpp != NULL) + return (error); + + /* + * Lock out the creation of new entries in the FFS hash table in + * case getnewvnode() or MALLOC() blocks, otherwise a duplicate + * may occur! + */ + mtx_lock(&ifs_inode_hash_mtx); + if (ifs_inode_hash_lock) { + while (ifs_inode_hash_lock) { + ifs_inode_hash_lock = -1; + msleep(&ifs_inode_hash_lock, &ifs_inode_hash_mtx, PVM, "ifsvgt", 0); + } + mtx_unlock(&ifs_inode_hash_mtx); + goto restart; + } + ifs_inode_hash_lock = 1; + mtx_unlock(&ifs_inode_hash_mtx); + + /* + * We must promote to an exclusive lock for vnode creation. This + * can happen if lookup is passed LOCKSHARED. + */ + if ((flags & LK_TYPE_MASK) == LK_SHARED) { + flags &= ~LK_TYPE_MASK; + flags |= LK_EXCLUSIVE; + } + + ump = VFSTOUFS(mp); + dev = ump->um_dev; + fs = ump->um_fs; + + /* + * If this MALLOC() is performed after the getnewvnode() + * it might block, leaving a vnode with a NULL v_data to be + * found by ffs_sync() if a sync happens to fire right then, + * which will cause a panic because ffs_sync() blindly + * dereferences vp->v_data (as well it should). + */ + ip = uma_zalloc(uma_inode, M_WAITOK | M_ZERO); + + /* Allocate a new vnode/inode. */ + error = getnewvnode("ufs", mp, &ifs_vnodeops, &vp); + if (error) { + /* + * Do not wake up processes while holding the mutex, + * otherwise the processes waken up immediately hit + * themselves into the mutex. + */ + mtx_lock(&ifs_inode_hash_mtx); + want_wakeup = ifs_inode_hash_lock < 0; + ifs_inode_hash_lock = 0; + mtx_unlock(&ifs_inode_hash_mtx); + if (want_wakeup) + wakeup(&ifs_inode_hash_lock); + *vpp = NULL; + uma_zfree(uma_inode, ip); + return (error); + } + /* + * IFS supports lock sharing in the stack of vnodes + */ +// vp->v_vnlock = &vp->v_lock; +// lockinit(vp->v_vnlock, PINOD, "inode", VLKTIMEOUT, LK_CANRECURSE); + vp->v_vnlock->lk_flags |= LK_CANRECURSE; + vp->v_vnlock->lk_flags &= ~LK_NOSHARE; + vp->v_data = ip; + vp->v_bufobj.bo_bsize = fs->fs_bsize; + ip->i_vnode = vp; + ip->i_ump = ump; + ip->i_fs = fs; + ip->i_dev = dev; + ip->i_number = ino; +#ifdef QUOTA + { + int i; + for (i = 0; i < MAXQUOTAS; i++) + ip->i_dquot[i] = NODQUOT; + } +#endif + error = vfs_hash_insert(vp, ino, flags, curthread, vpp, NULL, NULL); + if (error || *vpp != NULL) + return (error); + + /* + * Do not wake up processes while holding the mutex, + * otherwise the processes waken up immediately hit + * themselves into the mutex. + */ + mtx_lock(&ifs_inode_hash_mtx); + want_wakeup = ifs_inode_hash_lock < 0; + ifs_inode_hash_lock = 0; + mtx_unlock(&ifs_inode_hash_mtx); + if (want_wakeup) + wakeup(&ifs_inode_hash_lock); + + /* Read in the disk contents for the inode, copy into the inode. */ + error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), + (int)fs->fs_bsize, NOCRED, &bp); + if (error) { + /* + * The inode does not contain anything useful, so it would + * be misleading to leave it on its hash chain. With mode + * still zero, it will be unlinked and returned to the free + * list by vput(). + */ + brelse(bp); + vput(vp); + *vpp = NULL; + return (error); + } + printf("fstype = %ul\n", (unsigned int)ip->i_ump->um_fstype); + if (ip->i_ump->um_fstype != UFS2) + return (EINVAL); + ip->i_din2 = uma_zalloc(uma_ufs2, M_WAITOK); + ffs_load_inode(bp, ip, fs, ino); + if (DOINGSOFTDEP(vp)) + softdep_load_inodeblock(ip); + else + ip->i_effnlink = ip->i_nlink; + bqrelse(bp); + + /* + * Initialize the vnode from the inode, check for aliases. + * Note that the underlying vnode may have changed. + */ + error = ufs_vinit(mp, &ifs_fifoops, &vp); + if (error) { + vput(vp); + *vpp = NULL; + return (error); + } + /* + * Finish inode initialization now that aliasing has been resolved. + */ + + /* + * Set up a generation number for this inode if it does not + * already have one. This should only happen on old filesystems. + */ + if (ip->i_gen == 0) { + ip->i_gen = arc4random() / 2 + 1; + if ((vp->v_mount->mnt_flag & MNT_RDONLY) == 0) { + ip->i_flag |= IN_MODIFIED; + DIP_SET(ip, i_gen, ip->i_gen); + } + } +#if 0 + /* + * Ensure that uid and gid are correct. This is a temporary + * fix until fsck has been changed to do the update. + */ + if (fs->fs_old_inodefmt < FS_44INODEFMT) { /* XXX */ + ip->i_uid = ip->i_din.di_ouid; /* XXX */ + ip->i_gid = ip->i_din.di_ogid; /* XXX */ + } /* XXX */ +#endif + + *vpp = vp; + return (0); +} Index: src/sys/ufs/ifs/ifs_vnops.c =================================================================== --- src/sys/ufs/ifs/ifs_vnops.c (revision 0) +++ src/sys/ufs/ifs/ifs_vnops.c (revision 0) @@ -0,0 +1,419 @@ +/* + * Copyright (c) 1999, 2000 + * Adrian Chadd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ffs_vnops.c 8.15 (Berkeley) 5/14/95 + * $FreeBSD: /repoman/r/ncvs/src/sys/ufs/ifs/ifs_vnops.c,v 1.8 2002/05/18 18:51:10 iedowse Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +/* IFS debugging */ +#undef DEBUG_IFS_READDIR + +static int ifs_getattr(struct vop_getattr_args *); +static int ifs_create(struct vop_create_args *); +static int ifs_makeinode(int mode, struct vnode *, struct vnode **, + struct componentname *); +static int ifs_remove(struct vop_remove_args *); +static int ifs_readdir(struct vop_readdir_args *); +static int ifs_dirremove(struct vnode *, struct inode *, int, int); + + + +/* Global vfs data structures for ifs. */ +struct vop_vector ifs_vnodeops = { + .vop_default = &default_vnodeops, + .vop_access = &ufs_access, + .vop_fsync = &ffs_fsync, + .vop_getpages = &ffs_getpages, + .vop_read = &ffs_read, + .vop_reallocblks = &ffs_reallocblks, + .vop_write = &ffs_write, + + .vop_lookup = &ifs_lookup, + .vop_getattr = &ifs_getattr, + .vop_create = &ifs_create, + .vop_remove = &ifs_remove, + .vop_readdir = &ifs_readdir, + +/* NULL operations for ifs */ + //.vop_cachedlookup = VOP_EOPNOTSUPP, + //.vop_mkdir = VOP_EOPNOTSUPP, + //.vop_mknod = VOP_EOPNOTSUPP, + //.vop_readlink = VOP_EOPNOTSUPP, + //.vop_rename = VOP_EOPNOTSUPP, + //.vop_rmdir = VOP_EOPNOTSUPP, + //.vop_symlink = VOP_EOPNOTSUPP, + //.vop_link = VOP_EOPNOTSUPP, + //.vop_whiteout = VOP_EOPNOTSUPP, +}; + +struct vop_vector ifs_fifoops = { + .vop_default = &ufs_fifoops, + .vop_fsync = &ffs_fsync, +}; + +/* ARGSUSED */ +static int +ifs_getattr(ap) + struct vop_getattr_args /* { + struct vnode *a_vp; + struct vattr *a_vap; + struct ucred *a_cred; + struct proc *a_p; + } */ *ap; +{ + struct vnode *vp = ap->a_vp; + struct inode *ip = VTOI(vp); + struct vattr *vap = ap->a_vap; + + ufs_itimes(vp); + /* + * Copy from inode table + */ + vap->va_fsid = dev2udev(ip->i_dev); + vap->va_fileid = ip->i_number; + vap->va_mode = ip->i_mode & ~IFMT; + vap->va_nlink = ip->i_effnlink; + vap->va_uid = ip->i_uid; + vap->va_gid = ip->i_gid; + vap->va_rdev = ip->i_din2->di_rdev; + vap->va_size = ip->i_din2->di_size; + vap->va_atime.tv_sec = ip->i_din2->di_atime; + vap->va_atime.tv_nsec = ip->i_din2->di_atimensec; + vap->va_mtime.tv_sec = ip->i_din2->di_mtime; + vap->va_mtime.tv_nsec = ip->i_din2->di_mtimensec; + vap->va_ctime.tv_sec = ip->i_din2->di_ctime; + vap->va_ctime.tv_nsec = ip->i_din2->di_ctimensec; + vap->va_birthtime.tv_sec = ip->i_din2->di_birthtime; + vap->va_birthtime.tv_nsec = ip->i_din2->di_birthnsec; + vap->va_flags = ip->i_flags; + vap->va_gen = ip->i_gen; + vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize; + vap->va_type = IFTOVT(ip->i_mode); + vap->va_filerev = ip->i_modrev; + return (0); +} + + +/* + * Create a regular file + */ +int +ifs_create(ap) + struct vop_create_args /* { + struct vnode *a_dvp; + struct vnode **a_vpp; + struct componentname *a_cnp; + struct vattr *a_vap; + } */ *ap; +{ + return (ifs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode), + ap->a_dvp, ap->a_vpp, ap->a_cnp)); +} + + +/* + * Allocate a new inode. + */ +int +ifs_makeinode(mode, dvp, vpp, cnp) + int mode; + struct vnode *dvp; + struct vnode **vpp; + struct componentname *cnp; +{ + struct inode *ip, *pdir; + struct vnode *tvp; + int error; + + pdir = VTOI(dvp); + printf("pdir is %ul\n", (unsigned int)pdir->i_number); +#ifdef DIAGNOSTIC + if ((cnp->cn_flags & HASBUF) == 0) + panic("ifs_makeinode: no name"); +#endif + *vpp = NULL; + if ((mode & IFMT) == 0) + mode |= IFREG; + error = UFS_VALLOC(dvp, mode, cnp->cn_cred, &tvp); + printf("UFS_VALLOC returned %d\n", error); + if (error) { + uma_zfree(namei_zone, cnp->cn_pnbuf); + return (error); + } + ip = VTOI(tvp); + printf("created inode %ul\n", (unsigned int)ip->i_number); + ip->i_gid = pdir->i_gid; + ip->i_uid = cnp->cn_cred->cr_uid; +#ifdef QUOTA + if ((error = getinoquota(ip)) || + (error = chkiq(ip, 1, cnp->cn_cred, 0))) { + UFS_VFREE(tvp, ip->i_number, mode); + vput(tvp); + return (error); + } +#endif + ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; + ip->i_mode = mode; + tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */ + ip->i_effnlink = 1; + ip->i_nlink = 1; + if (DOINGSOFTDEP(tvp)) + softdep_change_linkcnt(ip); + if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, cnp->cn_cred) && + suser_cred(cnp->cn_cred, 0)) + ip->i_mode &= ~ISGID; + + if (cnp->cn_flags & ISWHITEOUT) + ip->i_flags |= UF_OPAQUE; + + /* + * Make sure inode goes to disk before directory entry. + */ + error = UFS_UPDATE(tvp, !(DOINGSOFTDEP(tvp) | DOINGASYNC(tvp))); + if (error) + goto bad; + *vpp = tvp; + return (0); +bad: + /* + * Write error occurred trying to update the inode + * or the directory so must deallocate the inode. + */ + ip->i_effnlink = 0; + ip->i_nlink = 0; + ip->i_flag |= IN_CHANGE; + if (DOINGSOFTDEP(tvp)) + softdep_change_linkcnt(ip); + vput(tvp); + return (error); +} + + +int +ifs_remove(ap) + struct vop_remove_args /* { + struct vnode *a_dvp; + struct vnode *a_vp; + struct componentname *a_cnp; + } */ *ap; +{ + struct inode *ip; + struct vnode *vp = ap->a_vp; + struct vnode *dvp = ap->a_dvp; + + ip = VTOI(vp); + if ((ip->i_flags & (NOUNLINK | IMMUTABLE | APPEND)) || + (VTOI(dvp)->i_flags & APPEND)) + return (EPERM); + return (ifs_dirremove(dvp, ip, ap->a_cnp->cn_flags, 0)); +} + + +/* + * highly cutdown ufs_dirremove, since we're not updating + * any directory entries. :-) + */ +static int +ifs_dirremove(struct vnode *dvp, struct inode *ip, int flags, int isrmdir) +{ + int error; + + if (ip) { + ip->i_effnlink--; + ip->i_flag |= IN_CHANGE; + ip->i_nlink--; + error = 0; + } else + error = ENOENT; + return (error); +} + + +/* + * ifs_readdir + * + * Do the directory listing, representing the allocated inodes + * making up this filesystem. + * + */ + +static int +ifs_readdir(ap) + struct vop_readdir_args /* { + struct vnode *a_vp; + struct uio *a_uio; + struct ucred *a_cred; + int *a_eofflag; + int *ncookies; + u_long **a_cookies; + } */ *ap; +{ + int inodenum; + struct dirent *dent, *lastdp = NULL; + struct dirent *tmpdp; + char *dirbuf; + struct inode *ip = VTOI(ap->a_vp); /* To get the mount info later */ + struct mount *mp = ap->a_vp->v_mount; + struct fs *fs = VFSTOUFS(mp)->um_fs; + int maxnuminode = fs->fs_ncg * fs->fs_ipg; + int error = 0; + int count; + int dircount = 0; + int copylen = 0; + char iret; + + /* + * Get the offset, which represents the inode we're going to + * start from + */ + inodenum = ap->a_uio->uio_offset; +#ifdef DEBUG_IFS_READDIR + printf("ifs_readdir: starting with inode %d\n", inodenum); +#endif + if (inodenum < 0) + return EINVAL; + /* + * Next, get the buffer size, round it down to a dirent, and + * figure out how many allocated inodes we need to match + */ + count = ap->a_uio->uio_resid; + /* + * Next, create a dirbuf to fill with directory entries + */ + MALLOC(tmpdp, struct dirent *, sizeof (struct dirent), M_TEMP, M_WAITOK); + MALLOC(dirbuf, char *, count, M_TEMP, M_WAITOK); + dent = (struct dirent *)dirbuf; + /* now, keep reading until we run out of inodes */ + while (inodenum <= maxnuminode) { + /* Get bitmap info and see if we bother with this cg */ + iret = ifs_isinodealloc(ip, inodenum); + if (iret == IFS_INODE_EMPTYCG) { + /* Skip this CG */ + /* Next cg please */ + inodenum -= inodenum % fs->fs_ipg; + inodenum += fs->fs_ipg; + continue; + } + /* Allocated and not special? */ + if ((inodenum > 2) && iret == IFS_INODE_ISALLOC) { + /* Create a new entry */ + sprintf(tmpdp->d_name, "%d", inodenum); + tmpdp->d_fileno = inodenum; + tmpdp->d_type = DT_REG; + tmpdp->d_namlen = strlen(tmpdp->d_name); + tmpdp->d_reclen = DIRECTSIZ(tmpdp->d_namlen); + /* Make sure we have enough space for this entry */ + if (tmpdp->d_reclen > count) + break; + /* Copy it to the given buffer */ + bcopy(tmpdp, dent, tmpdp->d_reclen); + /* Decrement the count */ + count -= dent->d_reclen; + copylen += dent->d_reclen; + lastdp = dent; + /* Increment the offset pointer */ + dent = (struct dirent *)((char *)dent + dent->d_reclen); + dircount++; + } + /* Increment the inode number we are checking */ + inodenum++; + } + /* End */ +#ifdef DEBUG_IFS_READDIR + printf("ifs_readdir: copied %d directories\n", dircount); +#endif + /* + * Get the last dent updated, and make the record d_reclen last the whole + * buffer. + */ + if (lastdp != NULL) { + /* Update the length of the last entry */ + lastdp->d_reclen += count; + } + /* Copy the data out */ +#ifdef DEBUG_IFS_READDIR + printf("ifs_readdir: copied %d bytes\n", copylen); +#endif + error = uiomove(dirbuf, copylen, ap->a_uio); + /* Free memory we've used */ + FREE(dirbuf, M_TEMP); + FREE(tmpdp, M_TEMP); + /* Set uio_offset to the last inode number */ + ap->a_uio->uio_offset = inodenum; + /* Handle EOF/eofflag */ + if ((inodenum >= maxnuminode) && (ap->a_eofflag != NULL)) { + *ap->a_eofflag = 1; +#ifdef DEBUG_IFS_READDIR + printf("ifs_readdir: setting EOF flag\n"); +#endif + } +#ifdef DEBUG_IFS_READDIR + printf("ifs_readdir: new offset: %d\n", inodenum); +#endif + return error; +} + Index: src/sys/ufs/ifs/ifs_lookup.c =================================================================== --- src/sys/ufs/ifs/ifs_lookup.c (revision 0) +++ src/sys/ufs/ifs/ifs_lookup.c (revision 0) @@ -0,0 +1,248 @@ +/* + * Copyright (c) 1999, 2000 + * Adrian Chadd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ufs_lookup.c 8.15 (Berkeley) 6/16/95 + * $FreeBSD: /repoman/r/ncvs/src/sys/ufs/ifs/ifs_lookup.c,v 1.4 2002/03/17 01:25:47 mckusick Exp $ + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +/* true if old FS format...*/ +#define OFSFMT(vp) ((vp)->v_mount->mnt_maxsymlinklen <= 0) + +/* Define if you want my debug printfs inside ifs_lookup() */ +#define DEBUG_IFS_LOOKUP + + +#if 0 +static char * +getnameiopstr(int nameiop) +{ + switch (nameiop) { + case LOOKUP: + return "LOOKUP"; + break; + case CREATE: + return "CREATE"; + break; + case DELETE: + return "DELETE"; + break; + case RENAME: + return "RENAME"; + break; + default: + return "unknown"; + break; + } +} +#endif + +/* + * Convert a path to an inode. + * + * This is HIGHLY simplified - we just take the path fragment given to us, + * attempt to convert it to an inode, and return the inode if we can. + * No permission checking is done here, that is done further up in the + * VFS call layers. + */ +int +ifs_lookup(ap) + struct vop_lookup_args /* { + struct vnode *a_dvp; + struct vnode **a_vpp; + struct componentname *a_cnp; + } */ *ap; +{ + struct vnode *vdp; /* vnode for directory being searched */ + struct inode *dp; /* inode for directory being searched */ + struct vnode *pdp; /* saved dp during symlink work */ + struct vnode *tdp; /* returned by VFS_VGET */ + struct vnode **vpp = ap->a_vpp; + struct componentname *cnp = ap->a_cnp; + struct ucred *cred = cnp->cn_cred; + struct mount *mp = ap->a_dvp->v_mount; + struct fs *fs = VFSTOUFS(mp)->um_fs; + int nameiop = cnp->cn_nameiop; + int error; + struct thread *td = cnp->cn_thread; + ufs2_daddr_t inodenum; + char *endp; + + *vpp = NULL; + vdp = ap->a_dvp; + dp = VTOI(vdp); + pdp = vdp; + /* + * Firstly, we are NOT dealing with RENAME, at all + */ + if (nameiop == RENAME) { + *vpp = NULL; +#ifdef DEBUG_IFS_LOOKUP + printf("ifs_lookup(): Denying RENAME nameiop\n"); +#endif + return (EPERM); + } + /* Deal with the '.' directory */ + /* VOP_UNLOCK(vdp, 0, td); */ + if (cnp->cn_namelen == 1 && *(cnp->cn_nameptr) == '.') { + /* We don't unlock the parent dir since the're the same */ + *vpp = vdp; + VREF(vdp); + /* vn_lock(vdp, LK_SHARED | LK_RETRY, td); */ + return (0); + } + /* + * 'newfile' is considered something special .. read below why + * we're returning NULL + */ + if ((cnp->cn_namelen) == 7 && (strncmp(cnp->cn_nameptr, "newfile", 7) == 0)) { + if (nameiop == CREATE) { + /* Check for write permissions in . */ + error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_thread); + if (error) + return (error); + printf("creating!\n"); + *vpp = NULL; + cnp->cn_flags |= SAVENAME; + return (EJUSTRETURN); + } else { + *vpp = NULL; +#ifdef DEBUG_IFS_LOOKUP + printf("ifs_lookup(): Denying !CREATE on 'newfile'\n"); +#endif + return (EPERM); + } + } + /* Grab the hex inode number */ + inodenum = strtouq(cnp->cn_nameptr, &endp, 0); + /* Sanity Check */ + if (endp != (cnp->cn_nameptr + cnp->cn_namelen)) { + *vpp = NULL; + return (ENOENT); + } + /* + * error check here - inodes 0-2 are considered 'special' even here + * so we will hide it from the user. + */ + if (inodenum <= 2) { +#ifdef DEBUG_IFS_LOOKUP + printf("ifs_lookup(): Access to disk inode '%d' denied\n", + (int)inodenum); +#endif + return EPERM; + } + /* Check we haven't overflowed the number of inodes in the fs */ + if (inodenum > (fs->fs_ncg * fs->fs_ipg)) { +#ifdef DEBUG_IFS_LOOKUP + //printf("ifs_lookup(): disk inode '%d' is outside the disk\n"), + // (int)inodenum); +#endif + return EINVAL; + } + /* + * The next bit of code grabs the inode, checks to see whether + * we're allowed to do our nameiop on it. The only one we need + * to check here is CREATE - only allow create on an inode + * that exists. + * + * Comment for VFS-newbies: + * read vn_open() - you'll learn that if you return a name here, + * it assumes you don't need to call VOP_CREATE. Bad juju as + * you now have a vnode that isn't tagged with the right type, + * and it'll panic in the VOP_READ/VOP_WRITE routines.. + */ + /* + * If we get here and its a CREATE, then return EPERM if the inode + * doesn't exist. + */ + if ((nameiop == CREATE) && + (ifs_isinodealloc(VTOI(vdp), inodenum) != IFS_INODE_ISALLOC)) { +#ifdef DEBUG_IFS_LOOKUP + printf("ifs_lookup(): CREATE on inode %d which doesn't exist\n", + (int)inodenum); +#endif + return EPERM; +#ifdef DEBUG_IFS_LOOKUP + } else if (nameiop == CREATE) { + /* It does exist, allow CREATE */ + printf("ifs_lookup(): CREATE on inode %d which exists\n", + (int)inodenum); + } +#else + } +#endif + /* + * Make sure that the inode exists if we're trying to delete or + * modify + */ + if ((nameiop == LOOKUP || nameiop == DELETE) && + ifs_isinodealloc(VTOI(vdp), inodenum) != IFS_INODE_ISALLOC) { + /* it doesn't exist */ +#ifdef DEBUG_IFS_LOOKUP + printf("ifs_lookup(): Inode %d isn't allocated\n", (int)inodenum); +#endif + return ENOENT; + } + /* Now, we can get the vnode */ + error = VFS_VGET(vdp->v_mount, (long)inodenum, LK_EXCLUSIVE, &tdp); + if (error) + return (error); + *vpp = tdp; + printf("%s: islocked = %d\n", __func__, VOP_ISLOCKED(tdp, td)); + return (0); +} + Index: src/sys/ufs/ifs/ifs_extern.h =================================================================== --- src/sys/ufs/ifs/ifs_extern.h (revision 0) +++ src/sys/ufs/ifs/ifs_extern.h (revision 0) @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 1991, 1993, 1994 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ffs_extern.h 8.6 (Berkeley) 3/30/95 + * $FreeBSD: /repoman/r/ncvs/src/sys/ufs/ifs/ifs_extern.h,v 1.3 2001/09/12 08:38:08 julian Exp $ + */ + +#ifndef _UFS_IFS_EXTERN_H +#define _UFS_IFS_EXTERN_H + +/* + * Sysctl values for the fast filesystem. + */ +#define IFS_REALLOCBLKS 3 /* block reallocation enabled */ +#define IFS_ASYNCFREE 4 /* asynchronous block freeing enabled */ +#define IFS_MAXID 5 /* number of valid ffs ids */ + + +/* Return vals from ifs_isinodealloc */ +#define IFS_INODE_ISALLOC 1 +#define IFS_INODE_NOALLOC 0 +#define IFS_INODE_EMPTYCG -1 + +#define IFS_NAMES { \ + { 0, 0 }, \ + { 0, 0 }, \ + { 0, 0 }, \ + { "doreallocblks", CTLTYPE_INT }, \ + { "doasyncfree", CTLTYPE_INT }, \ +} + +struct buf; +struct fid; +struct fs; +struct inode; +struct malloc_type; +struct mount; +struct sockaddr; +struct statfs; +struct ucred; +struct vnode; +//struct vop_balloc_args; +//struct vop_fsync_args; +//struct vop_reallocblks_args; + +extern struct vop_vector ifs_vnodeops; +extern struct vop_vector ifs_specops; +extern struct vop_vector ifs_fifoops; + +int ifs_lookup(struct vop_lookup_args *); +int ifs_isinodealloc(struct inode *, ufs2_daddr_t); + +#endif /* !_UFS_IFS_EXTERN_H */ Index: src/sys/ufs/ifs/ifs_subr.c =================================================================== --- src/sys/ufs/ifs/ifs_subr.c (revision 0) +++ src/sys/ufs/ifs/ifs_subr.c (revision 0) @@ -0,0 +1,120 @@ +/* + * Copyright (c) 1999, 2000 + * Adrian Chadd + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)ffs_vnops.c 8.15 (Berkeley) 5/14/95 + * $FreeBSD: /repoman/r/ncvs/src/sys/ufs/ifs/ifs_subr.c,v 1.3 2002/03/20 08:48:07 jeff Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +/* + * Check whether the given inode number is free. + * + * This routine is a chunk of ffs_nodealloccg - we aren't + * allocating here. We also check whether there will be + * any other inodes in the cylinder group, and if not, + * we return -1. + */ +int +ifs_isinodealloc(struct inode *ip, ufs2_daddr_t ino) +{ + struct fs *fs; + struct cg *cgp; + struct buf *bp; + int error; + int cg; + int retval = 0; + + /* Grab the filesystem info and cylinder group */ + fs = ip->i_fs; + cg = ino_to_cg(fs, ino); + + /* Read in the cylinder group inode allocation bitmap .. */ + error = bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), + (int)fs->fs_cgsize, NOCRED, &bp); + if (error) { + retval = IFS_INODE_NOALLOC; + goto end; + } + cgp = (struct cg *)bp->b_data; + if (!cg_chkmagic(cgp)) { + retval = IFS_INODE_NOALLOC; + goto end; + } + ino %= fs->fs_ipg; + /* + * Check whether we have any inodes in this cg, or whether the + * inode is allocated + */ + if (!isclr(cg_inosused(cgp), ino)) + retval = IFS_INODE_ISALLOC; /* it is allocated */ + else if (cgp->cg_niblk == cgp->cg_cs.cs_nifree) + retval = IFS_INODE_EMPTYCG; /* empty cg */ + else + retval = IFS_INODE_NOALLOC; /* its not allocated */ +end: + /* Close the buffer and return */ + brelse(bp); + return (retval); +} + Index: src/sys/ufs/ufs/ufs_vnops.c =================================================================== --- src/sys/ufs/ufs/ufs_vnops.c (revision 177) +++ src/sys/ufs/ufs/ufs_vnops.c (working copy) @@ -85,7 +85,6 @@ #include -static vop_access_t ufs_access; static vop_advlock_t ufs_advlock; static int ufs_chmod(struct vnode *, int, struct ucred *, struct thread *); static int ufs_chown(struct vnode *, uid_t, gid_t, struct ucred *, struct thread *); @@ -281,7 +280,7 @@ return (0); } -static int +int ufs_access(ap) struct vop_access_args /* { struct vnode *a_vp; Index: src/sys/ufs/ufs/ufs_extern.h =================================================================== --- src/sys/ufs/ufs/ufs_extern.h (revision 177) +++ src/sys/ufs/ufs/ufs_extern.h (working copy) @@ -54,6 +54,7 @@ extern struct vop_vector ufs_fifoops; extern struct vop_vector ufs_vnodeops; +vop_access_t ufs_access; int ufs_bmap(struct vop_bmap_args *); int ufs_bmaparray(struct vnode *, ufs2_daddr_t, ufs2_daddr_t *, struct buf *, int *, int *); Index: src/sys/ufs/ffs/ffs_vnops.c =================================================================== --- src/sys/ufs/ffs/ffs_vnops.c (revision 177) +++ src/sys/ufs/ffs/ffs_vnops.c (working copy) @@ -102,11 +102,7 @@ #ifdef DIRECTIO extern int ffs_rawread(struct vnode *vp, struct uio *uio, int *workdone); #endif -static vop_fsync_t ffs_fsync; static vop_lock_t ffs_lock; -static vop_getpages_t ffs_getpages; -static vop_read_t ffs_read; -static vop_write_t ffs_write; static int ffs_extread(struct vnode *vp, struct uio *uio, int ioflag); static int ffs_extwrite(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred); @@ -171,7 +167,7 @@ * Synch an open file. */ /* ARGSUSED */ -static int +int ffs_fsync(struct vop_fsync_args *ap) { int error; @@ -345,7 +341,7 @@ * Vnode op for reading. */ /* ARGSUSED */ -static int +int ffs_read(ap) struct vop_read_args /* { struct vnode *a_vp; @@ -554,7 +550,7 @@ /* * Vnode op for writing. */ -static int +int ffs_write(ap) struct vop_write_args /* { struct vnode *a_vp; @@ -755,7 +751,7 @@ /* * get page routine */ -static int +int ffs_getpages(ap) struct vop_getpages_args *ap; { Index: src/sys/ufs/ffs/ffs_extern.h =================================================================== --- src/sys/ufs/ffs/ffs_extern.h (revision 177) +++ src/sys/ufs/ffs/ffs_extern.h (working copy) @@ -63,12 +63,17 @@ void ffs_clrblock(struct fs *, u_char *, ufs1_daddr_t); int ffs_copyonwrite(struct vnode *, struct buf *); int ffs_flushfiles(struct mount *, int, struct thread *); +vfs_fhtovp_t ffs_fhtovp; void ffs_fragacct(struct fs *, int, int32_t [], int); int ffs_freefile(struct ufsmount *, struct fs *, struct vnode *, ino_t, int); +vop_fsync_t ffs_fsync; +vop_getpages_t ffs_getpages; int ffs_isblock(struct fs *, u_char *, ufs1_daddr_t); void ffs_load_inode(struct buf *, struct inode *, struct fs *, ino_t); +vfs_mount_t ffs_mount; int ffs_mountroot(void); +vop_read_t ffs_read; int ffs_reallocblks(struct vop_reallocblks_args *); int ffs_realloccg(struct inode *, ufs2_daddr_t, ufs2_daddr_t, ufs2_daddr_t, int, int, struct ucred *, struct buf **); @@ -78,13 +83,18 @@ int ffs_snapshot(struct mount *mp, char *snapfile); void ffs_snapshot_mount(struct mount *mp); void ffs_snapshot_unmount(struct mount *mp); +vfs_statfs_t ffs_statfs; +vfs_sync_t ffs_sync; int ffs_syncvnode(struct vnode *vp, int waitfor); int ffs_truncate(struct vnode *, off_t, int, struct ucred *, struct thread *); +vfs_unmount_t ffs_unmount; int ffs_update(struct vnode *, int); int ffs_valloc(struct vnode *, int, struct ucred *, struct vnode **); int ffs_vfree(struct vnode *, ino_t, int); vfs_vget_t ffs_vget; +vfs_vptofh_t ffs_vptofh; +vop_write_t ffs_write; extern struct vop_vector ffs_vnodeops1; extern struct vop_vector ffs_fifoops1; Index: src/sys/ufs/ffs/ffs_vfsops.c =================================================================== --- src/sys/ufs/ffs/ffs_vfsops.c (revision 177) +++ src/sys/ufs/ffs/ffs_vfsops.c (working copy) @@ -68,7 +68,7 @@ #include #include -static uma_zone_t uma_inode, uma_ufs1, uma_ufs2; +uma_zone_t uma_inode, uma_ufs1, uma_ufs2; static int ffs_sbupdate(struct ufsmount *, int); static int ffs_reload(struct mount *, struct thread *); @@ -81,12 +81,6 @@ static vfs_uninit_t ffs_uninit; static vfs_extattrctl_t ffs_extattrctl; static vfs_cmount_t ffs_cmount; -static vfs_unmount_t ffs_unmount; -static vfs_mount_t ffs_mount; -static vfs_statfs_t ffs_statfs; -static vfs_fhtovp_t ffs_fhtovp; -static vfs_vptofh_t ffs_vptofh; -static vfs_sync_t ffs_sync; static struct vfsops ufs_vfsops = { .vfs_extattrctl = ffs_extattrctl, @@ -118,7 +112,7 @@ static const char *ffs_opts[] = { "from", "export", NULL }; -static int +int ffs_mount(struct mount *mp, struct thread *td) { struct vnode *devvp; @@ -900,7 +894,7 @@ /* * unmount system call */ -static int +int ffs_unmount(mp, mntflags, td) struct mount *mp; int mntflags; @@ -1020,7 +1014,7 @@ /* * Get filesystem statistics. */ -static int +int ffs_statfs(mp, sbp, td) struct mount *mp; struct statfs *sbp; @@ -1056,7 +1050,7 @@ * * Note: we are always called with the filesystem marked `MPBUSY'. */ -static int +int ffs_sync(mp, waitfor, td) struct mount *mp; int waitfor; @@ -1334,7 +1328,7 @@ * - check that the given client host has export rights and return * those rights via. exflagsp and credanonp */ -static int +int ffs_fhtovp(mp, fhp, vpp) struct mount *mp; struct fid *fhp; @@ -1355,7 +1349,7 @@ * Vnode pointer to File handle */ /* ARGSUSED */ -static int +int ffs_vptofh(vp, fhp) struct vnode *vp; struct fid *fhp; Index: src/sys/kern/vfs_vnops.c =================================================================== --- src/sys/kern/vfs_vnops.c (revision 177) +++ src/sys/kern/vfs_vnops.c (working copy) @@ -122,7 +122,7 @@ if ((fmode & O_EXCL) == 0 && (fmode & O_NOFOLLOW) == 0) ndp->ni_cnd.cn_flags |= FOLLOW; bwillwrite(); - if ((error = namei(ndp)) != 0) + if ((error = namei(ndp)) != 0) return (error); vfslocked = (ndp->ni_cnd.cn_flags & GIANTHELD) != 0; ndp->ni_cnd.cn_flags &= ~MPSAFE; Index: src/sys/kern/vfs_lookup.c =================================================================== --- src/sys/kern/vfs_lookup.c (revision 177) +++ src/sys/kern/vfs_lookup.c (working copy) @@ -255,6 +255,7 @@ auio.uio_resid = MAXPATHLEN; error = VOP_READLINK(ndp->ni_vp, &auio, cnp->cn_cred); if (error) { + printf("%s: VOP_READLINK returned %d\n", __func__, error); if (ndp->ni_pathlen > 1) uma_zfree(namei_zone, cp); break; @@ -554,6 +555,9 @@ goto unionlookup; } + if (error == EOPNOTSUPP) { + printf("%s: EOPNOTSUPP!\n", __func__); + } if (error != EJUSTRETURN) goto bad; /* Index: src/sys/kern/vfs_subr.c =================================================================== --- src/sys/kern/vfs_subr.c (revision 177) +++ src/sys/kern/vfs_subr.c (working copy) @@ -1962,6 +1962,7 @@ v_incr_usecount(vp, -1); vp->v_iflag |= VI_OWEINACT; if (VOP_ISLOCKED(vp, NULL) != LK_EXCLUSIVE) { + printf("%s: VOP_ISLOCKED(%p, NULL) = %d\n", __func__, vp, VOP_ISLOCKED(vp, NULL)); error = VOP_LOCK(vp, LK_EXCLUPGRADE|LK_INTERLOCK|LK_NOWAIT, td); VI_LOCK(vp); if (error)