summaryrefslogtreecommitdiff
path: root/nfs
diff options
context:
space:
mode:
Diffstat (limited to 'nfs')
-rw-r--r--nfs/cache.c74
1 files changed, 74 insertions, 0 deletions
diff --git a/nfs/cache.c b/nfs/cache.c
index 3a14ef27..9b76fd73 100644
--- a/nfs/cache.c
+++ b/nfs/cache.c
@@ -20,10 +20,84 @@
#include "nfs.h"
+#include <string.h>
+#define CACHESIZE 512
+static struct node *nodehash [CACHESIZE];
+static inline int
+hash (void *fhandle)
+{
+ unsigned int h = 0;
+ int i;
+ for (i = 0; i < NFS_FHSIZE; i++)
+ h += ((char *)fhandle)[i];
+
+ return h % CACHESIZE;
+}
+
+struct node *
+lookup_fhandle (void *fhandle)
+{
+ struct node *np;
+ struct netnode *nn;
+ int h = hash (fhandle);
+ spin_lock (&netfs_node_refcnt_lock);
+ for (np = nodehash[h]; np; np = np->nn->hnext)
+ {
+ if (bcmp (np->nn->handle, fhandle, NFS_FHSIZE) != 0)
+ continue;
+
+ np->references++;
+ spin_unlock (&netfs_node_refcnt_lock);
+ mutex_lock (&np->lock);
+ return np;
+ }
+
+ nn = malloc (sizeof (struct netnode));
+ bcopy (fhandle, nn->handle, NFS_FHSIZE);
+ nn->stat_updated = 0;
+ np = netfs_make_node (nn);
+ mutex_lock (&np->lock);
+ nn->hnext = nodehash[h];
+ if (nn->hnext)
+ nn->hnext->nn->hprevp = &nn->hnext;
+ nn->hprevp = &nodehash[h];
+
+ spin_unlock (&netfs_node_refcnt_lock);
+ return np;
+}
+
+void
+netfs_node_norefs (struct node *np)
+{
+ if (np->nn->dead_dir)
+ {
+ np->references++;
+ spin_unlock (&diskfs_node_refcnt_lock);
+
+ netfs_attempt_unlink ((struct netcred *)-1, np->nn->dead_dir,
+ np->nn->dead_name);
+ diskfs_nrele (np->nn->dead_dir);
+ free (np->nn->dead_name);
+ np->nn->dead_dir = 0;
+ np->nn->dead_name = 0;
+ diskfs_nput (np);
+
+ /* Caller expects us to leave this locked... */
+ spin_lock (&diskfs_node_refcnt_lock);
+ }
+ else
+ {
+ *np->nn->hprevp = np->nn->hnext;
+ if (np->nn->hnext)
+ np->nn->hnext->nn->hprevp = np->nn->hprevp;
+ free (np->nn);
+ free (np);
+ }
+}