1 /* Virtual mount table related routines.
11 static int is_vmnt_locked(struct vmnt
*vmp
);
12 static void clear_vmnt(struct vmnt
*vmp
);
14 /* Is vmp pointer reasonable? */
15 #define SANEVMP(v) ((((v) >= &vmnt[0] && (v) < &vmnt[NR_MNTS])))
16 #define BADVMP(v, f, l) printf("%s:%d: bad vmp %p\n", f, l, v)
17 /* vp check that panics */
18 #define ASSERTVMP(v) if(!SANEVMP(v)) { \
19 BADVMP(v, __FILE__, __LINE__); panic("bad vmp"); }
22 /*===========================================================================*
23 * check_vmnt_locks_by_me *
24 *===========================================================================*/
25 void check_vmnt_locks_by_me(struct fproc
*rfp
)
27 /* Check whether this thread still has locks held on vmnts */
30 for (vmp
= &vmnt
[0]; vmp
< &vmnt
[NR_MNTS
]; vmp
++) {
31 if (tll_locked_by_me(&vmp
->m_lock
))
32 panic("Thread %d still holds vmnt lock on vmp %p call_nr=%d\n",
33 mthread_self(), vmp
, job_call_nr
);
36 if (rfp
->fp_vmnt_rdlocks
!= 0)
37 panic("Thread %d still holds read locks on a vmnt (%d) call_nr=%d\n",
38 mthread_self(), rfp
->fp_vmnt_rdlocks
, job_call_nr
);
42 /*===========================================================================*
44 *===========================================================================*/
45 void check_vmnt_locks()
50 for (vmp
= &vmnt
[0]; vmp
< &vmnt
[NR_MNTS
]; vmp
++)
51 if (is_vmnt_locked(vmp
)) {
53 printf("vmnt %p is %s, fs_e=%d dev=%d\n", vmp
, (tll_islocked(&vmp
->m_lock
) ? "locked":"pending locked"), vmp
->m_fs_e
, vmp
->m_dev
);
56 if (count
) panic("%d locked vmnts\n", count
);
58 printf("check_vmnt_locks OK\n");
62 /*===========================================================================*
64 *===========================================================================*/
65 void mark_vmnt_free(struct vmnt
*vmp
)
73 /*===========================================================================*
75 *===========================================================================*/
76 static void clear_vmnt(struct vmnt
*vmp
)
78 /* Reset vmp to initial parameters */
84 vmp
->m_mounted_on
= NULL
;
85 vmp
->m_root_node
= NULL
;
86 vmp
->m_label
[0] = '\0';
87 vmp
->m_comm
.c_max_reqs
= 1;
88 vmp
->m_comm
.c_cur_reqs
= 0;
89 vmp
->m_comm
.c_req_queue
= NULL
;
92 /*===========================================================================*
94 *===========================================================================*/
95 struct vmnt
*get_free_vmnt(void)
99 for (vmp
= &vmnt
[0]; vmp
< &vmnt
[NR_MNTS
]; ++vmp
) {
100 if (vmp
->m_dev
== NO_DEV
) {
109 /*===========================================================================*
111 *===========================================================================*/
112 struct vmnt
*find_vmnt(endpoint_t fs_e
)
114 /* Find the vmnt belonging to an FS with endpoint 'fs_e' iff it's in use */
117 for (vp
= &vmnt
[0]; vp
< &vmnt
[NR_MNTS
]; ++vp
)
118 if (vp
->m_fs_e
== fs_e
&& vp
->m_dev
!= NO_DEV
)
124 /*===========================================================================*
126 *===========================================================================*/
127 void init_vmnts(void)
129 /* Initialize vmnt table */
132 for (vmp
= &vmnt
[0]; vmp
< &vmnt
[NR_MNTS
]; vmp
++) {
134 tll_init(&vmp
->m_lock
);
138 /*===========================================================================*
140 *===========================================================================*/
141 static int is_vmnt_locked(struct vmnt
*vmp
)
144 return(tll_islocked(&vmp
->m_lock
) || tll_haspendinglock(&vmp
->m_lock
));
147 /*===========================================================================*
149 *===========================================================================*/
150 int lock_vmnt(struct vmnt
*vmp
, tll_access_t locktype
)
153 tll_access_t initial_locktype
;
157 initial_locktype
= (locktype
== VMNT_EXCL
) ? VMNT_WRITE
: locktype
;
159 if (vmp
->m_fs_e
== who_e
) return(EDEADLK
);
161 r
= tll_lock(&vmp
->m_lock
, initial_locktype
);
163 if (r
== EBUSY
) return(r
);
165 if (initial_locktype
!= locktype
) {
166 tll_upgrade(&vmp
->m_lock
);
170 if (locktype
== VMNT_READ
)
171 fp
->fp_vmnt_rdlocks
++;
177 /*===========================================================================*
178 * vmnt_unmap_by_endpoint *
179 *===========================================================================*/
180 void vmnt_unmap_by_endpt(endpoint_t proc_e
)
184 if ((vmp
= find_vmnt(proc_e
)) != NULL
) {
187 invalidate_filp_by_endpt(proc_e
);
188 if (vmp
->m_mounted_on
) {
189 /* Only put mount point when it was actually used as mount
190 * point. That is, the mount was succesful. */
191 put_vnode(vmp
->m_mounted_on
);
196 /*===========================================================================*
198 *===========================================================================*/
199 void unlock_vmnt(struct vmnt
*vmp
)
204 /* Decrease read-only lock counter when not locked as VMNT_WRITE or
206 if (!tll_locked_by_me(&vmp
->m_lock
))
207 fp
->fp_vmnt_rdlocks
--;
210 tll_unlock(&vmp
->m_lock
);
213 assert(!tll_locked_by_me(&vmp
->m_lock
));