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.
This commit is contained in:
hannken 2015-03-17 09:39:29 +00:00
parent b01cc29bb1
commit 54fa474e3e
10 changed files with 260 additions and 215 deletions

View File

@ -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_genfsops = {
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. */

View File

@ -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, kauth_cred_t cred,
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;
}
/*

View File

@ -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, 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);

View File

@ -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, kauth_cred_t cred)
}
/*
* 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,23 +1950,11 @@ ffs_loadvnode(struct mount *mp, struct vnode *vp,
/* 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 defined(QUOTA) || defined(QUOTA2)
ufsquota_init(ip);
#endif
/* Initialize genfs node. */
genfs_node_init(vp, &ffs_genfsops);
if (ip->i_ump->um_fstype == UFS1)
if (ump->um_fstype == UFS1)
ip->i_din.ffs1_din = pool_cache_get(ffs_dinode1_cache,
PR_WAITOK);
else
@ -1981,6 +1962,70 @@ ffs_loadvnode(struct mount *mp, struct vnode *vp,
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);
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
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);
@ -2003,6 +2048,119 @@ ffs_loadvnode(struct mount *mp, struct vnode *vp,
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
*

View File

@ -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, 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;
vp->v_type = VREG;
error = vn_lock(vp, LK_EXCLUSIVE);
if (error) {
vrele(vp);
return error;
}
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,

View File

@ -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,

View File

@ -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 ufid *, struct vnode **);
/* 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);

View File

@ -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 *ufhp, struct vnode **vpp)
int error;
if ((error = VFS_VGET(mp, ufhp->ufid_ino, &nvp)) != 0) {
if (error == ENOENT)
error = ESTALE;
*vpp = NULLVP;
return (error);
}

View File

@ -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_MAXNAMLEN);
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;
error = vn_lock(*ap->a_vpp, LK_EXCLUSIVE);
if (error) {
vrele(*ap->a_vpp);
*ap->a_vpp = NULL;
goto out;
}
error = UFS_WAPBL_BEGIN(ap->a_dvp->v_mount);
if (error) {
vput(*ap->a_vpp);
goto out;
}
tvp = *ap->a_vpp;
ip = VTOI(tvp);
error = UFS_WAPBL_BEGIN(ap->a_dvp->v_mount);
if (error) {
UFS_VFREE(tvp, ip->i_number, dmode);
vput(tvp);
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);
}
#endif
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 (**specops)(void *), int (**fifoops)(void *),
* 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 *dvp, const struct ufs_lookup_results *ulr,
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 *dvp, const struct ufs_lookup_results *ulr,
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);

View File

@ -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) \