Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 64259
b: refs/heads/master
c: 1864f7b
h: refs/heads/master
i:
  64257: 8678f0b
  64255: 4024b62
v: v3
  • Loading branch information
Ian Kent authored and Linus Torvalds committed Aug 23, 2007
1 parent b2c334c commit 94fbebf
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 15 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: f4768ffd1d4b7b07ae2c4c3d93c9f99cd68e996c
refs/heads/master: 1864f7bd58351732593def024e73eca1f75bc352
31 changes: 17 additions & 14 deletions trunk/fs/autofs4/root.c
Original file line number Diff line number Diff line change
Expand Up @@ -587,35 +587,38 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
unhashed = autofs4_lookup_unhashed(sbi, dentry->d_parent, &dentry->d_name);
if (!unhashed) {
/*
* Mark the dentry incomplete, but add it. This is needed so
* that the VFS layer knows about the dentry, and we can count
* on catching any lookups through the revalidate.
*
* Let all the hard work be done by the revalidate function that
* needs to be able to do this anyway..
*
* We need to do this before we release the directory semaphore.
* Mark the dentry incomplete but don't hash it. We do this
* to serialize our inode creation operations (symlink and
* mkdir) which prevents deadlock during the callback to
* the daemon. Subsequent user space lookups for the same
* dentry are placed on the wait queue while the daemon
* itself is allowed passage unresticted so the create
* operation itself can then hash the dentry. Finally,
* we check for the hashed dentry and return the newly
* hashed dentry.
*/
dentry->d_op = &autofs4_root_dentry_operations;

dentry->d_fsdata = NULL;
d_add(dentry, NULL);
d_instantiate(dentry, NULL);
} else {
struct autofs_info *ino = autofs4_dentry_ino(unhashed);
DPRINTK("rehash %p with %p", dentry, unhashed);
/*
* If we are racing with expire the request might not
* be quite complete but the directory has been removed
* so it must have been successful, so just wait for it.
* We need to ensure the AUTOFS_INF_EXPIRING flag is clear
* before continuing as revalidate may fail when calling
* try_to_fill_dentry (returning EAGAIN) if we don't.
*/
if (ino && (ino->flags & AUTOFS_INF_EXPIRING)) {
while (ino && (ino->flags & AUTOFS_INF_EXPIRING)) {
DPRINTK("wait for incomplete expire %p name=%.*s",
unhashed, unhashed->d_name.len,
unhashed->d_name.name);
autofs4_wait(sbi, unhashed, NFY_NONE);
DPRINTK("request completed");
}
d_rehash(unhashed);
dentry = unhashed;
}

Expand Down Expand Up @@ -658,7 +661,7 @@ static struct dentry *autofs4_lookup(struct inode *dir, struct dentry *dentry, s
* for all system calls, but it should be OK for the operations
* we permit from an autofs.
*/
if (dentry->d_inode && d_unhashed(dentry)) {
if (!oz_mode && d_unhashed(dentry)) {
/*
* A user space application can (and has done in the past)
* remove and re-create this directory during the callback.
Expand Down Expand Up @@ -716,7 +719,7 @@ static int autofs4_dir_symlink(struct inode *dir,
strcpy(cp, symname);

inode = autofs4_get_inode(dir->i_sb, ino);
d_instantiate(dentry, inode);
d_add(dentry, inode);

if (dir == dir->i_sb->s_root->d_inode)
dentry->d_op = &autofs4_root_dentry_operations;
Expand Down Expand Up @@ -844,7 +847,7 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
return -ENOSPC;

inode = autofs4_get_inode(dir->i_sb, ino);
d_instantiate(dentry, inode);
d_add(dentry, inode);

if (dir == dir->i_sb->s_root->d_inode)
dentry->d_op = &autofs4_root_dentry_operations;
Expand Down

0 comments on commit 94fbebf

Please sign in to comment.