Fix autofs_expire()
mnt should remain the same for all iterations through the list; as it is, if we have a busy mount, mnt follows into it and isn't restored for the next iteration. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
parent
24b6f16ecf
commit
117aff744a
|
@ -39,10 +39,12 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
|
||||||
{
|
{
|
||||||
struct autofs_dirhash *dh = &sbi->dirhash;
|
struct autofs_dirhash *dh = &sbi->dirhash;
|
||||||
struct autofs_dir_ent *ent;
|
struct autofs_dir_ent *ent;
|
||||||
struct dentry *dentry;
|
|
||||||
unsigned long timeout = sbi->exp_timeout;
|
unsigned long timeout = sbi->exp_timeout;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
|
struct path path;
|
||||||
|
int umount_ok;
|
||||||
|
|
||||||
if ( list_empty(&dh->expiry_head) || sbi->catatonic )
|
if ( list_empty(&dh->expiry_head) || sbi->catatonic )
|
||||||
return NULL; /* No entries */
|
return NULL; /* No entries */
|
||||||
/* We keep the list sorted by last_usage and want old stuff */
|
/* We keep the list sorted by last_usage and want old stuff */
|
||||||
|
@ -57,17 +59,17 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
|
||||||
return ent; /* Symlinks are always expirable */
|
return ent; /* Symlinks are always expirable */
|
||||||
|
|
||||||
/* Get the dentry for the autofs subdirectory */
|
/* Get the dentry for the autofs subdirectory */
|
||||||
dentry = ent->dentry;
|
path.dentry = ent->dentry;
|
||||||
|
|
||||||
if ( !dentry ) {
|
if (!path.dentry) {
|
||||||
/* Should only happen in catatonic mode */
|
/* Should only happen in catatonic mode */
|
||||||
printk("autofs: dentry == NULL but inode range is directory, entry %s\n", ent->name);
|
printk("autofs: dentry == NULL but inode range is directory, entry %s\n", ent->name);
|
||||||
autofs_delete_usage(ent);
|
autofs_delete_usage(ent);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !dentry->d_inode ) {
|
if (!path.dentry->d_inode) {
|
||||||
dput(dentry);
|
dput(path.dentry);
|
||||||
printk("autofs: negative dentry on expiry queue: %s\n",
|
printk("autofs: negative dentry on expiry queue: %s\n",
|
||||||
ent->name);
|
ent->name);
|
||||||
autofs_delete_usage(ent);
|
autofs_delete_usage(ent);
|
||||||
|
@ -76,29 +78,29 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb,
|
||||||
|
|
||||||
/* Make sure entry is mounted and unused; note that dentry will
|
/* Make sure entry is mounted and unused; note that dentry will
|
||||||
point to the mounted-on-top root. */
|
point to the mounted-on-top root. */
|
||||||
if (!S_ISDIR(dentry->d_inode->i_mode)||!d_mountpoint(dentry)) {
|
if (!S_ISDIR(path.dentry->d_inode->i_mode) ||
|
||||||
|
!d_mountpoint(path.dentry)) {
|
||||||
DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
|
DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mntget(mnt);
|
path.mnt = mnt;
|
||||||
dget(dentry);
|
path_get(&path);
|
||||||
if (!follow_down(&mnt, &dentry)) {
|
if (!follow_down(&path.mnt, &path.dentry)) {
|
||||||
dput(dentry);
|
path_put(&path);
|
||||||
mntput(mnt);
|
|
||||||
DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
|
DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
while (d_mountpoint(dentry) && follow_down(&mnt, &dentry))
|
while (d_mountpoint(path.dentry) &&
|
||||||
|
follow_down(&path.mnt, &path.dentry))
|
||||||
;
|
;
|
||||||
dput(dentry);
|
umount_ok = may_umount(path.mnt);
|
||||||
|
path_put(&path);
|
||||||
|
|
||||||
if ( may_umount(mnt) ) {
|
if (umount_ok) {
|
||||||
mntput(mnt);
|
|
||||||
DPRINTK(("autofs: signaling expire on %s\n", ent->name));
|
DPRINTK(("autofs: signaling expire on %s\n", ent->name));
|
||||||
return ent; /* Expirable! */
|
return ent; /* Expirable! */
|
||||||
}
|
}
|
||||||
DPRINTK(("autofs: didn't expire due to may_umount: %s\n", ent->name));
|
DPRINTK(("autofs: didn't expire due to may_umount: %s\n", ent->name));
|
||||||
mntput(mnt);
|
|
||||||
}
|
}
|
||||||
return NULL; /* No expirable entries */
|
return NULL; /* No expirable entries */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue