blob: 26a48fea42f47a1812a860f3a4a7e8f9a0a7e3cc [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
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"
Adrian Bunk9f56f742005-11-08 16:56:17 +010022#include "cmservice.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070023
Linus Torvalds1da177e2005-04-16 15:20:36 -070024/*
25 * allow the fileserver to request callback state (re-)initialisation
26 */
27int 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;
David Howellsec268152007-04-26 15:49:28 -070081}
Linus Torvalds1da177e2005-04-16 15:20:36 -070082
Linus Torvalds1da177e2005-04-16 15:20:36 -070083/*
84 * allow the fileserver to break callback promises
85 */
86int SRXAFSCM_CallBack(struct afs_server *server, size_t count,
87 struct afs_callback callbacks[])
88{
89 _enter("%p,%u,", server, count);
90
91 for (; count > 0; callbacks++, count--) {
92 struct afs_vnode *vnode = NULL;
93 struct inode *inode = NULL;
94 int valid = 0;
95
96 _debug("- Fid { vl=%08x n=%u u=%u } CB { v=%u x=%u t=%u }",
97 callbacks->fid.vid,
98 callbacks->fid.vnode,
99 callbacks->fid.unique,
100 callbacks->version,
101 callbacks->expiry,
102 callbacks->type
103 );
104
105 /* find the inode for this fid */
106 spin_lock(&afs_cb_hash_lock);
107
108 list_for_each_entry(vnode,
109 &afs_cb_hash(server, &callbacks->fid),
110 cb_hash_link) {
111 if (memcmp(&vnode->fid, &callbacks->fid,
112 sizeof(struct afs_fid)) != 0)
113 continue;
114
115 /* right vnode, but is it same server? */
116 if (vnode->cb_server != server)
117 break; /* no */
118
119 /* try and nail the inode down */
120 inode = igrab(AFS_VNODE_TO_I(vnode));
121 break;
122 }
123
124 spin_unlock(&afs_cb_hash_lock);
125
126 if (inode) {
127 /* we've found the record for this vnode */
128 spin_lock(&vnode->lock);
129 if (vnode->cb_server == server) {
130 /* the callback _is_ on the calling server */
131 vnode->cb_server = NULL;
132 valid = 1;
133
134 afs_kafstimod_del_timer(&vnode->cb_timeout);
135 vnode->flags |= AFS_VNODE_CHANGED;
136
137 spin_lock(&server->cb_lock);
138 list_del_init(&vnode->cb_link);
139 spin_unlock(&server->cb_lock);
140
141 spin_lock(&afs_cb_hash_lock);
142 list_del_init(&vnode->cb_hash_link);
143 spin_unlock(&afs_cb_hash_lock);
144 }
145 spin_unlock(&vnode->lock);
146
147 if (valid) {
148 invalidate_remote_inode(inode);
149 afs_put_server(server);
150 }
151 iput(inode);
152 }
153 }
154
155 _leave(" = 0");
156 return 0;
David Howellsec268152007-04-26 15:49:28 -0700157}
Linus Torvalds1da177e2005-04-16 15:20:36 -0700158
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159/*
160 * allow the fileserver to see if the cache manager is still alive
161 */
162int SRXAFSCM_Probe(struct afs_server *server)
163{
164 _debug("SRXAFSCM_Probe(%p)\n", server);
165 return 0;
David Howellsec268152007-04-26 15:49:28 -0700166}