- 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);