Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 26695
b: refs/heads/master
c: a537055
h: refs/heads/master
i:
  26693: c5e6606
  26691: e8227c8
  26687: 2d546db
v: v3
  • Loading branch information
Ian Kent authored and Linus Torvalds committed May 15, 2006
1 parent 44ca3f6 commit 47af307
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 35 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 6aff5cb8ec270db569800b1bb59bd20003a76f07
refs/heads/master: a5370553952a9a414860d878b67c49eff11313bd
5 changes: 2 additions & 3 deletions trunk/fs/autofs4/autofs_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ struct autofs_wait_queue {
struct autofs_wait_queue *next;
autofs_wqt_t wait_queue_token;
/* We use the following to see what we are waiting for */
int hash;
int len;
unsigned int hash;
unsigned int len;
char *name;
u32 dev;
u64 ino;
Expand All @@ -85,7 +85,6 @@ struct autofs_wait_queue {
pid_t tgid;
/* This is for status reporting upon return */
int status;
atomic_t notify;
atomic_t wait_ctr;
};

Expand Down
10 changes: 3 additions & 7 deletions trunk/fs/autofs4/root.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ static int try_to_fill_dentry(struct dentry *dentry, int flags)
static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
{
struct autofs_sb_info *sbi = autofs4_sbi(dentry->d_sb);
struct autofs_info *ino = autofs4_dentry_ino(dentry);
int oz_mode = autofs4_oz_mode(sbi);
unsigned int lookup_type;
int status;
Expand All @@ -340,13 +341,8 @@ static void *autofs4_follow_link(struct dentry *dentry, struct nameidata *nd)
if (oz_mode || !lookup_type)
goto done;

/*
* If a request is pending wait for it.
* If it's a mount then it won't be expired till at least
* a liitle later and if it's an expire then we might need
* to mount it again.
*/
if (autofs4_ispending(dentry)) {
/* If an expire request is pending wait for it. */
if (ino && (ino->flags & AUTOFS_INF_EXPIRING)) {
DPRINTK("waiting for active request %p name=%.*s",
dentry, dentry->d_name.len, dentry->d_name.name);

Expand Down
77 changes: 53 additions & 24 deletions trunk/fs/autofs4/waitq.c
Original file line number Diff line number Diff line change
Expand Up @@ -189,14 +189,30 @@ static int autofs4_getpath(struct autofs_sb_info *sbi,
return len;
}

static struct autofs_wait_queue *
autofs4_find_wait(struct autofs_sb_info *sbi,
char *name, unsigned int hash, unsigned int len)
{
struct autofs_wait_queue *wq;

for (wq = sbi->queues; wq; wq = wq->next) {
if (wq->hash == hash &&
wq->len == len &&
wq->name && !memcmp(wq->name, name, len))
break;
}
return wq;
}

int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
enum autofs_notify notify)
{
struct autofs_info *ino;
struct autofs_wait_queue *wq;
char *name;
unsigned int len = 0;
unsigned int hash = 0;
int status;
int status, type;

/* In catatonic mode, we don't wait for nobody */
if (sbi->catatonic)
Expand All @@ -223,21 +239,41 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
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;
}
wq = autofs4_find_wait(sbi, name, hash, len);
ino = autofs4_dentry_ino(dentry);
if (!wq && ino && notify == NFY_NONE) {
/*
* Either we've betean the pending expire to post it's
* wait or it finished while we waited on the mutex.
* So we need to wait till either, the wait appears
* or the expire finishes.
*/

while (ino->flags & AUTOFS_INF_EXPIRING) {
mutex_unlock(&sbi->wq_mutex);
schedule_timeout_interruptible(HZ/10);
if (mutex_lock_interruptible(&sbi->wq_mutex)) {
kfree(name);
return -EINTR;
}
wq = autofs4_find_wait(sbi, name, hash, len);
if (wq)
break;
}

if (!wq) {
/* Can't wait for an expire if there's no mount */
if (notify == NFY_NONE && !d_mountpoint(dentry)) {
/*
* Not ideal but the status has already gone. Of the two
* cases where we wait on NFY_NONE neither depend on the
* return status of the wait.
*/
if (!wq) {
kfree(name);
mutex_unlock(&sbi->wq_mutex);
return -ENOENT;
return 0;
}
}

if (!wq) {
/* Create a new wait queue */
wq = kmalloc(sizeof(struct autofs_wait_queue),GFP_KERNEL);
if (!wq) {
Expand All @@ -263,20 +299,7 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,
wq->tgid = current->tgid;
wq->status = -EINTR; /* Status return if interrupted */
atomic_set(&wq->wait_ctr, 2);
atomic_set(&wq->notify, 1);
mutex_unlock(&sbi->wq_mutex);
} else {
atomic_inc(&wq->wait_ctr);
mutex_unlock(&sbi->wq_mutex);
kfree(name);
DPRINTK("existing wait id = 0x%08lx, name = %.*s, nfy=%d",
(unsigned long) wq->wait_queue_token, wq->len, wq->name, notify);
}

if (notify != NFY_NONE && atomic_read(&wq->notify)) {
int type;

atomic_dec(&wq->notify);

if (sbi->version < 5) {
if (notify == NFY_MOUNT)
Expand All @@ -299,6 +322,12 @@ int autofs4_wait(struct autofs_sb_info *sbi, struct dentry *dentry,

/* autofs4_notify_daemon() may block */
autofs4_notify_daemon(sbi, wq, type);
} else {
atomic_inc(&wq->wait_ctr);
mutex_unlock(&sbi->wq_mutex);
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 */
Expand Down

0 comments on commit 47af307

Please sign in to comment.