Index: sys/ufs/ext2fs/ext2fs_vfsops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ext2fs/ext2fs_vfsops.c,v retrieving revision 1.190 diff -p -u -4 -r1.190 ext2fs_vfsops.c --- sys/ufs/ext2fs/ext2fs_vfsops.c 23 Feb 2015 17:05:58 -0000 1.190 +++ sys/ufs/ext2fs/ext2fs_vfsops.c 9 Mar 2015 09:35:11 -0000 @@ -155,9 +155,8 @@ static const struct genfs_ops ext2fs_gen static const struct ufs_ops ext2fs_ufsops = { .uo_itimes = ext2fs_itimes, .uo_update = ext2fs_update, - .uo_vfree = ext2fs_vfree, }; /* Fill in the inode uid/gid from ext2 halves. */ void Index: sys/ufs/ffs/ffs_alloc.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ffs/ffs_alloc.c,v retrieving revision 1.147 diff -p -u -4 -r1.147 ffs_alloc.c --- sys/ufs/ffs/ffs_alloc.c 8 Sep 2014 20:52:37 -0000 1.147 +++ sys/ufs/ffs/ffs_alloc.c 9 Mar 2015 09:35:12 -0000 @@ -554,22 +554,18 @@ nospace: * * => um_lock not held upon entry or return */ int -ffs_valloc(struct vnode *pvp, int mode, kauth_cred_t cred, - struct vnode **vpp) +ffs_valloc(struct vnode *pvp, int mode, kauth_cred_t cred, ino_t *inop) { struct ufsmount *ump; struct inode *pip; struct fs *fs; - struct inode *ip; - struct timespec ts; ino_t ino, ipref; int cg, error; UFS_WAPBL_JUNLOCK_ASSERT(pvp->v_mount); - *vpp = NULL; pip = VTOI(pvp); fs = pip->i_fs; ump = pip->i_ump; @@ -602,65 +598,17 @@ ffs_valloc(struct vnode *pvp, int mode, ino = (ino_t)ffs_hashalloc(pip, cg, ipref, mode, 0, ffs_nodealloccg); if (ino == 0) goto noinodes; UFS_WAPBL_END(pvp->v_mount); - error = VFS_VGET(pvp->v_mount, ino, vpp); - if (error) { - int err; - err = UFS_WAPBL_BEGIN(pvp->v_mount); - if (err == 0) - ffs_vfree(pvp, ino, mode); - if (err == 0) - UFS_WAPBL_END(pvp->v_mount); - return (error); - } - KASSERT((*vpp)->v_type == VNON); - ip = VTOI(*vpp); - if (ip->i_mode) { -#if 0 - printf("mode = 0%o, inum = %d, fs = %s\n", - ip->i_mode, ip->i_number, fs->fs_fsmnt); -#else - printf("dmode %x mode %x dgen %x gen %x\n", - DIP(ip, mode), ip->i_mode, - DIP(ip, gen), ip->i_gen); - printf("size %llx blocks %llx\n", - (long long)DIP(ip, size), (long long)DIP(ip, blocks)); - printf("ino %llu ipref %llu\n", (unsigned long long)ino, - (unsigned long long)ipref); -#if 0 - error = bread(ump->um_devvp, FFS_FSBTODB(fs, ino_to_fsba(fs, ino)), - (int)fs->fs_bsize, NOCRED, 0, &bp); -#endif + *inop = ino; + return 0; -#endif - panic("ffs_valloc: dup alloc"); - } - if (DIP(ip, blocks)) { /* XXX */ - printf("free inode %llu on %s had %" PRId64 " blocks\n", - (unsigned long long)ino, fs->fs_fsmnt, DIP(ip, blocks)); - DIP_ASSIGN(ip, blocks, 0); - } - ip->i_flag &= ~IN_SPACECOUNTED; - ip->i_flags = 0; - DIP_ASSIGN(ip, flags, 0); - /* - * Set up a new generation number for this inode. - */ - ip->i_gen++; - DIP_ASSIGN(ip, gen, ip->i_gen); - if (fs->fs_magic == FS_UFS2_MAGIC) { - vfs_timestamp(&ts); - ip->i_ffs2_birthtime = ts.tv_sec; - ip->i_ffs2_birthnsec = ts.tv_nsec; - } - return (0); noinodes: mutex_exit(&ump->um_lock); UFS_WAPBL_END(pvp->v_mount); ffs_fserr(fs, kauth_cred_geteuid(cred), "out of inodes"); uprintf("\n%s: create/symlink failed, no inodes free\n", fs->fs_fsmnt); - return (ENOSPC); + return ENOSPC; } /* * Find a cylinder group in which to place a directory. Index: sys/ufs/ffs/ffs_extern.h =================================================================== RCS file: /cvsroot/src/sys/ufs/ffs/ffs_extern.h,v retrieving revision 1.80 diff -p -u -4 -r1.80 ffs_extern.h --- sys/ufs/ffs/ffs_extern.h 16 Jun 2013 13:33:30 -0000 1.80 +++ sys/ufs/ffs/ffs_extern.h 9 Mar 2015 09:35:12 -0000 @@ -91,9 +91,9 @@ __BEGIN_DECLS int ffs_alloc(struct inode *, daddr_t, daddr_t , int, int, kauth_cred_t, daddr_t *); int ffs_realloccg(struct inode *, daddr_t, daddr_t, int, int , kauth_cred_t, struct buf **, daddr_t *); -int ffs_valloc(struct vnode *, int, kauth_cred_t, struct vnode **); +int ffs_valloc(struct vnode *, int, kauth_cred_t, ino_t *); daddr_t ffs_blkpref_ufs1(struct inode *, daddr_t, int, int, int32_t *); daddr_t ffs_blkpref_ufs2(struct inode *, daddr_t, int, int, int64_t *); int ffs_blkalloc(struct inode *, daddr_t, long); int ffs_blkalloc_ump(struct ufsmount *, daddr_t, long); Index: sys/ufs/ffs/ffs_vfsops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ffs/ffs_vfsops.c,v retrieving revision 1.321 diff -p -u -4 -r1.321 ffs_vfsops.c --- sys/ufs/ffs/ffs_vfsops.c 3 Mar 2015 17:56:51 -0000 1.321 +++ sys/ufs/ffs/ffs_vfsops.c 9 Mar 2015 09:35:12 -0000 @@ -113,8 +113,11 @@ MODULE(MODULE_CLASS_VFS, ffs, NULL); static int ffs_vfs_fsync(vnode_t *, int); static int ffs_superblock_validate(struct fs *); +static int ffs_init_vnode(struct ufsmount *, struct vnode *, ino_t); +static void ffs_deinit_vnode(struct ufsmount *, struct vnode *); + static struct sysctllog *ffs_sysctl_log; static kauth_listener_t ffs_snapshot_listener; @@ -149,8 +152,9 @@ struct vfsops ffs_vfsops = { .vfs_statvfs = ffs_statvfs, .vfs_sync = ffs_sync, .vfs_vget = ufs_vget, .vfs_loadvnode = ffs_loadvnode, + .vfs_newvnode = ffs_newvnode, .vfs_fhtovp = ffs_fhtovp, .vfs_vptofh = ffs_vptofh, .vfs_init = ffs_init, .vfs_reinit = ffs_reinit, @@ -175,10 +179,8 @@ static const struct genfs_ops ffs_genfso static const struct ufs_ops ffs_ufsops = { .uo_itimes = ffs_itimes, .uo_update = ffs_update, .uo_truncate = ffs_truncate, - .uo_valloc = ffs_valloc, - .uo_vfree = ffs_vfree, .uo_balloc = ffs_balloc, .uo_snapgone = ffs_snapgone, }; @@ -1910,27 +1912,18 @@ ffs_sync(struct mount *mp, int waitfor, return (allerror); } /* - * Read an inode from disk and initialize this vnode / inode pair. - * Caller assures no other thread will try to load this inode. + * Load inode from disk and initialize vnode. */ -int -ffs_loadvnode(struct mount *mp, struct vnode *vp, - const void *key, size_t key_len, const void **new_key) +static int +ffs_init_vnode(struct ufsmount *ump, struct vnode *vp, ino_t ino) { - ino_t ino; struct fs *fs; struct inode *ip; - struct ufsmount *ump; struct buf *bp; - dev_t dev; int error; - KASSERT(key_len == sizeof(ino)); - memcpy(&ino, key, key_len); - ump = VFSTOUFS(mp); - dev = ump->um_dev; fs = ump->um_fs; /* Read in the disk contents for the inode. */ error = bread(ump->um_devvp, FFS_FSBTODB(fs, ino_to_fsba(fs, ino)), @@ -1940,32 +1933,84 @@ ffs_loadvnode(struct mount *mp, struct v /* Allocate and initialize inode. */ ip = pool_cache_get(ffs_inode_cache, PR_WAITOK); memset(ip, 0, sizeof(struct inode)); - vp->v_tag = VT_UFS; - vp->v_op = ffs_vnodeop_p; - vp->v_vflag |= VV_LOCKSWORK; - vp->v_data = ip; - ip->i_vnode = vp; ip->i_ump = ump; ip->i_fs = fs; - ip->i_dev = dev; + ip->i_dev = ump->um_dev; ip->i_number = ino; + if (ump->um_fstype == UFS1) + ip->i_din.ffs1_din = pool_cache_get(ffs_dinode1_cache, + PR_WAITOK); + else + ip->i_din.ffs2_din = pool_cache_get(ffs_dinode2_cache, + PR_WAITOK); + ffs_load_inode(bp, ip, fs, ino); + brelse(bp, 0); + ip->i_vnode = vp; #if defined(QUOTA) || defined(QUOTA2) ufsquota_init(ip); #endif + /* Initialise vnode with this inode. */ + vp->v_tag = VT_UFS; + vp->v_op = ffs_vnodeop_p; + vp->v_vflag |= VV_LOCKSWORK; + vp->v_data = ip; + /* Initialize genfs node. */ genfs_node_init(vp, &ffs_genfsops); - if (ip->i_ump->um_fstype == UFS1) - ip->i_din.ffs1_din = pool_cache_get(ffs_dinode1_cache, - PR_WAITOK); + return 0; +} + +/* + * Undo ffs_init_vnode(). + */ +static void +ffs_deinit_vnode(struct ufsmount *ump, struct vnode *vp) +{ + struct inode *ip = VTOI(vp); + + if (ump->um_fstype == UFS1) + pool_cache_put(ffs_dinode1_cache, ip->i_din.ffs1_din); else - ip->i_din.ffs2_din = pool_cache_get(ffs_dinode2_cache, - PR_WAITOK); - ffs_load_inode(bp, ip, fs, ino); - brelse(bp, 0); + pool_cache_put(ffs_dinode2_cache, ip->i_din.ffs2_din); + pool_cache_put(ffs_inode_cache, ip); + + genfs_node_destroy(vp); + vp->v_data = NULL; +} + +/* + * Read an inode from disk and initialize this vnode / inode pair. + * Caller assures no other thread will try to load this inode. + */ +int +ffs_loadvnode(struct mount *mp, struct vnode *vp, + const void *key, size_t key_len, const void **new_key) +{ + ino_t ino; + struct fs *fs; + struct inode *ip; + struct ufsmount *ump; + int error; + + KASSERT(key_len == sizeof(ino)); + memcpy(&ino, key, key_len); + ump = VFSTOUFS(mp); + fs = ump->um_fs; + + error = ffs_init_vnode(ump, vp, ino); + if (error) + return error; + + ip = VTOI(vp); + if (ip->i_mode == 0) { + ffs_deinit_vnode(ump, vp); + + return ENOENT; + } /* Initialize the vnode from the inode. */ ufs_vinit(mp, ffs_specop_p, ffs_fifoop_p, &vp); @@ -1987,8 +2032,121 @@ ffs_loadvnode(struct mount *mp, struct v return 0; } /* + * Create a new inode on disk and initialize this vnode / inode pair. + */ +int +ffs_newvnode(struct mount *mp, struct vnode *dvp, struct vnode *vp, + struct vattr *vap, kauth_cred_t cred, + size_t *key_len, const void **new_key) +{ + ino_t ino; + struct fs *fs; + struct inode *ip; + struct timespec ts; + struct ufsmount *ump; + int error, mode; + + KASSERT(dvp->v_mount == mp); + KASSERT(vap->va_type != VNON); + + *key_len = sizeof(ino); + ump = VFSTOUFS(mp); + fs = ump->um_fs; + mode = MAKEIMODE(vap->va_type, vap->va_mode); + + /* Allocate fresh inode. */ + error = ffs_valloc(dvp, mode, cred, &ino); + if (error) + return error; + + /* Attach inode to vnode. */ + error = ffs_init_vnode(ump, vp, ino); + if (error) { + if (UFS_WAPBL_BEGIN(mp) == 0) { + ffs_vfree(dvp, ino, mode); + UFS_WAPBL_END(mp); + } + return error; + } + + ip = VTOI(vp); + if (ip->i_mode || DIP(ip, size) || DIP(ip, blocks)) { + printf("free ino %" PRId64 " on %s:\n", ino, fs->fs_fsmnt); + printf("dmode %x mode %x dgen %x gen %x\n", + DIP(ip, mode), ip->i_mode, + DIP(ip, gen), ip->i_gen); + printf("size %" PRIx64 " blocks %" PRIx64 "\n", + DIP(ip, size), DIP(ip, blocks)); + panic("ffs_init_vnode: dup alloc"); + } + + /* Set uid / gid. */ + if (cred == NOCRED || cred == FSCRED) { + ip->i_gid = 0; + ip->i_uid = 0; + } else { + ip->i_gid = VTOI(dvp)->i_gid; + ip->i_uid = kauth_cred_geteuid(cred); + } + DIP_ASSIGN(ip, gid, ip->i_gid); + DIP_ASSIGN(ip, uid, ip->i_uid); + +#if defined(QUOTA) || defined(QUOTA2) + error = UFS_WAPBL_BEGIN(mp); + if (error) { + ffs_deinit_vnode(ump, vp); + + return error; + } + error = chkiq(ip, 1, cred, 0); + if (error) { + ffs_vfree(dvp, ino, mode); + UFS_WAPBL_END(mp); + ffs_deinit_vnode(ump, vp); + + return error; + } + UFS_WAPBL_END(mp); +#endif + + /* Set type and finalize. */ + ip->i_flags = 0; + DIP_ASSIGN(ip, flags, 0); + ip->i_mode = mode; + DIP_ASSIGN(ip, mode, mode); + if (vap->va_rdev != VNOVAL) { + /* + * Want to be able to use this to make badblock + * inodes, so don't truncate the dev number. + */ + if (ump->um_fstype == UFS1) + ip->i_ffs1_rdev = ufs_rw32(vap->va_rdev, + UFS_MPNEEDSWAP(ump)); + else + ip->i_ffs2_rdev = ufs_rw64(vap->va_rdev, + UFS_MPNEEDSWAP(ump)); + } + ufs_vinit(mp, ffs_specop_p, ffs_fifoop_p, &vp); + ip->i_devvp = ump->um_devvp; + vref(ip->i_devvp); + + /* Set up a new generation number for this inode. */ + ip->i_gen++; + DIP_ASSIGN(ip, gen, ip->i_gen); + if (fs->fs_magic == FS_UFS2_MAGIC) { + vfs_timestamp(&ts); + ip->i_ffs2_birthtime = ts.tv_sec; + ip->i_ffs2_birthnsec = ts.tv_nsec; + } + + uvm_vnp_setsize(vp, ip->i_size); + *new_key = &ip->i_number; + return 0; +} + +/* * File handle to vnode * * Have to be really careful about stale file handles: * - check that the inode number is valid Index: sys/ufs/ffs/ffs_wapbl.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ffs/ffs_wapbl.c,v retrieving revision 1.28 diff -p -u -4 -r1.28 ffs_wapbl.c --- sys/ufs/ffs/ffs_wapbl.c 11 Jul 2014 16:17:29 -0000 1.28 +++ sys/ufs/ffs/ffs_wapbl.c 9 Mar 2015 09:35:12 -0000 @@ -609,33 +609,36 @@ static int wapbl_create_infs_log(struct mount *mp, struct fs *fs, struct vnode *devvp, daddr_t *startp, size_t *countp, uint64_t *extradatap) { struct vnode *vp, *rvp; + struct vattr va; struct inode *ip; int error; if ((error = VFS_ROOT(mp, &rvp)) != 0) return error; - error = UFS_VALLOC(rvp, 0 | S_IFREG, NOCRED, &vp); - if (mp->mnt_flag & MNT_UPDATE) { - vput(rvp); - } else { - VOP_UNLOCK(rvp); - vgone(rvp); - } - if (error != 0) + vattr_null(&va); + va.va_type = VREG; + va.va_mode = 0; + + error = vcache_new(mp, rvp, &va, NOCRED, &vp); + vput(rvp); + if (error) + return error; + + error = vn_lock(vp, LK_EXCLUSIVE); + if (error) { + vrele(vp); return error; + } - vp->v_type = VREG; ip = VTOI(vp); - ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; - ip->i_mode = 0 | IFREG; - DIP_ASSIGN(ip, mode, ip->i_mode); ip->i_flags = SF_LOG; DIP_ASSIGN(ip, flags, ip->i_flags); ip->i_nlink = 1; DIP_ASSIGN(ip, nlink, 1); + ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; ffs_update(vp, NULL, NULL, UPDATE_WAIT); if ((error = wapbl_allocate_log_file(mp, vp, startp, countp, extradatap)) != 0) { Index: sys/ufs/mfs/mfs_vfsops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/mfs/mfs_vfsops.c,v retrieving revision 1.109 diff -p -u -4 -r1.109 mfs_vfsops.c --- sys/ufs/mfs/mfs_vfsops.c 14 Jan 2015 11:21:31 -0000 1.109 +++ sys/ufs/mfs/mfs_vfsops.c 9 Mar 2015 09:35:12 -0000 @@ -100,8 +100,9 @@ struct vfsops mfs_vfsops = { .vfs_statvfs = mfs_statvfs, .vfs_sync = ffs_sync, .vfs_vget = ufs_vget, .vfs_loadvnode = ffs_loadvnode, + .vfs_newvnode = ffs_newvnode, .vfs_fhtovp = ffs_fhtovp, .vfs_vptofh = ffs_vptofh, .vfs_init = mfs_init, .vfs_reinit = mfs_reinit, Index: sys/ufs/ufs/ufs_extern.h =================================================================== RCS file: /cvsroot/src/sys/ufs/ufs/ufs_extern.h,v retrieving revision 1.77 diff -p -u -4 -r1.77 ufs_extern.h --- sys/ufs/ufs/ufs_extern.h 29 Oct 2014 01:13:28 -0000 1.77 +++ sys/ufs/ufs/ufs_extern.h 9 Mar 2015 09:35:13 -0000 @@ -183,10 +183,8 @@ int ufs_fhtovp(struct mount *, struct uf /* ufs_vnops.c */ void ufs_vinit(struct mount *, int (**)(void *), int (**)(void *), struct vnode **); -int ufs_makeinode(int, struct vnode *, const struct ufs_lookup_results *, - struct vnode **, struct componentname *); int ufs_gop_alloc(struct vnode *, off_t, off_t, int, kauth_cred_t); void ufs_gop_markupdate(struct vnode *, int); __END_DECLS Index: sys/ufs/ufs/ufs_vfsops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ufs/ufs_vfsops.c,v retrieving revision 1.53 diff -p -u -4 -r1.53 ufs_vfsops.c --- sys/ufs/ufs/ufs_vfsops.c 8 May 2014 08:21:53 -0000 1.53 +++ sys/ufs/ufs/ufs_vfsops.c 9 Mar 2015 09:35:13 -0000 @@ -238,8 +238,10 @@ ufs_fhtovp(struct mount *mp, struct ufid struct inode *ip; int error; if ((error = VFS_VGET(mp, ufhp->ufid_ino, &nvp)) != 0) { + if (error == ENOENT) + error = ESTALE; *vpp = NULLVP; return (error); } ip = VTOI(nvp); Index: sys/ufs/ufs/ufs_vnops.c =================================================================== RCS file: /cvsroot/src/sys/ufs/ufs/ufs_vnops.c,v retrieving revision 1.224 diff -p -u -4 -r1.224 ufs_vnops.c --- sys/ufs/ufs/ufs_vnops.c 29 Oct 2014 01:13:28 -0000 1.224 +++ sys/ufs/ufs/ufs_vnops.c 9 Mar 2015 09:35:13 -0000 @@ -118,8 +118,10 @@ __CTASSERT(LFS_MAXNAMLEN == FFS_MAXNAMLE static int ufs_chmod(struct vnode *, int, kauth_cred_t, struct lwp *); static int ufs_chown(struct vnode *, uid_t, gid_t, kauth_cred_t, struct lwp *); +static int ufs_makeinode(struct vattr *, struct vnode *, + const struct ufs_lookup_results *, struct vnode **, struct componentname *); /* * A virgin directory (no blushing please). */ @@ -152,11 +154,9 @@ ufs_create(void *v) * UFS_WAPBL_BEGIN1(dvp->v_mount, dvp) performed by successful * ufs_makeinode */ fstrans_start(dvp->v_mount, FSTRANS_SHARED); - error = - ufs_makeinode(MAKEIMODE(ap->a_vap->va_type, ap->a_vap->va_mode), - dvp, ulr, ap->a_vpp, ap->a_cnp); + error = ufs_makeinode(ap->a_vap, dvp, ulr, ap->a_vpp, ap->a_cnp); if (error) { fstrans_done(dvp->v_mount); return (error); } @@ -183,10 +183,8 @@ ufs_mknod(void *v) struct vattr *vap; struct vnode **vpp; struct inode *ip; int error; - struct mount *mp; - ino_t ino; struct ufs_lookup_results *ulr; vap = ap->a_vap; vpp = ap->a_vpp; @@ -199,41 +197,16 @@ ufs_mknod(void *v) * UFS_WAPBL_BEGIN1(dvp->v_mount, dvp) performed by successful * ufs_makeinode */ fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED); - if ((error = - ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode), - ap->a_dvp, ulr, vpp, ap->a_cnp)) != 0) + if ((error = ufs_makeinode(vap, ap->a_dvp, ulr, vpp, ap->a_cnp)) != 0) goto out; VN_KNOTE(ap->a_dvp, NOTE_WRITE); ip = VTOI(*vpp); - mp = (*vpp)->v_mount; - ino = ip->i_number; ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; - if (vap->va_rdev != VNOVAL) { - struct ufsmount *ump = ip->i_ump; - /* - * Want to be able to use this to make badblock - * inodes, so don't truncate the dev number. - */ - if (ump->um_fstype == UFS1) - ip->i_ffs1_rdev = ufs_rw32(vap->va_rdev, - UFS_MPNEEDSWAP(ump)); - else - ip->i_ffs2_rdev = ufs_rw64(vap->va_rdev, - UFS_MPNEEDSWAP(ump)); - } UFS_WAPBL_UPDATE(*vpp, NULL, NULL, 0); UFS_WAPBL_END1(ap->a_dvp->v_mount, ap->a_dvp); - /* - * Remove inode so that it will be reloaded by vcache_get and - * checked to see if it is an alias of an existing entry in - * the inode cache. - */ - (*vpp)->v_type = VNON; VOP_UNLOCK(*vpp); - vgone(*vpp); - error = vcache_get(mp, &ino, sizeof(ino), vpp); out: fstrans_done(ap->a_dvp->v_mount); if (error != 0) { *vpp = NULL; @@ -950,9 +923,9 @@ ufs_mkdir(void *v) struct inode *ip, *dp = VTOI(dvp); struct buf *bp; struct dirtemplate dirtemplate; struct direct *newdir; - int error, dmode; + int error; struct ufsmount *ump = dp->i_ump; int dirblksiz = ump->um_dirblksiz; struct ufs_lookup_results *ulr; @@ -961,48 +934,37 @@ ufs_mkdir(void *v) /* XXX should handle this material another way */ ulr = &dp->i_crap; UFS_CHECK_CRAPCOUNTER(dp); + KASSERT(vap->va_type == VDIR); + if ((nlink_t)dp->i_nlink >= LINK_MAX) { error = EMLINK; goto out; } - dmode = vap->va_mode & ACCESSPERMS; - dmode |= IFDIR; /* * Must simulate part of ufs_makeinode here to acquire the inode, * but not have it entered in the parent directory. The entry is * made later after writing "." and ".." entries. */ - if ((error = UFS_VALLOC(dvp, dmode, cnp->cn_cred, ap->a_vpp)) != 0) + error = vcache_new(dvp->v_mount, dvp, vap, cnp->cn_cred, ap->a_vpp); + if (error) goto out; - - tvp = *ap->a_vpp; - ip = VTOI(tvp); - - error = UFS_WAPBL_BEGIN(ap->a_dvp->v_mount); + error = vn_lock(*ap->a_vpp, LK_EXCLUSIVE); if (error) { - UFS_VFREE(tvp, ip->i_number, dmode); - vput(tvp); + vrele(*ap->a_vpp); + *ap->a_vpp = NULL; goto out; } - ip->i_uid = kauth_cred_geteuid(cnp->cn_cred); - DIP_ASSIGN(ip, uid, ip->i_uid); - ip->i_gid = dp->i_gid; - DIP_ASSIGN(ip, gid, ip->i_gid); -#if defined(QUOTA) || defined(QUOTA2) - if ((error = chkiq(ip, 1, cnp->cn_cred, 0))) { - UFS_VFREE(tvp, ip->i_number, dmode); - UFS_WAPBL_END(dvp->v_mount); - fstrans_done(dvp->v_mount); - vput(tvp); - return (error); + error = UFS_WAPBL_BEGIN(ap->a_dvp->v_mount); + if (error) { + vput(*ap->a_vpp); + goto out; } -#endif + + tvp = *ap->a_vpp; + ip = VTOI(tvp); ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; - ip->i_mode = dmode; - DIP_ASSIGN(ip, mode, dmode); - tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */ ip->i_nlink = 2; DIP_ASSIGN(ip, nlink, 2); if (cnp->cn_flags & ISWHITEOUT) { ip->i_flags |= UF_OPAQUE; @@ -1222,10 +1184,10 @@ ufs_symlink(void *v) * UFS_WAPBL_BEGIN1(dvp->v_mount, dvp) performed by successful * ufs_makeinode */ fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED); - error = ufs_makeinode(IFLNK | ap->a_vap->va_mode, ap->a_dvp, ulr, - vpp, ap->a_cnp); + KASSERT(ap->a_vap->va_type == VLNK); + error = ufs_makeinode(ap->a_vap, ap->a_dvp, ulr, vpp, ap->a_cnp); if (error) goto out; VN_KNOTE(ap->a_dvp, NOTE_WRITE); vp = *vpp; @@ -1781,62 +1743,43 @@ ufs_vinit(struct mount *mntp, int (**spe /* * Allocate a new inode. */ int -ufs_makeinode(int mode, struct vnode *dvp, const struct ufs_lookup_results *ulr, +ufs_makeinode(struct vattr *vap, struct vnode *dvp, + const struct ufs_lookup_results *ulr, struct vnode **vpp, struct componentname *cnp) { - struct inode *ip, *pdir; + struct inode *ip; struct direct *newdir; struct vnode *tvp; int error; UFS_WAPBL_JUNLOCK_ASSERT(dvp->v_mount); - pdir = VTOI(dvp); - - if ((mode & IFMT) == 0) - mode |= IFREG; - - if ((error = UFS_VALLOC(dvp, mode, cnp->cn_cred, vpp)) != 0) { - return (error); + error = vcache_new(dvp->v_mount, dvp, vap, cnp->cn_cred, &tvp); + if (error) + return error; + error = vn_lock(tvp, LK_EXCLUSIVE); + if (error) { + vrele(tvp); + return error; } - tvp = *vpp; + *vpp = tvp; ip = VTOI(tvp); - ip->i_gid = pdir->i_gid; - DIP_ASSIGN(ip, gid, ip->i_gid); - ip->i_uid = kauth_cred_geteuid(cnp->cn_cred); - DIP_ASSIGN(ip, uid, ip->i_uid); error = UFS_WAPBL_BEGIN1(dvp->v_mount, dvp); if (error) { - /* - * Note, we can't VOP_VFREE(tvp) here like we should - * because we can't write to the disk. Instead, we leave - * the vnode dangling from the journal. - */ vput(tvp); return (error); } -#if defined(QUOTA) || defined(QUOTA2) - if ((error = chkiq(ip, 1, cnp->cn_cred, 0))) { - UFS_VFREE(tvp, ip->i_number, mode); - UFS_WAPBL_END1(dvp->v_mount, dvp); - vput(tvp); - return (error); - } -#endif ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE; - ip->i_mode = mode; - DIP_ASSIGN(ip, mode, mode); - tvp->v_type = IFTOVT(mode); /* Rest init'd in getnewvnode(). */ ip->i_nlink = 1; DIP_ASSIGN(ip, nlink, 1); /* Authorize setting SGID if needed. */ if (ip->i_mode & ISGID) { error = kauth_authorize_vnode(cnp->cn_cred, KAUTH_VNODE_WRITE_SECURITY, tvp, NULL, genfs_can_chmod(tvp->v_type, cnp->cn_cred, ip->i_uid, - ip->i_gid, mode)); + ip->i_gid, MAKEIMODE(vap->va_type, vap->va_mode))); if (error) { ip->i_mode &= ~ISGID; DIP_ASSIGN(ip, mode, ip->i_mode); } @@ -1869,9 +1812,8 @@ ufs_makeinode(int mode, struct vnode *dv ip->i_nlink = 0; DIP_ASSIGN(ip, nlink, 0); ip->i_flag |= IN_CHANGE; UFS_WAPBL_UPDATE(tvp, NULL, NULL, 0); - tvp->v_type = VNON; /* explodes later if VBLK */ UFS_WAPBL_END1(dvp->v_mount, dvp); vput(tvp); return (error); } Index: sys/ufs/ufs/ufsmount.h =================================================================== RCS file: /cvsroot/src/sys/ufs/ufs/ufsmount.h,v retrieving revision 1.41 diff -p -u -4 -r1.41 ufsmount.h --- sys/ufs/ufs/ufsmount.h 11 Aug 2013 04:36:17 -0000 1.41 +++ sys/ufs/ufs/ufsmount.h 9 Mar 2015 09:35:13 -0000 @@ -133,10 +133,8 @@ struct ufs_ops { const struct timespec *, const struct timespec *); int (*uo_update)(struct vnode *, const struct timespec *, const struct timespec *, int); int (*uo_truncate)(struct vnode *, off_t, int, kauth_cred_t); - int (*uo_valloc)(struct vnode *, int, kauth_cred_t, struct vnode **); - int (*uo_vfree)(struct vnode *, ino_t, int); int (*uo_balloc)(struct vnode *, off_t, int, kauth_cred_t, int, struct buf **); void (*uo_snapgone)(struct vnode *); }; @@ -148,12 +146,8 @@ struct ufs_ops { #define UFS_UPDATE(vp, acc, mod, flags) \ (*UFS_OPS(vp)->uo_update)((vp), (acc), (mod), (flags)) #define UFS_TRUNCATE(vp, off, flags, cr) \ (*UFS_OPS(vp)->uo_truncate)((vp), (off), (flags), (cr)) -#define UFS_VALLOC(vp, mode, cr, vpp) \ - (*UFS_OPS(vp)->uo_valloc)((vp), (mode), (cr), (vpp)) -#define UFS_VFREE(vp, ino, mode) \ - (*UFS_OPS(vp)->uo_vfree)((vp), (ino), (mode)) #define UFS_BALLOC(vp, off, size, cr, flags, bpp) \ (*UFS_OPS(vp)->uo_balloc)((vp), (off), (size), (cr), (flags), (bpp)) #define UFS_SNAPGONE(vp) \ (*UFS_OPS(vp)->uo_snapgone)((vp))