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
- Lines: 146
- Date:
Wed Jul 30 20:53:50 1997
- Orig file:
v2.1.47/linux/fs/autofs/root.c
- Orig date:
Thu Jul 17 10:06:06 1997
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