]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - fs/afs/callback.c
[AFS]: Clean up the AFS sources
[linux-2.6-omap-h63xx.git] / fs / afs / callback.c
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 #include "cmservice.h"
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 }
82
83 /*
84  * allow the fileserver to break callback promises
85  */
86 int 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;
157 }
158
159 /*
160  * allow the fileserver to see if the cache manager is still alive
161  */
162 int SRXAFSCM_Probe(struct afs_server *server)
163 {
164         _debug("SRXAFSCM_Probe(%p)\n", server);
165         return 0;
166 }