autofs4: Add d_manage() dentry operation

This patch required a previous patch to add the ->d_automount()
dentry operation.

Add a function to use the newly defined ->d_manage() dentry operation
for blocking during mount and expire.

Whether the VFS calls the dentry operations d_automount() and d_manage()
is controled by the DMANAGED_AUTOMOUNT and DMANAGED_TRANSIT flags. autofs
uses the d_automount() operation to callback to user space to request
mount operations and the d_manage() operation to block walks into mounts
that are under construction or destruction.

In order to prevent these functions from being called unnecessarily the
DMANAGED_* flags are cleared for cases which would cause this. In the
common case the DMANAGED_AUTOMOUNT and DMANAGED_TRANSIT flags are both
set for dentrys waiting to be mounted. The DMANAGED_TRANSIT flag is
cleared upon successful mount request completion and set during expire
runs, both during the dentry expire check, and if selected for expire,
is left set until a subsequent successful mount request completes.

The exception to this is the so-called rootless multi-mount which has
no actual mount at its base. In this case the DMANAGED_AUTOMOUNT flag
is cleared upon successful mount request completion as well and set
again after a successful expire.

Signed-off-by: Ian Kent <raven@themaw.net>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Ian Kent
2011-01-14 18:46:03 +00:00
gecommit door Al Viro
bovenliggende 10584211e4
commit b5b801779d
4 gewijzigde bestanden met toevoegingen van 159 en 40 verwijderingen

Bestand weergeven

@@ -99,7 +99,6 @@ struct autofs_info {
};
#define AUTOFS_INF_EXPIRING (1<<0) /* dentry is in the process of expiring */
#define AUTOFS_INF_MOUNTPOINT (1<<1) /* mountpoint status for direct expire */
#define AUTOFS_INF_PENDING (1<<2) /* dentry pending mount */
struct autofs_wait_queue {
@@ -221,6 +220,7 @@ extern const struct file_operations autofs4_root_operations;
/* Operations methods */
struct vfsmount *autofs4_d_automount(struct path *);
int autofs4_d_manage(struct dentry *, bool);
/* VFS automount flags management functions */
@@ -248,6 +248,54 @@ static inline void managed_dentry_clear_automount(struct dentry *dentry)
spin_unlock(&dentry->d_lock);
}
static inline void __managed_dentry_set_transit(struct dentry *dentry)
{
dentry->d_flags |= DCACHE_MANAGE_TRANSIT;
}
static inline void managed_dentry_set_transit(struct dentry *dentry)
{
spin_lock(&dentry->d_lock);
__managed_dentry_set_transit(dentry);
spin_unlock(&dentry->d_lock);
}
static inline void __managed_dentry_clear_transit(struct dentry *dentry)
{
dentry->d_flags &= ~DCACHE_MANAGE_TRANSIT;
}
static inline void managed_dentry_clear_transit(struct dentry *dentry)
{
spin_lock(&dentry->d_lock);
__managed_dentry_clear_transit(dentry);
spin_unlock(&dentry->d_lock);
}
static inline void __managed_dentry_set_managed(struct dentry *dentry)
{
dentry->d_flags |= (DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT);
}
static inline void managed_dentry_set_managed(struct dentry *dentry)
{
spin_lock(&dentry->d_lock);
__managed_dentry_set_managed(dentry);
spin_unlock(&dentry->d_lock);
}
static inline void __managed_dentry_clear_managed(struct dentry *dentry)
{
dentry->d_flags &= ~(DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT);
}
static inline void managed_dentry_clear_managed(struct dentry *dentry)
{
spin_lock(&dentry->d_lock);
__managed_dentry_clear_managed(dentry);
spin_unlock(&dentry->d_lock);
}
/* Initializing function */
int autofs4_fill_super(struct super_block *, void *, int);