Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/fs/msdosfs Change msdosfs from hashlist to vcache:
details: https://anonhg.NetBSD.org/src/rev/7456524a92b9
branches: trunk
changeset: 330419:7456524a92b9
user: hannken <hannken%NetBSD.org@localhost>
date: Tue Jul 08 09:21:52 2014 +0000
description:
Change msdosfs from hashlist to vcache:
- Use (dir_cluster, dir_offset, dir_generation) as key, where
dir_generation is non-zero and unique for unlinked but open nodes.
- Change deget() to return a vnode as it is unsafe to return a
referenced but unlocked denode.
diffstat:
sys/fs/msdosfs/denode.h | 19 +-
sys/fs/msdosfs/msdosfs_denode.c | 288 ++++++++++-----------------------------
sys/fs/msdosfs/msdosfs_lookup.c | 103 ++++++-------
sys/fs/msdosfs/msdosfs_vfsops.c | 35 ++-
sys/fs/msdosfs/msdosfs_vnops.c | 21 +-
sys/fs/msdosfs/msdosfsmount.h | 6 +-
6 files changed, 180 insertions(+), 292 deletions(-)
diffs (truncated from 849 to 300 lines):
diff -r c700a490f947 -r 7456524a92b9 sys/fs/msdosfs/denode.h
--- a/sys/fs/msdosfs/denode.h Tue Jul 08 09:08:05 2014 +0000
+++ b/sys/fs/msdosfs/denode.h Tue Jul 08 09:21:52 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: denode.h,v 1.23 2013/01/26 19:45:02 christos Exp $ */
+/* $NetBSD: denode.h,v 1.24 2014/07/08 09:21:52 hannken Exp $ */
/*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@@ -153,15 +153,21 @@
* This is the in memory variant of a dos directory entry. It is usually
* contained within a vnode.
*/
+struct denode_key {
+ u_long dk_dirclust; /* cluster of the directory file containing this entry */
+ u_long dk_diroffset; /* offset of this entry in the directory cluster */
+ void *dk_dirgen; /* non zero and unique for unlinked nodes */
+};
struct denode {
struct genfs_node de_gnode;
- LIST_ENTRY(denode) de_hash;
struct vnode *de_vnode; /* addr of vnode we are part of */
struct vnode *de_devvp; /* vnode of blk dev we live on */
u_long de_flag; /* flag bits */
dev_t de_dev; /* device where direntry lives */
- u_long de_dirclust; /* cluster of the directory file containing this entry */
- u_long de_diroffset; /* offset of this entry in the directory cluster */
+ struct denode_key de_key;
+#define de_dirclust de_key.dk_dirclust
+#define de_diroffset de_key.dk_diroffset
+#define de_dirgen de_key.dk_dirgen
u_long de_fndoffset; /* offset of found dir entry */
int de_fndcnt; /* number of slots before de_fndoffset */
long de_refcnt; /* reference count */
@@ -303,7 +309,11 @@
int createde(struct denode *, struct denode *,
struct denode **, struct componentname *);
int deextend(struct denode *, u_long, struct kauth_cred *);
+#ifdef MAKEFS
int deget(struct msdosfsmount *, u_long, u_long, struct denode **);
+#else
+int deget(struct msdosfsmount *, u_long, u_long, struct vnode **);
+#endif
int detrunc(struct denode *, u_long, int, struct kauth_cred *);
int deupdat(struct denode *, int);
int doscheckpath(struct denode *, struct denode *);
@@ -311,7 +321,6 @@
int readde(struct denode *, struct buf **, struct direntry **);
int readep(struct msdosfsmount *, u_long, u_long,
struct buf **, struct direntry **);
-void reinsert(struct denode *);
int removede(struct denode *, struct denode *);
int uniqdosname(struct denode *, struct componentname *, u_char *);
int findwin95(struct denode *);
diff -r c700a490f947 -r 7456524a92b9 sys/fs/msdosfs/msdosfs_denode.c
--- a/sys/fs/msdosfs/msdosfs_denode.c Tue Jul 08 09:08:05 2014 +0000
+++ b/sys/fs/msdosfs/msdosfs_denode.c Tue Jul 08 09:21:52 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: msdosfs_denode.c,v 1.49 2014/05/30 08:42:35 hannken Exp $ */
+/* $NetBSD: msdosfs_denode.c,v 1.50 2014/07/08 09:21:52 hannken Exp $ */
/*-
* Copyright (C) 1994, 1995, 1997 Wolfgang Solfrank.
@@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: msdosfs_denode.c,v 1.49 2014/05/30 08:42:35 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: msdosfs_denode.c,v 1.50 2014/07/08 09:21:52 hannken Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -72,14 +72,6 @@
#include <fs/msdosfs/denode.h>
#include <fs/msdosfs/fat.h>
-LIST_HEAD(ihashhead, denode) *dehashtbl;
-u_long dehash; /* size of hash table - 1 */
-#define DEHASH(dev, dcl, doff) \
- (((dev) + (dcl) + (doff) / sizeof(struct direntry)) & dehash)
-
-kmutex_t msdosfs_ihash_lock;
-kmutex_t msdosfs_hashlock;
-
struct pool msdosfs_denode_pool;
extern int prtactive;
@@ -138,10 +130,6 @@
.gop_markupdate = msdosfs_gop_markupdate,
};
-static struct denode *msdosfs_hashget(dev_t, u_long, u_long, int);
-static void msdosfs_hashins(struct denode *);
-static void msdosfs_hashrem(struct denode *);
-
MALLOC_DECLARE(M_MSDOSFSFAT);
void
@@ -155,112 +143,33 @@
"msdosnopl", &pool_allocator_nointr, IPL_NONE);
pool_init(&fh_pool, sizeof(struct fh_node), 0, 0, 0,
"msdosfhpl", &pool_allocator_nointr, IPL_NONE);
- dehashtbl = hashinit(desiredvnodes / 2, HASH_LIST, true, &dehash);
rb_tree_init(&fh_rbtree, &fh_rbtree_ops);
- mutex_init(&msdosfs_ihash_lock, MUTEX_DEFAULT, IPL_NONE);
mutex_init(&fh_lock, MUTEX_DEFAULT, IPL_NONE);
- mutex_init(&msdosfs_hashlock, MUTEX_DEFAULT, IPL_NONE);
}
/*
- * Reinitialize inode hash table.
+ * Reinitialize.
*/
void
msdosfs_reinit(void)
{
- struct denode *dep;
- struct ihashhead *oldhash, *hash;
- u_long oldmask, mask, val;
- int i;
- hash = hashinit(desiredvnodes / 2, HASH_LIST, true, &mask);
-
- mutex_enter(&msdosfs_ihash_lock);
- oldhash = dehashtbl;
- oldmask = dehash;
- dehashtbl = hash;
- dehash = mask;
- for (i = 0; i <= oldmask; i++) {
- while ((dep = LIST_FIRST(&oldhash[i])) != NULL) {
- LIST_REMOVE(dep, de_hash);
- val = DEHASH(dep->de_dev, dep->de_dirclust,
- dep->de_diroffset);
- LIST_INSERT_HEAD(&hash[val], dep, de_hash);
- }
- }
- mutex_exit(&msdosfs_ihash_lock);
- hashdone(oldhash, HASH_LIST, oldmask);
}
void
msdosfs_done(void)
{
- hashdone(dehashtbl, HASH_LIST, dehash);
pool_destroy(&msdosfs_denode_pool);
pool_destroy(&fh_pool);
- mutex_destroy(&msdosfs_ihash_lock);
mutex_destroy(&fh_lock);
- mutex_destroy(&msdosfs_hashlock);
malloc_type_detach(M_MSDOSFSTMP);
malloc_type_detach(M_MSDOSFSFAT);
malloc_type_detach(M_MSDOSFSMNT);
}
-static struct denode *
-msdosfs_hashget(dev_t dev, u_long dirclust, u_long diroff, int flags)
-{
- struct denode *dep;
- struct vnode *vp;
-
-loop:
- mutex_enter(&msdosfs_ihash_lock);
- LIST_FOREACH(dep, &dehashtbl[DEHASH(dev, dirclust, diroff)], de_hash) {
- if (dirclust == dep->de_dirclust &&
- diroff == dep->de_diroffset &&
- dev == dep->de_dev &&
- dep->de_refcnt != 0) {
- vp = DETOV(dep);
- if (flags == 0) {
- mutex_exit(&msdosfs_ihash_lock);
- } else {
- mutex_enter(vp->v_interlock);
- mutex_exit(&msdosfs_ihash_lock);
- if (vget(vp, flags))
- goto loop;
- }
- return (dep);
- }
- }
- mutex_exit(&msdosfs_ihash_lock);
- return (NULL);
-}
-
-static void
-msdosfs_hashins(struct denode *dep)
-{
- struct ihashhead *depp;
- int val;
-
- KASSERT(mutex_owned(&msdosfs_hashlock));
-
- mutex_enter(&msdosfs_ihash_lock);
- val = DEHASH(dep->de_dev, dep->de_dirclust, dep->de_diroffset);
- depp = &dehashtbl[val];
- LIST_INSERT_HEAD(depp, dep, de_hash);
- mutex_exit(&msdosfs_ihash_lock);
-}
-
-static void
-msdosfs_hashrem(struct denode *dep)
-{
- mutex_enter(&msdosfs_ihash_lock);
- LIST_REMOVE(dep, de_hash);
- mutex_exit(&msdosfs_ihash_lock);
-}
-
/*
- * If deget() succeeds it returns with the gotten denode locked().
+ * If deget() succeeds it returns with the gotten denode unlocked.
*
* pmp - address of msdosfsmount structure of the filesystem containing
* the denode of interest. The pm_dev field and the address of
@@ -269,26 +178,18 @@
* diroffset is relative to the beginning of the root directory,
* otherwise it is cluster relative.
* diroffset - offset past begin of cluster of denode we want
- * depp - returns the address of the gotten denode.
+ * vpp - returns the address of the gotten vnode.
*/
int
-deget(struct msdosfsmount *pmp, u_long dirclust, u_long diroffset, struct denode **depp)
+deget(struct msdosfsmount *pmp, u_long dirclust, u_long diroffset,
+ struct vnode **vpp)
/* pmp: so we know the maj/min number */
/* dirclust: cluster this dir entry came from */
/* diroffset: index of entry within the cluster */
- /* depp: returns the addr of the gotten denode */
+ /* vpp: returns the addr of the gotten vnode */
{
int error;
- extern int (**msdosfs_vnodeop_p)(void *);
- struct direntry *direntptr;
- struct denode *ldep;
- struct vnode *nvp;
- struct buf *bp;
-
-#ifdef MSDOSFS_DEBUG
- printf("deget(pmp %p, dirclust %lu, diroffset %lx, depp %p)\n",
- pmp, dirclust, diroffset, depp);
-#endif
+ struct denode_key key;
/*
* On FAT32 filesystems, root is a (more or less) normal
@@ -297,78 +198,59 @@
if (FAT32(pmp) && dirclust == MSDOSFSROOT)
dirclust = pmp->pm_rootdirblk;
- /*
- * See if the denode is in the denode cache. Use the location of
- * the directory entry to compute the hash value. For subdir use
- * address of "." entry. For root dir (if not FAT32) use cluster
- * MSDOSFSROOT, offset MSDOSFSROOT_OFS
- *
- * NOTE: The check for de_refcnt > 0 below insures the denode being
- * examined does not represent an unlinked but still open file.
- * These files are not to be accessible even when the directory
- * entry that represented the file happens to be reused while the
- * deleted file is still open.
- */
- retry:
- ldep = msdosfs_hashget(pmp->pm_dev, dirclust, diroffset, LK_EXCLUSIVE);
- if (ldep) {
- *depp = ldep;
- return (0);
- }
+ memset(&key, 0, sizeof(key));
+ key.dk_dirclust = dirclust;
+ key.dk_diroffset = diroffset;
+ /* key.dk_dirgen = NULL; */
+
+ error = vcache_get(pmp->pm_mountp, &key, sizeof(key), vpp);
+ return error;
+}
+
+int
+msdosfs_loadvnode(struct mount *mp, struct vnode *vp,
+ const void *key, size_t key_len, const void **new_key)
+{
+ bool is_root;
+ int error;
+ extern int (**msdosfs_vnodeop_p)(void *);
+ struct msdosfsmount *pmp;
+ struct direntry *direntptr;
+ struct denode *ldep;
+ struct buf *bp;
+ struct denode_key dkey;
- /*
- * Directory entry was not in cache, have to create a vnode and
- * copy it from the passed disk buffer.
- */
- error = getnewvnode(VT_MSDOSFS, pmp->pm_mountp, msdosfs_vnodeop_p,
- NULL, &nvp);
- if (error) {
- *depp = 0;
- return (error);
- }
- ldep = pool_get(&msdosfs_denode_pool, PR_WAITOK);
Home |
Main Index |
Thread Index |
Old Index