2855 ASSERT(arg0 != NULL);
2856 return ((*func)(arg0, vp, nstate));
2857 }
2858
2859
2860 /*
2861 * Create a new fem_head and associate with the vnode.
2862 * To keep the unaugmented vnode access path lock free, we spin
2863 * update this - create a new one, then try and install it. If
2864 * we fail to install, release the old one and pretend we succeeded.
2865 */
2866
2867 static struct fem_head *
2868 new_femhead(struct fem_head **hp)
2869 {
2870 struct fem_head *head;
2871
2872 head = kmem_alloc(sizeof (*head), KM_SLEEP);
2873 mutex_init(&head->femh_lock, NULL, MUTEX_DEFAULT, NULL);
2874 head->femh_list = NULL;
2875 if (casptr(hp, NULL, head) != NULL) {
2876 kmem_free(head, sizeof (*head));
2877 head = *hp;
2878 }
2879 return (head);
2880 }
2881
2882 /*
2883 * Create a fem_list. The fem_list that gets returned is in a
2884 * very rudimentary state and MUST NOT be used until it's initialized
2885 * (usually by femlist_construct() or fem_dup_list()). The refcount
2886 * and size is set properly and top-of-stack is set to the "guard" node
2887 * just to be consistent.
2888 *
2889 * If anyone were to accidentally trying to run on this fem_list before
2890 * it's initialized then the system would likely panic trying to defererence
2891 * the (NULL) fn_op pointer.
2892 *
2893 */
2894 static struct fem_list *
2895 femlist_create(int numnodes)
3348 void
3349 fem_setvnops(vnode_t *v, vnodeops_t *newops)
3350 {
3351 vnodeops_t *r;
3352
3353 ASSERT(v != NULL);
3354 ASSERT(newops != NULL);
3355
3356 do {
3357 r = v->v_op;
3358 membar_consumer();
3359 if (v->v_femhead != NULL) {
3360 struct fem_list *fl;
3361 if ((fl = fem_lock(v->v_femhead)) != NULL) {
3362 fl->feml_nodes[1].fn_op.vnode = newops;
3363 fem_unlock(v->v_femhead);
3364 return;
3365 }
3366 fem_unlock(v->v_femhead);
3367 }
3368 } while (casptr(&v->v_op, r, newops) != r);
3369 }
3370
3371 vnodeops_t *
3372 fem_getvnops(vnode_t *v)
3373 {
3374 vnodeops_t *r;
3375
3376 ASSERT(v != NULL);
3377
3378 r = v->v_op;
3379 membar_consumer();
3380 if (v->v_femhead != NULL) {
3381 struct fem_list *fl;
3382 if ((fl = fem_lock(v->v_femhead)) != NULL) {
3383 r = fl->feml_nodes[1].fn_op.vnode;
3384 }
3385 fem_unlock(v->v_femhead);
3386 }
3387 return (r);
3388 }
3491 fsem_setvfsops(vfs_t *v, vfsops_t *newops)
3492 {
3493 vfsops_t *r;
3494
3495 ASSERT(v != NULL);
3496 ASSERT(newops != NULL);
3497 ASSERT(v->vfs_implp);
3498
3499 do {
3500 r = v->vfs_op;
3501 membar_consumer();
3502 if (v->vfs_femhead != NULL) {
3503 struct fem_list *fl;
3504 if ((fl = fem_lock(v->vfs_femhead)) != NULL) {
3505 fl->feml_nodes[1].fn_op.vfs = newops;
3506 fem_unlock(v->vfs_femhead);
3507 return;
3508 }
3509 fem_unlock(v->vfs_femhead);
3510 }
3511 } while (casptr(&v->vfs_op, r, newops) != r);
3512 }
3513
3514 vfsops_t *
3515 fsem_getvfsops(vfs_t *v)
3516 {
3517 vfsops_t *r;
3518
3519 ASSERT(v != NULL);
3520 ASSERT(v->vfs_implp);
3521
3522 r = v->vfs_op;
3523 membar_consumer();
3524 if (v->vfs_femhead != NULL) {
3525 struct fem_list *fl;
3526 if ((fl = fem_lock(v->vfs_femhead)) != NULL) {
3527 r = fl->feml_nodes[1].fn_op.vfs;
3528 }
3529 fem_unlock(v->vfs_femhead);
3530 }
3531 return (r);
|
2855 ASSERT(arg0 != NULL);
2856 return ((*func)(arg0, vp, nstate));
2857 }
2858
2859
2860 /*
2861 * Create a new fem_head and associate with the vnode.
2862 * To keep the unaugmented vnode access path lock free, we spin
2863 * update this - create a new one, then try and install it. If
2864 * we fail to install, release the old one and pretend we succeeded.
2865 */
2866
2867 static struct fem_head *
2868 new_femhead(struct fem_head **hp)
2869 {
2870 struct fem_head *head;
2871
2872 head = kmem_alloc(sizeof (*head), KM_SLEEP);
2873 mutex_init(&head->femh_lock, NULL, MUTEX_DEFAULT, NULL);
2874 head->femh_list = NULL;
2875 if (atomic_cas_ptr(hp, NULL, head) != NULL) {
2876 kmem_free(head, sizeof (*head));
2877 head = *hp;
2878 }
2879 return (head);
2880 }
2881
2882 /*
2883 * Create a fem_list. The fem_list that gets returned is in a
2884 * very rudimentary state and MUST NOT be used until it's initialized
2885 * (usually by femlist_construct() or fem_dup_list()). The refcount
2886 * and size is set properly and top-of-stack is set to the "guard" node
2887 * just to be consistent.
2888 *
2889 * If anyone were to accidentally trying to run on this fem_list before
2890 * it's initialized then the system would likely panic trying to defererence
2891 * the (NULL) fn_op pointer.
2892 *
2893 */
2894 static struct fem_list *
2895 femlist_create(int numnodes)
3348 void
3349 fem_setvnops(vnode_t *v, vnodeops_t *newops)
3350 {
3351 vnodeops_t *r;
3352
3353 ASSERT(v != NULL);
3354 ASSERT(newops != NULL);
3355
3356 do {
3357 r = v->v_op;
3358 membar_consumer();
3359 if (v->v_femhead != NULL) {
3360 struct fem_list *fl;
3361 if ((fl = fem_lock(v->v_femhead)) != NULL) {
3362 fl->feml_nodes[1].fn_op.vnode = newops;
3363 fem_unlock(v->v_femhead);
3364 return;
3365 }
3366 fem_unlock(v->v_femhead);
3367 }
3368 } while (atomic_cas_ptr(&v->v_op, r, newops) != r);
3369 }
3370
3371 vnodeops_t *
3372 fem_getvnops(vnode_t *v)
3373 {
3374 vnodeops_t *r;
3375
3376 ASSERT(v != NULL);
3377
3378 r = v->v_op;
3379 membar_consumer();
3380 if (v->v_femhead != NULL) {
3381 struct fem_list *fl;
3382 if ((fl = fem_lock(v->v_femhead)) != NULL) {
3383 r = fl->feml_nodes[1].fn_op.vnode;
3384 }
3385 fem_unlock(v->v_femhead);
3386 }
3387 return (r);
3388 }
3491 fsem_setvfsops(vfs_t *v, vfsops_t *newops)
3492 {
3493 vfsops_t *r;
3494
3495 ASSERT(v != NULL);
3496 ASSERT(newops != NULL);
3497 ASSERT(v->vfs_implp);
3498
3499 do {
3500 r = v->vfs_op;
3501 membar_consumer();
3502 if (v->vfs_femhead != NULL) {
3503 struct fem_list *fl;
3504 if ((fl = fem_lock(v->vfs_femhead)) != NULL) {
3505 fl->feml_nodes[1].fn_op.vfs = newops;
3506 fem_unlock(v->vfs_femhead);
3507 return;
3508 }
3509 fem_unlock(v->vfs_femhead);
3510 }
3511 } while (atomic_cas_ptr(&v->vfs_op, r, newops) != r);
3512 }
3513
3514 vfsops_t *
3515 fsem_getvfsops(vfs_t *v)
3516 {
3517 vfsops_t *r;
3518
3519 ASSERT(v != NULL);
3520 ASSERT(v->vfs_implp);
3521
3522 r = v->vfs_op;
3523 membar_consumer();
3524 if (v->vfs_femhead != NULL) {
3525 struct fem_list *fl;
3526 if ((fl = fem_lock(v->vfs_femhead)) != NULL) {
3527 r = fl->feml_nodes[1].fn_op.vfs;
3528 }
3529 fem_unlock(v->vfs_femhead);
3530 }
3531 return (r);
|