/* * Wakeup processes waiting on a socket buffer. * Do asynchronous notification via SIGIO * if the socket has the SS_ASYNC flag set. */ void sowakeup(struct socket *so, struct sockbuf *sb) { sb->sb_flags &= ~SB_SEL; selwakeup(&sb->sb_sel); if (sb->sb_flags & SB_WAIT) { sb->sb_flags &= ~SB_WAIT; wakeup((caddr_t)&sb->sb_cc); } #if 0 // Intentially commented if (so->so_state & SS_ASYNC) { if (so->so_pgid < 0) gsignal(-so->so_pgid, SIGIO); else if (so->so_pgid > 0) proc_signal(so->so_pgid, SIGIO); } if (sb->sb_flags & SB_KNOTE) { KNOTE(&sb->sb_sel.si_note, SO_FILT_HINT_LOCKED); } if (sb->sb_flags & SB_UPCALL) { void (*so_upcall)(struct socket *, caddr_t, int); caddr_t so_upcallarg; so_upcall = so->so_upcall; so_upcallarg = so->so_upcallarg; /* Let close know that we're about to do an upcall */ so->so_flags |= SOF_UPCALLINUSE; socket_unlock(so, 0); (*so_upcall)(so, so_upcallarg, M_DONTWAIT); socket_lock(so, 0); so->so_flags &= ~SOF_UPCALLINUSE; /* Tell close that it's safe to proceed */ if (so->so_flags & SOF_CLOSEWAIT) wakeup((caddr_t)&so->so_upcall); } #endif }
static errno_t fuse_vfsop_unmount(mount_t mp, int mntflags, vfs_context_t context) { int err = 0; int flags = 0; int needsignal = 0; pid_t daemonpid = 0; fuse_device_t fdev; struct fuse_data *data; struct fuse_dispatcher fdi; vnode_t fuse_rootvp = NULLVP; fuse_trace_printf_vfsop(); if (mntflags & MNT_FORCE) { flags |= FORCECLOSE; } data = fuse_get_mpdata(mp); if (!data) { panic("MacFUSE: no mount private data in vfs_unmount"); } fdev = data->fdev; if (fdata_dead_get(data)) { /* * If the file system daemon is dead, it's pointless to try to do * any unmount-time operations that go out to user space. Therefore, * we pretend that this is a force unmount. However, this isn't of much * use. That's because if any non-root vnode is in use, the vflush() * that the kernel does before calling our VFS_UNMOUNT will fail * if the original unmount wasn't forcible already. That earlier * vflush is called with SKIPROOT though, so it wouldn't bail out * on the root vnode being in use. * * If we want, we could set FORCECLOSE here so that a non-forced * unmount will be "upgraded" to a forced unmount if the root vnode * is busy (you are cd'd to the mount point, for example). It's not * quite pure to do that though. * * flags |= FORCECLOSE; * IOLog("MacFUSE: forcing unmount on a dead file system\n"); */ } else if (!(data->dataflags & FSESS_INITED)) { flags |= FORCECLOSE; IOLog("MacFUSE: forcing unmount on not-yet-alive file system\n"); fdata_set_dead(data); } fuse_rootvp = data->rootvp; err = vflush(mp, fuse_rootvp, flags); if (err) { return err; } if (vnode_isinuse(fuse_rootvp, 1) && !(flags & FORCECLOSE)) { return EBUSY; } if (fdata_dead_get(data)) { goto alreadydead; } fdisp_init(&fdi, 0 /* no data to send along */); fdisp_make(&fdi, FUSE_DESTROY, mp, FUSE_ROOT_ID, context); err = fdisp_wait_answ(&fdi); if (!err) { fuse_ticket_drop(fdi.tick); } /* * Note that dounmount() signals a VQ_UNMOUNT VFS event. */ fdata_set_dead(data); alreadydead: needsignal = data->dataflags & FSESS_KILL_ON_UNMOUNT; daemonpid = data->daemonpid; vnode_rele(fuse_rootvp); /* We got this reference in fuse_vfsop_mount(). */ data->rootvp = NULLVP; (void)vflush(mp, NULLVP, FORCECLOSE); fuse_device_lock(fdev); vfs_setfsprivate(mp, NULL); data->mount_state = FM_NOTMOUNTED; OSAddAtomic(-1, (SInt32 *)&fuse_mount_count); if (!(data->dataflags & FSESS_OPENED)) { /* fdev->data was left for us to clean up */ fuse_device_close_final(fdev); /* fdev->data is gone now */ } fuse_device_unlock(fdev); if (daemonpid && needsignal) { proc_signal(daemonpid, MACFUSE_POSTUNMOUNT_SIGNAL); } return 0; }