Commit 4dcd00b1 authored by Ian Kent's avatar Ian Kent Committed by Linus Torvalds
Browse files

[PATCH] autofs4: wait order fix



It's possible for an event wait request to arive before the event
requestor.  If this happens the daemon never gets notified and autofs
hangs.

Signed-off-by: default avatarIan Kent <raven@themaw.net>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 945b0920
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -84,6 +84,7 @@ struct autofs_wait_queue {
	char *name;
	/* This is for status reporting upon return */
	int status;
	atomic_t notified;
	atomic_t wait_ctr;
};

+12 −10
Original line number Diff line number Diff line
@@ -210,17 +210,8 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
		wq->len = len;
		wq->status = -EINTR; /* Status return if interrupted */
		atomic_set(&wq->wait_ctr, 2);
		atomic_set(&wq->notified, 1);
		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);
@@ -229,6 +220,17 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
			(unsigned long) wq->wait_queue_token, wq->len, wq->name, notify);
	}

	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);
	}

	/* wq->name is NULL if and only if the lock is already released */

	if ( sbi->catatonic ) {