Beispiel #1
0
/*
 * 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
}
Beispiel #2
0
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;
}