summaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorMiguel de Icaza <miguel@nuclecu.unam.mx>1997-08-06 19:14:48 +0000
committerMiguel de Icaza <miguel@nuclecu.unam.mx>1997-08-06 19:14:48 +0000
commite2819e52a162873ff5061de81bb749831bdb5de9 (patch)
tree6067ea700202750ba335a423696f2972700e5f76 /fs/nfs/dir.c
parent17a005074429bbf143e40401f405ae4363e56828 (diff)
Merge to 2.1.38.
IMPORTANT NOTE: I could not figure out what information is the one that should be used for the following files (ie, those that were in our tree, or those that came from Linus' patch), please, check these: include/asm-mips/jazz.h include/asm-mips/jazzdma.h include/asm-mips/ioctls.h
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c35
1 files changed, 34 insertions, 1 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index b10331c6a..83546d460 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -326,7 +326,28 @@ nfs_free_dircache(void)
cache->entry = NULL;
}
}
-
+
+/*
+ * This is called every time the dcache has a lookup hit,
+ * and we should check whether we can really trust that
+ * lookup.
+ *
+ * NOTE! The hit can be a negative hit too, don't assume
+ * we have an inode!
+ *
+ * The decision to drop the dentry should probably be
+ * smarter than this. Right now we believe in directories
+ * for 10 seconds, and in normal files for five..
+ */
+static int nfs_lookup_revalidate(struct dentry * dentry)
+{
+ unsigned long time = jiffies - dentry->d_time;
+ unsigned long max = 5*HZ;
+
+ if (dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode))
+ max = 10*HZ;
+ return time < max;
+}
static int nfs_lookup(struct inode *dir, struct dentry * dentry)
{
@@ -358,6 +379,8 @@ static int nfs_lookup(struct inode *dir, struct dentry * dentry)
} else if (error != -ENOENT)
return error;
+ dentry->d_time = jiffies;
+ dentry->d_revalidate = nfs_lookup_revalidate;
d_add(dentry, inode);
return 0;
}
@@ -394,6 +417,7 @@ static int nfs_create(struct inode *dir, struct dentry * dentry, int mode)
if (!inode)
return -EACCES;
+ nfs_invalidate_dircache(dir);
d_instantiate(dentry, inode);
return 0;
}
@@ -433,6 +457,7 @@ static int nfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int rde
if (!inode)
return -EACCES;
+ nfs_invalidate_dircache(dir);
d_instantiate(dentry, inode);
return 0;
}
@@ -470,6 +495,7 @@ static int nfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
if (!inode)
return -EACCES;
+ nfs_invalidate_dircache(dir);
d_instantiate(dentry, inode);
return 0;
}
@@ -493,6 +519,7 @@ static int nfs_rmdir(struct inode *dir, struct dentry *dentry)
if (error)
return error;
+ nfs_invalidate_dircache(dir);
d_delete(dentry);
return 0;
}
@@ -520,6 +547,7 @@ static int nfs_unlink(struct inode *dir, struct dentry *dentry)
if (error)
return error;
+ nfs_invalidate_dircache(dir);
d_delete(dentry);
return 0;
}
@@ -560,6 +588,7 @@ static int nfs_symlink(struct inode *dir, struct dentry *dentry, const char *sym
if (!inode)
return -EACCES;
+ nfs_invalidate_dircache(dir);
d_instantiate(dentry, inode);
return 0;
}
@@ -586,6 +615,7 @@ static int nfs_link(struct inode *inode, struct inode *dir, struct dentry *dentr
if (error)
return error;
+ nfs_invalidate_dircache(dir);
inode->i_count++;
d_instantiate(dentry, inode);
return 0;
@@ -629,6 +659,9 @@ static int nfs_rename(struct inode *old_dir, struct dentry *old_dentry,
if (error)
return error;
+ nfs_invalidate_dircache(old_dir);
+ nfs_invalidate_dircache(new_dir);
+
/* Update the dcache */
d_move(old_dentry, new_dentry->d_parent, &new_dentry->d_name);
d_delete(new_dentry);