Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 231521
b: refs/heads/master
c: dd89f90
h: refs/heads/master
i:
  231519: c6c6122
v: v3
  • Loading branch information
Ian Kent authored and Al Viro committed Jan 16, 2011
1 parent 3540be8 commit e5fb679
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9e3fea16ba386fa549a0b2de8a203e5d412997a0
refs/heads/master: dd89f90d2deb9aa5bc8e1b15d726ff5c0bb2b623
58 changes: 58 additions & 0 deletions trunk/fs/autofs4/root.c
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,58 @@ static int autofs4_dir_unlink(struct inode *dir, struct dentry *dentry)
return 0;
}

/*
* Version 4 of autofs provides a pseudo direct mount implementation
* that relies on directories at the leaves of a directory tree under
* an indirect mount to trigger mounts. To allow for this we need to
* set the DMANAGED_AUTOMOUNT and DMANAGED_TRANSIT flags on the leaves
* of the directory tree. There is no need to clear the automount flag
* following a mount or restore it after an expire because these mounts
* are always covered. However, it is neccessary to ensure that these
* flags are clear on non-empty directories to avoid unnecessary calls
* during path walks.
*/
static void autofs_set_leaf_automount_flags(struct dentry *dentry)
{
struct dentry *parent;

/* root and dentrys in the root are already handled */
if (IS_ROOT(dentry->d_parent))
return;

managed_dentry_set_managed(dentry);

parent = dentry->d_parent;
/* only consider parents below dentrys in the root */
if (IS_ROOT(parent->d_parent))
return;
managed_dentry_clear_managed(parent);
return;
}

static void autofs_clear_leaf_automount_flags(struct dentry *dentry)
{
struct list_head *d_child;
struct dentry *parent;

/* flags for dentrys in the root are handled elsewhere */
if (IS_ROOT(dentry->d_parent))
return;

managed_dentry_clear_managed(dentry);

parent = dentry->d_parent;
/* only consider parents below dentrys in the root */
if (IS_ROOT(parent->d_parent))
return;
d_child = &dentry->d_u.d_child;
/* Set parent managed if it's becoming empty */
if (d_child->next == &parent->d_subdirs &&
d_child->prev == &parent->d_subdirs)
managed_dentry_set_managed(parent);
return;
}

static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
{
struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb);
Expand Down Expand Up @@ -657,6 +709,9 @@ static int autofs4_dir_rmdir(struct inode *dir, struct dentry *dentry)
spin_unlock(&dentry->d_lock);
spin_unlock(&autofs4_lock);

if (sbi->version < 5)
autofs_clear_leaf_automount_flags(dentry);

if (atomic_dec_and_test(&ino->count)) {
p_ino = autofs4_dentry_ino(dentry->d_parent);
if (p_ino && dentry->d_parent != dentry)
Expand Down Expand Up @@ -699,6 +754,9 @@ static int autofs4_dir_mkdir(struct inode *dir, struct dentry *dentry, int mode)
}
d_add(dentry, inode);

if (sbi->version < 5)
autofs_set_leaf_automount_flags(dentry);

dentry->d_fsdata = ino;
ino->dentry = dget(dentry);
atomic_inc(&ino->count);
Expand Down

0 comments on commit e5fb679

Please sign in to comment.