aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@fys.uio.no>2005-01-04 21:36:52 +0100
committerTrond Myklebust <trond.myklebust@fys.uio.no>2005-01-04 21:36:52 +0100
commit14a98a0292d01bb28c33d0aee5accf1a5b19629c (patch)
treea07d26284d90f40ab5c2bc6f7b46d748accdbf58 /fs
parent49deafa1b3335dca26b54e8c1cbec2d849199b7b (diff)
downloadhistory-14a98a0292d01bb28c33d0aee5accf1a5b19629c.tar.gz
NFS: The fact that readdirplus calls now create dentries from within readdir
calls renders nfs_cached_lookup() obsolete. Signed-off-by: Trond Myklebust <trond.myklebust@fys.uio.no>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/dir.c112
1 files changed, 6 insertions, 106 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index c09d9db3cb9111..8a1e63629d6232 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -40,8 +40,6 @@
static int nfs_opendir(struct inode *, struct file *);
static int nfs_readdir(struct file *, void *, filldir_t);
static struct dentry *nfs_lookup(struct inode *, struct dentry *, struct nameidata *);
-static int nfs_cached_lookup(struct inode *, struct dentry *,
- struct nfs_fh *, struct nfs_fattr *);
static int nfs_create(struct inode *, struct dentry *, int, struct nameidata *);
static int nfs_mkdir(struct inode *, struct dentry *, int);
static int nfs_rmdir(struct inode *, struct dentry *);
@@ -613,24 +611,10 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
goto out_valid;
}
- /*
- * Note: we're not holding inode->i_sem and so may be racing with
- * operations that change the directory. We therefore save the
- * change attribute *before* we do the RPC call.
- */
- verifier = nfs_save_change_attribute(dir);
- error = nfs_cached_lookup(dir, dentry, &fhandle, &fattr);
- if (!error) {
- if (nfs_compare_fh(NFS_FH(inode), &fhandle))
- goto out_bad;
- if (nfs_lookup_verify_inode(inode, isopen))
- goto out_zap_parent;
- goto out_valid_renew;
- }
-
if (NFS_STALE(inode))
goto out_bad;
+ verifier = nfs_save_change_attribute(dir);
error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
if (error)
goto out_bad;
@@ -639,7 +623,6 @@ static int nfs_lookup_revalidate(struct dentry * dentry, struct nameidata *nd)
if ((error = nfs_refresh_inode(inode, &fattr)) != 0)
goto out_bad;
- out_valid_renew:
nfs_renew_times(dentry);
nfs_set_verifier(dentry, verifier);
out_valid:
@@ -744,15 +727,11 @@ static struct dentry *nfs_lookup(struct inode *dir, struct dentry * dentry, stru
if (nfs_is_exclusive_create(dir, nd))
goto no_entry;
- error = nfs_cached_lookup(dir, dentry, &fhandle, &fattr);
- if (error != 0) {
- error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name,
- &fhandle, &fattr);
- if (error == -ENOENT)
- goto no_entry;
- if (error != 0)
- goto out_unlock;
- }
+ error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
+ if (error == -ENOENT)
+ goto no_entry;
+ if (error != 0)
+ goto out_unlock;
error = -EACCES;
inode = nfs_fhget(dentry->d_sb, &fhandle, &fattr);
if (!inode)
@@ -947,85 +926,6 @@ static struct dentry *nfs_readdir_lookup(nfs_readdir_descriptor_t *desc)
return dentry;
}
-static inline
-int find_dirent_name(nfs_readdir_descriptor_t *desc, struct page *page, struct dentry *dentry)
-{
- struct nfs_entry *entry = desc->entry;
- int status;
-
- while((status = dir_decode(desc)) == 0) {
- if (entry->len != dentry->d_name.len)
- continue;
- if (memcmp(entry->name, dentry->d_name.name, entry->len))
- continue;
- if (!(entry->fattr->valid & NFS_ATTR_FATTR))
- continue;
- break;
- }
- return status;
-}
-
-/*
- * Use the cached Readdirplus results in order to avoid a LOOKUP call
- * whenever we believe that the parent directory has not changed.
- *
- * We assume that any file creation/rename changes the directory mtime.
- * As this results in a page cache invalidation whenever it occurs,
- * we don't require any other tests for cache coherency.
- */
-static
-int nfs_cached_lookup(struct inode *dir, struct dentry *dentry,
- struct nfs_fh *fh, struct nfs_fattr *fattr)
-{
- nfs_readdir_descriptor_t desc;
- struct nfs_server *server;
- struct nfs_entry entry;
- struct page *page;
- unsigned long timestamp;
- int res;
-
- if (!NFS_USE_READDIRPLUS(dir))
- return -ENOENT;
- server = NFS_SERVER(dir);
- /* Don't use readdirplus unless the cache is stable */
- if ((server->flags & NFS_MOUNT_NOAC) != 0
- || nfs_caches_unstable(dir)
- || nfs_attribute_timeout(dir))
- return -ENOENT;
- if ((NFS_FLAGS(dir) & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA)) != 0)
- return -ENOENT;
- timestamp = NFS_I(dir)->readdir_timestamp;
-
- entry.fh = fh;
- entry.fattr = fattr;
-
- desc.decode = NFS_PROTO(dir)->decode_dirent;
- desc.entry = &entry;
- desc.page_index = 0;
- desc.plus = 1;
-
- for(;(page = find_get_page(dir->i_mapping, desc.page_index)); desc.page_index++) {
-
- res = -EIO;
- if (PageUptodate(page)) {
- void * kaddr = kmap_atomic(page, KM_USER0);
- desc.ptr = kaddr;
- res = find_dirent_name(&desc, page, dentry);
- kunmap_atomic(kaddr, KM_USER0);
- }
- page_cache_release(page);
-
- if (res == 0)
- goto out_found;
- if (res != -EAGAIN)
- break;
- }
- return -ENOENT;
- out_found:
- fattr->timestamp = timestamp;
- return 0;
-}
-
/*
* Code common to create, mkdir, and mknod.
*/