4 * Copyright (C) 1997 by Bill Hawes
6 * Routines to support directory cacheing using the page cache.
7 * This cache code is almost directly taken from ncpfs.
9 * Please add a note about your changes to smbfs in the ChangeLog file.
12 #include <linux/time.h>
13 #include <linux/errno.h>
14 #include <linux/kernel.h>
16 #include <linux/pagemap.h>
17 #include <linux/net.h>
22 #include "smb_debug.h"
26 * Force the next attempt to use the cache to be a timeout.
27 * If we can't find the page that's fine, it will cause a refresh.
30 smb_invalid_dir_cache(struct inode * dir)
32 struct smb_sb_info *server = server_from_inode(dir);
33 union smb_dir_cache *cache = NULL;
34 struct page *page = NULL;
36 page = grab_cache_page(&dir->i_data, 0);
40 if (!PageUptodate(page))
44 cache->head.time = jiffies - SMB_MAX_AGE(server);
47 SetPageUptodate(page);
50 page_cache_release(page);
56 * Mark all dentries for 'parent' as invalid, forcing them to be re-read
59 smb_invalidate_dircache_entries(struct dentry *parent)
61 struct smb_sb_info *server = server_from_dentry(parent);
62 struct list_head *next;
63 struct dentry *dentry;
65 spin_lock(&dcache_lock);
66 spin_lock(&parent->d_lock);
67 next = parent->d_subdirs.next;
68 while (next != &parent->d_subdirs) {
69 dentry = list_entry(next, struct dentry, d_u.d_child);
70 dentry->d_fsdata = NULL;
71 smb_age_dentry(server, dentry);
74 spin_unlock(&parent->d_lock);
75 spin_unlock(&dcache_lock);
79 * dget, but require that fpos and parent matches what the dentry contains.
80 * dentry is not known to be a valid pointer at entry.
83 smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos)
85 struct dentry *dent = dentry;
86 struct list_head *next;
88 if (d_validate(dent, parent)) {
89 if (dent->d_name.len <= SMB_MAXNAMELEN &&
90 (unsigned long)dent->d_fsdata == fpos) {
100 /* If a pointer is invalid, we search the dentry. */
101 spin_lock(&dcache_lock);
102 spin_lock(&parent->d_lock);
103 next = parent->d_subdirs.next;
104 while (next != &parent->d_subdirs) {
105 dent = list_entry(next, struct dentry, d_u.d_child);
106 if ((unsigned long)dent->d_fsdata == fpos) {
117 spin_unlock(&parent->d_lock);
118 spin_unlock(&dcache_lock);
124 * Create dentry/inode for this file and add it to the dircache.
127 smb_fill_cache(struct file *filp, void *dirent, filldir_t filldir,
128 struct smb_cache_control *ctrl, struct qstr *qname,
129 struct smb_fattr *entry)
131 struct dentry *newdent, *dentry = filp->f_path.dentry;
132 struct inode *newino, *inode = dentry->d_inode;
133 struct smb_cache_control ctl = *ctrl;
138 qname->hash = full_name_hash(qname->name, qname->len);
140 if (dentry->d_op && dentry->d_op->d_hash)
141 if (dentry->d_op->d_hash(dentry, inode, qname) != 0)
144 newdent = d_lookup(dentry, qname);
147 newdent = d_alloc(dentry, qname);
152 /* dir i_mutex is locked because we're in readdir */
153 dentry_update_name_case(newdent, qname);
156 if (!newdent->d_inode) {
157 smb_renew_times(newdent);
158 entry->f_ino = iunique(inode->i_sb, 2);
159 newino = smb_iget(inode->i_sb, entry);
161 smb_new_dentry(newdent);
162 d_instantiate(newdent, newino);
167 smb_set_inode_attr(newdent->d_inode, entry);
169 if (newdent->d_inode) {
170 ino = newdent->d_inode->i_ino;
171 newdent->d_fsdata = (void *) ctl.fpos;
172 smb_new_dentry(newdent);
175 if (ctl.idx >= SMB_DIRCACHE_SIZE) {
178 SetPageUptodate(ctl.page);
179 unlock_page(ctl.page);
180 page_cache_release(ctl.page);
183 ctl.idx -= SMB_DIRCACHE_SIZE;
185 ctl.page = grab_cache_page(&inode->i_data, ctl.ofs);
187 ctl.cache = kmap(ctl.page);
190 ctl.cache->dentry[ctl.idx] = newdent;
198 if (!ctl.filled && (ctl.fpos == filp->f_pos)) {
200 ino = find_inode_number(dentry, qname);
202 ino = iunique(inode->i_sb, 2);
203 ctl.filled = filldir(dirent, qname->name, qname->len,
204 filp->f_pos, ino, DT_UNKNOWN);
211 return (ctl.valid || !ctl.filled);