Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
68 7u83 1
#include <sys/param.h>
2
#include <sys/sockio.h>
3
#include <sys/proc.h>
4
#include <sys/vnode.h>
5
#include <sys/kernel.h>
6
#include <sys/sysctl.h>
7
#include <sys/malloc.h>
8
#include <sys/mount.h>
9
#include <sys/mbuf.h>
10
#include <sys/socket.h>
11
#include <sys/socketvar.h>
12
#include <sys/systm.h>
13
#include <sys/protosw.h>
14
#include <sys/syslog.h>
15
 
16
#include <netinet/in.h>
17
#include <netinet/tcp.h>
18
 
19
#include <vm/vm.h>
20
#include <vm/vm_extern.h>
21
#include <vm/vm_zone.h>
22
 
23
#include <net/if.h>
24
#include <net/route.h>
25
#include <netinet/in.h>
26
 
27
#include <9fs/bitstring.h>
28
#include <9fs/9p.h>
29
#include <9fs/9auth.h>
30
#include <9fs/9fs.h>
31
 
32
vm_zone_t u9fsnode_zone;
33
static LIST_HEAD(u9fsnodehashhead, u9fsnode) *u9fsnodehashtbl;
34
static u_long u9fsnodehash;
35
MALLOC_DEFINE(M_U9FSHASH, "U9FS hash", "U9FS hash tables");
36
 
37
/*
38
 * Initialize hash links for u9fsnodes
39
 * and build u9fsnode free list.
40
 */
41
void
42
u9fs_nhinit()
43
{
44
  u9fsnode_zone = zinit("U9FSNODE", sizeof(struct u9fsnode), 0, 0, 1);
45
  u9fsnodehashtbl = phashinit(desiredvnodes, M_U9FSHASH, &u9fsnodehash);
46
}
47
 
48
/*
49
 * Look up a vnode/u9fsnode by file handle.
50
 * Callers must check for mount points!!
51
 * In all cases, a pointer to a
52
 * u9fsnode structure is returned.
53
 */
54
static int u9fs_node_hash_lock;
55
 
56
int
57
u9fs_nget(mntp, fh, npp, p)
58
     struct mount *mntp;
59
     register u9fsfh_t fh;
60
     struct u9fsnode **npp;
61
     struct proc * p;
62
{
63
  struct u9fsnode *np;
64
  struct u9fsnodehashhead *nhpp;
65
  register struct vnode *vp;
66
  struct vnode *nvp;
67
  int error;
68
 
69
  nhpp = U9FSNOHASH(fh);
70
loop:
71
  for (np = nhpp->lh_first; np != 0; np = np->n_hash.le_next) {
72
    if (mntp != U9FSTOV(np)->v_mount || fh != np->n_qid.path )
73
      continue;
74
    vp = U9FSTOV(np);
75
    if (vget(vp, LK_EXCLUSIVE, p))
76
      goto loop;
77
    *npp = np;
78
    return(0);
79
  }
80
  /*
81
   * Obtain a lock to prevent a race condition if the getnewvnode()
82
   * or MALLOC() below happens to block.
83
   */
84
  if (u9fs_node_hash_lock) {
85
    while (u9fs_node_hash_lock) {
86
      u9fs_node_hash_lock = -1;
87
      tsleep(&u9fs_node_hash_lock, PVM, "u9fsngt", 0);
88
    }
89
    goto loop;
90
  }
91
  u9fs_node_hash_lock = 1;
92
 
93
  /*
94
   * allocate before getnewvnode since doing so afterward
95
   * might cause a bogus v_data pointer to get dereferenced
96
   * elsewhere if zalloc should block.
97
   */
98
  np = zalloc(u9fsnode_zone);
99
 
100
  error = getnewvnode(VT_U9FS, mntp, u9fs_vnodeop_p, &nvp);
101
  if (error) {
102
    if (u9fs_node_hash_lock < 0)
103
      wakeup(&u9fs_node_hash_lock);
104
    u9fs_node_hash_lock = 0;
105
    *npp = 0;
106
    zfree(u9fsnode_zone, np);
107
    return (error);
108
  }
109
  vp = nvp;
110
  bzero((caddr_t)np, sizeof *np);
111
  vp->v_data = np;
112
  np->n_vnode = vp;
113
  /*
114
   * Insert the u9fsnode in the hash queue for its new file handle
115
   */
116
  LIST_INSERT_HEAD(nhpp, np, n_hash);
117
  np->n_qid.path = fh;
118
  np->n_qid.vers = 0; /* not in cache yet */
119
  np->n_fid = 0; /* should be set by the caller */
120
  *npp = np;
121
 
122
  if (u9fs_node_hash_lock < 0)
123
    wakeup(&u9fs_node_hash_lock);
124
  u9fs_node_hash_lock = 0;
125
 
126
  /*
127
   * Lock the new u9fsnode.
128
   */
129
  vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
130
 
131
  return (0);
132
}