1 // SPDX-License-Identifier: CDDL-1.0 2 /* 3 * CDDL HEADER START 4 * 5 * The contents of this file are subject to the terms of the 6 * Common Development and Distribution License (the "License"). 7 * You may not use this file except in compliance with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or https://opensource.org/licenses/CDDL-1.0. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright (c) 2012, 2018 by Delphix. All rights reserved. 25 * Copyright (c) 2016 Actifio, Inc. All rights reserved. 26 * Copyright (c) 2025, Klara, Inc. 27 */ 28 29 #include <assert.h> 30 #include <fcntl.h> 31 #include <libgen.h> 32 #include <poll.h> 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <limits.h> 37 #include <libzutil.h> 38 #include <sys/crypto/icp.h> 39 #include <sys/processor.h> 40 #include <sys/rrwlock.h> 41 #include <sys/spa.h> 42 #include <sys/spa_impl.h> 43 #include <sys/sid.h> 44 #include <sys/stat.h> 45 #include <sys/systeminfo.h> 46 #include <sys/time.h> 47 #include <sys/tsd.h> 48 49 #include <libspl.h> 50 #include <libzpool.h> 51 #include <sys/zfs_context.h> 52 #include <sys/zfs_onexit.h> 53 #include <sys/zfs_vfsops.h> 54 #include <sys/zstd/zstd.h> 55 #include <sys/zvol.h> 56 #include <zfs_fletcher.h> 57 #include <zlib.h> 58 59 /* 60 * Emulation of kernel services in userland. 61 */ 62 63 uint32_t hostid; 64 65 /* If set, all blocks read will be copied to the specified directory. */ 66 char *vn_dumpdir = NULL; 67 68 uint32_t 69 zone_get_hostid(void *zonep) 70 { 71 /* 72 * We're emulating the system's hostid in userland. 73 */ 74 (void) zonep; 75 return (hostid); 76 } 77 78 /* 79 * ========================================================================= 80 * vnode operations 81 * ========================================================================= 82 */ 83 84 /* 85 * ========================================================================= 86 * Figure out which debugging statements to print 87 * ========================================================================= 88 */ 89 90 static char *dprintf_string; 91 static int dprintf_print_all; 92 93 int 94 dprintf_find_string(const char *string) 95 { 96 char *tmp_str = dprintf_string; 97 int len = strlen(string); 98 99 /* 100 * Find out if this is a string we want to print. 101 * String format: file1.c,function_name1,file2.c,file3.c 102 */ 103 104 while (tmp_str != NULL) { 105 if (strncmp(tmp_str, string, len) == 0 && 106 (tmp_str[len] == ',' || tmp_str[len] == '\0')) 107 return (1); 108 tmp_str = strchr(tmp_str, ','); 109 if (tmp_str != NULL) 110 tmp_str++; /* Get rid of , */ 111 } 112 return (0); 113 } 114 115 void 116 dprintf_setup(int *argc, char **argv) 117 { 118 int i, j; 119 120 /* 121 * Debugging can be specified two ways: by setting the 122 * environment variable ZFS_DEBUG, or by including a 123 * "debug=..." argument on the command line. The command 124 * line setting overrides the environment variable. 125 */ 126 127 for (i = 1; i < *argc; i++) { 128 int len = strlen("debug="); 129 /* First look for a command line argument */ 130 if (strncmp("debug=", argv[i], len) == 0) { 131 dprintf_string = argv[i] + len; 132 /* Remove from args */ 133 for (j = i; j < *argc; j++) 134 argv[j] = argv[j+1]; 135 argv[j] = NULL; 136 (*argc)--; 137 } 138 } 139 140 if (dprintf_string == NULL) { 141 /* Look for ZFS_DEBUG environment variable */ 142 dprintf_string = getenv("ZFS_DEBUG"); 143 } 144 145 /* 146 * Are we just turning on all debugging? 147 */ 148 if (dprintf_find_string("on")) 149 dprintf_print_all = 1; 150 151 if (dprintf_string != NULL) 152 zfs_flags |= ZFS_DEBUG_DPRINTF; 153 } 154 155 /* 156 * ========================================================================= 157 * debug printfs 158 * ========================================================================= 159 */ 160 void 161 __dprintf(boolean_t dprint, const char *file, const char *func, 162 int line, const char *fmt, ...) 163 { 164 /* Get rid of annoying "../common/" prefix to filename. */ 165 const char *newfile = zfs_basename(file); 166 167 va_list adx; 168 if (dprint) { 169 /* dprintf messages are printed immediately */ 170 171 if (!dprintf_print_all && 172 !dprintf_find_string(newfile) && 173 !dprintf_find_string(func)) 174 return; 175 176 /* Print out just the function name if requested */ 177 flockfile(stdout); 178 if (dprintf_find_string("pid")) 179 (void) printf("%d ", getpid()); 180 if (dprintf_find_string("tid")) 181 (void) printf("%ju ", 182 (uintmax_t)(uintptr_t)pthread_self()); 183 if (dprintf_find_string("cpu")) 184 (void) printf("%u ", getcpuid()); 185 if (dprintf_find_string("time")) 186 (void) printf("%llu ", gethrtime()); 187 if (dprintf_find_string("long")) 188 (void) printf("%s, line %d: ", newfile, line); 189 (void) printf("dprintf: %s: ", func); 190 va_start(adx, fmt); 191 (void) vprintf(fmt, adx); 192 va_end(adx); 193 funlockfile(stdout); 194 } else { 195 /* zfs_dbgmsg is logged for dumping later */ 196 size_t size; 197 char *buf; 198 int i; 199 200 size = 1024; 201 buf = umem_alloc(size, UMEM_NOFAIL); 202 i = snprintf(buf, size, "%s:%d:%s(): ", newfile, line, func); 203 204 if (i < size) { 205 va_start(adx, fmt); 206 (void) vsnprintf(buf + i, size - i, fmt, adx); 207 va_end(adx); 208 } 209 210 __zfs_dbgmsg(buf); 211 212 umem_free(buf, size); 213 } 214 } 215 216 /* 217 * ========================================================================= 218 * cmn_err() and panic() 219 * ========================================================================= 220 */ 221 222 static __attribute__((noreturn)) void 223 panic_stop_or_abort(void) 224 { 225 const char *stopenv = getenv("LIBZPOOL_PANIC_STOP"); 226 if (stopenv != NULL && atoi(stopenv)) { 227 fputs("libzpool: LIBZPOOL_PANIC_STOP is set, sending " 228 "SIGSTOP to process group\n", stderr); 229 fflush(stderr); 230 231 kill(0, SIGSTOP); 232 233 fputs("libzpool: continued after panic stop, " 234 "aborting\n", stderr); 235 } 236 237 abort(); /* think of it as a "user-level crash dump" */ 238 } 239 240 static void 241 vcmn_msg(int ce, const char *fmt, va_list adx) 242 { 243 switch (ce) { 244 case CE_IGNORE: 245 return; 246 case CE_CONT: 247 break; 248 case CE_NOTE: 249 fputs("libzpool: NOTICE: ", stderr); 250 break; 251 case CE_WARN: 252 fputs("libzpool: WARNING: ", stderr); 253 break; 254 case CE_PANIC: 255 fputs("libzpool: PANIC: ", stderr); 256 break; 257 default: 258 fputs("libzpool: [unknown severity %d]: ", stderr); 259 break; 260 } 261 262 vfprintf(stderr, fmt, adx); 263 if (ce != CE_CONT) 264 fputc('\n', stderr); 265 fflush(stderr); 266 } 267 268 void 269 vcmn_err(int ce, const char *fmt, va_list adx) 270 { 271 vcmn_msg(ce, fmt, adx); 272 273 if (ce == CE_PANIC) 274 panic_stop_or_abort(); 275 } 276 277 void 278 cmn_err(int ce, const char *fmt, ...) 279 { 280 va_list adx; 281 282 va_start(adx, fmt); 283 vcmn_err(ce, fmt, adx); 284 va_end(adx); 285 } 286 287 __attribute__((noreturn)) void 288 panic(const char *fmt, ...) 289 { 290 va_list adx; 291 292 va_start(adx, fmt); 293 vcmn_msg(CE_PANIC, fmt, adx); 294 va_end(adx); 295 296 panic_stop_or_abort(); 297 } 298 299 __attribute__((noreturn)) void 300 vpanic(const char *fmt, va_list adx) 301 { 302 vcmn_msg(CE_PANIC, fmt, adx); 303 panic_stop_or_abort(); 304 } 305 306 /* 307 * ========================================================================= 308 * misc routines 309 * ========================================================================= 310 */ 311 312 void 313 delay(clock_t ticks) 314 { 315 (void) poll(0, 0, ticks * (1000 / hz)); 316 } 317 318 /* 319 * Find highest one bit set. 320 * Returns bit number + 1 of highest bit that is set, otherwise returns 0. 321 * The __builtin_clzll() function is supported by both GCC and Clang. 322 */ 323 int 324 highbit64(uint64_t i) 325 { 326 if (i == 0) 327 return (0); 328 329 return (NBBY * sizeof (uint64_t) - __builtin_clzll(i)); 330 } 331 332 /* 333 * Find lowest one bit set. 334 * Returns bit number + 1 of lowest bit that is set, otherwise returns 0. 335 * The __builtin_ffsll() function is supported by both GCC and Clang. 336 */ 337 int 338 lowbit64(uint64_t i) 339 { 340 if (i == 0) 341 return (0); 342 343 return (__builtin_ffsll(i)); 344 } 345 346 int 347 ddi_strtoull(const char *str, char **nptr, int base, u_longlong_t *result) 348 { 349 errno = 0; 350 *result = strtoull(str, nptr, base); 351 if (*result == 0) 352 return (errno); 353 return (0); 354 } 355 356 /* 357 * ========================================================================= 358 * kernel emulation setup & teardown 359 * ========================================================================= 360 */ 361 static int 362 umem_out_of_memory(void) 363 { 364 char errmsg[] = "out of memory -- generating core dump\n"; 365 366 (void) fprintf(stderr, "%s", errmsg); 367 abort(); 368 return (0); 369 } 370 371 static void 372 spa_config_load(void) 373 { 374 void *buf = NULL; 375 nvlist_t *nvlist, *child; 376 nvpair_t *nvpair; 377 char *pathname; 378 zfs_file_t *fp; 379 zfs_file_attr_t zfa; 380 uint64_t fsize; 381 int err; 382 383 /* 384 * Open the configuration file. 385 */ 386 pathname = kmem_alloc(MAXPATHLEN, KM_SLEEP); 387 388 (void) snprintf(pathname, MAXPATHLEN, "%s", spa_config_path); 389 390 err = zfs_file_open(pathname, O_RDONLY, 0, &fp); 391 if (err) 392 err = zfs_file_open(ZPOOL_CACHE_BOOT, O_RDONLY, 0, &fp); 393 394 kmem_free(pathname, MAXPATHLEN); 395 396 if (err) 397 return; 398 399 if (zfs_file_getattr(fp, &zfa)) 400 goto out; 401 402 fsize = zfa.zfa_size; 403 buf = kmem_alloc(fsize, KM_SLEEP); 404 405 /* 406 * Read the nvlist from the file. 407 */ 408 if (zfs_file_read(fp, buf, fsize, NULL) < 0) 409 goto out; 410 411 /* 412 * Unpack the nvlist. 413 */ 414 if (nvlist_unpack(buf, fsize, &nvlist, KM_SLEEP) != 0) 415 goto out; 416 417 /* 418 * Iterate over all elements in the nvlist, creating a new spa_t for 419 * each one with the specified configuration. 420 */ 421 spa_namespace_enter(FTAG); 422 nvpair = NULL; 423 while ((nvpair = nvlist_next_nvpair(nvlist, nvpair)) != NULL) { 424 if (nvpair_type(nvpair) != DATA_TYPE_NVLIST) 425 continue; 426 427 child = fnvpair_value_nvlist(nvpair); 428 429 if (spa_lookup(nvpair_name(nvpair)) != NULL) 430 continue; 431 (void) spa_add(nvpair_name(nvpair), child, NULL); 432 } 433 spa_namespace_exit(FTAG); 434 435 nvlist_free(nvlist); 436 437 out: 438 if (buf != NULL) 439 kmem_free(buf, fsize); 440 441 zfs_file_close(fp); 442 } 443 444 void 445 kernel_init(int mode) 446 { 447 extern uint_t rrw_tsd_key; 448 449 libspl_init(); 450 451 umem_nofail_callback(umem_out_of_memory); 452 453 dprintf("physmem = %llu pages (%.2f GB)\n", (u_longlong_t)physmem, 454 (double)physmem * sysconf(_SC_PAGE_SIZE) / (1ULL << 30)); 455 456 hostid = (mode & SPA_MODE_WRITE) ? get_system_hostid() : 0; 457 458 system_taskq_init(); 459 icp_init(); 460 461 zstd_init(); 462 463 spa_init((spa_mode_t)mode); 464 spa_config_load(); 465 466 fletcher_4_init(); 467 468 tsd_create(&rrw_tsd_key, rrw_tsd_destroy); 469 } 470 471 void 472 kernel_fini(void) 473 { 474 fletcher_4_fini(); 475 spa_fini(); 476 477 zstd_fini(); 478 479 icp_fini(); 480 system_taskq_fini(); 481 482 libspl_fini(); 483 } 484 485 zfs_file_t * 486 zfs_onexit_fd_hold(int fd, minor_t *minorp) 487 { 488 (void) fd; 489 *minorp = 0; 490 return (NULL); 491 } 492 493 void 494 zfs_onexit_fd_rele(zfs_file_t *fp) 495 { 496 (void) fp; 497 } 498 499 int 500 zfs_onexit_add_cb(minor_t minor, void (*func)(void *), void *data, 501 uintptr_t *action_handle) 502 { 503 (void) minor, (void) func, (void) data, (void) action_handle; 504 return (0); 505 } 506 507 void 508 zvol_create_minors(const char *name) 509 { 510 (void) name; 511 } 512 513 void 514 zvol_remove_minors(spa_t *spa, const char *name, boolean_t async) 515 { 516 (void) spa, (void) name, (void) async; 517 } 518 519 void 520 zvol_rename_minors(spa_t *spa, const char *oldname, const char *newname, 521 boolean_t async) 522 { 523 (void) spa, (void) oldname, (void) newname, (void) async; 524 } 525 526 /* 527 * Open file 528 * 529 * path - fully qualified path to file 530 * flags - file attributes O_READ / O_WRITE / O_EXCL 531 * fpp - pointer to return file pointer 532 * 533 * Returns 0 on success underlying error on failure. 534 */ 535 int 536 zfs_file_open(const char *path, int flags, int mode, zfs_file_t **fpp) 537 { 538 int fd; 539 int dump_fd; 540 int err; 541 int old_umask = 0; 542 zfs_file_t *fp; 543 struct stat64 st; 544 545 if (!(flags & O_CREAT) && stat64(path, &st) == -1) 546 return (errno); 547 548 if (!(flags & O_CREAT) && S_ISBLK(st.st_mode)) 549 flags |= O_DIRECT; 550 551 if (flags & O_CREAT) 552 old_umask = umask(0); 553 554 fd = open64(path, flags, mode); 555 if (fd == -1) 556 return (errno); 557 558 if (flags & O_CREAT) 559 (void) umask(old_umask); 560 561 if (vn_dumpdir != NULL) { 562 char *dumppath = umem_zalloc(MAXPATHLEN, UMEM_NOFAIL); 563 const char *inpath = zfs_basename(path); 564 565 (void) snprintf(dumppath, MAXPATHLEN, 566 "%s/%s", vn_dumpdir, inpath); 567 dump_fd = open64(dumppath, O_CREAT | O_WRONLY, 0666); 568 umem_free(dumppath, MAXPATHLEN); 569 if (dump_fd == -1) { 570 err = errno; 571 close(fd); 572 return (err); 573 } 574 } else { 575 dump_fd = -1; 576 } 577 578 (void) fcntl(fd, F_SETFD, FD_CLOEXEC); 579 580 fp = umem_zalloc(sizeof (zfs_file_t), UMEM_NOFAIL); 581 fp->f_fd = fd; 582 fp->f_dump_fd = dump_fd; 583 *fpp = fp; 584 585 return (0); 586 } 587 588 void 589 zfs_file_close(zfs_file_t *fp) 590 { 591 close(fp->f_fd); 592 if (fp->f_dump_fd != -1) 593 close(fp->f_dump_fd); 594 595 umem_free(fp, sizeof (zfs_file_t)); 596 } 597 598 /* 599 * Stateful write - use os internal file pointer to determine where to 600 * write and update on successful completion. 601 * 602 * fp - pointer to file (pipe, socket, etc) to write to 603 * buf - buffer to write 604 * count - # of bytes to write 605 * resid - pointer to count of unwritten bytes (if short write) 606 * 607 * Returns 0 on success errno on failure. 608 */ 609 int 610 zfs_file_write(zfs_file_t *fp, const void *buf, size_t count, ssize_t *resid) 611 { 612 ssize_t rc; 613 614 rc = write(fp->f_fd, buf, count); 615 if (rc < 0) 616 return (errno); 617 618 if (resid) { 619 *resid = count - rc; 620 } else if (rc != count) { 621 return (EIO); 622 } 623 624 return (0); 625 } 626 627 /* 628 * Stateless write - os internal file pointer is not updated. 629 * 630 * fp - pointer to file (pipe, socket, etc) to write to 631 * buf - buffer to write 632 * count - # of bytes to write 633 * off - file offset to write to (only valid for seekable types) 634 * resid - pointer to count of unwritten bytes 635 * 636 * Returns 0 on success errno on failure. 637 */ 638 int 639 zfs_file_pwrite(zfs_file_t *fp, const void *buf, 640 size_t count, loff_t pos, uint8_t ashift, ssize_t *resid) 641 { 642 ssize_t rc, split, done; 643 int sectors; 644 645 /* 646 * To simulate partial disk writes, we split writes into two 647 * system calls so that the process can be killed in between. 648 * This is used by ztest to simulate realistic failure modes. 649 */ 650 sectors = count >> ashift; 651 split = (sectors > 0 ? rand() % sectors : 0) << ashift; 652 rc = pwrite64(fp->f_fd, buf, split, pos); 653 if (rc != -1) { 654 done = rc; 655 rc = pwrite64(fp->f_fd, (char *)buf + split, 656 count - split, pos + split); 657 } 658 #ifdef __linux__ 659 if (rc == -1 && errno == EINVAL) { 660 /* 661 * Under Linux, this most likely means an alignment issue 662 * (memory or disk) due to O_DIRECT, so we abort() in order 663 * to catch the offender. 664 */ 665 abort(); 666 } 667 #endif 668 669 if (rc < 0) 670 return (errno); 671 672 done += rc; 673 674 if (resid) { 675 *resid = count - done; 676 } else if (done != count) { 677 return (EIO); 678 } 679 680 return (0); 681 } 682 683 /* 684 * Stateful read - use os internal file pointer to determine where to 685 * read and update on successful completion. 686 * 687 * fp - pointer to file (pipe, socket, etc) to read from 688 * buf - buffer to write 689 * count - # of bytes to read 690 * resid - pointer to count of unread bytes (if short read) 691 * 692 * Returns 0 on success errno on failure. 693 */ 694 int 695 zfs_file_read(zfs_file_t *fp, void *buf, size_t count, ssize_t *resid) 696 { 697 int rc; 698 699 rc = read(fp->f_fd, buf, count); 700 if (rc < 0) 701 return (errno); 702 703 if (resid) { 704 *resid = count - rc; 705 } else if (rc != count) { 706 return (EIO); 707 } 708 709 return (0); 710 } 711 712 /* 713 * Stateless read - os internal file pointer is not updated. 714 * 715 * fp - pointer to file (pipe, socket, etc) to read from 716 * buf - buffer to write 717 * count - # of bytes to write 718 * off - file offset to read from (only valid for seekable types) 719 * resid - pointer to count of unwritten bytes (if short write) 720 * 721 * Returns 0 on success errno on failure. 722 */ 723 int 724 zfs_file_pread(zfs_file_t *fp, void *buf, size_t count, loff_t off, 725 ssize_t *resid) 726 { 727 ssize_t rc; 728 729 rc = pread64(fp->f_fd, buf, count, off); 730 if (rc < 0) { 731 #ifdef __linux__ 732 /* 733 * Under Linux, this most likely means an alignment issue 734 * (memory or disk) due to O_DIRECT, so we abort() in order to 735 * catch the offender. 736 */ 737 if (errno == EINVAL) 738 abort(); 739 #endif 740 return (errno); 741 } 742 743 if (fp->f_dump_fd != -1) { 744 int status; 745 746 status = pwrite64(fp->f_dump_fd, buf, rc, off); 747 ASSERT(status != -1); 748 } 749 750 if (resid) { 751 *resid = count - rc; 752 } else if (rc != count) { 753 return (EIO); 754 } 755 756 return (0); 757 } 758 759 /* 760 * lseek - set / get file pointer 761 * 762 * fp - pointer to file (pipe, socket, etc) to read from 763 * offp - value to seek to, returns current value plus passed offset 764 * whence - see man pages for standard lseek whence values 765 * 766 * Returns 0 on success errno on failure (ESPIPE for non seekable types) 767 */ 768 int 769 zfs_file_seek(zfs_file_t *fp, loff_t *offp, int whence) 770 { 771 loff_t rc; 772 773 rc = lseek(fp->f_fd, *offp, whence); 774 if (rc < 0) 775 return (errno); 776 777 *offp = rc; 778 779 return (0); 780 } 781 782 /* 783 * Get file attributes 784 * 785 * filp - file pointer 786 * zfattr - pointer to file attr structure 787 * 788 * Currently only used for fetching size and file mode 789 * 790 * Returns 0 on success or error code of underlying getattr call on failure. 791 */ 792 int 793 zfs_file_getattr(zfs_file_t *fp, zfs_file_attr_t *zfattr) 794 { 795 struct stat64 st; 796 797 if (fstat64_blk(fp->f_fd, &st) == -1) 798 return (errno); 799 800 zfattr->zfa_size = st.st_size; 801 zfattr->zfa_mode = st.st_mode; 802 803 return (0); 804 } 805 806 /* 807 * Sync file to disk 808 * 809 * filp - file pointer 810 * flags - O_SYNC and or O_DSYNC 811 * 812 * Returns 0 on success or error code of underlying sync call on failure. 813 */ 814 int 815 zfs_file_fsync(zfs_file_t *fp, int flags) 816 { 817 (void) flags; 818 819 if (fsync(fp->f_fd) < 0) 820 return (errno); 821 822 return (0); 823 } 824 825 /* 826 * deallocate - zero and/or deallocate file storage 827 * 828 * fp - file pointer 829 * offset - offset to start zeroing or deallocating 830 * len - length to zero or deallocate 831 */ 832 int 833 zfs_file_deallocate(zfs_file_t *fp, loff_t offset, loff_t len) 834 { 835 int rc; 836 #if defined(__linux__) 837 rc = fallocate(fp->f_fd, 838 FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, offset, len); 839 #elif defined(__FreeBSD__) && (__FreeBSD_version >= 1400029) 840 struct spacectl_range rqsr = { 841 .r_offset = offset, 842 .r_len = len, 843 }; 844 rc = fspacectl(fp->f_fd, SPACECTL_DEALLOC, &rqsr, 0, &rqsr); 845 #else 846 (void) fp, (void) offset, (void) len; 847 rc = EOPNOTSUPP; 848 #endif 849 if (rc) 850 return (SET_ERROR(rc)); 851 return (0); 852 } 853 854 /* 855 * Request current file pointer offset 856 * 857 * fp - pointer to file 858 * 859 * Returns current file offset. 860 */ 861 loff_t 862 zfs_file_off(zfs_file_t *fp) 863 { 864 return (lseek(fp->f_fd, SEEK_CUR, 0)); 865 } 866 867 /* 868 * unlink file 869 * 870 * path - fully qualified file path 871 * 872 * Returns 0 on success. 873 * 874 * OPTIONAL 875 */ 876 int 877 zfs_file_unlink(const char *path) 878 { 879 return (remove(path)); 880 } 881 882 /* 883 * Get reference to file pointer 884 * 885 * fd - input file descriptor 886 * 887 * Returns pointer to file struct or NULL. 888 * Unsupported in user space. 889 */ 890 zfs_file_t * 891 zfs_file_get(int fd) 892 { 893 (void) fd; 894 abort(); 895 return (NULL); 896 } 897 /* 898 * Drop reference to file pointer 899 * 900 * fp - pointer to file struct 901 * 902 * Unsupported in user space. 903 */ 904 void 905 zfs_file_put(zfs_file_t *fp) 906 { 907 abort(); 908 (void) fp; 909 } 910 911 void 912 zfsvfs_update_fromname(const char *oldname, const char *newname) 913 { 914 (void) oldname, (void) newname; 915 } 916 917 void 918 spa_import_os(spa_t *spa) 919 { 920 (void) spa; 921 } 922 923 void 924 spa_export_os(spa_t *spa) 925 { 926 (void) spa; 927 } 928 929 void 930 spa_activate_os(spa_t *spa) 931 { 932 (void) spa; 933 } 934 935 void 936 spa_deactivate_os(spa_t *spa) 937 { 938 (void) spa; 939 } 940