Blame patches/autofs4-2.6.29-v5-update-20090903.patch

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;