patch-2.2.8 linux/fs/nfs/dir.c
Next file: linux/fs/nfs/file.c
Previous file: linux/fs/ncpfs/dir.c
Back to the patch index
Back to the overall index
- Lines: 131
- Date:
Sat May 8 23:18:22 1999
- Orig file:
v2.2.7/linux/fs/nfs/dir.c
- Orig date:
Wed Apr 28 11:37:31 1999
diff -u --recursive --new-file v2.2.7/linux/fs/nfs/dir.c linux/fs/nfs/dir.c
@@ -72,9 +72,9 @@
NULL, /* select - default */
NULL, /* ioctl - default */
NULL, /* mmap */
- NULL, /* no special open is needed */
+ nfs_open, /* open */
NULL, /* flush */
- NULL, /* no special release code */
+ nfs_release, /* release */
NULL /* fsync */
};
@@ -364,7 +364,48 @@
dentry->d_time = jiffies;
}
-#define NFS_REVALIDATE_INTERVAL (5*HZ)
+static inline int nfs_dentry_force_reval(struct dentry *dentry, int flags)
+{
+ struct inode *inode = dentry->d_inode;
+ unsigned long timeout = NFS_ATTRTIMEO(inode);
+
+ /*
+ * If it's the last lookup in a series, we use a stricter
+ * cache consistency check by looking at the parent mtime.
+ *
+ * If it's been modified in the last hour, be really strict.
+ * (This still means that we can avoid doing unnecessary
+ * work on directories like /usr/share/bin etc which basically
+ * never change).
+ */
+ if (!(flags & LOOKUP_CONTINUE)) {
+ long diff = CURRENT_TIME - dentry->d_parent->d_inode->i_mtime;
+
+ if (diff < 15*60)
+ timeout = 0;
+ }
+
+ return time_after(jiffies,dentry->d_time + timeout);
+}
+
+/*
+ * We judge how long we want to trust negative
+ * dentries by looking at the parent inode mtime.
+ *
+ * If mtime is close to present time, we revalidate
+ * more often.
+ */
+static inline int nfs_neg_need_reval(struct dentry *dentry)
+{
+ unsigned long timeout = 30 * HZ;
+ long diff = CURRENT_TIME - dentry->d_parent->d_inode->i_mtime;
+
+ if (diff < 5*60)
+ timeout = 1 * HZ;
+
+ return time_after(jiffies, dentry->d_time + timeout);
+}
+
/*
* This is called every time the dcache has a lookup hit,
* and we should check whether we can really trust that
@@ -377,7 +418,7 @@
* we do a new lookup and verify that the dentry is still
* correct.
*/
-static int nfs_lookup_revalidate(struct dentry * dentry)
+static int nfs_lookup_revalidate(struct dentry * dentry, int flags)
{
struct dentry * parent = dentry->d_parent;
struct inode * inode = dentry->d_inode;
@@ -386,11 +427,15 @@
struct nfs_fattr fattr;
/*
- * If we don't have an inode, let's just assume
- * a 5-second "live" time for negative dentries.
+ * If we don't have an inode, let's look at the parent
+ * directory mtime to get a hint about how often we
+ * should validate things..
*/
- if (!inode)
- goto do_lookup;
+ if (!inode) {
+ if (nfs_neg_need_reval(dentry))
+ goto out_bad;
+ goto out_valid;
+ }
if (is_bad_inode(inode)) {
dfprintk(VFS, "nfs_lookup_validate: %s/%s has dud inode\n",
@@ -398,27 +443,17 @@
goto out_bad;
}
- if (_nfs_revalidate_inode(NFS_DSERVER(dentry), dentry))
- goto out_bad;
-
- if (time_before(jiffies,dentry->d_time+NFS_ATTRTIMEO(inode)))
+ if (IS_ROOT(dentry))
goto out_valid;
- if (IS_ROOT(dentry))
+ if (!nfs_dentry_force_reval(dentry, flags))
goto out_valid;
-do_lookup:
/*
* Do a new lookup and check the dentry attributes.
*/
- error = nfs_proc_lookup(NFS_DSERVER(parent), NFS_FH(parent),
+ error = nfs_proc_lookup(NFS_DSERVER(parent), NFS_FH(parent),
dentry->d_name.name, &fhandle, &fattr);
- if (dentry->d_inode == NULL) {
- if (error == -ENOENT &&
- time_before(jiffies,dentry->d_time+NFS_REVALIDATE_INTERVAL))
- goto out_valid;
- goto out_bad;
- }
if (error)
goto out_bad;
@@ -496,7 +531,7 @@
}
struct dentry_operations nfs_dentry_operations = {
- nfs_lookup_revalidate, /* d_validate(struct dentry *) */
+ nfs_lookup_revalidate, /* d_revalidate(struct dentry *, int) */
NULL, /* d_hash */
NULL, /* d_compare */
nfs_dentry_delete, /* d_delete(struct dentry *) */
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)