/* Removes a "struct epitem" from the eventpoll RB tree and deallocates all the associated resources. Must be called with "mtx" held.  */
static int ep_remove(struct eventpoll *ep, struct epitem *epi)
/* Removes a "struct epitem" from the eventpoll RB tree and deallocates all the associated resources. Must be called with "mtx" held.  */
static int ep_remove(struct eventpoll *ep, struct epitem *epi)
{
	unsigned long flags;
	struct file *file = epi->ffd.file;
	ep_unregister_pollwait(ep, epi);
	spin_lock(&file->f_lock);
	if (ep_is_linked(&epi->fllink))
		list_del_init(&epi->fllink);
	spin_unlock(&file->f_lock);
	rb_erase(&epi->rbn, &ep->rbr);
	spin_lock_irqsave(&ep->lock, flags);
	if (ep_is_linked(&epi->rdllink))
		list_del_init(&epi->rdllink);
	spin_unlock_irqrestore(&ep->lock, flags);
	kmem_cache_free(epi_cache, epi);
	atomic_dec(&ep->user->epoll_watches);
	return 0;
}