/* * 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"#include "cmservice.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() */
/*
* 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"
#include "cmservice.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() */