488 */
489 if (!removal)
490 mutex_exit(&state->ins_lock);
491 return;
492 }
493
494 if (name != NULL) {
495 len = strlen(name) + 1;
496 len = roundup(len, sizeof (struct inotify_event));
497 } else {
498 len = 0;
499 }
500
501 event = kmem_zalloc(sizeof (inotify_kevent_t) + len, KM_SLEEP);
502 event->ine_event.wd = wd;
503 event->ine_event.mask = (uint32_t)mask;
504 event->ine_event.cookie = cookie;
505 event->ine_event.len = len;
506
507 if (name != NULL)
508 strcpy(event->ine_event.name, name);
509
510 if (tail != NULL) {
511 tail->ine_next = event;
512 } else {
513 VERIFY(state->ins_head == NULL);
514 state->ins_head = event;
515 cv_broadcast(&state->ins_cv);
516 }
517
518 state->ins_tail = event;
519 state->ins_nevents++;
520 state->ins_size += sizeof (event->ine_event) + len;
521
522 if (removal)
523 return;
524
525 if ((watch->inw_mask & IN_ONESHOT) && !watch->inw_fired) {
526 /*
527 * If this is a one-shot, we need to remove the watch. (Note
528 * that this will recurse back into inotify_watch_event() to
612 watch->inw_mask = mask;
613 watch->inw_state = state;
614 watch->inw_refcnt = 1;
615
616 if (parent == NULL) {
617 watch->inw_wd = (int)(uintptr_t)vmem_alloc(state->ins_wds,
618 1, VM_BESTFIT | VM_SLEEP);
619 avl_add(&state->ins_byvp, watch);
620 avl_add(&state->ins_bywd, watch);
621
622 avl_create(&watch->inw_children,
623 (int(*)(const void *, const void *))inotify_watch_cmpvp,
624 sizeof (inotify_watch_t),
625 offsetof(inotify_watch_t, inw_byvp));
626 } else {
627 VERIFY(name != NULL);
628 inotify_watch_hold(parent);
629 watch->inw_mask &= IN_CHILD_EVENTS;
630 watch->inw_parent = parent;
631 watch->inw_name = kmem_alloc(strlen(name) + 1, KM_SLEEP);
632 strcpy(watch->inw_name, name);
633
634 avl_add(&parent->inw_children, watch);
635 }
636
637 /*
638 * Add our monitor to the vnode. We must not have the watch lock held
639 * when we do this, as it will immediately hold our watch.
640 */
641 err = fem_install(vp, inotify_femp, watch, OPARGUNIQ,
642 (void (*)(void *))inotify_watch_hold,
643 (void (*)(void *))inotify_watch_release);
644
645 VERIFY(err == 0);
646
647 return (watch);
648 }
649
650 /*
651 * Remove a (non-child) watch. This is called from either synchronous context
652 * via inotify_rm_watch() or monitor context via either a vnevent or a
|
488 */
489 if (!removal)
490 mutex_exit(&state->ins_lock);
491 return;
492 }
493
494 if (name != NULL) {
495 len = strlen(name) + 1;
496 len = roundup(len, sizeof (struct inotify_event));
497 } else {
498 len = 0;
499 }
500
501 event = kmem_zalloc(sizeof (inotify_kevent_t) + len, KM_SLEEP);
502 event->ine_event.wd = wd;
503 event->ine_event.mask = (uint32_t)mask;
504 event->ine_event.cookie = cookie;
505 event->ine_event.len = len;
506
507 if (name != NULL)
508 (void) strcpy(event->ine_event.name, name);
509
510 if (tail != NULL) {
511 tail->ine_next = event;
512 } else {
513 VERIFY(state->ins_head == NULL);
514 state->ins_head = event;
515 cv_broadcast(&state->ins_cv);
516 }
517
518 state->ins_tail = event;
519 state->ins_nevents++;
520 state->ins_size += sizeof (event->ine_event) + len;
521
522 if (removal)
523 return;
524
525 if ((watch->inw_mask & IN_ONESHOT) && !watch->inw_fired) {
526 /*
527 * If this is a one-shot, we need to remove the watch. (Note
528 * that this will recurse back into inotify_watch_event() to
612 watch->inw_mask = mask;
613 watch->inw_state = state;
614 watch->inw_refcnt = 1;
615
616 if (parent == NULL) {
617 watch->inw_wd = (int)(uintptr_t)vmem_alloc(state->ins_wds,
618 1, VM_BESTFIT | VM_SLEEP);
619 avl_add(&state->ins_byvp, watch);
620 avl_add(&state->ins_bywd, watch);
621
622 avl_create(&watch->inw_children,
623 (int(*)(const void *, const void *))inotify_watch_cmpvp,
624 sizeof (inotify_watch_t),
625 offsetof(inotify_watch_t, inw_byvp));
626 } else {
627 VERIFY(name != NULL);
628 inotify_watch_hold(parent);
629 watch->inw_mask &= IN_CHILD_EVENTS;
630 watch->inw_parent = parent;
631 watch->inw_name = kmem_alloc(strlen(name) + 1, KM_SLEEP);
632 /* strcpy() is safe, because strlen(name) bounds us. */
633 (void) strcpy(watch->inw_name, name);
634
635 avl_add(&parent->inw_children, watch);
636 }
637
638 /*
639 * Add our monitor to the vnode. We must not have the watch lock held
640 * when we do this, as it will immediately hold our watch.
641 */
642 err = fem_install(vp, inotify_femp, watch, OPARGUNIQ,
643 (void (*)(void *))inotify_watch_hold,
644 (void (*)(void *))inotify_watch_release);
645
646 VERIFY(err == 0);
647
648 return (watch);
649 }
650
651 /*
652 * Remove a (non-child) watch. This is called from either synchronous context
653 * via inotify_rm_watch() or monitor context via either a vnevent or a
|