|
Packit |
8480eb |
--- linux-2.6.29.orig/fs/autofs4/autofs_i.h
|
|
Packit |
8480eb |
+++ linux-2.6.29/fs/autofs4/autofs_i.h
|
|
Packit |
8480eb |
@@ -186,6 +186,8 @@ int autofs4_expire_wait(struct dentry *d
|
|
Packit |
8480eb |
int autofs4_expire_run(struct super_block *, struct vfsmount *,
|
|
Packit |
8480eb |
struct autofs_sb_info *,
|
|
Packit |
8480eb |
struct autofs_packet_expire __user *);
|
|
Packit |
8480eb |
+int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
|
|
Packit |
8480eb |
+ struct autofs_sb_info *sbi, int when);
|
|
Packit |
8480eb |
int autofs4_expire_multi(struct super_block *, struct vfsmount *,
|
|
Packit |
8480eb |
struct autofs_sb_info *, int __user *);
|
|
Packit |
8480eb |
struct dentry *autofs4_expire_direct(struct super_block *sb,
|
|
Packit |
8480eb |
--- linux-2.6.29.orig/fs/autofs4/dev-ioctl.c
|
|
Packit |
8480eb |
+++ linux-2.6.29/fs/autofs4/dev-ioctl.c
|
|
Packit |
8480eb |
@@ -525,40 +525,13 @@ static int autofs_dev_ioctl_expire(struc
|
|
Packit |
8480eb |
struct autofs_sb_info *sbi,
|
|
Packit |
8480eb |
struct autofs_dev_ioctl *param)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
- struct dentry *dentry;
|
|
Packit |
8480eb |
struct vfsmount *mnt;
|
|
Packit |
8480eb |
- int err = -EAGAIN;
|
|
Packit |
8480eb |
int how;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
how = param->expire.how;
|
|
Packit |
8480eb |
mnt = fp->f_path.mnt;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
- if (autofs_type_trigger(sbi->type))
|
|
Packit |
8480eb |
- dentry = autofs4_expire_direct(sbi->sb, mnt, sbi, how);
|
|
Packit |
8480eb |
- else
|
|
Packit |
8480eb |
- dentry = autofs4_expire_indirect(sbi->sb, mnt, sbi, how);
|
|
Packit |
8480eb |
-
|
|
Packit |
8480eb |
- if (dentry) {
|
|
Packit |
8480eb |
- struct autofs_info *ino = autofs4_dentry_ino(dentry);
|
|
Packit |
8480eb |
-
|
|
Packit |
8480eb |
- /*
|
|
Packit |
8480eb |
- * This is synchronous because it makes the daemon a
|
|
Packit |
8480eb |
- * little easier
|
|
Packit |
8480eb |
- */
|
|
Packit |
8480eb |
- err = autofs4_wait(sbi, dentry, NFY_EXPIRE);
|
|
Packit |
8480eb |
-
|
|
Packit |
8480eb |
- spin_lock(&sbi->fs_lock);
|
|
Packit |
8480eb |
- if (ino->flags & AUTOFS_INF_MOUNTPOINT) {
|
|
Packit |
8480eb |
- ino->flags &= ~AUTOFS_INF_MOUNTPOINT;
|
|
Packit |
8480eb |
- sbi->sb->s_root->d_mounted++;
|
|
Packit |
8480eb |
- }
|
|
Packit |
8480eb |
- ino->flags &= ~AUTOFS_INF_EXPIRING;
|
|
Packit |
8480eb |
- complete_all(&ino->expire_complete);
|
|
Packit |
8480eb |
- spin_unlock(&sbi->fs_lock);
|
|
Packit |
8480eb |
- dput(dentry);
|
|
Packit |
8480eb |
- }
|
|
Packit |
8480eb |
-
|
|
Packit |
8480eb |
- return err;
|
|
Packit |
8480eb |
+ return autofs4_do_expire_multi(sbi->sb, mnt, sbi, how);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
/* Check if autofs mount point is in use */
|
|
Packit |
8480eb |
--- linux-2.6.29.orig/fs/autofs4/expire.c
|
|
Packit |
8480eb |
+++ linux-2.6.29/fs/autofs4/expire.c
|
|
Packit |
8480eb |
@@ -70,8 +70,10 @@ static int autofs4_mount_busy(struct vfs
|
|
Packit |
8480eb |
* Otherwise it's an offset mount and we need to check
|
|
Packit |
8480eb |
* if we can umount its mount, if there is one.
|
|
Packit |
8480eb |
*/
|
|
Packit |
8480eb |
- if (!d_mountpoint(dentry))
|
|
Packit |
8480eb |
+ if (!d_mountpoint(dentry)) {
|
|
Packit |
8480eb |
+ status = 0;
|
|
Packit |
8480eb |
goto done;
|
|
Packit |
8480eb |
+ }
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
/* Update the expiry counter if fs is busy */
|
|
Packit |
8480eb |
@@ -478,22 +480,16 @@ int autofs4_expire_run(struct super_bloc
|
|
Packit |
8480eb |
return ret;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
-/* Call repeatedly until it returns -EAGAIN, meaning there's nothing
|
|
Packit |
8480eb |
- more to be done */
|
|
Packit |
8480eb |
-int autofs4_expire_multi(struct super_block *sb, struct vfsmount *mnt,
|
|
Packit |
8480eb |
- struct autofs_sb_info *sbi, int __user *arg)
|
|
Packit |
8480eb |
+int autofs4_do_expire_multi(struct super_block *sb, struct vfsmount *mnt,
|
|
Packit |
8480eb |
+ struct autofs_sb_info *sbi, int when)
|
|
Packit |
8480eb |
{
|
|
Packit |
8480eb |
struct dentry *dentry;
|
|
Packit |
8480eb |
int ret = -EAGAIN;
|
|
Packit |
8480eb |
- int do_now = 0;
|
|
Packit |
8480eb |
-
|
|
Packit |
8480eb |
- if (arg && get_user(do_now, arg))
|
|
Packit |
8480eb |
- return -EFAULT;
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (autofs_type_trigger(sbi->type))
|
|
Packit |
8480eb |
- dentry = autofs4_expire_direct(sb, mnt, sbi, do_now);
|
|
Packit |
8480eb |
+ dentry = autofs4_expire_direct(sb, mnt, sbi, when);
|
|
Packit |
8480eb |
else
|
|
Packit |
8480eb |
- dentry = autofs4_expire_indirect(sb, mnt, sbi, do_now);
|
|
Packit |
8480eb |
+ dentry = autofs4_expire_indirect(sb, mnt, sbi, when);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (dentry) {
|
|
Packit |
8480eb |
struct autofs_info *ino = autofs4_dentry_ino(dentry);
|
|
Packit |
8480eb |
@@ -516,3 +512,16 @@ int autofs4_expire_multi(struct super_bl
|
|
Packit |
8480eb |
return ret;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
+/* Call repeatedly until it returns -EAGAIN, meaning there's nothing
|
|
Packit |
8480eb |
+ more to be done */
|
|
Packit |
8480eb |
+int autofs4_expire_multi(struct super_block *sb, struct vfsmount *mnt,
|
|
Packit |
8480eb |
+ struct autofs_sb_info *sbi, int __user *arg)
|
|
Packit |
8480eb |
+{
|
|
Packit |
8480eb |
+ int do_now = 0;
|
|
Packit |
8480eb |
+
|
|
Packit |
8480eb |
+ if (arg && get_user(do_now, arg))
|
|
Packit |
8480eb |
+ return -EFAULT;
|
|
Packit |
8480eb |
+
|
|
Packit |
8480eb |
+ return autofs4_do_expire_multi(sb, mnt, sbi, do_now);
|
|
Packit |
8480eb |
+}
|
|
Packit |
8480eb |
+
|
|
Packit |
8480eb |
--- linux-2.6.29.orig/fs/autofs4/root.c
|
|
Packit |
8480eb |
+++ linux-2.6.29/fs/autofs4/root.c
|
|
Packit |
8480eb |
@@ -485,22 +485,6 @@ static struct dentry *autofs4_lookup(str
|
|
Packit |
8480eb |
DPRINTK("pid = %u, pgrp = %u, catatonic = %d, oz_mode = %d",
|
|
Packit |
8480eb |
current->pid, task_pgrp_nr(current), sbi->catatonic, oz_mode);
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
- expiring = autofs4_lookup_expiring(sbi, dentry->d_parent, &dentry->d_name);
|
|
Packit |
8480eb |
- if (expiring) {
|
|
Packit |
8480eb |
- /*
|
|
Packit |
8480eb |
- * If we are racing with expire the request might not
|
|
Packit |
8480eb |
- * be quite complete but the directory has been removed
|
|
Packit |
8480eb |
- * so it must have been successful, so just wait for it.
|
|
Packit |
8480eb |
- */
|
|
Packit |
8480eb |
- ino = autofs4_dentry_ino(expiring);
|
|
Packit |
8480eb |
- autofs4_expire_wait(expiring);
|
|
Packit |
8480eb |
- spin_lock(&sbi->lookup_lock);
|
|
Packit |
8480eb |
- if (!list_empty(&ino->expiring))
|
|
Packit |
8480eb |
- list_del_init(&ino->expiring);
|
|
Packit |
8480eb |
- spin_unlock(&sbi->lookup_lock);
|
|
Packit |
8480eb |
- dput(expiring);
|
|
Packit |
8480eb |
- }
|
|
Packit |
8480eb |
-
|
|
Packit |
8480eb |
unhashed = autofs4_lookup_active(sbi, dentry->d_parent, &dentry->d_name);
|
|
Packit |
8480eb |
if (unhashed)
|
|
Packit |
8480eb |
dentry = unhashed;
|
|
Packit |
8480eb |
@@ -538,14 +522,31 @@ static struct dentry *autofs4_lookup(str
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
if (!oz_mode) {
|
|
Packit |
8480eb |
+ mutex_unlock(&dir->i_mutex);
|
|
Packit |
8480eb |
+ expiring = autofs4_lookup_expiring(sbi,
|
|
Packit |
8480eb |
+ dentry->d_parent,
|
|
Packit |
8480eb |
+ &dentry->d_name);
|
|
Packit |
8480eb |
+ if (expiring) {
|
|
Packit |
8480eb |
+ /*
|
|
Packit |
8480eb |
+ * If we are racing with expire the request might not
|
|
Packit |
8480eb |
+ * be quite complete but the directory has been removed
|
|
Packit |
8480eb |
+ * so it must have been successful, so just wait for it.
|
|
Packit |
8480eb |
+ */
|
|
Packit |
8480eb |
+ ino = autofs4_dentry_ino(expiring);
|
|
Packit |
8480eb |
+ autofs4_expire_wait(expiring);
|
|
Packit |
8480eb |
+ spin_lock(&sbi->lookup_lock);
|
|
Packit |
8480eb |
+ if (!list_empty(&ino->expiring))
|
|
Packit |
8480eb |
+ list_del_init(&ino->expiring);
|
|
Packit |
8480eb |
+ spin_unlock(&sbi->lookup_lock);
|
|
Packit |
8480eb |
+ dput(expiring);
|
|
Packit |
8480eb |
+ }
|
|
Packit |
8480eb |
+
|
|
Packit |
8480eb |
spin_lock(&dentry->d_lock);
|
|
Packit |
8480eb |
dentry->d_flags |= DCACHE_AUTOFS_PENDING;
|
|
Packit |
8480eb |
spin_unlock(&dentry->d_lock);
|
|
Packit |
8480eb |
- if (dentry->d_op && dentry->d_op->d_revalidate) {
|
|
Packit |
8480eb |
- mutex_unlock(&dir->i_mutex);
|
|
Packit |
8480eb |
+ if (dentry->d_op && dentry->d_op->d_revalidate)
|
|
Packit |
8480eb |
(dentry->d_op->d_revalidate)(dentry, nd);
|
|
Packit |
8480eb |
- mutex_lock(&dir->i_mutex);
|
|
Packit |
8480eb |
- }
|
|
Packit |
8480eb |
+ mutex_lock(&dir->i_mutex);
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
/*
|
|
Packit |
8480eb |
--- linux-2.6.29.orig/include/linux/auto_dev-ioctl.h
|
|
Packit |
8480eb |
+++ linux-2.6.29/include/linux/auto_dev-ioctl.h
|
|
Packit |
8480eb |
@@ -10,8 +10,13 @@
|
|
Packit |
8480eb |
#ifndef _LINUX_AUTO_DEV_IOCTL_H
|
|
Packit |
8480eb |
#define _LINUX_AUTO_DEV_IOCTL_H
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
+#include <linux/auto_fs.h>
|
|
Packit |
8480eb |
+
|
|
Packit |
8480eb |
+#ifdef __KERNEL__
|
|
Packit |
8480eb |
#include <linux/string.h>
|
|
Packit |
8480eb |
-#include <linux/types.h>
|
|
Packit |
8480eb |
+#else
|
|
Packit |
8480eb |
+#include <string.h>
|
|
Packit |
8480eb |
+#endif /* __KERNEL__ */
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
#define AUTOFS_DEVICE_NAME "autofs"
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
--- linux-2.6.29.orig/include/linux/auto_fs.h
|
|
Packit |
8480eb |
+++ linux-2.6.29/include/linux/auto_fs.h
|
|
Packit |
8480eb |
@@ -17,11 +17,13 @@
|
|
Packit |
8480eb |
#ifdef __KERNEL__
|
|
Packit |
8480eb |
#include <linux/fs.h>
|
|
Packit |
8480eb |
#include <linux/limits.h>
|
|
Packit |
8480eb |
+#include <linux/types.h>
|
|
Packit |
8480eb |
+#include <linux/ioctl.h>
|
|
Packit |
8480eb |
+#else
|
|
Packit |
8480eb |
#include <asm/types.h>
|
|
Packit |
8480eb |
+#include <sys/ioctl.h>
|
|
Packit |
8480eb |
#endif /* __KERNEL__ */
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
-#include <linux/ioctl.h>
|
|
Packit |
8480eb |
-
|
|
Packit |
8480eb |
/* This file describes autofs v3 */
|
|
Packit |
8480eb |
#define AUTOFS_PROTO_VERSION 3
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
--- linux-2.6.29.orig/fs/autofs4/waitq.c
|
|
Packit |
8480eb |
+++ linux-2.6.29/fs/autofs4/waitq.c
|
|
Packit |
8480eb |
@@ -297,20 +297,14 @@ static int validate_request(struct autof
|
|
Packit |
8480eb |
*/
|
|
Packit |
8480eb |
if (notify == NFY_MOUNT) {
|
|
Packit |
8480eb |
/*
|
|
Packit |
8480eb |
- * If the dentry isn't hashed just go ahead and try the
|
|
Packit |
8480eb |
- * mount again with a new wait (not much else we can do).
|
|
Packit |
8480eb |
- */
|
|
Packit |
8480eb |
- if (!d_unhashed(dentry)) {
|
|
Packit |
8480eb |
- /*
|
|
Packit |
8480eb |
- * But if the dentry is hashed, that means that we
|
|
Packit |
8480eb |
- * got here through the revalidate path. Thus, we
|
|
Packit |
8480eb |
- * need to check if the dentry has been mounted
|
|
Packit |
8480eb |
- * while we waited on the wq_mutex. If it has,
|
|
Packit |
8480eb |
- * simply return success.
|
|
Packit |
8480eb |
- */
|
|
Packit |
8480eb |
- if (d_mountpoint(dentry))
|
|
Packit |
8480eb |
- return 0;
|
|
Packit |
8480eb |
- }
|
|
Packit |
8480eb |
+ * If the dentry was successfully mounted while we slept
|
|
Packit |
8480eb |
+ * on the wait queue mutex we can return success. If it
|
|
Packit |
8480eb |
+ * isn't mounted (doesn't have submounts for the case of
|
|
Packit |
8480eb |
+ * a multi-mount with no mount at it's base) we can
|
|
Packit |
8480eb |
+ * continue on and create a new request.
|
|
Packit |
8480eb |
+ */
|
|
Packit |
8480eb |
+ if (have_submounts(dentry))
|
|
Packit |
8480eb |
+ return 0;
|
|
Packit |
8480eb |
}
|
|
Packit |
8480eb |
|
|
Packit |
8480eb |
return 1;
|