Module Name: src Committed By: hannken Date: Tue Mar 17 09:39:29 UTC 2015
Modified Files: src/sys/ufs/ext2fs: ext2fs_vfsops.c src/sys/ufs/ffs: ffs_alloc.c ffs_extern.h ffs_vfsops.c ffs_wapbl.c src/sys/ufs/mfs: mfs_vfsops.c src/sys/ufs/ufs: ufs_extern.h ufs_vfsops.c ufs_vnops.c ufsmount.h Log Message: Change ffs to use vcache_new: - Change ffs_valloc to return an inode number. - Remove now obsolete UFS operations UFS_VALLOC and UFS_VFREE. - Make ufs_makeinode private to ufs_vnops.c and pass vattr instead of mode. To generate a diff of this commit: cvs rdiff -u -r1.190 -r1.191 src/sys/ufs/ext2fs/ext2fs_vfsops.c cvs rdiff -u -r1.147 -r1.148 src/sys/ufs/ffs/ffs_alloc.c cvs rdiff -u -r1.80 -r1.81 src/sys/ufs/ffs/ffs_extern.h cvs rdiff -u -r1.324 -r1.325 src/sys/ufs/ffs/ffs_vfsops.c cvs rdiff -u -r1.28 -r1.29 src/sys/ufs/ffs/ffs_wapbl.c cvs rdiff -u -r1.109 -r1.110 src/sys/ufs/mfs/mfs_vfsops.c cvs rdiff -u -r1.77 -r1.78 src/sys/ufs/ufs/ufs_extern.h cvs rdiff -u -r1.53 -r1.54 src/sys/ufs/ufs/ufs_vfsops.c cvs rdiff -u -r1.224 -r1.225 src/sys/ufs/ufs/ufs_vnops.c cvs rdiff -u -r1.41 -r1.42 src/sys/ufs/ufs/ufsmount.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/ufs/ext2fs/ext2fs_vfsops.c diff -u src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.190 src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.191 --- src/sys/ufs/ext2fs/ext2fs_vfsops.c:1.190 Mon Feb 23 17:05:58 2015 +++ src/sys/ufs/ext2fs/ext2fs_vfsops.c Tue Mar 17 09:39:29 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: ext2fs_vfsops.c,v 1.190 2015/02/23 17:05:58 maxv Exp $ */ +/* $NetBSD: ext2fs_vfsops.c,v 1.191 2015/03/17 09:39:29 hannken Exp $ */ /* * Copyright (c) 1989, 1991, 1993, 1994 @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.190 2015/02/23 17:05:58 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ext2fs_vfsops.c,v 1.191 2015/03/17 09:39:29 hannken Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -156,7 +156,6 @@ 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. */ Index: src/sys/ufs/ffs/ffs_alloc.c diff -u src/sys/ufs/ffs/ffs_alloc.c:1.147 src/sys/ufs/ffs/ffs_alloc.c:1.148 --- src/sys/ufs/ffs/ffs_alloc.c:1.147 Mon Sep 8 20:52:37 2014 +++ src/sys/ufs/ffs/ffs_alloc.c Tue Mar 17 09:39:29 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: ffs_alloc.c,v 1.147 2014/09/08 20:52:37 joerg Exp $ */ +/* $NetBSD: ffs_alloc.c,v 1.148 2015/03/17 09:39:29 hannken Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -70,7 +70,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ffs_alloc.c,v 1.147 2014/09/08 20:52:37 joerg Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ffs_alloc.c,v 1.148 2015/03/17 09:39:29 hannken Exp $"); #if defined(_KERNEL_OPT) #include "opt_ffs.h" @@ -555,20 +555,16 @@ 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; @@ -603,63 +599,15 @@ ffs_valloc(struct vnode *pvp, int mode, 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; } /* Index: src/sys/ufs/ffs/ffs_extern.h diff -u src/sys/ufs/ffs/ffs_extern.h:1.80 src/sys/ufs/ffs/ffs_extern.h:1.81 --- src/sys/ufs/ffs/ffs_extern.h:1.80 Sun Jun 16 13:33:30 2013 +++ src/sys/ufs/ffs/ffs_extern.h Tue Mar 17 09:39:29 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: ffs_extern.h,v 1.80 2013/06/16 13:33:30 hannken Exp $ */ +/* $NetBSD: ffs_extern.h,v 1.81 2015/03/17 09:39:29 hannken Exp $ */ /*- * Copyright (c) 1991, 1993, 1994 @@ -92,7 +92,7 @@ int ffs_alloc(struct inode *, daddr_t, d 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); Index: src/sys/ufs/ffs/ffs_vfsops.c diff -u src/sys/ufs/ffs/ffs_vfsops.c:1.324 src/sys/ufs/ffs/ffs_vfsops.c:1.325 --- src/sys/ufs/ffs/ffs_vfsops.c:1.324 Sun Mar 15 09:21:01 2015 +++ src/sys/ufs/ffs/ffs_vfsops.c Tue Mar 17 09:39:29 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: ffs_vfsops.c,v 1.324 2015/03/15 09:21:01 maxv Exp $ */ +/* $NetBSD: ffs_vfsops.c,v 1.325 2015/03/17 09:39:29 hannken Exp $ */ /*- * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.324 2015/03/15 09:21:01 maxv Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.325 2015/03/17 09:39:29 hannken Exp $"); #if defined(_KERNEL_OPT) #include "opt_ffs.h" @@ -114,6 +114,9 @@ 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; @@ -150,6 +153,7 @@ struct vfsops ffs_vfsops = { .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, @@ -176,8 +180,6 @@ 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, }; @@ -1927,25 +1929,16 @@ ffs_sync(struct mount *mp, int waitfor, } /* - * 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. */ @@ -1957,30 +1950,82 @@ 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); @@ -2004,6 +2049,119 @@ ffs_loadvnode(struct mount *mp, struct v } /* + * 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: Index: src/sys/ufs/ffs/ffs_wapbl.c diff -u src/sys/ufs/ffs/ffs_wapbl.c:1.28 src/sys/ufs/ffs/ffs_wapbl.c:1.29 --- src/sys/ufs/ffs/ffs_wapbl.c:1.28 Fri Jul 11 16:17:29 2014 +++ src/sys/ufs/ffs/ffs_wapbl.c Tue Mar 17 09:39:29 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: ffs_wapbl.c,v 1.28 2014/07/11 16:17:29 christos Exp $ */ +/* $NetBSD: ffs_wapbl.c,v 1.29 2015/03/17 09:39:29 hannken Exp $ */ /*- * Copyright (c) 2003,2006,2008 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ffs_wapbl.c,v 1.28 2014/07/11 16:17:29 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ffs_wapbl.c,v 1.29 2015/03/17 09:39:29 hannken Exp $"); #define WAPBL_INTERNAL @@ -610,31 +610,34 @@ wapbl_create_infs_log(struct mount *mp, 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, Index: src/sys/ufs/mfs/mfs_vfsops.c diff -u src/sys/ufs/mfs/mfs_vfsops.c:1.109 src/sys/ufs/mfs/mfs_vfsops.c:1.110 --- src/sys/ufs/mfs/mfs_vfsops.c:1.109 Wed Jan 14 11:21:31 2015 +++ src/sys/ufs/mfs/mfs_vfsops.c Tue Mar 17 09:39:29 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: mfs_vfsops.c,v 1.109 2015/01/14 11:21:31 hannken Exp $ */ +/* $NetBSD: mfs_vfsops.c,v 1.110 2015/03/17 09:39:29 hannken Exp $ */ /* * Copyright (c) 1989, 1990, 1993, 1994 @@ -32,7 +32,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: mfs_vfsops.c,v 1.109 2015/01/14 11:21:31 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: mfs_vfsops.c,v 1.110 2015/03/17 09:39:29 hannken Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -101,6 +101,7 @@ struct vfsops mfs_vfsops = { .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, Index: src/sys/ufs/ufs/ufs_extern.h diff -u src/sys/ufs/ufs/ufs_extern.h:1.77 src/sys/ufs/ufs/ufs_extern.h:1.78 --- src/sys/ufs/ufs/ufs_extern.h:1.77 Wed Oct 29 01:13:28 2014 +++ src/sys/ufs/ufs/ufs_extern.h Tue Mar 17 09:39:29 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_extern.h,v 1.77 2014/10/29 01:13:28 christos Exp $ */ +/* $NetBSD: ufs_extern.h,v 1.78 2015/03/17 09:39:29 hannken Exp $ */ /*- * Copyright (c) 1991, 1993, 1994 @@ -184,8 +184,6 @@ 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); Index: src/sys/ufs/ufs/ufs_vfsops.c diff -u src/sys/ufs/ufs/ufs_vfsops.c:1.53 src/sys/ufs/ufs/ufs_vfsops.c:1.54 --- src/sys/ufs/ufs/ufs_vfsops.c:1.53 Thu May 8 08:21:53 2014 +++ src/sys/ufs/ufs/ufs_vfsops.c Tue Mar 17 09:39:29 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_vfsops.c,v 1.53 2014/05/08 08:21:53 hannken Exp $ */ +/* $NetBSD: ufs_vfsops.c,v 1.54 2015/03/17 09:39:29 hannken Exp $ */ /* * Copyright (c) 1991, 1993, 1994 @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ufs_vfsops.c,v 1.53 2014/05/08 08:21:53 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ufs_vfsops.c,v 1.54 2015/03/17 09:39:29 hannken Exp $"); #if defined(_KERNEL_OPT) #include "opt_ffs.h" @@ -239,6 +239,8 @@ ufs_fhtovp(struct mount *mp, struct ufid int error; if ((error = VFS_VGET(mp, ufhp->ufid_ino, &nvp)) != 0) { + if (error == ENOENT) + error = ESTALE; *vpp = NULLVP; return (error); } Index: src/sys/ufs/ufs/ufs_vnops.c diff -u src/sys/ufs/ufs/ufs_vnops.c:1.224 src/sys/ufs/ufs/ufs_vnops.c:1.225 --- src/sys/ufs/ufs/ufs_vnops.c:1.224 Wed Oct 29 01:13:28 2014 +++ src/sys/ufs/ufs/ufs_vnops.c Tue Mar 17 09:39:29 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: ufs_vnops.c,v 1.224 2014/10/29 01:13:28 christos Exp $ */ +/* $NetBSD: ufs_vnops.c,v 1.225 2015/03/17 09:39:29 hannken Exp $ */ /*- * Copyright (c) 2008 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.224 2014/10/29 01:13:28 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ufs_vnops.c,v 1.225 2015/03/17 09:39:29 hannken Exp $"); #if defined(_KERNEL_OPT) #include "opt_ffs.h" @@ -119,6 +119,8 @@ __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). @@ -153,9 +155,7 @@ ufs_create(void *v) * 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); @@ -184,8 +184,6 @@ ufs_mknod(void *v) struct vnode **vpp; struct inode *ip; int error; - struct mount *mp; - ino_t ino; struct ufs_lookup_results *ulr; vap = ap->a_vap; @@ -200,39 +198,14 @@ ufs_mknod(void *v) * 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) { @@ -951,7 +924,7 @@ ufs_mkdir(void *v) 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; @@ -962,46 +935,35 @@ ufs_mkdir(void *v) 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) { @@ -1223,8 +1185,8 @@ ufs_symlink(void *v) * 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); @@ -1782,52 +1744,33 @@ 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); @@ -1835,7 +1778,7 @@ ufs_makeinode(int mode, struct vnode *dv 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); @@ -1870,7 +1813,6 @@ ufs_makeinode(int mode, struct vnode *dv 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: src/sys/ufs/ufs/ufsmount.h diff -u src/sys/ufs/ufs/ufsmount.h:1.41 src/sys/ufs/ufs/ufsmount.h:1.42 --- src/sys/ufs/ufs/ufsmount.h:1.41 Sun Aug 11 04:36:17 2013 +++ src/sys/ufs/ufs/ufsmount.h Tue Mar 17 09:39:29 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: ufsmount.h,v 1.41 2013/08/11 04:36:17 dholland Exp $ */ +/* $NetBSD: ufsmount.h,v 1.42 2015/03/17 09:39:29 hannken Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -134,8 +134,6 @@ struct ufs_ops { 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 *); @@ -149,10 +147,6 @@ struct ufs_ops { (*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) \