Module Name:    src
Committed By:   hannken
Date:           Wed Oct 15 09:03:53 UTC 2014

Modified Files:
        src/sys/fs/nilfs: nilfs_subr.c nilfs_subr.h nilfs_vfsops.c
            nilfs_vnops.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.10 -r1.11 src/sys/fs/nilfs/nilfs_subr.c
cvs rdiff -u -r1.1 -r1.2 src/sys/fs/nilfs/nilfs_subr.h
cvs rdiff -u -r1.16 -r1.17 src/sys/fs/nilfs/nilfs_vfsops.c
cvs rdiff -u -r1.28 -r1.29 src/sys/fs/nilfs/nilfs_vnops.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/fs/nilfs/nilfs_subr.c
diff -u src/sys/fs/nilfs/nilfs_subr.c:1.10 src/sys/fs/nilfs/nilfs_subr.c:1.11
--- src/sys/fs/nilfs/nilfs_subr.c:1.10	Fri Oct 18 19:57:28 2013
+++ src/sys/fs/nilfs/nilfs_subr.c	Wed Oct 15 09:03:53 2014
@@ -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 *n
 }
 
 
-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 *
 	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 *
 		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, 
 	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 **n
 		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);
 

Index: src/sys/fs/nilfs/nilfs_subr.h
diff -u src/sys/fs/nilfs/nilfs_subr.h:1.1 src/sys/fs/nilfs/nilfs_subr.h:1.2
--- src/sys/fs/nilfs/nilfs_subr.h:1.1	Sat Jul 18 16:31:42 2009
+++ src/sys/fs/nilfs/nilfs_subr.h	Wed Oct 15 09:03:53 2014
@@ -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_nod
 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);
 

Index: src/sys/fs/nilfs/nilfs_vfsops.c
diff -u src/sys/fs/nilfs/nilfs_vfsops.c:1.16 src/sys/fs/nilfs/nilfs_vfsops.c:1.17
--- src/sys/fs/nilfs/nilfs_vfsops.c:1.16	Wed Apr 16 18:55:18 2014
+++ src/sys/fs/nilfs/nilfs_vfsops.c	Wed Oct 15 09:03:53 2014
@@ -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_d
 	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_
 	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
 	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_moun
 		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 mntf
 	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 mntf
 	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;

Index: src/sys/fs/nilfs/nilfs_vnops.c
diff -u src/sys/fs/nilfs/nilfs_vnops.c:1.28 src/sys/fs/nilfs/nilfs_vnops.c:1.29
--- src/sys/fs/nilfs/nilfs_vnops.c:1.28	Fri Jul 25 08:20:51 2014
+++ src/sys/fs/nilfs/nilfs_vnops.c	Wed Oct 15 09:03:53 2014
@@ -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);

Reply via email to