450 vfssw[fstype].vsw_flag &= ~VSW_INSTALLED;
451 WUNLOCK_VFSSW();
452
453 return (0);
454 }
455
456 /* Support routines used to reference vfs_op */
457
458 /* Set the operations vector for a vfs */
459 void
460 vfs_setops(vfs_t *vfsp, vfsops_t *vfsops)
461 {
462 vfsops_t *op;
463
464 ASSERT(vfsp != NULL);
465 ASSERT(vfsops != NULL);
466
467 op = vfsp->vfs_op;
468 membar_consumer();
469 if (vfsp->vfs_femhead == NULL &&
470 casptr(&vfsp->vfs_op, op, vfsops) == op) {
471 return;
472 }
473 fsem_setvfsops(vfsp, vfsops);
474 }
475
476 /* Retrieve the operations vector for a vfs */
477 vfsops_t *
478 vfs_getops(vfs_t *vfsp)
479 {
480 vfsops_t *op;
481
482 ASSERT(vfsp != NULL);
483
484 op = vfsp->vfs_op;
485 membar_consumer();
486 if (vfsp->vfs_femhead == NULL && op == vfsp->vfs_op) {
487 return (op);
488 } else {
489 return (fsem_getvfsops(vfsp));
490 }
2952 }
2953
2954 /* Provide a unique and monotonically-increasing timestamp. */
2955 void
2956 vfs_mono_time(timespec_t *ts)
2957 {
2958 static volatile hrtime_t hrt; /* The saved time. */
2959 hrtime_t newhrt, oldhrt; /* For effecting the CAS. */
2960 timespec_t newts;
2961
2962 /*
2963 * Try gethrestime() first, but be prepared to fabricate a sensible
2964 * answer at the first sign of any trouble.
2965 */
2966 gethrestime(&newts);
2967 newhrt = ts2hrt(&newts);
2968 for (;;) {
2969 oldhrt = hrt;
2970 if (newhrt <= hrt)
2971 newhrt = hrt + 1;
2972 if (cas64((uint64_t *)&hrt, oldhrt, newhrt) == oldhrt)
2973 break;
2974 }
2975 hrt2ts(newhrt, ts);
2976 }
2977
2978 /*
2979 * Update the mnttab modification time and wake up any waiters for
2980 * mnttab changes
2981 */
2982 void
2983 vfs_mnttab_modtimeupd()
2984 {
2985 hrtime_t oldhrt, newhrt;
2986
2987 ASSERT(RW_WRITE_HELD(&vfslist));
2988 oldhrt = ts2hrt(&vfs_mnttab_mtime);
2989 gethrestime(&vfs_mnttab_mtime);
2990 newhrt = ts2hrt(&vfs_mnttab_mtime);
2991 if (oldhrt == (hrtime_t)0)
2992 vfs_mnttab_ctime = vfs_mnttab_mtime;
|
450 vfssw[fstype].vsw_flag &= ~VSW_INSTALLED;
451 WUNLOCK_VFSSW();
452
453 return (0);
454 }
455
456 /* Support routines used to reference vfs_op */
457
458 /* Set the operations vector for a vfs */
459 void
460 vfs_setops(vfs_t *vfsp, vfsops_t *vfsops)
461 {
462 vfsops_t *op;
463
464 ASSERT(vfsp != NULL);
465 ASSERT(vfsops != NULL);
466
467 op = vfsp->vfs_op;
468 membar_consumer();
469 if (vfsp->vfs_femhead == NULL &&
470 atomic_cas_ptr(&vfsp->vfs_op, op, vfsops) == op) {
471 return;
472 }
473 fsem_setvfsops(vfsp, vfsops);
474 }
475
476 /* Retrieve the operations vector for a vfs */
477 vfsops_t *
478 vfs_getops(vfs_t *vfsp)
479 {
480 vfsops_t *op;
481
482 ASSERT(vfsp != NULL);
483
484 op = vfsp->vfs_op;
485 membar_consumer();
486 if (vfsp->vfs_femhead == NULL && op == vfsp->vfs_op) {
487 return (op);
488 } else {
489 return (fsem_getvfsops(vfsp));
490 }
2952 }
2953
2954 /* Provide a unique and monotonically-increasing timestamp. */
2955 void
2956 vfs_mono_time(timespec_t *ts)
2957 {
2958 static volatile hrtime_t hrt; /* The saved time. */
2959 hrtime_t newhrt, oldhrt; /* For effecting the CAS. */
2960 timespec_t newts;
2961
2962 /*
2963 * Try gethrestime() first, but be prepared to fabricate a sensible
2964 * answer at the first sign of any trouble.
2965 */
2966 gethrestime(&newts);
2967 newhrt = ts2hrt(&newts);
2968 for (;;) {
2969 oldhrt = hrt;
2970 if (newhrt <= hrt)
2971 newhrt = hrt + 1;
2972 if (atomic_cas_64((uint64_t *)&hrt, oldhrt, newhrt) == oldhrt)
2973 break;
2974 }
2975 hrt2ts(newhrt, ts);
2976 }
2977
2978 /*
2979 * Update the mnttab modification time and wake up any waiters for
2980 * mnttab changes
2981 */
2982 void
2983 vfs_mnttab_modtimeupd()
2984 {
2985 hrtime_t oldhrt, newhrt;
2986
2987 ASSERT(RW_WRITE_HELD(&vfslist));
2988 oldhrt = ts2hrt(&vfs_mnttab_mtime);
2989 gethrestime(&vfs_mnttab_mtime);
2990 newhrt = ts2hrt(&vfs_mnttab_mtime);
2991 if (oldhrt == (hrtime_t)0)
2992 vfs_mnttab_ctime = vfs_mnttab_mtime;
|