1 /* 2 * Copyright (c) 2002 Red Hat, Inc. All rights reserved. 3 * 4 * This software may be freely redistributed under the terms of the 5 * GNU General Public License. 6 * 7 * You should have received a copy of the GNU General Public License 8 * along with this program; if not, write to the Free Software 9 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 10 * 11 * Authors: David Woodhouse <dwmw2@cambridge.redhat.com> 12 * David Howells <dhowells@redhat.com> 13 * 14 */ 15 16 #include <linux/kernel.h> 17 #include <linux/module.h> 18 #include <linux/init.h> 19 #include "server.h" 20 #include "vnode.h" 21 #include "internal.h" 22 23 /*****************************************************************************/ 24 /* 25 * allow the fileserver to request callback state (re-)initialisation 26 */ 27 int SRXAFSCM_InitCallBackState(struct afs_server *server) 28 { 29 struct list_head callbacks; 30 31 _enter("%p", server); 32 33 INIT_LIST_HEAD(&callbacks); 34 35 /* transfer the callback list from the server to a temp holding area */ 36 spin_lock(&server->cb_lock); 37 38 list_add(&callbacks, &server->cb_promises); 39 list_del_init(&server->cb_promises); 40 41 /* munch our way through the list, grabbing the inode, dropping all the 42 * locks and regetting them in the right order 43 */ 44 while (!list_empty(&callbacks)) { 45 struct afs_vnode *vnode; 46 struct inode *inode; 47 48 vnode = list_entry(callbacks.next, struct afs_vnode, cb_link); 49 list_del_init(&vnode->cb_link); 50 51 /* try and grab the inode - may fail */ 52 inode = igrab(AFS_VNODE_TO_I(vnode)); 53 if (inode) { 54 int release = 0; 55 56 spin_unlock(&server->cb_lock); 57 spin_lock(&vnode->lock); 58 59 if (vnode->cb_server == server) { 60 vnode->cb_server = NULL; 61 afs_kafstimod_del_timer(&vnode->cb_timeout); 62 spin_lock(&afs_cb_hash_lock); 63 list_del_init(&vnode->cb_hash_link); 64 spin_unlock(&afs_cb_hash_lock); 65 release = 1; 66 } 67 68 spin_unlock(&vnode->lock); 69 70 iput(inode); 71 afs_put_server(server); 72 73 spin_lock(&server->cb_lock); 74 } 75 } 76 77 spin_unlock(&server->cb_lock); 78 79 _leave(" = 0"); 80 return 0; 81 } /* end SRXAFSCM_InitCallBackState() */ 82 83 /*****************************************************************************/ 84 /* 85 * allow the fileserver to break callback promises 86 */ 87 int SRXAFSCM_CallBack(struct afs_server *server, size_t count, 88 struct afs_callback callbacks[]) 89 { 90 _enter("%p,%u,", server, count); 91 92 for (; count > 0; callbacks++, count--) { 93 struct afs_vnode *vnode = NULL; 94 struct inode *inode = NULL; 95 int valid = 0; 96 97 _debug("- Fid { vl=%08x n=%u u=%u } CB { v=%u x=%u t=%u }", 98 callbacks->fid.vid, 99 callbacks->fid.vnode, 100 callbacks->fid.unique, 101 callbacks->version, 102 callbacks->expiry, 103 callbacks->type 104 ); 105 106 /* find the inode for this fid */ 107 spin_lock(&afs_cb_hash_lock); 108 109 list_for_each_entry(vnode, 110 &afs_cb_hash(server, &callbacks->fid), 111 cb_hash_link) { 112 if (memcmp(&vnode->fid, &callbacks->fid, 113 sizeof(struct afs_fid)) != 0) 114 continue; 115 116 /* right vnode, but is it same server? */ 117 if (vnode->cb_server != server) 118 break; /* no */ 119 120 /* try and nail the inode down */ 121 inode = igrab(AFS_VNODE_TO_I(vnode)); 122 break; 123 } 124 125 spin_unlock(&afs_cb_hash_lock); 126 127 if (inode) { 128 /* we've found the record for this vnode */ 129 spin_lock(&vnode->lock); 130 if (vnode->cb_server == server) { 131 /* the callback _is_ on the calling server */ 132 vnode->cb_server = NULL; 133 valid = 1; 134 135 afs_kafstimod_del_timer(&vnode->cb_timeout); 136 vnode->flags |= AFS_VNODE_CHANGED; 137 138 spin_lock(&server->cb_lock); 139 list_del_init(&vnode->cb_link); 140 spin_unlock(&server->cb_lock); 141 142 spin_lock(&afs_cb_hash_lock); 143 list_del_init(&vnode->cb_hash_link); 144 spin_unlock(&afs_cb_hash_lock); 145 } 146 spin_unlock(&vnode->lock); 147 148 if (valid) { 149 invalidate_remote_inode(inode); 150 afs_put_server(server); 151 } 152 iput(inode); 153 } 154 } 155 156 _leave(" = 0"); 157 return 0; 158 } /* end SRXAFSCM_CallBack() */ 159 160 /*****************************************************************************/ 161 /* 162 * allow the fileserver to see if the cache manager is still alive 163 */ 164 int SRXAFSCM_Probe(struct afs_server *server) 165 { 166 _debug("SRXAFSCM_Probe(%p)\n", server); 167 return 0; 168 } /* end SRXAFSCM_Probe() */ 169