From: Ian Kent <raven@themaw.net>

Needed for support coming development plans.


---

 25-akpm/fs/autofs4/autofs_i.h    |    2 +
 25-akpm/fs/autofs4/root.c        |   71 ++++++++++++++++++++++++++++++++++++++-
 25-akpm/include/linux/auto_fs4.h |    8 ++--
 3 files changed, 77 insertions(+), 4 deletions(-)

diff -puN fs/autofs4/autofs_i.h~7-autofs4-2.6.0-extra-20040405 fs/autofs4/autofs_i.h
--- 25/fs/autofs4/autofs_i.h~7-autofs4-2.6.0-extra-20040405	2004-04-18 15:39:20.832946288 -0700
+++ 25-akpm/fs/autofs4/autofs_i.h	2004-04-18 15:39:20.838945376 -0700
@@ -97,6 +97,8 @@ struct autofs_sb_info {
 	int version;
 	int sub_version;
 	unsigned long exp_timeout;
+	int reghost_enabled;
+	int needs_reghost;
 	struct super_block *sb;
 	struct autofs_wait_queue *queues; /* Wait queue pointer */
 };
diff -puN fs/autofs4/root.c~7-autofs4-2.6.0-extra-20040405 fs/autofs4/root.c
--- 25/fs/autofs4/root.c~7-autofs4-2.6.0-extra-20040405	2004-04-18 15:39:20.833946136 -0700
+++ 25-akpm/fs/autofs4/root.c	2004-04-18 15:40:45.690046048 -0700
@@ -28,13 +28,15 @@ static int autofs4_root_ioctl(struct ino
 static int autofs4_dir_open(struct inode *inode, struct file *file);
 static int autofs4_dir_close(struct inode *inode, struct file *file);
 static int autofs4_dir_readdir(struct file * filp, void * dirent, filldir_t filldir);
+static int autofs4_root_readdir(struct file * filp, void * dirent, filldir_t filldir);
 static struct dentry *autofs4_root_lookup(struct inode *,struct dentry *, struct nameidata *);
+static int autofs4_dcache_readdir(struct file *, void *, filldir_t);
 
 struct file_operations autofs4_root_operations = {
 	.open		= dcache_dir_open,
 	.release	= dcache_dir_close,
 	.read		= generic_read_dir,
-	.readdir	= dcache_readdir,
+	.readdir	= autofs4_root_readdir,
 	.ioctl		= autofs4_root_ioctl,
 };
 
@@ -61,6 +63,30 @@ struct inode_operations autofs4_dir_inod
 	.rmdir		= autofs4_dir_rmdir,
 };
 
+static int autofs4_root_readdir(struct file *file, void *dirent,
+				filldir_t filldir)
+{
+	struct autofs_sb_info *sbi = autofs4_sbi(file->f_dentry->d_sb);
+	int oz_mode = autofs4_oz_mode(sbi);
+
+	DPRINTK(("autofs4_root_readdir called, filp->f_pos = %lld\n",
+			file->f_pos));
+
+	/*
+	 * Don't set reghost flag if:
+	 * 1) f_pos is larger than zero -- we've already been here.
+	 * 2) we haven't even enabled reghosting in the 1st place.
+	 * 3) this is the daemon doing a readdir
+	 */
+	if (oz_mode && file->f_pos == 0 && sbi->reghost_enabled)
+		sbi->needs_reghost = 1;
+
+	DPRINTK(("autofs4_root_readdir: needs_reghost = %d\n",
+			sbi->needs_reghost));
+
+	return autofs4_dcache_readdir(file, dirent, filldir);
+}
+
 /* Update usage from here to top of tree, so that scan of
    top-level directories will give a useful result */
 static void autofs4_update_usage(struct dentry *dentry)
@@ -663,6 +689,44 @@ static inline int autofs4_get_protosubve
 }
 
 /*
+ * Tells the daemon whether we need to reghost or not. Also, clears
+ * the reghost_needed flag.
+ */
+static inline int autofs4_ask_reghost(struct autofs_sb_info *sbi, int *p)
+{
+	int status;
+
+	DPRINTK(("autofs_ask_reghost: returning %d\n", sbi->needs_reghost));
+
+	status = put_user(sbi->needs_reghost, p);
+	if ( status )
+		return status;
+
+	sbi->needs_reghost = 0;
+	return 0;
+}
+
+/*
+ * Enable / Disable reghosting ioctl() operation
+ */
+static inline int autofs4_toggle_reghost(struct autofs_sb_info *sbi, int *p)
+{
+	int status;
+	int val;
+
+	status = get_user(val, p);
+
+	DPRINTK(("autofs4_toggle_reghost: reghost = %d\n", val));
+
+	if (status)
+		return status;
+
+	/* turn on/off reghosting, with the val */
+	sbi->reghost_enabled = val;
+	return 0;
+}
+
+/*
 * Tells the daemon whether it can umount the autofs mount.
 */
 static inline int autofs4_ask_umount(struct vfsmount *mnt, int *p)
@@ -725,6 +789,11 @@ static int autofs4_root_ioctl(struct ino
 	case AUTOFS_IOC_SETTIMEOUT:
 		return autofs4_get_set_timeout(sbi,(unsigned long *)arg);
 
+	case AUTOFS_IOC_TOGGLEREGHOST:
+		return autofs4_toggle_reghost(sbi, (int *) arg);
+	case AUTOFS_IOC_ASKREGHOST:
+		return autofs4_ask_reghost(sbi, (int *) arg);
+
 	case AUTOFS_IOC_ASKUMOUNT:
 		return autofs4_ask_umount(filp->f_vfsmnt, (int *) arg);
 
diff -puN include/linux/auto_fs4.h~7-autofs4-2.6.0-extra-20040405 include/linux/auto_fs4.h
--- 25/include/linux/auto_fs4.h~7-autofs4-2.6.0-extra-20040405	2004-04-18 15:39:20.835945832 -0700
+++ 25-akpm/include/linux/auto_fs4.h	2004-04-18 15:39:20.840945072 -0700
@@ -47,9 +47,11 @@ union autofs_packet_union {
 	struct autofs_packet_expire_multi expire_multi;
 };
 
-#define AUTOFS_IOC_EXPIRE_MULTI _IOW(0x93,0x66,int)
-#define AUTOFS_IOC_PROTOSUBVER  _IOR(0x93,0x67,int)
-#define AUTOFS_IOC_ASKUMOUNT	_IOR(0x93,0x70,int)
+#define AUTOFS_IOC_EXPIRE_MULTI		_IOW(0x93,0x66,int)
+#define AUTOFS_IOC_PROTOSUBVER		_IOR(0x93,0x67,int)
+#define AUTOFS_IOC_ASKREGHOST           _IOR(0x93,0x68,int)
+#define AUTOFS_IOC_TOGGLEREGHOST        _IOR(0x93,0x69,int)
+#define AUTOFS_IOC_ASKUMOUNT		_IOR(0x93,0x70,int)
 
 
 #endif /* _LINUX_AUTO_FS4_H */

_