Module Name: src Committed By: hannken Date: Wed Oct 15 09:05:46 UTC 2014
Modified Files: src/sys/fs/nilfs: nilfs.h nilfs_subr.c nilfs_subr.h nilfs_vfsops.c nilfs_vnops.c Log Message: Change nilfs to vcache. To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/sys/fs/nilfs/nilfs.h cvs rdiff -u -r1.11 -r1.12 src/sys/fs/nilfs/nilfs_subr.c cvs rdiff -u -r1.2 -r1.3 src/sys/fs/nilfs/nilfs_subr.h cvs rdiff -u -r1.17 -r1.18 src/sys/fs/nilfs/nilfs_vfsops.c cvs rdiff -u -r1.29 -r1.30 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.h diff -u src/sys/fs/nilfs/nilfs.h:1.4 src/sys/fs/nilfs/nilfs.h:1.5 --- src/sys/fs/nilfs/nilfs.h:1.4 Fri Oct 18 19:57:28 2013 +++ src/sys/fs/nilfs/nilfs.h Wed Oct 15 09:05:46 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: nilfs.h,v 1.4 2013/10/18 19:57:28 christos Exp $ */ +/* $NetBSD: nilfs.h,v 1.5 2014/10/15 09:05:46 hannken Exp $ */ /* * Copyright (c) 2008, 2009 Reinoud Zandijk @@ -172,11 +172,6 @@ struct nilfs_mount { /* instance values */ struct nilfs_node *ifile_node; - /* hash table to lookup ino -> nilfs_node */ - kmutex_t ihash_lock; - kmutex_t get_node_lock; - LIST_HEAD(, nilfs_node) nilfs_nodes[NILFS_INODE_HASHSIZE]; - /* lists */ STAILQ_ENTRY(nilfs_mount) next_mount; /* in nilfs_device */ }; Index: src/sys/fs/nilfs/nilfs_subr.c diff -u src/sys/fs/nilfs/nilfs_subr.c:1.11 src/sys/fs/nilfs/nilfs_subr.c:1.12 --- src/sys/fs/nilfs/nilfs_subr.c:1.11 Wed Oct 15 09:03:53 2014 +++ src/sys/fs/nilfs/nilfs_subr.c Wed Oct 15 09:05:46 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: nilfs_subr.c,v 1.11 2014/10/15 09:03:53 hannken Exp $ */ +/* $NetBSD: nilfs_subr.c,v 1.12 2014/10/15 09:05:46 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.11 2014/10/15 09:03:53 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nilfs_subr.c,v 1.12 2014/10/15 09:05:46 hannken Exp $"); #endif /* not lint */ #include <sys/param.h> @@ -125,13 +125,6 @@ crc32_le(uint32_t crc, const uint8_t *bu } -static int -nilfs_calchash(uint64_t ino) -{ - return (int) ino; -} - - /* dev reading */ static int nilfs_dev_bread(struct nilfs_device *nilfsdev, uint64_t blocknr, @@ -354,7 +347,7 @@ nilfs_btree_nlookup(struct nilfs_node *n /* vtop operations */ /* translate index to a file block number and an entry */ -static void +void nilfs_mdt_trans(struct nilfs_mdt *mdt, uint64_t index, uint64_t *blocknr, uint32_t *entry_in_block) { @@ -667,143 +660,6 @@ nilfs_search_super_root(struct nilfs_dev /* --------------------------------------------------------------------- */ -/* - * Genfs interfacing - * - * static const struct genfs_ops nilfs_genfsops = { - * .gop_size = genfs_size, - * size of transfers - * .gop_alloc = nilfs_gop_alloc, - * allocate len bytes at offset - * .gop_write = genfs_gop_write, - * putpages interface code - * .gop_markupdate = nilfs_gop_markupdate, - * set update/modify flags etc. - * } - */ - -/* - * Callback from genfs to allocate len bytes at offset off; only called when - * filling up gaps in the allocation. - */ -static int -nilfs_gop_alloc(struct vnode *vp, off_t off, - off_t len, int flags, kauth_cred_t cred) -{ - DPRINTF(NOTIMPL, ("nilfs_gop_alloc not implemented\n")); - DPRINTF(ALLOC, ("nilfs_gop_alloc called for %"PRIu64" bytes\n", len)); - - return 0; -} - - -/* - * callback from genfs to update our flags - */ -static void -nilfs_gop_markupdate(struct vnode *vp, int flags) -{ - struct nilfs_node *nilfs_node = VTOI(vp); - u_long mask = 0; - - if ((flags & GOP_UPDATE_ACCESSED) != 0) { - mask = IN_ACCESS; - } - if ((flags & GOP_UPDATE_MODIFIED) != 0) { - if (vp->v_type == VREG) { - mask |= IN_CHANGE | IN_UPDATE; - } else { - mask |= IN_MODIFY; - } - } - if (mask) { - nilfs_node->i_flags |= mask; - } -} - - -static const struct genfs_ops nilfs_genfsops = { - .gop_size = genfs_size, - .gop_alloc = nilfs_gop_alloc, - .gop_write = genfs_gop_write_rwmap, - .gop_markupdate = nilfs_gop_markupdate, -}; - -/* --------------------------------------------------------------------- */ - -static void -nilfs_register_node(struct nilfs_node *node) -{ - struct nilfs_mount *ump; - uint32_t hashline; - - ump = node->ump; - mutex_enter(&ump->ihash_lock); - - /* add to our hash table */ - hashline = nilfs_calchash(node->ino) & NILFS_INODE_HASHMASK; -#ifdef DEBUG - struct nilfs_node *chk; - LIST_FOREACH(chk, &ump->nilfs_nodes[hashline], hashchain) { - assert(chk); - if (chk->ino == node->ino) - panic("Double node entered\n"); - } -#endif - LIST_INSERT_HEAD(&ump->nilfs_nodes[hashline], node, hashchain); - - mutex_exit(&ump->ihash_lock); -} - - -void -nilfs_deregister_node(struct nilfs_node *node) -{ - struct nilfs_mount *ump; - - ump = node->ump; - mutex_enter(&ump->ihash_lock); - - /* remove from hash list */ - LIST_REMOVE(node, hashchain); - - mutex_exit(&ump->ihash_lock); -} - - -static struct nilfs_node * -nilfs_hash_lookup(struct nilfs_mount *ump, ino_t ino) -{ - struct nilfs_node *node; - struct vnode *vp; - uint32_t hashline; - -loop: - mutex_enter(&ump->ihash_lock); - - /* search our hash table */ - hashline = nilfs_calchash(ino) & NILFS_INODE_HASHMASK; - LIST_FOREACH(node, &ump->nilfs_nodes[hashline], hashchain) { - assert(node); - if (node->ino == ino) { - vp = node->vnode; - assert(vp); - mutex_enter(vp->v_interlock); - mutex_exit(&ump->ihash_lock); - if (vget(vp, LK_EXCLUSIVE)) - goto loop; - return node; - } - } - mutex_exit(&ump->ihash_lock); - - return NULL; -} - - -/* node action implementators */ -extern int (**nilfs_vnodeop_p)(void *); - int nilfs_get_node_raw(struct nilfs_device *nilfsdev, struct nilfs_mount *ump, uint64_t ino, struct nilfs_inode *inode, struct nilfs_node **nodep) @@ -841,127 +697,6 @@ nilfs_get_node_raw(struct nilfs_device * return 0; } -int -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 */ - 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 */ - node = nilfs_hash_lookup(ump, ino); - if (node) { - *vpp = node->vnode; - mutex_exit(&ump->get_node_lock); - VOP_UNLOCK(*vpp); - return 0; - } - - /* create new inode; XXX check could be handier */ - if ((ino < NILFS_ATIME_INO) && (ino != NILFS_ROOT_INO)) { - printf("nilfs_get_node: system ino %"PRIu64" not in mount " - "point!\n", ino); - mutex_exit(&ump->get_node_lock); - return ENOENT; - } - - /* lookup inode in the ifile */ - DPRINTF(NODE, ("lookup ino %"PRIu64"\n", ino)); - - /* lookup inode structure in mountpoints ifile */ - nilfsdev = ump->nilfsdev; - nilfs_mdt_trans(&nilfsdev->ifile_mdt, ino, &ivblocknr, &entry_in_block); - - error = nilfs_bread(ump->ifile_node, ivblocknr, NOCRED, 0, &bp); - if (error) { - mutex_exit(&ump->get_node_lock); - return ENOENT; - } - - /* get inode entry */ - entry = (struct nilfs_inode *) bp->b_data + entry_in_block; - inode = *entry; - brelse(bp, BC_AGE); - - /* get node */ - 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); - - *vpp = nvp; - VOP_UNLOCK(*vpp); - - return 0; -} - - void nilfs_dispose_node(struct nilfs_node **nodep) { Index: src/sys/fs/nilfs/nilfs_subr.h diff -u src/sys/fs/nilfs/nilfs_subr.h:1.2 src/sys/fs/nilfs/nilfs_subr.h:1.3 --- src/sys/fs/nilfs/nilfs_subr.h:1.2 Wed Oct 15 09:03:53 2014 +++ src/sys/fs/nilfs/nilfs_subr.h Wed Oct 15 09:05:46 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: nilfs_subr.h,v 1.2 2014/10/15 09:03:53 hannken Exp $ */ +/* $NetBSD: nilfs_subr.h,v 1.3 2014/10/15 09:05:46 hannken Exp $ */ /* * Copyright (c) 2008, 2009 Reinoud Zandijk @@ -53,11 +53,10 @@ int nilfs_bread(struct nilfs_node *node, int nilfs_btree_nlookup(struct nilfs_node *node, uint64_t from, uint64_t blks, uint64_t *l2vmap); /* vtop operations */ +void nilfs_mdt_trans(struct nilfs_mdt *mdt, uint64_t index, uint64_t *blocknr, uint32_t *entry_in_block); int nilfs_nvtop(struct nilfs_node *node, uint64_t blks, uint64_t *l2vmap, uint64_t *v2pmap); /* node action implementators */ -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.17 src/sys/fs/nilfs/nilfs_vfsops.c:1.18 --- src/sys/fs/nilfs/nilfs_vfsops.c:1.17 Wed Oct 15 09:03:53 2014 +++ src/sys/fs/nilfs/nilfs_vfsops.c Wed Oct 15 09:05:46 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: nilfs_vfsops.c,v 1.17 2014/10/15 09:03:53 hannken Exp $ */ +/* $NetBSD: nilfs_vfsops.c,v 1.18 2014/10/15 09:05:46 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.17 2014/10/15 09:03:53 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nilfs_vfsops.c,v 1.18 2014/10/15 09:05:46 hannken Exp $"); #endif /* not lint */ @@ -88,6 +88,70 @@ VFS_PROTOS(nilfs); /* --------------------------------------------------------------------- */ +/* + * Genfs interfacing + * + * static const struct genfs_ops nilfs_genfsops = { + * .gop_size = genfs_size, + * size of transfers + * .gop_alloc = nilfs_gop_alloc, + * allocate len bytes at offset + * .gop_write = genfs_gop_write, + * putpages interface code + * .gop_markupdate = nilfs_gop_markupdate, + * set update/modify flags etc. + * } + */ + +/* + * Callback from genfs to allocate len bytes at offset off; only called when + * filling up gaps in the allocation. + */ +static int +nilfs_gop_alloc(struct vnode *vp, off_t off, + off_t len, int flags, kauth_cred_t cred) +{ + DPRINTF(NOTIMPL, ("nilfs_gop_alloc not implemented\n")); + DPRINTF(ALLOC, ("nilfs_gop_alloc called for %"PRIu64" bytes\n", len)); + + return 0; +} + + +/* + * callback from genfs to update our flags + */ +static void +nilfs_gop_markupdate(struct vnode *vp, int flags) +{ + struct nilfs_node *nilfs_node = VTOI(vp); + u_long mask = 0; + + if ((flags & GOP_UPDATE_ACCESSED) != 0) { + mask = IN_ACCESS; + } + if ((flags & GOP_UPDATE_MODIFIED) != 0) { + if (vp->v_type == VREG) { + mask |= IN_CHANGE | IN_UPDATE; + } else { + mask |= IN_MODIFY; + } + } + if (mask) { + nilfs_node->i_flags |= mask; + } +} + + +static const struct genfs_ops nilfs_genfsops = { + .gop_size = genfs_size, + .gop_alloc = nilfs_gop_alloc, + .gop_write = genfs_gop_write_rwmap, + .gop_markupdate = nilfs_gop_markupdate, +}; + +/* --------------------------------------------------------------------- */ + /* predefine vnode-op list descriptor */ extern const struct vnodeopv_desc nilfs_vnodeop_opv_desc; @@ -109,6 +173,7 @@ struct vfsops nilfs_vfsops = { .vfs_statvfs = nilfs_statvfs, .vfs_sync = nilfs_sync, .vfs_vget = nilfs_vget, + .vfs_loadvnode = nilfs_loadvnode, .vfs_fhtovp = nilfs_fhtovp, .vfs_vptofh = nilfs_vptofh, .vfs_init = nilfs_init, @@ -759,8 +824,6 @@ free_nilfs_mountinfo(struct mount *mp) if (ump == NULL) return; - mutex_destroy(&ump->ihash_lock); - mutex_destroy(&ump->get_node_lock); MPFREE(ump, M_NILFSMNT); } #undef MPFREE @@ -773,7 +836,7 @@ nilfs_mount(struct mount *mp, const char struct nilfs_device *nilfsdev; struct nilfs_mount *ump; struct vnode *devvp; - int lst, error; + int error; DPRINTF(VFSCALL, ("nilfs_mount called\n")); @@ -845,15 +908,6 @@ nilfs_mount(struct mount *mp, const char /* allocate nilfs part of mount structure; malloc always succeeds */ ump = malloc(sizeof(struct nilfs_mount), M_NILFSMNT, M_WAITOK | M_ZERO); - /* init locks */ - mutex_init(&ump->ihash_lock, MUTEX_DEFAULT, IPL_NONE); - mutex_init(&ump->get_node_lock, MUTEX_DEFAULT, IPL_NONE); - - /* init our hash table for inode lookup */ - for (lst = 0; lst < NILFS_INODE_HASHSIZE; lst++) { - LIST_INIT(&ump->nilfs_nodes[lst]); - } - /* set up linkage */ mp->mnt_data = ump; ump->vfs_mountp = mp; @@ -970,11 +1024,12 @@ nilfs_start(struct mount *mp, int flags) int nilfs_root(struct mount *mp, struct vnode **vpp) { + uint64_t ino = NILFS_ROOT_INO; int error; DPRINTF(NODE, ("nilfs_root called\n")); - error = nilfs_get_node(mp, NILFS_ROOT_INO, vpp); + error = vcache_get(mp, &ino, sizeof(ino), vpp); if (error == 0) { error = vn_lock(*vpp, LK_EXCLUSIVE); if (error) { @@ -1044,6 +1099,92 @@ nilfs_vget(struct mount *mp, ino_t ino, /* --------------------------------------------------------------------- */ /* + * Read an inode from disk and initialize this vnode / inode pair. + * Caller assures no other thread will try to load this inode. + */ +int +nilfs_loadvnode(struct mount *mp, struct vnode *vp, + const void *key, size_t key_len, const void **new_key) +{ + uint64_t ino; + struct nilfs_device *nilfsdev; + struct nilfs_inode inode, *entry; + struct nilfs_node *node; + struct nilfs_mount *ump; + struct buf *bp; + uint64_t ivblocknr; + uint32_t entry_in_block; + int error; + extern int (**nilfs_vnodeop_p)(void *); + + KASSERT(key_len == sizeof(ino)); + memcpy(&ino, key, key_len); + + ump = VFSTONILFS(mp); + + /* create new inode; XXX check could be handier */ + if ((ino < NILFS_USER_INO) && (ino != NILFS_ROOT_INO)) { + printf("nilfs_get_node: system ino %"PRIu64" not in mount " + "point!\n", ino); + return ENOENT; + } + + /* lookup inode in the ifile */ + DPRINTF(NODE, ("lookup ino %"PRIu64"\n", ino)); + + /* lookup inode structure in mountpoints ifile */ + nilfsdev = ump->nilfsdev; + nilfs_mdt_trans(&nilfsdev->ifile_mdt, ino, &ivblocknr, &entry_in_block); + + error = nilfs_bread(ump->ifile_node, ivblocknr, NOCRED, 0, &bp); + if (error) + return ENOENT; + + /* get inode entry */ + entry = (struct nilfs_inode *) bp->b_data + entry_in_block; + inode = *entry; + brelse(bp, BC_AGE); + + /* get node */ + error = nilfs_get_node_raw(ump->nilfsdev, ump, ino, &inode, &node); + if (error) + return error; + + vp->v_type = IFTOVT(inode.i_mode); + switch (vp->v_type) { + case VREG: + case VDIR: + case VLNK: + break; + /* other types not yet supported. */ + default: + vp->v_type = VNON; + nilfs_dispose_node(&node); + return ENXIO; + } + + vp->v_tag = VT_NILFS; + vp->v_op = nilfs_vnodeop_p; + vp->v_data = node; + node->vnode = vp; + + /* initialise genfs */ + genfs_node_init(vp, &nilfs_genfsops); + + /* check if we're fetching the root */ + if (ino == NILFS_ROOT_INO) + vp->v_vflag |= VV_ROOT; + + uvm_vnp_setsize(vp, nilfs_rw64(inode.i_size)); + *new_key = &node->ino; + + return 0; + +} + +/* --------------------------------------------------------------------- */ + +/* * Lookup vnode for file handle specified */ int Index: src/sys/fs/nilfs/nilfs_vnops.c diff -u src/sys/fs/nilfs/nilfs_vnops.c:1.29 src/sys/fs/nilfs/nilfs_vnops.c:1.30 --- src/sys/fs/nilfs/nilfs_vnops.c:1.29 Wed Oct 15 09:03:53 2014 +++ src/sys/fs/nilfs/nilfs_vnops.c Wed Oct 15 09:05:46 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: nilfs_vnops.c,v 1.29 2014/10/15 09:03:53 hannken Exp $ */ +/* $NetBSD: nilfs_vnops.c,v 1.30 2014/10/15 09:05:46 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.29 2014/10/15 09:03:53 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: nilfs_vnops.c,v 1.30 2014/10/15 09:05:46 hannken Exp $"); #endif /* not lint */ @@ -118,8 +118,8 @@ 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); + /* remove from vnode cache. */ + vcache_remove(vp->v_mount, &nilfs_node->ino, sizeof(nilfs_node->ino)); /* dispose all node knowledge */ genfs_node_destroy(vp); @@ -697,7 +697,7 @@ nilfs_lookup(void *v) if (error == 0) { DPRINTF(LOOKUP, ("\tfound '..'\n")); /* try to create/reuse the node */ - error = nilfs_get_node(mp, ino, vpp); + error = vcache_get(mp, &ino, sizeof(ino), vpp); if (!error) { DPRINTF(LOOKUP, @@ -734,7 +734,7 @@ nilfs_lookup(void *v) /* done */ } else { /* try to create/reuse the node */ - error = nilfs_get_node(mp, ino, vpp); + error = vcache_get(mp, &ino, sizeof(ino), vpp); if (!error) { /* * If we are not at the last path component