}  if (notify != NFY_NONE && atomic_dec_and_test(&wq->notified)) { int type = (notify == NFY_MOUNT ? autofs_ptype_missing : autofs_ptype_expire_multi);  DPRINTK(("new wait id = 0x%08lx, name = %.*s, nfy=%d\n", (unsigned long) wq->wait_queue_token, wq->len, wq->name, notify));  /* autofs4_notify_daemon() may block */ autofs4_notify_daemon(sbi, wq, type); 
int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,		enum autofs_notify notify){	struct autofs_wait_queue *wq;	char *name;	int len, status;	/* In catatonic mode, we don't wait for nobody */	if ( sbi->catatonic )		return -ENOENT;		name = kmalloc(NAME_MAX + 1, GFP_KERNEL);	if (!name)		return -ENOMEM;	len = autofs4_getpath(sbi, dentry, &name);	if (!len) {		kfree(name);		return -ENOENT;	}	if (down_interruptible(&sbi->wq_sem)) {		kfree(name);		return -EINTR;	}	for (wq = sbi->queues ; wq ; wq = wq->next) {		if (wq->hash == dentry->d_name.hash &&		    wq->len == len &&		    wq->name && !memcmp(wq->name, name, len))			break;	}	if ( !wq ) {		/* Create a new wait queue */		wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL);		if ( !wq ) {			kfree(name);			up(&sbi->wq_sem);			return -ENOMEM;		}		wq->wait_queue_token = autofs4_next_wait_queue;		if (++autofs4_next_wait_queue == 0)			autofs4_next_wait_queue = 1;		wq->next = sbi->queues;		sbi->queues = wq;		init_waitqueue_head(&wq->queue);		wq->hash = dentry->d_name.hash;		wq->name = name;		wq->len = len;		wq->status = -EINTR; /* Status return if interrupted */		atomic_set(&wq->wait_ctr, 2);		up(&sbi->wq_sem);		DPRINTK("new wait id = 0x%08lx, name = %.*s, nfy=%d",			(unsigned long) wq->wait_queue_token, wq->len, wq->name, notify);		/* autofs4_notify_daemon() may block */		if (notify != NFY_NONE) {			autofs4_notify_daemon(sbi,wq, 					notify == NFY_MOUNT ?						  autofs_ptype_missing :						  autofs_ptype_expire_multi);		}	} else {		atomic_inc(&wq->wait_ctr);		up(&sbi->wq_sem);		kfree(name);		DPRINTK("existing wait id = 0x%08lx, name = %.*s, nfy=%d",			(unsigned long) wq->wait_queue_token, wq->len, wq->name, notify);	}	/* wq->name is NULL if and only if the lock is already released */	if ( sbi->catatonic ) {		/* We might have slept, so check again for catatonic mode */		wq->status = -ENOENT;		if ( wq->name ) {			kfree(wq->name);			wq->name = NULL;		}	}	if ( wq->name ) {		/* Block all but "shutdown" signals while waiting */		sigset_t oldset;		unsigned long irqflags;		spin_lock_irqsave(&current->sighand->siglock, irqflags);		oldset = current->blocked;		siginitsetinv(&current->blocked, SHUTDOWN_SIGS & ~oldset.sig[0]);		recalc_sigpending();		spin_unlock_irqrestore(&current->sighand->siglock, irqflags);		wait_event_interruptible(wq->queue, wq->name == NULL);		spin_lock_irqsave(&current->sighand->siglock, irqflags);		current->blocked = oldset;		recalc_sigpending();		spin_unlock_irqrestore(&current->sighand->siglock, irqflags);	} else {		DPRINTK("skipped sleeping");	}	status = wq->status;	/* Are we the last process to need status? */	if (atomic_dec_and_test(&wq->wait_ctr))		kfree(wq);	return status;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/4dcd00b18118d174c4b8d838c11f437f0af3c20c/waitq.c/buggy/fs/autofs4/waitq.c