Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
This commit is contained in:
168
fs/afs/callback.c
Normal file
168
fs/afs/callback.c
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
* Copyright (c) 2002 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This software may be freely redistributed under the terms of the
|
||||
* GNU General Public License.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
* Authors: David Woodhouse <dwmw2@cambridge.redhat.com>
|
||||
* David Howells <dhowells@redhat.com>
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include "server.h"
|
||||
#include "vnode.h"
|
||||
#include "internal.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* allow the fileserver to request callback state (re-)initialisation
|
||||
*/
|
||||
int SRXAFSCM_InitCallBackState(struct afs_server *server)
|
||||
{
|
||||
struct list_head callbacks;
|
||||
|
||||
_enter("%p", server);
|
||||
|
||||
INIT_LIST_HEAD(&callbacks);
|
||||
|
||||
/* transfer the callback list from the server to a temp holding area */
|
||||
spin_lock(&server->cb_lock);
|
||||
|
||||
list_add(&callbacks, &server->cb_promises);
|
||||
list_del_init(&server->cb_promises);
|
||||
|
||||
/* munch our way through the list, grabbing the inode, dropping all the
|
||||
* locks and regetting them in the right order
|
||||
*/
|
||||
while (!list_empty(&callbacks)) {
|
||||
struct afs_vnode *vnode;
|
||||
struct inode *inode;
|
||||
|
||||
vnode = list_entry(callbacks.next, struct afs_vnode, cb_link);
|
||||
list_del_init(&vnode->cb_link);
|
||||
|
||||
/* try and grab the inode - may fail */
|
||||
inode = igrab(AFS_VNODE_TO_I(vnode));
|
||||
if (inode) {
|
||||
int release = 0;
|
||||
|
||||
spin_unlock(&server->cb_lock);
|
||||
spin_lock(&vnode->lock);
|
||||
|
||||
if (vnode->cb_server == server) {
|
||||
vnode->cb_server = NULL;
|
||||
afs_kafstimod_del_timer(&vnode->cb_timeout);
|
||||
spin_lock(&afs_cb_hash_lock);
|
||||
list_del_init(&vnode->cb_hash_link);
|
||||
spin_unlock(&afs_cb_hash_lock);
|
||||
release = 1;
|
||||
}
|
||||
|
||||
spin_unlock(&vnode->lock);
|
||||
|
||||
iput(inode);
|
||||
afs_put_server(server);
|
||||
|
||||
spin_lock(&server->cb_lock);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&server->cb_lock);
|
||||
|
||||
_leave(" = 0");
|
||||
return 0;
|
||||
} /* end SRXAFSCM_InitCallBackState() */
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* allow the fileserver to break callback promises
|
||||
*/
|
||||
int SRXAFSCM_CallBack(struct afs_server *server, size_t count,
|
||||
struct afs_callback callbacks[])
|
||||
{
|
||||
_enter("%p,%u,", server, count);
|
||||
|
||||
for (; count > 0; callbacks++, count--) {
|
||||
struct afs_vnode *vnode = NULL;
|
||||
struct inode *inode = NULL;
|
||||
int valid = 0;
|
||||
|
||||
_debug("- Fid { vl=%08x n=%u u=%u } CB { v=%u x=%u t=%u }",
|
||||
callbacks->fid.vid,
|
||||
callbacks->fid.vnode,
|
||||
callbacks->fid.unique,
|
||||
callbacks->version,
|
||||
callbacks->expiry,
|
||||
callbacks->type
|
||||
);
|
||||
|
||||
/* find the inode for this fid */
|
||||
spin_lock(&afs_cb_hash_lock);
|
||||
|
||||
list_for_each_entry(vnode,
|
||||
&afs_cb_hash(server, &callbacks->fid),
|
||||
cb_hash_link) {
|
||||
if (memcmp(&vnode->fid, &callbacks->fid,
|
||||
sizeof(struct afs_fid)) != 0)
|
||||
continue;
|
||||
|
||||
/* right vnode, but is it same server? */
|
||||
if (vnode->cb_server != server)
|
||||
break; /* no */
|
||||
|
||||
/* try and nail the inode down */
|
||||
inode = igrab(AFS_VNODE_TO_I(vnode));
|
||||
break;
|
||||
}
|
||||
|
||||
spin_unlock(&afs_cb_hash_lock);
|
||||
|
||||
if (inode) {
|
||||
/* we've found the record for this vnode */
|
||||
spin_lock(&vnode->lock);
|
||||
if (vnode->cb_server == server) {
|
||||
/* the callback _is_ on the calling server */
|
||||
vnode->cb_server = NULL;
|
||||
valid = 1;
|
||||
|
||||
afs_kafstimod_del_timer(&vnode->cb_timeout);
|
||||
vnode->flags |= AFS_VNODE_CHANGED;
|
||||
|
||||
spin_lock(&server->cb_lock);
|
||||
list_del_init(&vnode->cb_link);
|
||||
spin_unlock(&server->cb_lock);
|
||||
|
||||
spin_lock(&afs_cb_hash_lock);
|
||||
list_del_init(&vnode->cb_hash_link);
|
||||
spin_unlock(&afs_cb_hash_lock);
|
||||
}
|
||||
spin_unlock(&vnode->lock);
|
||||
|
||||
if (valid) {
|
||||
invalidate_remote_inode(inode);
|
||||
afs_put_server(server);
|
||||
}
|
||||
iput(inode);
|
||||
}
|
||||
}
|
||||
|
||||
_leave(" = 0");
|
||||
return 0;
|
||||
} /* end SRXAFSCM_CallBack() */
|
||||
|
||||
/*****************************************************************************/
|
||||
/*
|
||||
* allow the fileserver to see if the cache manager is still alive
|
||||
*/
|
||||
int SRXAFSCM_Probe(struct afs_server *server)
|
||||
{
|
||||
_debug("SRXAFSCM_Probe(%p)\n", server);
|
||||
return 0;
|
||||
} /* end SRXAFSCM_Probe() */
|
Reference in New Issue
Block a user