2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 #include <afsconfig.h>
11 #include "afs/param.h"
13 #include "afs/sysincludes.h" /*Standard vendor system headers */
14 #include "afsincludes.h" /*AFS-based standard headers */
16 #include "osi_compat.h"
19 TryEvictDentries(struct vcache *avc)
21 #ifndef D_INVALIDATE_IS_VOID
22 struct dentry *dentry;
24 struct inode *inode = AFSTOV(avc);
25 #if defined(D_ALIAS_IS_HLIST) && !defined(HLIST_ITERATOR_NO_NODE)
29 #if defined(D_INVALIDATE_IS_VOID)
30 /* At this kernel level, d_invalidate always succeeds;
31 * that is, it will now invalidate even an active directory,
32 * Therefore we must use a different method to evict dentries.
34 d_prune_aliases(inode);
36 #if defined(HAVE_DCACHE_LOCK)
37 spin_lock(&dcache_lock);
40 list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
41 if (d_unhashed(dentry))
45 spin_unlock(&dcache_lock);
46 if (d_invalidate(dentry) == -EBUSY) {
48 /* perhaps lock and try to continue? (use cur as head?) */
52 spin_lock(&dcache_lock);
55 spin_unlock(&dcache_lock);
56 #else /* HAVE_DCACHE_LOCK */
57 spin_lock(&inode->i_lock);
60 #if defined(D_ALIAS_IS_HLIST)
61 # if defined(HLIST_ITERATOR_NO_NODE)
62 hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
64 hlist_for_each_entry(dentry, p, &inode->i_dentry, d_alias) {
67 list_for_each_entry(dentry, &inode->i_dentry, d_alias) {
69 spin_lock(&dentry->d_lock);
70 if (d_unhashed(dentry)) {
71 spin_unlock(&dentry->d_lock);
74 spin_unlock(&dentry->d_lock);
77 spin_unlock(&inode->i_lock);
78 if (afs_d_invalidate(dentry) == -EBUSY) {
80 /* perhaps lock and try to continue? (use cur as head?) */
84 spin_lock(&inode->i_lock);
87 spin_unlock(&inode->i_lock);
88 #endif /* HAVE_DCACHE_LOCK */
90 #endif /* D_INVALIDATE_IS_VOID */
96 osi_TryEvictVCache(struct vcache *avc, int *slept, int defersleep)
100 /* First, see if we can evict the inode from the dcache */
101 if (defersleep && avc != afs_globalVp && VREFCOUNT(avc) > 1
102 && avc->opens == 0) {
105 ReleaseWriteLock(&afs_xvcache);
108 TryEvictDentries(avc);
111 ObtainWriteLock(&afs_xvcache, 733);
115 /* See if we can evict it from the VLRUQ */
116 if (VREFCOUNT_GT(avc, 0) && !VREFCOUNT_GT(avc, 1) && avc->opens == 0
117 && (avc->f.states & CUnlinkedDel) == 0) {
118 int didsleep = *slept;
120 code = afs_FlushVCache(avc, slept);
121 /* flushvcache wipes slept; restore slept if we did before */
139 ip = new_inode(afs_globalVFS);
141 osi_Panic("afs_NewVCache: no more inodes");
143 #if defined(STRUCT_SUPER_OPERATIONS_HAS_ALLOC_INODE)
146 tvc = afs_osi_Alloc(sizeof(struct vcache));
147 ip->u.generic_ip = tvc;
151 INIT_LIST_HEAD(&tvc->pagewriters);
152 spin_lock_init(&tvc->pagewriter_lock);
158 osi_PrePopulateVCache(struct vcache *avc)
161 memset(&(avc->f), 0, sizeof(struct fvcache));
166 osi_AttachVnode(struct vcache *avc, int seq)
172 osi_PostPopulateVCache(struct vcache *avc)
178 * osi_ResetRootVCache - Reset the root vcache
179 * Reset the dentry associated with the afs root.
180 * Called from afs_CheckRootVolume when we notice that
181 * the root volume ID has changed.
183 * @volid: volume ID for the afs root
186 osi_ResetRootVCache(afs_uint32 volid)
188 struct vrequest *treq = NULL;
193 struct inode *root = AFSTOV(afs_globalVp);
195 afs_rootFid.Fid.Volume = volid;
196 afs_rootFid.Fid.Vnode = 1;
197 afs_rootFid.Fid.Unique = 1;
200 if (afs_CreateReq(&treq, credp))
202 vcp = afs_GetVCache(&afs_rootFid, treq, NULL, NULL);
205 afs_getattr(vcp, &vattr, credp);
206 afs_fill_inode(AFSTOV(vcp), &vattr);
208 dp = d_find_alias(root);
210 #if defined(HAVE_DCACHE_LOCK)
211 spin_lock(&dcache_lock);
213 spin_lock(&AFSTOV(vcp)->i_lock);
215 spin_lock(&dp->d_lock);
216 #if defined(D_ALIAS_IS_HLIST)
217 hlist_del_init(&dp->d_alias);
218 hlist_add_head(&dp->d_alias, &(AFSTOV(vcp)->i_dentry));
220 list_del_init(&dp->d_alias);
221 list_add(&dp->d_alias, &(AFSTOV(vcp)->i_dentry));
223 dp->d_inode = AFSTOV(vcp);
224 spin_unlock(&dp->d_lock);
225 #if defined(HAVE_DCACHE_LOCK)
226 spin_unlock(&dcache_lock);
228 spin_unlock(&AFSTOV(vcp)->i_lock);
236 afs_DestroyReq(treq);