/* * Wakeup all sleepers and cleanup. */ int xfs_devclose_common(dev_t dev, struct proc *proc) { struct xfs_channel *chan = &xfs_channel[minor(dev)]; struct xfs_link *first; /* Sanity check, paranoia? */ if (!(chan->status & CHANNEL_OPENED)) panic("xfs_devclose never opened?"); chan->status &= ~CHANNEL_OPENED; /* No one is going to read those messages so empty queue! */ while (!xfs_emptyq(&chan->messageq)) { XFSDEB(XDEBDEV, ("before outq(messageq)\n")); first = chan->messageq.next; xfs_outq(first); if (first->error_or_size != 0) xfs_free(first, first->error_or_size); XFSDEB(XDEBDEV, ("after outq(messageq)\n")); } /* Wakeup those waiting for replies that will never arrive. */ while (!xfs_emptyq(&chan->sleepq)) { XFSDEB(XDEBDEV, ("before outq(sleepq)\n")); first = chan->sleepq.next; xfs_outq(first); first->error_or_size = ENODEV; wakeup((caddr_t) first); XFSDEB(XDEBDEV, ("after outq(sleepq)\n")); } if (chan->status & CHANNEL_WAITING) wakeup((caddr_t) chan); if (chan->message_buffer) { xfs_free(chan->message_buffer, MAX_XMSG_SIZE); chan->message_buffer = NULL; } /* * Free all xfs nodes. */ if (xfs[minor(dev)].mp != NULL) { if (xfs_vfs_busy(xfs[minor(dev)].mp, 0, NULL, proc)) { XFSDEB(XDEBNODE, ("xfs_dev_close: vfs_busy() --> BUSY\n")); return EBUSY; } free_all_xfs_nodes(&xfs[minor(dev)], FORCECLOSE, 0); xfs_vfs_unbusy(xfs[minor(dev)].mp, proc); } return 0; }
int xfs_unmount_common(struct mount *mp, int mntflags) { struct xfs *xfsp = VFS_TO_NNPFS(mp); int flags = 0; int error; if (mntflags & MNT_FORCE) { #ifdef HAVE_KERNEL_DOFORCE if (!doforce) return EINVAL; #endif flags |= FORCECLOSE; } error = free_all_xfs_nodes(xfsp, flags, 1); if (error) return error; xfsp->status = 0; NNPFS_TO_VFS(xfsp) = NULL; return 0; }