patch-2.1.48 linux/fs/autofs/root.c

Next file: linux/fs/autofs/symlink.c
Previous file: linux/fs/autofs/inode.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.47/linux/fs/autofs/root.c linux/fs/autofs/root.c
@@ -24,16 +24,20 @@
 static int autofs_root_ioctl(struct inode *, struct file *,unsigned int,unsigned long);
 
 static struct file_operations autofs_root_operations = {
-        NULL,                   /* lseek */
+        NULL,                   /* llseek */
         NULL,                   /* read */
         NULL,                   /* write */
         autofs_root_readdir,    /* readdir */
-        NULL,                   /* select */
+        NULL,                   /* poll */
         autofs_root_ioctl,	/* ioctl */
         NULL,                   /* mmap */
         NULL,                   /* open */
         NULL,                   /* release */
-        NULL                    /* fsync */
+        NULL,			/* fsync */
+	NULL,			/* fasync */
+	NULL,			/* check_media_change */
+	NULL,			/* revalidate */
+	NULL			/* lock */
 };
 
 struct inode_operations autofs_root_inode_operations = {
@@ -53,7 +57,10 @@
         NULL,                   /* writepage */
         NULL,                   /* bmap */
         NULL,                   /* truncate */
-        NULL                    /* permission */
+        NULL,			/* permission */
+	NULL,			/* smap */
+	NULL,			/* updatepage */
+	NULL			/* revalidate */
 };
 
 static int autofs_root_readdir(struct inode *inode, struct file *filp,
@@ -97,24 +104,31 @@
 {
 	struct inode * inode;
 	struct autofs_dir_ent *ent;
-	
+
 	while (!(ent = autofs_hash_lookup(&sbi->dirhash, &dentry->d_name))) {
 		int status = autofs_wait(sbi, &dentry->d_name);
 
 		/* Turn this into a real negative dentry? */
 		if (status == -ENOENT) {
-			dentry->d_flags = 0;
-			return 0;
+			dentry->d_time = jiffies + AUTOFS_NEGATIVE_TIMEOUT;
+			dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
+			return 1;
+		} else if (status) {
+			/* Return a negative dentry, but leave it "pending" */
+			return 1;
 		}
-		if (status)
-			return status;
 	}
 
+	/* Abuse this field as a pointer to the directory entry, used to
+	   find the expire list pointers */
+	dentry->d_time = (unsigned long) ent;
+	
 	if (!dentry->d_inode) {
 		inode = iget(sb, ent->ino);
-		if (!inode)
-			return -EACCES;
-
+		if (!inode) {
+			/* Failed, but leave pending for next time */
+			return 1;
+		}
 		dentry->d_inode = inode;
 	}
 
@@ -122,8 +136,11 @@
 		while (dentry == dentry->d_mounts)
 			schedule();
 	}
-	dentry->d_flags = 0;
-	return 0;
+
+	autofs_update_usage(&sbi->dirhash,ent);
+
+	dentry->d_flags &= ~DCACHE_AUTOFS_PENDING;
+	return 1;
 }
 
 
@@ -133,28 +150,30 @@
  * yet completely filled in, and revalidate has to delay such
  * lookups..
  */
-static struct dentry * autofs_revalidate(struct dentry * dentry)
+static int autofs_revalidate(struct dentry * dentry)
 {
 	struct autofs_sb_info *sbi;
 	struct inode * dir = dentry->d_parent->d_inode;
+	struct autofs_dir_ent *ent;
 
 	sbi = (struct autofs_sb_info *) dir->i_sb->u.generic_sbp;
 
-	/* Incomplete dentry? */
-	if (dentry->d_flags) {
+	/* Pending dentry */
+	if (dentry->d_flags & DCACHE_AUTOFS_PENDING) {
 		if (autofs_oz_mode(sbi))
-			return dentry;
+			return 1;
 
-		try_to_fill_dentry(dentry, dir->i_sb, sbi);
-		return dentry;
+		return try_to_fill_dentry(dentry, dir->i_sb, sbi);
 	}
 
-	/* Negative dentry.. Should we time these out? */
+	/* Negative dentry.. invalidate if "old" */
 	if (!dentry->d_inode)
-		return dentry;
+		return (dentry->d_time - jiffies <= AUTOFS_NEGATIVE_TIMEOUT);
 
-	/* We should update the usage stuff here.. */
-	return dentry;
+	/* Update the usage list */
+	ent = (struct autofs_dir_ent *) dentry->d_time;
+	autofs_update_usage(&sbi->dirhash,ent);
+	return 1;
 }
 
 static int autofs_root_lookup(struct inode *dir, struct dentry * dentry)
@@ -186,12 +205,13 @@
 	 * We need to do this before we release the directory semaphore.
 	 */
 	dentry->d_revalidate = autofs_revalidate;
-	dentry->d_flags = 1;
+	dentry->d_flags |= DCACHE_AUTOFS_PENDING;
 	d_add(dentry, NULL);
 
 	up(&dir->i_sem);
 	autofs_revalidate(dentry);
 	down(&dir->i_sem);
+	
 	return 0;
 }
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov