Print this page
4374 dn_free_ranges should use range_tree_t
Reviewed by: George Wilson <george.wilson@delphix.com>
Reviewed by: Max Grossman <max.grossman@delphix.com>
Reviewed by: Christopher Siden <christopher.siden@delphix.com
Reviewed by: Garrett D'Amore <garrett@damore.org>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Approved by: Dan McDonald <danmcd@omniti.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/lib/libzpool/common/kernel.c
+++ new/usr/src/lib/libzpool/common/kernel.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 - * Copyright (c) 2012 by Delphix. All rights reserved.
23 + * Copyright (c) 2012, 2014 by Delphix. All rights reserved.
24 24 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
25 25 */
26 26
27 27 #include <assert.h>
28 28 #include <fcntl.h>
29 29 #include <poll.h>
30 30 #include <stdio.h>
31 31 #include <stdlib.h>
32 32 #include <string.h>
33 33 #include <zlib.h>
34 34 #include <sys/spa.h>
35 35 #include <sys/stat.h>
36 36 #include <sys/processor.h>
37 37 #include <sys/zfs_context.h>
38 38 #include <sys/rrwlock.h>
39 39 #include <sys/zmod.h>
40 40 #include <sys/utsname.h>
41 41 #include <sys/systeminfo.h>
42 42
43 43 /*
44 44 * Emulation of kernel services in userland.
45 45 */
46 46
47 47 int aok;
48 48 uint64_t physmem;
49 49 vnode_t *rootdir = (vnode_t *)0xabcd1234;
50 50 char hw_serial[HW_HOSTID_LEN];
51 51 kmutex_t cpu_lock;
52 52 vmem_t *zio_arena = NULL;
53 53
54 54 struct utsname utsname = {
55 55 "userland", "libzpool", "1", "1", "na"
56 56 };
57 57
58 58 /* this only exists to have its address taken */
59 59 struct proc p0;
60 60
61 61 /*
62 62 * =========================================================================
63 63 * threads
64 64 * =========================================================================
65 65 */
66 66 /*ARGSUSED*/
67 67 kthread_t *
68 68 zk_thread_create(void (*func)(), void *arg)
69 69 {
70 70 thread_t tid;
71 71
72 72 VERIFY(thr_create(0, 0, (void *(*)(void *))func, arg, THR_DETACHED,
73 73 &tid) == 0);
74 74
75 75 return ((void *)(uintptr_t)tid);
76 76 }
77 77
78 78 /*
79 79 * =========================================================================
80 80 * kstats
81 81 * =========================================================================
82 82 */
83 83 /*ARGSUSED*/
84 84 kstat_t *
85 85 kstat_create(const char *module, int instance, const char *name,
86 86 const char *class, uchar_t type, ulong_t ndata, uchar_t ks_flag)
87 87 {
88 88 return (NULL);
89 89 }
90 90
91 91 /*ARGSUSED*/
92 92 void
93 93 kstat_install(kstat_t *ksp)
94 94 {}
95 95
96 96 /*ARGSUSED*/
97 97 void
98 98 kstat_delete(kstat_t *ksp)
99 99 {}
100 100
101 101 /*ARGSUSED*/
102 102 void
103 103 kstat_waitq_enter(kstat_io_t *kiop)
104 104 {}
105 105
106 106 /*ARGSUSED*/
107 107 void
108 108 kstat_waitq_exit(kstat_io_t *kiop)
109 109 {}
110 110
111 111 /*ARGSUSED*/
112 112 void
113 113 kstat_runq_enter(kstat_io_t *kiop)
114 114 {}
115 115
116 116 /*ARGSUSED*/
117 117 void
118 118 kstat_runq_exit(kstat_io_t *kiop)
119 119 {}
120 120
121 121 /*ARGSUSED*/
122 122 void
123 123 kstat_waitq_to_runq(kstat_io_t *kiop)
124 124 {}
125 125
126 126 /*ARGSUSED*/
127 127 void
128 128 kstat_runq_back_to_waitq(kstat_io_t *kiop)
129 129 {}
130 130
131 131 /*
132 132 * =========================================================================
133 133 * mutexes
134 134 * =========================================================================
135 135 */
136 136 void
137 137 zmutex_init(kmutex_t *mp)
138 138 {
139 139 mp->m_owner = NULL;
140 140 mp->initialized = B_TRUE;
141 141 (void) _mutex_init(&mp->m_lock, USYNC_THREAD, NULL);
142 142 }
143 143
144 144 void
145 145 zmutex_destroy(kmutex_t *mp)
146 146 {
147 147 ASSERT(mp->initialized == B_TRUE);
148 148 ASSERT(mp->m_owner == NULL);
149 149 (void) _mutex_destroy(&(mp)->m_lock);
150 150 mp->m_owner = (void *)-1UL;
151 151 mp->initialized = B_FALSE;
152 152 }
153 153
154 154 void
155 155 mutex_enter(kmutex_t *mp)
156 156 {
157 157 ASSERT(mp->initialized == B_TRUE);
158 158 ASSERT(mp->m_owner != (void *)-1UL);
159 159 ASSERT(mp->m_owner != curthread);
160 160 VERIFY(mutex_lock(&mp->m_lock) == 0);
161 161 ASSERT(mp->m_owner == NULL);
162 162 mp->m_owner = curthread;
163 163 }
164 164
165 165 int
166 166 mutex_tryenter(kmutex_t *mp)
167 167 {
168 168 ASSERT(mp->initialized == B_TRUE);
169 169 ASSERT(mp->m_owner != (void *)-1UL);
170 170 if (0 == mutex_trylock(&mp->m_lock)) {
171 171 ASSERT(mp->m_owner == NULL);
172 172 mp->m_owner = curthread;
173 173 return (1);
174 174 } else {
175 175 return (0);
176 176 }
177 177 }
178 178
179 179 void
180 180 mutex_exit(kmutex_t *mp)
181 181 {
182 182 ASSERT(mp->initialized == B_TRUE);
183 183 ASSERT(mutex_owner(mp) == curthread);
184 184 mp->m_owner = NULL;
185 185 VERIFY(mutex_unlock(&mp->m_lock) == 0);
186 186 }
187 187
188 188 void *
189 189 mutex_owner(kmutex_t *mp)
190 190 {
191 191 ASSERT(mp->initialized == B_TRUE);
192 192 return (mp->m_owner);
193 193 }
194 194
195 195 /*
196 196 * =========================================================================
197 197 * rwlocks
198 198 * =========================================================================
199 199 */
200 200 /*ARGSUSED*/
201 201 void
202 202 rw_init(krwlock_t *rwlp, char *name, int type, void *arg)
203 203 {
204 204 rwlock_init(&rwlp->rw_lock, USYNC_THREAD, NULL);
205 205 rwlp->rw_owner = NULL;
206 206 rwlp->initialized = B_TRUE;
207 207 }
208 208
209 209 void
210 210 rw_destroy(krwlock_t *rwlp)
211 211 {
212 212 rwlock_destroy(&rwlp->rw_lock);
213 213 rwlp->rw_owner = (void *)-1UL;
214 214 rwlp->initialized = B_FALSE;
215 215 }
216 216
217 217 void
218 218 rw_enter(krwlock_t *rwlp, krw_t rw)
219 219 {
220 220 ASSERT(!RW_LOCK_HELD(rwlp));
221 221 ASSERT(rwlp->initialized == B_TRUE);
222 222 ASSERT(rwlp->rw_owner != (void *)-1UL);
223 223 ASSERT(rwlp->rw_owner != curthread);
224 224
225 225 if (rw == RW_WRITER)
226 226 VERIFY(rw_wrlock(&rwlp->rw_lock) == 0);
227 227 else
228 228 VERIFY(rw_rdlock(&rwlp->rw_lock) == 0);
229 229
230 230 rwlp->rw_owner = curthread;
231 231 }
232 232
233 233 void
234 234 rw_exit(krwlock_t *rwlp)
235 235 {
236 236 ASSERT(rwlp->initialized == B_TRUE);
237 237 ASSERT(rwlp->rw_owner != (void *)-1UL);
238 238
239 239 rwlp->rw_owner = NULL;
240 240 VERIFY(rw_unlock(&rwlp->rw_lock) == 0);
241 241 }
242 242
243 243 int
244 244 rw_tryenter(krwlock_t *rwlp, krw_t rw)
245 245 {
246 246 int rv;
247 247
248 248 ASSERT(rwlp->initialized == B_TRUE);
249 249 ASSERT(rwlp->rw_owner != (void *)-1UL);
250 250
251 251 if (rw == RW_WRITER)
252 252 rv = rw_trywrlock(&rwlp->rw_lock);
253 253 else
254 254 rv = rw_tryrdlock(&rwlp->rw_lock);
255 255
256 256 if (rv == 0) {
257 257 rwlp->rw_owner = curthread;
258 258 return (1);
259 259 }
260 260
261 261 return (0);
262 262 }
263 263
264 264 /*ARGSUSED*/
265 265 int
266 266 rw_tryupgrade(krwlock_t *rwlp)
267 267 {
268 268 ASSERT(rwlp->initialized == B_TRUE);
269 269 ASSERT(rwlp->rw_owner != (void *)-1UL);
270 270
271 271 return (0);
272 272 }
273 273
274 274 /*
275 275 * =========================================================================
276 276 * condition variables
277 277 * =========================================================================
278 278 */
279 279 /*ARGSUSED*/
280 280 void
281 281 cv_init(kcondvar_t *cv, char *name, int type, void *arg)
282 282 {
283 283 VERIFY(cond_init(cv, type, NULL) == 0);
284 284 }
285 285
286 286 void
287 287 cv_destroy(kcondvar_t *cv)
288 288 {
289 289 VERIFY(cond_destroy(cv) == 0);
290 290 }
291 291
292 292 void
293 293 cv_wait(kcondvar_t *cv, kmutex_t *mp)
294 294 {
295 295 ASSERT(mutex_owner(mp) == curthread);
296 296 mp->m_owner = NULL;
297 297 int ret = cond_wait(cv, &mp->m_lock);
298 298 VERIFY(ret == 0 || ret == EINTR);
299 299 mp->m_owner = curthread;
300 300 }
301 301
302 302 clock_t
303 303 cv_timedwait(kcondvar_t *cv, kmutex_t *mp, clock_t abstime)
304 304 {
305 305 int error;
306 306 timestruc_t ts;
307 307 clock_t delta;
308 308
309 309 top:
310 310 delta = abstime - ddi_get_lbolt();
311 311 if (delta <= 0)
312 312 return (-1);
313 313
314 314 ts.tv_sec = delta / hz;
315 315 ts.tv_nsec = (delta % hz) * (NANOSEC / hz);
316 316
317 317 ASSERT(mutex_owner(mp) == curthread);
318 318 mp->m_owner = NULL;
319 319 error = cond_reltimedwait(cv, &mp->m_lock, &ts);
320 320 mp->m_owner = curthread;
321 321
322 322 if (error == ETIME)
323 323 return (-1);
324 324
325 325 if (error == EINTR)
326 326 goto top;
327 327
328 328 ASSERT(error == 0);
329 329
330 330 return (1);
331 331 }
332 332
333 333 /*ARGSUSED*/
334 334 clock_t
335 335 cv_timedwait_hires(kcondvar_t *cv, kmutex_t *mp, hrtime_t tim, hrtime_t res,
336 336 int flag)
337 337 {
338 338 int error;
339 339 timestruc_t ts;
340 340 hrtime_t delta;
341 341
342 342 ASSERT(flag == 0);
343 343
344 344 top:
345 345 delta = tim - gethrtime();
346 346 if (delta <= 0)
347 347 return (-1);
348 348
349 349 ts.tv_sec = delta / NANOSEC;
350 350 ts.tv_nsec = delta % NANOSEC;
351 351
352 352 ASSERT(mutex_owner(mp) == curthread);
353 353 mp->m_owner = NULL;
354 354 error = cond_reltimedwait(cv, &mp->m_lock, &ts);
355 355 mp->m_owner = curthread;
356 356
357 357 if (error == ETIME)
358 358 return (-1);
359 359
360 360 if (error == EINTR)
361 361 goto top;
362 362
363 363 ASSERT(error == 0);
364 364
365 365 return (1);
366 366 }
367 367
368 368 void
369 369 cv_signal(kcondvar_t *cv)
370 370 {
371 371 VERIFY(cond_signal(cv) == 0);
372 372 }
373 373
374 374 void
375 375 cv_broadcast(kcondvar_t *cv)
376 376 {
377 377 VERIFY(cond_broadcast(cv) == 0);
378 378 }
379 379
380 380 /*
381 381 * =========================================================================
382 382 * vnode operations
383 383 * =========================================================================
384 384 */
385 385 /*
386 386 * Note: for the xxxat() versions of these functions, we assume that the
387 387 * starting vp is always rootdir (which is true for spa_directory.c, the only
388 388 * ZFS consumer of these interfaces). We assert this is true, and then emulate
389 389 * them by adding '/' in front of the path.
390 390 */
391 391
392 392 /*ARGSUSED*/
393 393 int
394 394 vn_open(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2, int x3)
395 395 {
396 396 int fd;
397 397 vnode_t *vp;
398 398 int old_umask;
399 399 char realpath[MAXPATHLEN];
400 400 struct stat64 st;
401 401
402 402 /*
403 403 * If we're accessing a real disk from userland, we need to use
404 404 * the character interface to avoid caching. This is particularly
405 405 * important if we're trying to look at a real in-kernel storage
406 406 * pool from userland, e.g. via zdb, because otherwise we won't
407 407 * see the changes occurring under the segmap cache.
408 408 * On the other hand, the stupid character device returns zero
409 409 * for its size. So -- gag -- we open the block device to get
410 410 * its size, and remember it for subsequent VOP_GETATTR().
411 411 */
412 412 if (strncmp(path, "/dev/", 5) == 0) {
413 413 char *dsk;
414 414 fd = open64(path, O_RDONLY);
415 415 if (fd == -1)
416 416 return (errno);
417 417 if (fstat64(fd, &st) == -1) {
418 418 close(fd);
419 419 return (errno);
420 420 }
421 421 close(fd);
422 422 (void) sprintf(realpath, "%s", path);
423 423 dsk = strstr(path, "/dsk/");
424 424 if (dsk != NULL)
425 425 (void) sprintf(realpath + (dsk - path) + 1, "r%s",
426 426 dsk + 1);
427 427 } else {
428 428 (void) sprintf(realpath, "%s", path);
429 429 if (!(flags & FCREAT) && stat64(realpath, &st) == -1)
430 430 return (errno);
431 431 }
432 432
433 433 if (flags & FCREAT)
434 434 old_umask = umask(0);
435 435
436 436 /*
437 437 * The construct 'flags - FREAD' conveniently maps combinations of
438 438 * FREAD and FWRITE to the corresponding O_RDONLY, O_WRONLY, and O_RDWR.
439 439 */
440 440 fd = open64(realpath, flags - FREAD, mode);
441 441
442 442 if (flags & FCREAT)
443 443 (void) umask(old_umask);
444 444
445 445 if (fd == -1)
446 446 return (errno);
447 447
448 448 if (fstat64(fd, &st) == -1) {
449 449 close(fd);
450 450 return (errno);
451 451 }
452 452
453 453 (void) fcntl(fd, F_SETFD, FD_CLOEXEC);
454 454
455 455 *vpp = vp = umem_zalloc(sizeof (vnode_t), UMEM_NOFAIL);
456 456
457 457 vp->v_fd = fd;
458 458 vp->v_size = st.st_size;
459 459 vp->v_path = spa_strdup(path);
460 460
461 461 return (0);
462 462 }
463 463
464 464 /*ARGSUSED*/
465 465 int
466 466 vn_openat(char *path, int x1, int flags, int mode, vnode_t **vpp, int x2,
467 467 int x3, vnode_t *startvp, int fd)
468 468 {
469 469 char *realpath = umem_alloc(strlen(path) + 2, UMEM_NOFAIL);
470 470 int ret;
471 471
472 472 ASSERT(startvp == rootdir);
473 473 (void) sprintf(realpath, "/%s", path);
474 474
475 475 /* fd ignored for now, need if want to simulate nbmand support */
476 476 ret = vn_open(realpath, x1, flags, mode, vpp, x2, x3);
477 477
478 478 umem_free(realpath, strlen(path) + 2);
479 479
480 480 return (ret);
481 481 }
482 482
483 483 /*ARGSUSED*/
484 484 int
485 485 vn_rdwr(int uio, vnode_t *vp, void *addr, ssize_t len, offset_t offset,
486 486 int x1, int x2, rlim64_t x3, void *x4, ssize_t *residp)
487 487 {
488 488 ssize_t iolen, split;
489 489
490 490 if (uio == UIO_READ) {
491 491 iolen = pread64(vp->v_fd, addr, len, offset);
492 492 } else {
493 493 /*
494 494 * To simulate partial disk writes, we split writes into two
495 495 * system calls so that the process can be killed in between.
496 496 */
497 497 int sectors = len >> SPA_MINBLOCKSHIFT;
498 498 split = (sectors > 0 ? rand() % sectors : 0) <<
499 499 SPA_MINBLOCKSHIFT;
500 500 iolen = pwrite64(vp->v_fd, addr, split, offset);
501 501 iolen += pwrite64(vp->v_fd, (char *)addr + split,
502 502 len - split, offset + split);
503 503 }
504 504
505 505 if (iolen == -1)
506 506 return (errno);
507 507 if (residp)
508 508 *residp = len - iolen;
509 509 else if (iolen != len)
510 510 return (EIO);
511 511 return (0);
512 512 }
513 513
514 514 void
515 515 vn_close(vnode_t *vp)
516 516 {
517 517 close(vp->v_fd);
518 518 spa_strfree(vp->v_path);
519 519 umem_free(vp, sizeof (vnode_t));
520 520 }
521 521
522 522 /*
523 523 * At a minimum we need to update the size since vdev_reopen()
524 524 * will no longer call vn_openat().
525 525 */
526 526 int
527 527 fop_getattr(vnode_t *vp, vattr_t *vap)
528 528 {
529 529 struct stat64 st;
530 530
531 531 if (fstat64(vp->v_fd, &st) == -1) {
532 532 close(vp->v_fd);
533 533 return (errno);
534 534 }
535 535
536 536 vap->va_size = st.st_size;
537 537 return (0);
538 538 }
539 539
540 540 #ifdef ZFS_DEBUG
541 541
542 542 /*
543 543 * =========================================================================
544 544 * Figure out which debugging statements to print
545 545 * =========================================================================
546 546 */
547 547
548 548 static char *dprintf_string;
549 549 static int dprintf_print_all;
550 550
551 551 int
552 552 dprintf_find_string(const char *string)
553 553 {
554 554 char *tmp_str = dprintf_string;
555 555 int len = strlen(string);
556 556
557 557 /*
558 558 * Find out if this is a string we want to print.
559 559 * String format: file1.c,function_name1,file2.c,file3.c
560 560 */
561 561
562 562 while (tmp_str != NULL) {
563 563 if (strncmp(tmp_str, string, len) == 0 &&
564 564 (tmp_str[len] == ',' || tmp_str[len] == '\0'))
565 565 return (1);
566 566 tmp_str = strchr(tmp_str, ',');
567 567 if (tmp_str != NULL)
568 568 tmp_str++; /* Get rid of , */
569 569 }
570 570 return (0);
571 571 }
572 572
573 573 void
574 574 dprintf_setup(int *argc, char **argv)
575 575 {
576 576 int i, j;
577 577
578 578 /*
579 579 * Debugging can be specified two ways: by setting the
580 580 * environment variable ZFS_DEBUG, or by including a
581 581 * "debug=..." argument on the command line. The command
582 582 * line setting overrides the environment variable.
583 583 */
584 584
585 585 for (i = 1; i < *argc; i++) {
586 586 int len = strlen("debug=");
587 587 /* First look for a command line argument */
588 588 if (strncmp("debug=", argv[i], len) == 0) {
589 589 dprintf_string = argv[i] + len;
590 590 /* Remove from args */
591 591 for (j = i; j < *argc; j++)
592 592 argv[j] = argv[j+1];
593 593 argv[j] = NULL;
594 594 (*argc)--;
595 595 }
596 596 }
597 597
598 598 if (dprintf_string == NULL) {
599 599 /* Look for ZFS_DEBUG environment variable */
600 600 dprintf_string = getenv("ZFS_DEBUG");
601 601 }
602 602
603 603 /*
604 604 * Are we just turning on all debugging?
605 605 */
606 606 if (dprintf_find_string("on"))
607 607 dprintf_print_all = 1;
608 608 }
609 609
610 610 /*
611 611 * =========================================================================
612 612 * debug printfs
613 613 * =========================================================================
614 614 */
615 615 void
616 616 __dprintf(const char *file, const char *func, int line, const char *fmt, ...)
617 617 {
618 618 const char *newfile;
619 619 va_list adx;
620 620
621 621 /*
622 622 * Get rid of annoying "../common/" prefix to filename.
623 623 */
624 624 newfile = strrchr(file, '/');
625 625 if (newfile != NULL) {
626 626 newfile = newfile + 1; /* Get rid of leading / */
627 627 } else {
628 628 newfile = file;
629 629 }
630 630
631 631 if (dprintf_print_all ||
632 632 dprintf_find_string(newfile) ||
633 633 dprintf_find_string(func)) {
634 634 /* Print out just the function name if requested */
635 635 flockfile(stdout);
636 636 if (dprintf_find_string("pid"))
637 637 (void) printf("%d ", getpid());
638 638 if (dprintf_find_string("tid"))
639 639 (void) printf("%u ", thr_self());
640 640 if (dprintf_find_string("cpu"))
641 641 (void) printf("%u ", getcpuid());
642 642 if (dprintf_find_string("time"))
643 643 (void) printf("%llu ", gethrtime());
644 644 if (dprintf_find_string("long"))
645 645 (void) printf("%s, line %d: ", newfile, line);
646 646 (void) printf("%s: ", func);
647 647 va_start(adx, fmt);
648 648 (void) vprintf(fmt, adx);
649 649 va_end(adx);
650 650 funlockfile(stdout);
651 651 }
652 652 }
653 653
654 654 #endif /* ZFS_DEBUG */
655 655
656 656 /*
657 657 * =========================================================================
658 658 * cmn_err() and panic()
659 659 * =========================================================================
660 660 */
661 661 static char ce_prefix[CE_IGNORE][10] = { "", "NOTICE: ", "WARNING: ", "" };
662 662 static char ce_suffix[CE_IGNORE][2] = { "", "\n", "\n", "" };
663 663
664 664 void
665 665 vpanic(const char *fmt, va_list adx)
666 666 {
667 667 (void) fprintf(stderr, "error: ");
668 668 (void) vfprintf(stderr, fmt, adx);
669 669 (void) fprintf(stderr, "\n");
670 670
671 671 abort(); /* think of it as a "user-level crash dump" */
672 672 }
673 673
674 674 void
675 675 panic(const char *fmt, ...)
676 676 {
677 677 va_list adx;
678 678
679 679 va_start(adx, fmt);
680 680 vpanic(fmt, adx);
681 681 va_end(adx);
682 682 }
683 683
684 684 void
685 685 vcmn_err(int ce, const char *fmt, va_list adx)
686 686 {
687 687 if (ce == CE_PANIC)
688 688 vpanic(fmt, adx);
689 689 if (ce != CE_NOTE) { /* suppress noise in userland stress testing */
690 690 (void) fprintf(stderr, "%s", ce_prefix[ce]);
691 691 (void) vfprintf(stderr, fmt, adx);
692 692 (void) fprintf(stderr, "%s", ce_suffix[ce]);
693 693 }
694 694 }
695 695
696 696 /*PRINTFLIKE2*/
697 697 void
698 698 cmn_err(int ce, const char *fmt, ...)
699 699 {
700 700 va_list adx;
701 701
702 702 va_start(adx, fmt);
703 703 vcmn_err(ce, fmt, adx);
704 704 va_end(adx);
705 705 }
706 706
707 707 /*
708 708 * =========================================================================
709 709 * kobj interfaces
710 710 * =========================================================================
711 711 */
712 712 struct _buf *
713 713 kobj_open_file(char *name)
714 714 {
715 715 struct _buf *file;
716 716 vnode_t *vp;
717 717
718 718 /* set vp as the _fd field of the file */
719 719 if (vn_openat(name, UIO_SYSSPACE, FREAD, 0, &vp, 0, 0, rootdir,
720 720 -1) != 0)
721 721 return ((void *)-1UL);
722 722
723 723 file = umem_zalloc(sizeof (struct _buf), UMEM_NOFAIL);
724 724 file->_fd = (intptr_t)vp;
725 725 return (file);
726 726 }
727 727
728 728 int
729 729 kobj_read_file(struct _buf *file, char *buf, unsigned size, unsigned off)
730 730 {
731 731 ssize_t resid;
732 732
733 733 vn_rdwr(UIO_READ, (vnode_t *)file->_fd, buf, size, (offset_t)off,
734 734 UIO_SYSSPACE, 0, 0, 0, &resid);
735 735
736 736 return (size - resid);
737 737 }
738 738
739 739 void
740 740 kobj_close_file(struct _buf *file)
741 741 {
742 742 vn_close((vnode_t *)file->_fd);
743 743 umem_free(file, sizeof (struct _buf));
744 744 }
745 745
746 746 int
747 747 kobj_get_filesize(struct _buf *file, uint64_t *size)
748 748 {
749 749 struct stat64 st;
750 750 vnode_t *vp = (vnode_t *)file->_fd;
751 751
752 752 if (fstat64(vp->v_fd, &st) == -1) {
753 753 vn_close(vp);
754 754 return (errno);
755 755 }
756 756 *size = st.st_size;
757 757 return (0);
758 758 }
759 759
760 760 /*
761 761 * =========================================================================
762 762 * misc routines
763 763 * =========================================================================
764 764 */
|
↓ open down ↓ |
731 lines elided |
↑ open up ↑ |
765 765
766 766 void
767 767 delay(clock_t ticks)
768 768 {
769 769 poll(0, 0, ticks * (1000 / hz));
770 770 }
771 771
772 772 /*
773 773 * Find highest one bit set.
774 774 * Returns bit number + 1 of highest bit that is set, otherwise returns 0.
775 - * High order bit is 31 (or 63 in _LP64 kernel).
776 775 */
777 776 int
778 -highbit(ulong_t i)
777 +highbit64(uint64_t i)
779 778 {
780 - register int h = 1;
779 + int h = 1;
781 780
782 781 if (i == 0)
783 782 return (0);
784 -#ifdef _LP64
785 - if (i & 0xffffffff00000000ul) {
783 + if (i & 0xffffffff00000000ULL) {
786 784 h += 32; i >>= 32;
787 785 }
788 -#endif
789 786 if (i & 0xffff0000) {
790 787 h += 16; i >>= 16;
791 788 }
792 789 if (i & 0xff00) {
793 790 h += 8; i >>= 8;
794 791 }
795 792 if (i & 0xf0) {
796 793 h += 4; i >>= 4;
797 794 }
798 795 if (i & 0xc) {
799 796 h += 2; i >>= 2;
800 797 }
801 798 if (i & 0x2) {
802 799 h += 1;
803 800 }
804 801 return (h);
805 802 }
806 803
807 804 static int random_fd = -1, urandom_fd = -1;
808 805
809 806 static int
810 807 random_get_bytes_common(uint8_t *ptr, size_t len, int fd)
811 808 {
812 809 size_t resid = len;
813 810 ssize_t bytes;
814 811
815 812 ASSERT(fd != -1);
816 813
817 814 while (resid != 0) {
818 815 bytes = read(fd, ptr, resid);
819 816 ASSERT3S(bytes, >=, 0);
820 817 ptr += bytes;
821 818 resid -= bytes;
822 819 }
823 820
824 821 return (0);
825 822 }
826 823
827 824 int
828 825 random_get_bytes(uint8_t *ptr, size_t len)
829 826 {
830 827 return (random_get_bytes_common(ptr, len, random_fd));
831 828 }
832 829
833 830 int
834 831 random_get_pseudo_bytes(uint8_t *ptr, size_t len)
835 832 {
836 833 return (random_get_bytes_common(ptr, len, urandom_fd));
837 834 }
838 835
839 836 int
840 837 ddi_strtoul(const char *hw_serial, char **nptr, int base, unsigned long *result)
841 838 {
842 839 char *end;
843 840
844 841 *result = strtoul(hw_serial, &end, base);
845 842 if (*result == 0)
846 843 return (errno);
847 844 return (0);
848 845 }
849 846
850 847 int
851 848 ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result)
852 849 {
853 850 char *end;
854 851
855 852 *result = strtoull(str, &end, base);
856 853 if (*result == 0)
857 854 return (errno);
858 855 return (0);
859 856 }
860 857
861 858 /* ARGSUSED */
862 859 cyclic_id_t
863 860 cyclic_add(cyc_handler_t *hdlr, cyc_time_t *when)
864 861 {
865 862 return (1);
866 863 }
867 864
868 865 /* ARGSUSED */
869 866 void
870 867 cyclic_remove(cyclic_id_t id)
871 868 {
872 869 }
873 870
874 871 /* ARGSUSED */
875 872 int
876 873 cyclic_reprogram(cyclic_id_t id, hrtime_t expiration)
877 874 {
878 875 return (1);
879 876 }
880 877
881 878 /*
882 879 * =========================================================================
883 880 * kernel emulation setup & teardown
884 881 * =========================================================================
885 882 */
886 883 static int
887 884 umem_out_of_memory(void)
888 885 {
889 886 char errmsg[] = "out of memory -- generating core dump\n";
890 887
891 888 write(fileno(stderr), errmsg, sizeof (errmsg));
892 889 abort();
893 890 return (0);
894 891 }
895 892
896 893 void
897 894 kernel_init(int mode)
898 895 {
899 896 extern uint_t rrw_tsd_key;
900 897
901 898 umem_nofail_callback(umem_out_of_memory);
902 899
903 900 physmem = sysconf(_SC_PHYS_PAGES);
904 901
905 902 dprintf("physmem = %llu pages (%.2f GB)\n", physmem,
906 903 (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30));
907 904
908 905 (void) snprintf(hw_serial, sizeof (hw_serial), "%ld",
909 906 (mode & FWRITE) ? gethostid() : 0);
910 907
911 908 VERIFY((random_fd = open("/dev/random", O_RDONLY)) != -1);
912 909 VERIFY((urandom_fd = open("/dev/urandom", O_RDONLY)) != -1);
913 910
914 911 system_taskq_init();
915 912
916 913 mutex_init(&cpu_lock, NULL, MUTEX_DEFAULT, NULL);
917 914
918 915 spa_init(mode);
919 916
920 917 tsd_create(&rrw_tsd_key, rrw_tsd_destroy);
921 918 }
922 919
923 920 void
924 921 kernel_fini(void)
925 922 {
926 923 spa_fini();
927 924
928 925 system_taskq_fini();
929 926
930 927 close(random_fd);
931 928 close(urandom_fd);
932 929
933 930 random_fd = -1;
934 931 urandom_fd = -1;
935 932 }
936 933
937 934 int
938 935 z_uncompress(void *dst, size_t *dstlen, const void *src, size_t srclen)
939 936 {
940 937 int ret;
941 938 uLongf len = *dstlen;
942 939
943 940 if ((ret = uncompress(dst, &len, src, srclen)) == Z_OK)
944 941 *dstlen = (size_t)len;
945 942
946 943 return (ret);
947 944 }
948 945
949 946 int
950 947 z_compress_level(void *dst, size_t *dstlen, const void *src, size_t srclen,
951 948 int level)
952 949 {
953 950 int ret;
954 951 uLongf len = *dstlen;
955 952
956 953 if ((ret = compress2(dst, &len, src, srclen, level)) == Z_OK)
957 954 *dstlen = (size_t)len;
958 955
959 956 return (ret);
960 957 }
961 958
962 959 uid_t
963 960 crgetuid(cred_t *cr)
964 961 {
965 962 return (0);
966 963 }
967 964
968 965 uid_t
969 966 crgetruid(cred_t *cr)
970 967 {
971 968 return (0);
972 969 }
973 970
974 971 gid_t
975 972 crgetgid(cred_t *cr)
976 973 {
977 974 return (0);
978 975 }
979 976
980 977 int
981 978 crgetngroups(cred_t *cr)
982 979 {
983 980 return (0);
984 981 }
985 982
986 983 gid_t *
987 984 crgetgroups(cred_t *cr)
988 985 {
989 986 return (NULL);
990 987 }
991 988
992 989 int
993 990 zfs_secpolicy_snapshot_perms(const char *name, cred_t *cr)
994 991 {
995 992 return (0);
996 993 }
997 994
998 995 int
999 996 zfs_secpolicy_rename_perms(const char *from, const char *to, cred_t *cr)
1000 997 {
1001 998 return (0);
1002 999 }
1003 1000
1004 1001 int
1005 1002 zfs_secpolicy_destroy_perms(const char *name, cred_t *cr)
1006 1003 {
1007 1004 return (0);
1008 1005 }
1009 1006
1010 1007 ksiddomain_t *
1011 1008 ksid_lookupdomain(const char *dom)
1012 1009 {
1013 1010 ksiddomain_t *kd;
1014 1011
1015 1012 kd = umem_zalloc(sizeof (ksiddomain_t), UMEM_NOFAIL);
1016 1013 kd->kd_name = spa_strdup(dom);
1017 1014 return (kd);
1018 1015 }
1019 1016
1020 1017 void
1021 1018 ksiddomain_rele(ksiddomain_t *ksid)
1022 1019 {
1023 1020 spa_strfree(ksid->kd_name);
1024 1021 umem_free(ksid, sizeof (ksiddomain_t));
1025 1022 }
1026 1023
1027 1024 /*
1028 1025 * Do not change the length of the returned string; it must be freed
1029 1026 * with strfree().
1030 1027 */
1031 1028 char *
1032 1029 kmem_asprintf(const char *fmt, ...)
1033 1030 {
1034 1031 int size;
1035 1032 va_list adx;
1036 1033 char *buf;
1037 1034
1038 1035 va_start(adx, fmt);
1039 1036 size = vsnprintf(NULL, 0, fmt, adx) + 1;
1040 1037 va_end(adx);
1041 1038
1042 1039 buf = kmem_alloc(size, KM_SLEEP);
1043 1040
1044 1041 va_start(adx, fmt);
1045 1042 size = vsnprintf(buf, size, fmt, adx);
1046 1043 va_end(adx);
1047 1044
1048 1045 return (buf);
1049 1046 }
1050 1047
1051 1048 /* ARGSUSED */
1052 1049 int
1053 1050 zfs_onexit_fd_hold(int fd, minor_t *minorp)
1054 1051 {
1055 1052 *minorp = 0;
1056 1053 return (0);
1057 1054 }
1058 1055
1059 1056 /* ARGSUSED */
1060 1057 void
1061 1058 zfs_onexit_fd_rele(int fd)
1062 1059 {
1063 1060 }
1064 1061
1065 1062 /* ARGSUSED */
1066 1063 int
1067 1064 zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data,
1068 1065 uint64_t *action_handle)
1069 1066 {
1070 1067 return (0);
1071 1068 }
1072 1069
1073 1070 /* ARGSUSED */
1074 1071 int
1075 1072 zfs_onexit_del_cb(minor_t minor, uint64_t action_handle, boolean_t fire)
1076 1073 {
1077 1074 return (0);
1078 1075 }
1079 1076
1080 1077 /* ARGSUSED */
1081 1078 int
1082 1079 zfs_onexit_cb_data(minor_t minor, uint64_t action_handle, void **data)
1083 1080 {
1084 1081 return (0);
1085 1082 }
1086 1083
1087 1084 void
1088 1085 bioinit(buf_t *bp)
1089 1086 {
1090 1087 bzero(bp, sizeof (buf_t));
1091 1088 }
1092 1089
1093 1090 void
1094 1091 biodone(buf_t *bp)
1095 1092 {
1096 1093 if (bp->b_iodone != NULL) {
1097 1094 (*(bp->b_iodone))(bp);
1098 1095 return;
1099 1096 }
1100 1097 ASSERT((bp->b_flags & B_DONE) == 0);
1101 1098 bp->b_flags |= B_DONE;
1102 1099 }
1103 1100
1104 1101 void
1105 1102 bioerror(buf_t *bp, int error)
1106 1103 {
1107 1104 ASSERT(bp != NULL);
1108 1105 ASSERT(error >= 0);
1109 1106
1110 1107 if (error != 0) {
1111 1108 bp->b_flags |= B_ERROR;
1112 1109 } else {
1113 1110 bp->b_flags &= ~B_ERROR;
1114 1111 }
1115 1112 bp->b_error = error;
1116 1113 }
1117 1114
1118 1115
1119 1116 int
1120 1117 geterror(struct buf *bp)
1121 1118 {
1122 1119 int error = 0;
1123 1120
1124 1121 if (bp->b_flags & B_ERROR) {
1125 1122 error = bp->b_error;
1126 1123 if (!error)
1127 1124 error = EIO;
1128 1125 }
1129 1126 return (error);
1130 1127 }
|
↓ open down ↓ |
332 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX