Print this page
fixes to fsh
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/fs/fsh.c
+++ new/usr/src/uts/common/fs/fsh.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 13 * Copyright 2013 Damian Bogel. All rights reserved.
14 14 */
15 15
16 16 #include <sys/sunddi.h>
17 17 #include <sys/fsh.h>
18 18 #include <sys/fsh_impl.h>
19 19 #include <sys/ksynch.h>
20 20 #include <sys/types.h>
21 21 #include <sys/vfs.h>
22 22 #include <sys/vnode.h>
23 23
24 24 /*
25 25 * TODO:
26 26 * - support more operations
27 27 * - describe the design of FSH in a comment
28 28 * - add DTrace and kstat
29 29 */
30 30
31 31 #define FSH_VFS_MOUNT 0
32 32 #define FSH_VFS_UNMOUNT 1
33 33 #define FSH_VFS_ROOT 2
34 34 #define FSH_VFS_STATFS 3
35 35 #define FSH_VFS_VGET 4
36 36
37 37 #define FSH_VOP_OPEN 5
38 38 #define FSH_VOP_CLOSE 6
39 39 #define FSH_VOP_READ 7
40 40 #define FSH_VOP_WRITE 8
41 41
42 42 #define FSH_SUPPORTED_OPS_COUNT 9
43 43
44 44 typedef union fsh_fn {
45 45 FSH_OPS;
46 46 } fsh_fn_t;
47 47
48 48 typedef struct fsh_int {
49 49 fsh_fn_t fshi_fn;
50 50 void *fshi_arg;
51 51 } fsh_int_t;
52 52
53 53
54 54 struct fsh_node {
55 55 fsh_int_t fshn_hooki;
56 56 struct fsh_node *fshn_next;
57 57 };
58 58 /* typedef struct fsh_node fsh_node_t; in fsh.h */
59 59
60 60 /*
61 61 * fshl_lock is being read-locked by every call to a fsh_vop/vfsop() for
62 62 * entire execution. This way, we guarantee that a list of hooks is unchanged
63 63 * during one fop_foo()/fsop_foo() execution.
64 64 */
65 65 typedef struct fsh_list {
66 66 krwlock_t fshl_lock;
67 67 fsh_node_t *fshl_head;
68 68 } fsh_list_t;
69 69
70 70 typedef fsh_list_t fsh_opvector[FSH_SUPPORTED_OPS_COUNT];
71 71 typedef fsh_opvector fsh_opvector_t;
72 72
73 73
74 74 typedef struct fsh_fsrecord {
75 75 krwlock_t fshfsr_en_lock; /* lock for fshfsr_enabled */
76 76 int fshfsr_enabled;
77 77 fsh_opvector_t fshfsr_opv;
78 78 } fsh_fsrecord_t;
79 79
80 80
81 81 typedef struct fsh_callback_node {
82 82 fsh_callback_t fshcn_callback;
83 83 struct fsh_callback_node *fshcn_next;
84 84 } fsh_callback_node_t;
85 85
86 86 typedef struct fsh_callback_list {
87 87 krwlock_t fshcl_lock;
↓ open down ↓ |
87 lines elided |
↑ open up ↑ |
88 88 fsh_callback_node_t *fshcl_head;
89 89 } fsh_callback_list_t;
90 90
91 91 fsh_callback_list_t fsh_global_callback_list;
92 92
93 93 /*
94 94 * It is assumed that VFS_HOLD() has been called before calling any of the
95 95 * fsh_fs_xxx()/fsh_hook_xxx() API. VFS_RELE() should be called after.
96 96 */
97 97
98 -#define FSH_GET_FSREC(vfsp) (vfsp->vfs_fshrecord)
98 +#define FSH_GET_FSRECP(vfsp) (vfsp->vfs_fshrecord)
99 99
100 100 int
101 101 fsh_fs_enable(vfs_t *vfsp)
102 102 {
103 103 fsh_fsrecord_t *fsrec;
104 104
105 - fsrec = FSH_GET_FSREC(vfsp);
105 + fsrec = FSH_GET_FSRECP(vfsp);
106 106 rw_enter(&fsrec->fshfsr_en_lock, RW_WRITER);
107 107 fsrec->fshfsr_enabled = 1;
108 108 rw_exit(&fsrec->fshfsr_en_lock);
109 109
110 110 return (0);
111 111 }
112 112
113 113 int
114 114 fsh_fs_disable(vfs_t *vfsp)
115 115 {
116 116 fsh_fsrecord_t *fsrec;
117 117
118 - fsrec = FSH_GET_FSREC(vfsp);
118 + fsrec = FSH_GET_FSRECP(vfsp);
119 119 rw_enter(&fsrec->fshfsr_en_lock, RW_WRITER);
120 120 fsrec->fshfsr_enabled = 0;
121 121 rw_exit(&fsrec->fshfsr_en_lock);
122 122
123 123 return (0);
124 124 }
125 125
126 126
127 127 #define FSH_INSTALL(type, hooks, fsrecp, listp, nodep, lower, upper) \
128 128 do { \
129 129 if (hooks->hook_##lower) { \
130 130 nodep = (fsh_node_t *) kmem_alloc(sizeof (*nodep), \
131 131 KM_SLEEP); \
132 132 nodep->fshn_hooki.fshi_fn.hook_##lower = \
133 133 hooks->hook_##lower; \
134 134 nodep->fshn_hooki.fshi_arg = hooks->arg; \
135 135 \
136 + listp = &fsrecp->fshfsr_opv[FSH_##type##_##upper]; \
136 137 rw_enter(&listp->fshl_lock, RW_WRITER); \
137 138 nodep->fshn_next = \
138 139 fsrecp \
139 140 ->fshfsr_opv[FSH_##type##_##upper].fshl_head; \
140 141 fsrecp->fshfsr_opv[FSH_##type##_##upper].fshl_head \
141 142 = nodep; \
142 143 rw_exit(&listp->fshl_lock); \
143 144 } \
145 +_NOTE(CONSTCOND) \
144 146 } while (0)
145 147
146 148 #define FSH_INSTALL_VN(hooks, fsrecp, listp, nodep, lower, upper) \
147 149 FSH_INSTALL(VOP, hooks, fsrecp, listp, nodep, lower, upper)
148 150
149 151 #define FSH_INSTALL_VFS(hooks, fsrecp, listp, nodep, lower, upper) \
150 152 FSH_INSTALL(VFS, hooks, fsrecp, listp, nodep, lower, upper)
151 153
152 154 int
153 155 fsh_hook_install(vfs_t *vfsp, fsh_t *hooks)
154 156 {
155 157 fsh_fsrecord_t *fsrec;
156 158 fsh_list_t *list;
157 159 fsh_node_t *node;
158 160
159 - fsrec = FSH_GET_FSREC(vfsp);
161 + fsrec = FSH_GET_FSRECP(vfsp);
160 162
161 163 FSH_INSTALL_VN(hooks, fsrec, list, node, open, OPEN);
162 164 FSH_INSTALL_VN(hooks, fsrec, list, node, close, CLOSE);
163 165 FSH_INSTALL_VN(hooks, fsrec, list, node, read, READ);
164 166 FSH_INSTALL_VN(hooks, fsrec, list, node, write, WRITE);
165 167 FSH_INSTALL_VFS(hooks, fsrec, list, node, mount, MOUNT);
166 168 FSH_INSTALL_VFS(hooks, fsrec, list, node, unmount, UNMOUNT);
167 169 FSH_INSTALL_VFS(hooks, fsrec, list, node, root, ROOT);
168 170 FSH_INSTALL_VFS(hooks, fsrec, list, node, vget, VGET);
169 171 FSH_INSTALL_VFS(hooks, fsrec, list, node, statfs, STATFS);
170 172
171 173 return (0);
172 174 }
173 175
174 176
175 177 #define FSH_REMOVE(type, hooks, fsrec, list, node, prev, lower, upper) \
176 178 do { \
177 179 if (hooks->hook_ ## lower == NULL) \
178 180 break; \
179 181 \
180 182 list = &fsrec->fshfsr_opv[FSH_ ## type ## _ ## upper]; \
181 183 rw_enter(&list->fshl_lock, RW_WRITER); \
182 184 node = list->fshl_head; \
183 185 \
184 186 if (node == NULL) { \
185 187 rw_exit(&list->fshl_lock); \
186 188 break; \
187 189 } \
188 190 \
189 191 while (node && \
190 192 !(node->fshn_hooki.fshi_fn.hook_ ## lower == \
191 193 hooks->hook_ ## lower && \
192 194 node->fshn_hooki.fshi_arg == hooks->arg)) { \
193 195 prev = node; \
194 196 node = node->fshn_next; \
195 197 } \
196 198 \
197 199 if (node == NULL) { \
198 200 rw_exit(&list->fshl_lock); \
↓ open down ↓ |
29 lines elided |
↑ open up ↑ |
199 201 break; \
200 202 } \
201 203 \
202 204 if (node == list->fshl_head) \
203 205 list->fshl_head = node->fshn_next; \
204 206 else \
205 207 prev->fshn_next = node->fshn_next; \
206 208 rw_exit(&list->fshl_lock); \
207 209 \
208 210 kmem_free(node, sizeof (*node)); \
211 +_NOTE(CONSTCOND) \
209 212 } while (0)
210 213
211 214 #define FSH_REMOVE_VN(hooks, fsrec, list, node, prev, lower, upper) \
212 215 FSH_REMOVE(VOP, hooks, fsrec, list, node, prev, lower, upper)
213 216
214 217 #define FSH_REMOVE_VFS(hooks, fsrec, list, node, prev, lower, upper) \
215 218 FSH_REMOVE(VFS, hooks, fsrec, list, node, prev, lower, upper)
216 219
217 220 int
218 221 fsh_hook_remove(vfs_t *vfsp, fsh_t *hooks)
219 222 {
220 223 fsh_fsrecord_t *fsrec;
221 224 fsh_list_t *list;
222 225 fsh_node_t *node;
223 226 fsh_node_t *prev;
224 227
225 - fsrec = FSH_GET_FSREC(vfsp);
228 + fsrec = FSH_GET_FSRECP(vfsp);
226 229
227 230 FSH_REMOVE_VN(hooks, fsrec, list, node, prev, open, OPEN);
228 231 FSH_REMOVE_VN(hooks, fsrec, list, node, prev, close, CLOSE);
229 232 FSH_REMOVE_VN(hooks, fsrec, list, node, prev, read, READ);
230 233 FSH_REMOVE_VN(hooks, fsrec, list, node, prev, write, WRITE);
231 234 FSH_REMOVE_VFS(hooks, fsrec, list, node, prev, mount, MOUNT);
232 235 FSH_REMOVE_VFS(hooks, fsrec, list, node, prev, unmount, UNMOUNT);
233 236 FSH_REMOVE_VFS(hooks, fsrec, list, node, prev, root, ROOT);
234 237 FSH_REMOVE_VFS(hooks, fsrec, list, node, prev, vget, VGET);
235 238 FSH_REMOVE_VFS(hooks, fsrec, list, node, prev, statfs, STATFS);
236 239
237 240 return (0);
238 241 }
239 242
240 243
241 244 int
242 245 fsh_callback_install(fsh_callback_t *fsh_callback)
243 246 {
244 247 fsh_callback_node_t *node;
245 248
246 249 node = (fsh_callback_node_t *) kmem_alloc(sizeof (*node), KM_SLEEP);
247 250 node->fshcn_callback = *fsh_callback;
248 251
249 252 rw_enter(&fsh_global_callback_list.fshcl_lock, RW_WRITER);
250 253 node->fshcn_next = fsh_global_callback_list.fshcl_head;
251 254 fsh_global_callback_list.fshcl_head = node;
252 255 rw_exit(&fsh_global_callback_list.fshcl_lock);
253 256
254 257 return (0);
255 258 }
256 259
257 260 int
258 261 fsh_callback_remove(fsh_callback_t *fsh_callback)
259 262 {
260 263 fsh_callback_node_t *node;
261 264 fsh_callback_node_t *prev;
262 265 fsh_callback_list_t *list;
263 266
264 267 list = &fsh_global_callback_list;
265 268
266 269 rw_enter(&list->fshcl_lock, RW_WRITER);
267 270 node = list->fshcl_head;
268 271
269 272 if (node == NULL) {
270 273 rw_exit(&list->fshcl_lock);
271 274 return (0);
272 275 }
273 276
274 277 while (node && memcmp(fsh_callback, &node->fshcn_callback,
275 278 sizeof (*fsh_callback))) {
276 279 prev = node;
277 280 node = node->fshcn_next;
278 281 }
279 282
280 283 if (node == NULL) {
281 284 rw_exit(&list->fshcl_lock);
282 285 return (0);
283 286 }
284 287
285 288 prev->fshcn_next = node->fshcn_next;
286 289 kmem_free(node, sizeof (*node));
↓ open down ↓ |
51 lines elided |
↑ open up ↑ |
287 290
288 291 rw_exit(&list->fshcl_lock);
289 292 return (0);
290 293 }
291 294
292 295
293 296
294 297
295 298 #define FSH_ENABLED(vfsp, enabled) \
296 299 do { \
297 - rw_enter(&FSH_GET_FSREC(vfsp)->fshfsr_en_lock, RW_READER); \
298 - *enabled = FSH_GET_FSREC(vfsp)->fshfsr_enabled; \
299 - rw_exit(&FSH_GET_FSREC(vfsp)->fshfsr_en_lock); \
300 + rw_enter(&FSH_GET_FSRECP(vfsp)->fshfsr_en_lock, RW_READER); \
301 + *enabled = FSH_GET_FSRECP(vfsp)->fshfsr_enabled; \
302 + rw_exit(&FSH_GET_FSRECP(vfsp)->fshfsr_en_lock); \
303 +_NOTE(CONSTCOND) \
300 304 } while (0)
301 305
302 306 int
303 307 fsh_open(vnode_t **vpp, int mode, cred_t *cr, caller_context_t *ct)
304 308 {
305 309 fsh_list_t *list;
306 310 int enabled;
307 311 int ret;
308 312
309 313 FSH_ENABLED((*vpp)->v_vfsp, &enabled);
310 314 if (!enabled)
311 315 return ((*((*vpp)->v_op->vop_open))(vpp, mode, cr, ct));
312 316
313 - list = &FSH_GET_FSREC((*vpp)->v_vfsp)->fshfsr_opv[FSH_VOP_OPEN];
317 + list = &FSH_GET_FSRECP((*vpp)->v_vfsp)->fshfsr_opv[FSH_VOP_OPEN];
314 318 rw_enter(&list->fshl_lock, RW_READER);
315 319 if (list->fshl_head == NULL)
316 320 ret = (*((*vpp)->v_op->vop_open))(vpp, mode, cr, ct);
317 321 else
318 322 ret = fsh_next_open(list->fshl_head, vpp, mode, cr, ct);
319 323 rw_exit(&list->fshl_lock);
320 324
321 325 return (ret);
322 326 }
323 327
324 328 int
325 329 fsh_close(vnode_t *vp, int flag, int count, offset_t offset, cred_t *cr,
326 330 caller_context_t *ct)
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
327 331 {
328 332 fsh_list_t *list;
329 333 int enabled;
330 334 int ret;
331 335
332 336 FSH_ENABLED(vp->v_vfsp, &enabled);
333 337 if (!enabled)
334 338 return ((*(vp->v_op->vop_close))(vp, flag, count, offset,
335 339 cr, ct));
336 340
337 - list = &FSH_GET_FSREC(vp->v_vfsp)->fshfsr_opv[FSH_VOP_CLOSE];
341 + list = &FSH_GET_FSRECP(vp->v_vfsp)->fshfsr_opv[FSH_VOP_CLOSE];
338 342 rw_enter(&list->fshl_lock, RW_READER);
339 343 if (list->fshl_head == NULL)
340 344 ret = (*(vp->v_op->vop_close))(vp, flag, count, offset,
341 345 cr, ct);
342 346 else
343 347 ret = fsh_next_close(list->fshl_head, vp, flag, count,
344 348 offset, cr, ct);
345 349 rw_exit(&list->fshl_lock);
346 350
347 351 return (ret);
348 352 }
349 353
350 354 int
351 355 fsh_read(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr,
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
352 356 caller_context_t *ct)
353 357 {
354 358 fsh_list_t *list;
355 359 int enabled;
356 360 int ret;
357 361
358 362 FSH_ENABLED(vp->v_vfsp, &enabled);
359 363 if (!enabled)
360 364 return ((*(vp->v_op->vop_read))(vp, uiop, ioflag, cr, ct));
361 365
362 - list = &FSH_GET_FSREC(vp->v_vfsp)->fshfsr_opv[FSH_VOP_READ];
366 + list = &FSH_GET_FSRECP(vp->v_vfsp)->fshfsr_opv[FSH_VOP_READ];
363 367 rw_enter(&list->fshl_lock, RW_READER);
364 368 if (list->fshl_head == NULL)
365 369 ret = (*(vp->v_op->vop_read))(vp, uiop, ioflag, cr, ct);
366 370 else
367 371 ret = fsh_next_read(list->fshl_head, vp, uiop, ioflag,
368 372 cr, ct);
369 373 rw_exit(&list->fshl_lock);
370 374
371 375 return (ret);
372 376 }
373 377
374 378 int
375 379 fsh_write(vnode_t *vp, uio_t *uiop, int ioflag, cred_t *cr,
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
376 380 caller_context_t *ct)
377 381 {
378 382 fsh_list_t *list;
379 383 int enabled;
380 384 int ret;
381 385
382 386 FSH_ENABLED(vp->v_vfsp, &enabled);
383 387 if (!enabled)
384 388 return ((*(vp->v_op->vop_write))(vp, uiop, ioflag, cr, ct));
385 389
386 - list = &FSH_GET_FSREC(vp->v_vfsp)->fshfsr_opv[FSH_VOP_WRITE];
390 + list = &FSH_GET_FSRECP(vp->v_vfsp)->fshfsr_opv[FSH_VOP_WRITE];
387 391 rw_enter(&list->fshl_lock, RW_READER);
388 392 if (list->fshl_head == NULL)
389 393 ret = (*(vp->v_op->vop_write))(vp, uiop, ioflag, cr, ct);
390 394 else
391 395 ret = fsh_next_write(list->fshl_head, vp, uiop, ioflag,
392 396 cr, ct);
393 397 rw_exit(&list->fshl_lock);
394 398
395 399 return (ret);
396 400 }
397 401
398 402 int
399 403 fsh_mount(vfs_t *vfsp, vnode_t *mvp, struct mounta *uap, cred_t *cr)
400 404 {
401 405 fsh_list_t *list;
402 406 int ret;
403 407
404 - list = &FSH_GET_FSREC(vfsp)->fshfsr_opv[FSH_VFS_MOUNT];
408 + list = &FSH_GET_FSRECP(vfsp)->fshfsr_opv[FSH_VFS_MOUNT];
405 409 rw_enter(&list->fshl_lock, RW_READER);
406 410 if (list->fshl_head == NULL)
407 411 ret = (*(vfsp->vfs_op->vfs_mount))(vfsp, mvp, uap, cr);
408 412 else
409 413 ret = fsh_next_mount(list->fshl_head, vfsp, mvp, uap,
410 414 cr);
411 415 rw_exit(&list->fshl_lock);
412 416
413 417 return (ret);
414 418 }
415 419
416 420 int
417 421 fsh_unmount(vfs_t *vfsp, int flag, cred_t *cr)
418 422 {
419 423 fsh_list_t *list;
420 424 int ret;
421 425
422 - list = &FSH_GET_FSREC(vfsp)->fshfsr_opv[FSH_VFS_UNMOUNT];
426 + list = &FSH_GET_FSRECP(vfsp)->fshfsr_opv[FSH_VFS_UNMOUNT];
423 427 rw_enter(&list->fshl_lock, RW_READER);
424 428 if (list->fshl_head == NULL)
425 429 ret = (*(vfsp->vfs_op->vfs_unmount))(vfsp, flag, cr);
426 430 else
427 431 ret = fsh_next_unmount(list->fshl_head, vfsp, flag, cr);
428 432 rw_exit(&list->fshl_lock);
429 433
430 434 return (ret);
431 435 }
432 436
433 437 int
434 438 fsh_root(vfs_t *vfsp, vnode_t **vpp)
435 439 {
436 440 fsh_list_t *list;
437 441 int ret;
438 442
439 - list = &FSH_GET_FSREC(vfsp)->fshfsr_opv[FSH_VFS_ROOT];
443 + list = &FSH_GET_FSRECP(vfsp)->fshfsr_opv[FSH_VFS_ROOT];
440 444 rw_enter(&list->fshl_lock, RW_READER);
441 445 if (list->fshl_head == NULL)
442 446 ret = (*(vfsp->vfs_op->vfs_root))(vfsp, vpp);
443 447 else
444 448 ret = fsh_next_root(list->fshl_head, vfsp, vpp);
445 449 rw_exit(&list->fshl_lock);
446 450
447 451 return (ret);
448 452 }
449 453
450 454 int
451 455 fsh_statfs(vfs_t *vfsp, statvfs64_t *sp)
452 456 {
453 457 fsh_list_t *list;
454 458 int ret;
455 459
456 - list = &FSH_GET_FSREC(vfsp)->fshfsr_opv[FSH_VFS_STATFS];
460 + list = &FSH_GET_FSRECP(vfsp)->fshfsr_opv[FSH_VFS_STATFS];
457 461 rw_enter(&list->fshl_lock, RW_READER);
458 462 if (list->fshl_head == NULL)
459 463 ret = (*(vfsp->vfs_op->vfs_statvfs))(vfsp, sp);
460 464 else
461 465 ret = fsh_next_statfs(list->fshl_head, vfsp, sp);
462 466 rw_exit(&list->fshl_lock);
463 467
464 468 return (ret);
465 469 }
466 470
467 471 int
468 472 fsh_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp)
469 473 {
470 474 fsh_list_t *list;
471 475 int ret;
472 476
473 - list = &FSH_GET_FSREC(vfsp)->fshfsr_opv[FSH_VFS_VGET];
477 + list = &FSH_GET_FSRECP(vfsp)->fshfsr_opv[FSH_VFS_VGET];
474 478 rw_enter(&list->fshl_lock, RW_READER);
475 479 if (list->fshl_head == NULL)
476 480 ret = (*(vfsp->vfs_op->vfs_vget))(vfsp, vpp, fidp);
477 481 else
478 482 ret = fsh_next_vget(list->fshl_head, vfsp, vpp, fidp);
479 483 rw_exit(&list->fshl_lock);
480 484
481 485 return (ret);
482 486 }
483 487
484 488 void
485 489 fsh_exec_create_callbacks(vfs_t *vfsp)
486 490 {
487 491 fsh_callback_node_t *node;
488 492 fsh_callback_t *callback;
489 493
490 494 rw_enter(&fsh_global_callback_list.fshcl_lock, RW_READER);
491 495 node = fsh_global_callback_list.fshcl_head;
492 496 while (node) {
493 497 callback = &node->fshcn_callback;
494 498 (*(callback->fshc_create))(vfsp, callback->fshc_arg);
495 499 node = node->fshcn_next;
496 500 }
497 501 rw_exit(&fsh_global_callback_list.fshcl_lock);
498 502 }
499 503
500 504 void
501 505 fsh_exec_destroy_callbacks(vfs_t *vfsp)
502 506 {
503 507 fsh_callback_node_t *node;
504 508 fsh_callback_t *callback;
505 509
506 510 rw_enter(&fsh_global_callback_list.fshcl_lock, RW_READER);
507 511 node = fsh_global_callback_list.fshcl_head;
508 512 while (node) {
509 513 callback = &node->fshcn_callback;
510 514 (*(callback->fshc_destroy))(vfsp, callback->fshc_arg);
511 515 node = node->fshcn_next;
512 516 }
513 517 rw_exit(&fsh_global_callback_list.fshcl_lock);
514 518 }
515 519
516 520 /* To be used ONLY in vfs_alloc() */
↓ open down ↓ |
33 lines elided |
↑ open up ↑ |
517 521 struct fsh_fsrecord *
518 522 fsh_fsrec_create()
519 523 {
520 524 struct fsh_fsrecord *fsrecp;
521 525 int i;
522 526
523 527 fsrecp = (fsh_fsrecord_t *) kmem_alloc(sizeof (*fsrecp), KM_SLEEP);
524 528 bzero(fsrecp, sizeof (*fsrecp));
525 529
526 530 rw_init(&fsrecp->fshfsr_en_lock, NULL, RW_DRIVER, NULL);
527 - fsrecp->fshfsr_enabled = 1;
531 + fsrecp->fshfsr_enabled = 0; // DEBUG
528 532
529 533 for (i = 0; i < FSH_SUPPORTED_OPS_COUNT; i++)
530 534 rw_init(&fsrecp->fshfsr_opv[i].fshl_lock, NULL, RW_DRIVER,
531 535 NULL);
532 - return fsrecp;
536 + return (fsrecp);
533 537 }
534 538
535 539 /* To be used ONLY in vfs_free() */
536 540 void
537 541 fsh_fsrec_destroy(fsh_fsrecord_t *fsrecp)
538 542 {
539 543 int i;
540 544 fsh_node_t *node, *next_node;
541 545
542 546 for (i = 0; i < FSH_SUPPORTED_OPS_COUNT; i++) {
543 547 node = fsrecp->fshfsr_opv[i].fshl_head;
544 548 while (node) {
545 549 next_node = node->fshn_next;
546 550 kmem_free(node, sizeof (*node));
547 551 node = next_node;
548 552 }
549 553 rw_destroy(&fsrecp->fshfsr_opv[i].fshl_lock);
550 554 }
551 555 rw_destroy(&fsrecp->fshfsr_en_lock);
552 556 kmem_free(fsrecp, sizeof (*fsrecp));
553 557 }
554 558
555 559
556 560 /* control passing */
557 561 int
558 562 fsh_next_open(fsh_node_t *fsh_node, vnode_t **vpp, int mode, cred_t *cr,
559 563 caller_context_t *ct)
560 564 {
561 565 if (fsh_node == NULL)
562 566 return ((*(*vpp)->v_op->vop_open)(vpp, mode, cr, ct));
563 567
564 568 return ((*(fsh_node->fshn_hooki.fshi_fn.hook_open))(
565 569 fsh_node->fshn_next, fsh_node->fshn_hooki.fshi_arg,
566 570 vpp, mode, cr, ct));
567 571
568 572 }
569 573
570 574 int
571 575 fsh_next_close(fsh_node_t *fsh_node, vnode_t *vp, int flag, int count,
572 576 offset_t offset, cred_t *cr, caller_context_t *ct)
573 577 {
574 578 if (fsh_node == NULL)
575 579 return ((*(vp->v_op->vop_close))(vp, flag, count, offset,
576 580 cr, ct));
577 581
578 582 return ((*(fsh_node->fshn_hooki.fshi_fn.hook_close))(
579 583 fsh_node->fshn_next, fsh_node->fshn_hooki.fshi_arg,
580 584 vp, flag, count, offset, cr, ct));
581 585 }
582 586
583 587 int
584 588 fsh_next_read(fsh_node_t *fsh_node, vnode_t *vp, uio_t *uiop, int ioflag,
585 589 cred_t *cr, caller_context_t *ct)
586 590 {
587 591 if (fsh_node == NULL)
588 592 return ((*(vp->v_op->vop_read))(vp, uiop, ioflag, cr, ct));
589 593
590 594 return ((*(fsh_node->fshn_hooki.fshi_fn.hook_read))(
591 595 fsh_node->fshn_next, fsh_node->fshn_hooki.fshi_arg,
592 596 vp, uiop, ioflag, cr, ct));
593 597 }
594 598
595 599 int
596 600 fsh_next_write(fsh_node_t *fsh_node, vnode_t *vp, uio_t *uiop, int ioflag,
597 601 cred_t *cr, caller_context_t *ct)
598 602 {
599 603 if (fsh_node == NULL)
600 604 return ((*(vp->v_op->vop_write))(vp, uiop, ioflag, cr, ct));
601 605
602 606 return ((*(fsh_node->fshn_hooki.fshi_fn.hook_write))(
603 607 fsh_node->fshn_next, fsh_node->fshn_hooki.fshi_arg,
604 608 vp, uiop, ioflag, cr, ct));
605 609 }
606 610
607 611 int
608 612 fsh_next_mount(fsh_node_t *fsh_node, vfs_t *vfsp, vnode_t *mvp,
609 613 struct mounta *uap, cred_t *cr)
610 614 {
611 615 if (fsh_node == NULL)
612 616 return ((*(vfsp->vfs_op->vfs_mount))(vfsp, mvp, uap, cr));
613 617
614 618 return ((*(fsh_node->fshn_hooki.fshi_fn.hook_mount))(
615 619 fsh_node->fshn_next, fsh_node->fshn_hooki.fshi_arg,
616 620 vfsp, mvp, uap, cr));
617 621 }
618 622
619 623 int
620 624 fsh_next_unmount(fsh_node_t *fsh_node, vfs_t *vfsp, int flag, cred_t *cr)
621 625 {
622 626 if (fsh_node == NULL)
623 627 return ((*(vfsp->vfs_op->vfs_unmount))(vfsp, flag, cr));
624 628
625 629 return ((*(fsh_node->fshn_hooki.fshi_fn.hook_unmount))(
626 630 fsh_node->fshn_next, fsh_node->fshn_hooki.fshi_arg,
627 631 vfsp, flag, cr));
628 632 }
629 633
630 634 int
631 635 fsh_next_root(fsh_node_t *fsh_node, vfs_t *vfsp, vnode_t **vpp)
632 636 {
633 637 if (fsh_node == NULL)
634 638 return ((*(vfsp->vfs_op->vfs_root))(vfsp, vpp));
635 639
636 640 return ((*(fsh_node->fshn_hooki.fshi_fn.hook_root))(
637 641 fsh_node->fshn_next, fsh_node->fshn_hooki.fshi_arg,
638 642 vfsp, vpp));
639 643 }
640 644
641 645 int
642 646 fsh_next_statfs(fsh_node_t *fsh_node, vfs_t *vfsp, statvfs64_t *sp)
643 647 {
644 648 if (fsh_node == NULL)
645 649 return ((*(vfsp->vfs_op->vfs_statvfs))(vfsp, sp));
646 650
647 651 return ((*(fsh_node->fshn_hooki.fshi_fn.hook_statfs))(
648 652 fsh_node->fshn_next, fsh_node->fshn_hooki.fshi_arg,
649 653 vfsp, sp));
650 654 }
651 655
652 656 int
653 657 fsh_next_vget(fsh_node_t *fsh_node, vfs_t *vfsp, vnode_t **vpp, fid_t *fidp)
654 658 {
655 659 if (fsh_node == NULL)
656 660 return ((*(vfsp->vfs_op->vfs_vget))(vfsp, vpp, fidp));
657 661
658 662 return ((*(fsh_node->fshn_hooki.fshi_fn.hook_vget))(
659 663 fsh_node->fshn_next, fsh_node->fshn_hooki.fshi_arg,
660 664 vfsp, vpp, fidp));
661 665 }
↓ open down ↓ |
119 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX