Prepare nilfs for vcache:
- Calling getnewvnode() with "mp == NULL" is wrong. Stop attaching a vnode to system file nodes and change nilfs_bread() to translate the block address and then uyse the device for the read. - Move the vnode initialisation to nilfs_get_node() and use nilfs_get_node_raw() to initialise the nilfs node only. - Same for nilfs_reclaim() versus nilfs_dispose_node(). - Change nilfs_get_node() to return an unlocked vnode instead of a nilfs node with locked vnode. Adapt nilfs_lookup() and nilfs_root(). - Don't treat unsupported node types (blk, chr ...) as regular, return ENXIO instead. - Fix nilfs_getattr() to mask the mode with ALLPERMS. - Destroy sync_cv before free.
This commit is contained in:
parent
13634ff2cf
commit
52473f33d5
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nilfs_subr.c,v 1.10 2013/10/18 19:57:28 christos Exp $ */
|
||||
/* $NetBSD: nilfs_subr.c,v 1.11 2014/10/15 09:03:53 hannken Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008, 2009 Reinoud Zandijk
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__KERNEL_RCSID(0, "$NetBSD: nilfs_subr.c,v 1.10 2013/10/18 19:57:28 christos Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: nilfs_subr.c,v 1.11 2014/10/15 09:03:53 hannken Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -149,12 +149,22 @@ int
|
||||
nilfs_bread(struct nilfs_node *node, uint64_t blocknr,
|
||||
struct kauth_cred *cred, int flags, struct buf **bpp)
|
||||
{
|
||||
uint64_t vblocknr;
|
||||
struct nilfs_device *nilfsdev = node->nilfsdev;
|
||||
uint64_t vblocknr, pblockno;
|
||||
int error;
|
||||
|
||||
error = nilfs_btree_lookup(node, blocknr, &vblocknr);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* Read special files through devvp as they have no vnode attached. */
|
||||
if (node->ino < NILFS_USER_INO && node->ino != NILFS_ROOT_INO) {
|
||||
error = nilfs_nvtop(node, 1, &vblocknr, &pblockno);
|
||||
if (error)
|
||||
return error;
|
||||
return nilfs_dev_bread(nilfsdev, pblockno, cred, flags, bpp);
|
||||
}
|
||||
|
||||
return bread(node->vnode, vblocknr, node->nilfsdev->blocksize,
|
||||
cred, flags, bpp);
|
||||
}
|
||||
@ -746,7 +756,7 @@ nilfs_register_node(struct nilfs_node *node)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
void
|
||||
nilfs_deregister_node(struct nilfs_node *node)
|
||||
{
|
||||
struct nilfs_mount *ump;
|
||||
@ -799,67 +809,25 @@ nilfs_get_node_raw(struct nilfs_device *nilfsdev, struct nilfs_mount *ump,
|
||||
uint64_t ino, struct nilfs_inode *inode, struct nilfs_node **nodep)
|
||||
{
|
||||
struct nilfs_node *node;
|
||||
struct vnode *nvp;
|
||||
struct mount *mp;
|
||||
int (**vnodeops)(void *);
|
||||
int error;
|
||||
|
||||
*nodep = NULL;
|
||||
vnodeops = nilfs_vnodeop_p;
|
||||
|
||||
/* associate with mountpoint if present*/
|
||||
mp = ump? ump->vfs_mountp : NULL;
|
||||
error = getnewvnode(VT_NILFS, mp, vnodeops, NULL, &nvp);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* lock node */
|
||||
error = vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY);
|
||||
if (error) {
|
||||
nvp->v_data = NULL;
|
||||
ungetnewvnode(nvp);
|
||||
return error;
|
||||
}
|
||||
|
||||
node = pool_get(&nilfs_node_pool, PR_WAITOK);
|
||||
memset(node, 0, sizeof(struct nilfs_node));
|
||||
|
||||
/* crosslink */
|
||||
node->vnode = nvp;
|
||||
node->ump = ump;
|
||||
node->nilfsdev = nilfsdev;
|
||||
nvp->v_data = node;
|
||||
|
||||
/* initiase nilfs node */
|
||||
node->ino = ino;
|
||||
node->inode = *inode;
|
||||
node->lockf = NULL;
|
||||
|
||||
/* needed? */
|
||||
/* initialise locks */
|
||||
mutex_init(&node->node_mutex, MUTEX_DEFAULT, IPL_NONE);
|
||||
cv_init(&node->node_lock, "nilfsnlk");
|
||||
|
||||
/* initialise genfs */
|
||||
genfs_node_init(nvp, &nilfs_genfsops);
|
||||
|
||||
/* check if we're fetching the root */
|
||||
if (ino == NILFS_ROOT_INO)
|
||||
nvp->v_vflag |= VV_ROOT;
|
||||
|
||||
/* update vnode's file type XXX is there a function for this? */
|
||||
nvp->v_type = VREG;
|
||||
if (S_ISDIR(inode->i_mode))
|
||||
nvp->v_type = VDIR;
|
||||
if (S_ISLNK(inode->i_mode))
|
||||
nvp->v_type = VLNK;
|
||||
#if 0
|
||||
if (S_ISCHR(inode->i_mode))
|
||||
nvp->v_type = VCHR;
|
||||
if (S_ISBLK(inode->i_mode))
|
||||
nvp->v_type = VBLK;
|
||||
#endif
|
||||
/* XXX what else? */
|
||||
|
||||
/* fixup inode size for system nodes */
|
||||
if ((ino < NILFS_USER_INO) && (ino != NILFS_ROOT_INO)) {
|
||||
DPRINTF(VOLUMES, ("NEED TO GET my size for inode %"PRIu64"\n",
|
||||
@ -868,39 +836,41 @@ nilfs_get_node_raw(struct nilfs_device *nilfsdev, struct nilfs_mount *ump,
|
||||
inode->i_size = nilfs_rw64(((uint64_t) -2));
|
||||
}
|
||||
|
||||
uvm_vnp_setsize(nvp, nilfs_rw64(inode->i_size));
|
||||
|
||||
if (ump)
|
||||
nilfs_register_node(node);
|
||||
|
||||
/* return node */
|
||||
*nodep = node;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nilfs_get_node(struct nilfs_mount *ump, uint64_t ino, struct nilfs_node **nodep)
|
||||
nilfs_get_node(struct mount *mp, uint64_t ino, struct vnode **vpp)
|
||||
{
|
||||
struct nilfs_device *nilfsdev;
|
||||
struct nilfs_inode inode, *entry;
|
||||
struct nilfs_node *node;
|
||||
struct nilfs_mount *ump = VFSTONILFS(mp);
|
||||
struct vnode *nvp;
|
||||
struct buf *bp;
|
||||
uint64_t ivblocknr;
|
||||
uint32_t entry_in_block;
|
||||
int error;
|
||||
|
||||
/* lookup node in hash table */
|
||||
*nodep = nilfs_hash_lookup(ump, ino);
|
||||
if (*nodep)
|
||||
node = nilfs_hash_lookup(ump, ino);
|
||||
if (node) {
|
||||
*vpp = node->vnode;
|
||||
VOP_UNLOCK(*vpp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* lock to disallow simultanious creation of same udf_node */
|
||||
mutex_enter(&ump->get_node_lock);
|
||||
|
||||
/* relookup since it could be created while waiting for the mutex */
|
||||
*nodep = nilfs_hash_lookup(ump, ino);
|
||||
if (*nodep) {
|
||||
node = nilfs_hash_lookup(ump, ino);
|
||||
if (node) {
|
||||
*vpp = node->vnode;
|
||||
mutex_exit(&ump->get_node_lock);
|
||||
VOP_UNLOCK(*vpp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -931,17 +901,70 @@ nilfs_get_node(struct nilfs_mount *ump, uint64_t ino, struct nilfs_node **nodep)
|
||||
brelse(bp, BC_AGE);
|
||||
|
||||
/* get node */
|
||||
error = nilfs_get_node_raw(ump->nilfsdev, ump, ino, &inode, nodep);
|
||||
error = nilfs_get_node_raw(ump->nilfsdev, ump, ino, &inode, &node);
|
||||
if (error) {
|
||||
mutex_exit(&ump->get_node_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = getnewvnode(VT_NILFS, mp, nilfs_vnodeop_p, NULL, &nvp);
|
||||
if (error) {
|
||||
nilfs_dispose_node(&node);
|
||||
mutex_exit(&ump->get_node_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
/* lock node */
|
||||
error = vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY);
|
||||
if (error) {
|
||||
ungetnewvnode(nvp);
|
||||
nilfs_dispose_node(&node);
|
||||
mutex_exit(&ump->get_node_lock);
|
||||
return error;
|
||||
}
|
||||
|
||||
nvp->v_type = IFTOVT(inode.i_mode);
|
||||
switch (nvp->v_type) {
|
||||
case VREG:
|
||||
case VDIR:
|
||||
case VLNK:
|
||||
break;
|
||||
/* other types not yet supported. */
|
||||
default:
|
||||
nvp->v_type = VNON;
|
||||
VOP_UNLOCK(nvp);
|
||||
ungetnewvnode(nvp);
|
||||
nilfs_dispose_node(&node);
|
||||
mutex_exit(&ump->get_node_lock);
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
node->vnode = nvp;
|
||||
nvp->v_data = node;
|
||||
|
||||
/* initialise genfs */
|
||||
genfs_node_init(nvp, &nilfs_genfsops);
|
||||
|
||||
/* check if we're fetching the root */
|
||||
if (ino == NILFS_ROOT_INO)
|
||||
nvp->v_vflag |= VV_ROOT;
|
||||
|
||||
uvm_vnp_setsize(nvp, nilfs_rw64(inode.i_size));
|
||||
|
||||
nilfs_register_node(node);
|
||||
|
||||
mutex_exit(&ump->get_node_lock);
|
||||
|
||||
return error;
|
||||
*vpp = nvp;
|
||||
VOP_UNLOCK(*vpp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nilfs_dispose_node(struct nilfs_node **nodep)
|
||||
{
|
||||
struct vnode *vp;
|
||||
struct nilfs_node *node;
|
||||
|
||||
/* protect against rogue values */
|
||||
@ -949,23 +972,14 @@ nilfs_dispose_node(struct nilfs_node **nodep)
|
||||
return;
|
||||
|
||||
node = *nodep;
|
||||
vp = node->vnode;
|
||||
|
||||
/* remove dirhash if present */
|
||||
dirhash_purge(&node->dir_hash);
|
||||
|
||||
/* remove from our hash lookup table */
|
||||
if (node->ump)
|
||||
nilfs_deregister_node(node);
|
||||
|
||||
/* destroy our locks */
|
||||
mutex_destroy(&node->node_mutex);
|
||||
cv_destroy(&node->node_lock);
|
||||
|
||||
/* dissociate from our vnode */
|
||||
genfs_node_destroy(node->vnode);
|
||||
vp->v_data = NULL;
|
||||
|
||||
/* free our associated memory */
|
||||
pool_put(&nilfs_node_pool, node);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nilfs_subr.h,v 1.1 2009/07/18 16:31:42 reinoud Exp $ */
|
||||
/* $NetBSD: nilfs_subr.h,v 1.2 2014/10/15 09:03:53 hannken Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008, 2009 Reinoud Zandijk
|
||||
@ -56,7 +56,8 @@ int nilfs_btree_nlookup(struct nilfs_node *node, uint64_t from, uint64_t blks, u
|
||||
int nilfs_nvtop(struct nilfs_node *node, uint64_t blks, uint64_t *l2vmap, uint64_t *v2pmap);
|
||||
|
||||
/* node action implementators */
|
||||
int nilfs_get_node(struct nilfs_mount *ump, uint64_t ino, struct nilfs_node **nodep);
|
||||
void nilfs_deregister_node(struct nilfs_node *);
|
||||
int nilfs_get_node(struct mount *mp, uint64_t ino, struct vnode **vpp);
|
||||
int nilfs_get_node_raw(struct nilfs_device *nilfsdev, struct nilfs_mount *ump, uint64_t ino, struct nilfs_inode *inode, struct nilfs_node **nodep);
|
||||
void nilfs_dispose_node(struct nilfs_node **node);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nilfs_vfsops.c,v 1.16 2014/04/16 18:55:18 maxv Exp $ */
|
||||
/* $NetBSD: nilfs_vfsops.c,v 1.17 2014/10/15 09:03:53 hannken Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008, 2009 Reinoud Zandijk
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__KERNEL_RCSID(0, "$NetBSD: nilfs_vfsops.c,v 1.16 2014/04/16 18:55:18 maxv Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: nilfs_vfsops.c,v 1.17 2014/10/15 09:03:53 hannken Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
@ -70,18 +70,6 @@ MODULE(MODULE_CLASS_VFS, nilfs, NULL);
|
||||
|
||||
#define VTOI(vnode) ((struct nilfs_node *) vnode->v_data)
|
||||
|
||||
#define NILFS_SET_SYSTEMFILE(vp) { \
|
||||
/* XXXAD Is the vnode locked? */ \
|
||||
(vp)->v_vflag |= VV_SYSTEM; \
|
||||
vref(vp); \
|
||||
vput(vp); }
|
||||
|
||||
#define NILFS_UNSET_SYSTEMFILE(vp) { \
|
||||
/* XXXAD Is the vnode locked? */ \
|
||||
(vp)->v_vflag &= ~VV_SYSTEM; \
|
||||
vrele(vp); }
|
||||
|
||||
|
||||
/* verbose levels of the nilfs filingsystem */
|
||||
int nilfs_verbose = NILFS_DEBUGGING;
|
||||
|
||||
@ -257,10 +245,6 @@ nilfs_create_system_nodes(struct nilfs_device *nilfsdev)
|
||||
if (error)
|
||||
goto errorout;
|
||||
|
||||
NILFS_SET_SYSTEMFILE(nilfsdev->dat_node->vnode);
|
||||
NILFS_SET_SYSTEMFILE(nilfsdev->cp_node->vnode);
|
||||
NILFS_SET_SYSTEMFILE(nilfsdev->su_node->vnode);
|
||||
|
||||
return 0;
|
||||
errorout:
|
||||
nilfs_dispose_node(&nilfsdev->dat_node);
|
||||
@ -279,13 +263,6 @@ nilfs_release_system_nodes(struct nilfs_device *nilfsdev)
|
||||
if (nilfsdev->refcnt > 0)
|
||||
return;
|
||||
|
||||
if (nilfsdev->dat_node)
|
||||
NILFS_UNSET_SYSTEMFILE(nilfsdev->dat_node->vnode);
|
||||
if (nilfsdev->cp_node)
|
||||
NILFS_UNSET_SYSTEMFILE(nilfsdev->cp_node->vnode);
|
||||
if (nilfsdev->su_node)
|
||||
NILFS_UNSET_SYSTEMFILE(nilfsdev->su_node->vnode);
|
||||
|
||||
nilfs_dispose_node(&nilfsdev->dat_node);
|
||||
nilfs_dispose_node(&nilfsdev->cp_node);
|
||||
nilfs_dispose_node(&nilfsdev->su_node);
|
||||
@ -513,6 +490,7 @@ nilfs_unmount_device(struct nilfs_device *nilfsdev)
|
||||
vput(nilfsdev->devvp);
|
||||
|
||||
/* free our device info */
|
||||
cv_destroy(&nilfsdev->sync_cv);
|
||||
free(nilfsdev, M_NILFSMNT);
|
||||
}
|
||||
|
||||
@ -745,7 +723,6 @@ nilfs_mount_checkpoint(struct nilfs_mount *ump)
|
||||
printf("mount_nilfs: can't read ifile node\n");
|
||||
return EINVAL;
|
||||
}
|
||||
NILFS_SET_SYSTEMFILE(ump->ifile_node->vnode);
|
||||
|
||||
/* get root node? */
|
||||
|
||||
@ -951,13 +928,10 @@ nilfs_unmount(struct mount *mp, int mntflags)
|
||||
nilfsdev = ump->nilfsdev;
|
||||
|
||||
/*
|
||||
* Flush all nodes associated to this mountpoint. By specifying
|
||||
* SKIPSYSTEM we can skip vnodes marked with VV_SYSTEM. This hardly
|
||||
* documented feature allows us to exempt certain files from being
|
||||
* flushed.
|
||||
* Flush all nodes associated to this mountpoint.
|
||||
*/
|
||||
flags = (mntflags & MNT_FORCE) ? FORCECLOSE : 0;
|
||||
if ((error = vflush(mp, NULLVP, flags | SKIPSYSTEM)) != 0)
|
||||
if ((error = vflush(mp, NULLVP, flags)) != 0)
|
||||
return error;
|
||||
|
||||
/* if we're the write mount, we ought to close the writing session */
|
||||
@ -965,8 +939,6 @@ nilfs_unmount(struct mount *mp, int mntflags)
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (ump->ifile_node)
|
||||
NILFS_UNSET_SYSTEMFILE(ump->ifile_node->vnode);
|
||||
nilfs_dispose_node(&ump->ifile_node);
|
||||
|
||||
/* remove our mount point */
|
||||
@ -998,17 +970,20 @@ nilfs_start(struct mount *mp, int flags)
|
||||
int
|
||||
nilfs_root(struct mount *mp, struct vnode **vpp)
|
||||
{
|
||||
struct nilfs_mount *ump = VFSTONILFS(mp);
|
||||
struct nilfs_node *node;
|
||||
int error;
|
||||
|
||||
DPRINTF(NODE, ("nilfs_root called\n"));
|
||||
|
||||
error = nilfs_get_node(ump, NILFS_ROOT_INO, &node);
|
||||
if (node) {
|
||||
*vpp = node->vnode;
|
||||
KASSERT(node->vnode->v_vflag & VV_ROOT);
|
||||
error = nilfs_get_node(mp, NILFS_ROOT_INO, vpp);
|
||||
if (error == 0) {
|
||||
error = vn_lock(*vpp, LK_EXCLUSIVE);
|
||||
if (error) {
|
||||
vrele(*vpp);
|
||||
*vpp = NULL;
|
||||
return error;
|
||||
}
|
||||
}
|
||||
KASSERT(error != 0 || ((*vpp)->v_vflag & VV_ROOT));
|
||||
|
||||
DPRINTF(NODE, ("nilfs_root finished\n"));
|
||||
return error;
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: nilfs_vnops.c,v 1.28 2014/07/25 08:20:51 dholland Exp $ */
|
||||
/* $NetBSD: nilfs_vnops.c,v 1.29 2014/10/15 09:03:53 hannken Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2008, 2009 Reinoud Zandijk
|
||||
@ -28,7 +28,7 @@
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#ifndef lint
|
||||
__KERNEL_RCSID(0, "$NetBSD: nilfs_vnops.c,v 1.28 2014/07/25 08:20:51 dholland Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: nilfs_vnops.c,v 1.29 2014/10/15 09:03:53 hannken Exp $");
|
||||
#endif /* not lint */
|
||||
|
||||
|
||||
@ -118,9 +118,15 @@ nilfs_reclaim(void *v)
|
||||
/* update note for closure */
|
||||
nilfs_update(vp, NULL, NULL, NULL, UPDATE_CLOSE);
|
||||
|
||||
/* remove from our hash lookup table */
|
||||
nilfs_deregister_node(nilfs_node);
|
||||
|
||||
/* dispose all node knowledge */
|
||||
genfs_node_destroy(vp);
|
||||
nilfs_dispose_node(&nilfs_node);
|
||||
|
||||
vp->v_data = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -621,16 +627,13 @@ nilfs_lookup(void *v)
|
||||
struct vnode *dvp = ap->a_dvp;
|
||||
struct vnode **vpp = ap->a_vpp;
|
||||
struct componentname *cnp = ap->a_cnp;
|
||||
struct nilfs_node *dir_node, *res_node;
|
||||
struct nilfs_mount *ump;
|
||||
struct mount *mp = dvp->v_mount;
|
||||
uint64_t ino;
|
||||
const char *name;
|
||||
int namelen, nameiop, islastcn, mounted_ro;
|
||||
int vnodetp;
|
||||
int error, found;
|
||||
|
||||
dir_node = VTOI(dvp);
|
||||
ump = dir_node->ump;
|
||||
*vpp = NULL;
|
||||
|
||||
DPRINTF(LOOKUP, ("nilfs_lookup called\n"));
|
||||
@ -638,7 +641,7 @@ nilfs_lookup(void *v)
|
||||
/* simplify/clarification flags */
|
||||
nameiop = cnp->cn_nameiop;
|
||||
islastcn = cnp->cn_flags & ISLASTCN;
|
||||
mounted_ro = dvp->v_mount->mnt_flag & MNT_RDONLY;
|
||||
mounted_ro = mp->mnt_flag & MNT_RDONLY;
|
||||
|
||||
/* check exec/dirread permissions first */
|
||||
error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred);
|
||||
@ -691,23 +694,16 @@ nilfs_lookup(void *v)
|
||||
if (!found)
|
||||
error = ENOENT;
|
||||
|
||||
/* first unlock parent */
|
||||
VOP_UNLOCK(dvp);
|
||||
|
||||
if (error == 0) {
|
||||
DPRINTF(LOOKUP, ("\tfound '..'\n"));
|
||||
/* try to create/reuse the node */
|
||||
error = nilfs_get_node(ump, ino, &res_node);
|
||||
error = nilfs_get_node(mp, ino, vpp);
|
||||
|
||||
if (!error) {
|
||||
DPRINTF(LOOKUP,
|
||||
("\tnode retrieved/created OK\n"));
|
||||
*vpp = res_node->vnode;
|
||||
}
|
||||
}
|
||||
|
||||
/* try to relock parent */
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
|
||||
} else {
|
||||
DPRINTF(LOOKUP, ("\tlookup file\n"));
|
||||
/* all other files */
|
||||
@ -738,7 +734,7 @@ nilfs_lookup(void *v)
|
||||
/* done */
|
||||
} else {
|
||||
/* try to create/reuse the node */
|
||||
error = nilfs_get_node(ump, ino, &res_node);
|
||||
error = nilfs_get_node(mp, ino, vpp);
|
||||
if (!error) {
|
||||
/*
|
||||
* If we are not at the last path component
|
||||
@ -746,16 +742,16 @@ nilfs_lookup(void *v)
|
||||
* (which may itself be pointing to a
|
||||
* directory), raise an error.
|
||||
*/
|
||||
vnodetp = res_node->vnode->v_type;
|
||||
vnodetp = (*vpp)->v_type;
|
||||
if ((vnodetp != VDIR) && (vnodetp != VLNK)) {
|
||||
if (!islastcn)
|
||||
if (!islastcn) {
|
||||
vrele(*vpp);
|
||||
*vpp = NULL;
|
||||
error = ENOTDIR;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (!error) {
|
||||
*vpp = res_node->vnode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -765,7 +761,7 @@ out:
|
||||
* the file might not be found and thus putting it into the namecache
|
||||
* might be seen as negative caching.
|
||||
*/
|
||||
if (nameiop != CREATE)
|
||||
if (error == 0 && nameiop != CREATE)
|
||||
cache_enter(dvp, *vpp, cnp->cn_nameptr, cnp->cn_namelen,
|
||||
cnp->cn_flags);
|
||||
|
||||
@ -773,8 +769,6 @@ out:
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
if (*vpp != dvp)
|
||||
VOP_UNLOCK(*vpp);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -807,7 +801,7 @@ nilfs_getattr(void *v)
|
||||
/* basic info */
|
||||
vattr_null(vap);
|
||||
vap->va_type = vp->v_type;
|
||||
vap->va_mode = nilfs_rw16(inode->i_mode); /* XXX same? */
|
||||
vap->va_mode = nilfs_rw16(inode->i_mode) & ALLPERMS;
|
||||
vap->va_nlink = nilfs_rw16(inode->i_links_count);
|
||||
vap->va_uid = nilfs_rw32(inode->i_uid);
|
||||
vap->va_gid = nilfs_rw32(inode->i_gid);
|
||||
|
Loading…
x
Reference in New Issue
Block a user