Commit 2244b109 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] AFS upgrade

From: David Howells <dhowells@redhat.com>

Here's a patch to improve the AFS linux support. It:

 (1) Includes Pete's patch to skip the colon in the volume name, compile
     directly into the kernel, and not try to access non-existent caching
     routines.

 (2) Changes if (...) BUG() to BUG_ON()

 (3) Gets rid of typedefs.

 (4) Changes list_for_each() into list_for_each_entry().

 (5) Adds more whitespace and wraps lines to please the CodingStyle sticklers.
parent ae450eb1
...@@ -24,28 +24,28 @@ ...@@ -24,28 +24,28 @@
/* /*
* allow the fileserver to request callback state (re-)initialisation * allow the fileserver to request callback state (re-)initialisation
*/ */
int SRXAFSCM_InitCallBackState(afs_server_t *server) int SRXAFSCM_InitCallBackState(struct afs_server *server)
{ {
struct list_head callbacks; struct list_head callbacks;
_enter("%p",server); _enter("%p", server);
INIT_LIST_HEAD(&callbacks); INIT_LIST_HEAD(&callbacks);
/* transfer the callback list from the server to a temp holding area */ /* transfer the callback list from the server to a temp holding area */
spin_lock(&server->cb_lock); spin_lock(&server->cb_lock);
list_add(&callbacks,&server->cb_promises); list_add(&callbacks, &server->cb_promises);
list_del_init(&server->cb_promises); list_del_init(&server->cb_promises);
/* munch our way through the list, grabbing the inode, dropping all the locks and regetting /* munch our way through the list, grabbing the inode, dropping all the
* them in the right order * locks and regetting them in the right order
*/ */
while (!list_empty(&callbacks)) { while (!list_empty(&callbacks)) {
struct afs_vnode *vnode;
struct inode *inode; struct inode *inode;
afs_vnode_t *vnode;
vnode = list_entry(callbacks.next,afs_vnode_t,cb_link); vnode = list_entry(callbacks.next, struct afs_vnode, cb_link);
list_del_init(&vnode->cb_link); list_del_init(&vnode->cb_link);
/* try and grab the inode - may fail */ /* try and grab the inode - may fail */
...@@ -56,7 +56,7 @@ int SRXAFSCM_InitCallBackState(afs_server_t *server) ...@@ -56,7 +56,7 @@ int SRXAFSCM_InitCallBackState(afs_server_t *server)
spin_unlock(&server->cb_lock); spin_unlock(&server->cb_lock);
spin_lock(&vnode->lock); spin_lock(&vnode->lock);
if (vnode->cb_server==server) { if (vnode->cb_server == server) {
vnode->cb_server = NULL; vnode->cb_server = NULL;
afs_kafstimod_del_timer(&vnode->cb_timeout); afs_kafstimod_del_timer(&vnode->cb_timeout);
spin_lock(&afs_cb_hash_lock); spin_lock(&afs_cb_hash_lock);
...@@ -84,15 +84,14 @@ int SRXAFSCM_InitCallBackState(afs_server_t *server) ...@@ -84,15 +84,14 @@ int SRXAFSCM_InitCallBackState(afs_server_t *server)
/* /*
* allow the fileserver to break callback promises * allow the fileserver to break callback promises
*/ */
int SRXAFSCM_CallBack(afs_server_t *server, size_t count, afs_callback_t callbacks[]) int SRXAFSCM_CallBack(struct afs_server *server, size_t count,
struct afs_callback callbacks[])
{ {
struct list_head *_p; _enter("%p,%u,", server, count);
_enter("%p,%u,",server,count); for (; count > 0; callbacks++, count--) {
struct afs_vnode *vnode = NULL;
for (; count>0; callbacks++, count--) {
struct inode *inode = NULL; struct inode *inode = NULL;
afs_vnode_t *vnode = NULL;
int valid = 0; int valid = 0;
_debug("- Fid { vl=%08x n=%u u=%u } CB { v=%u x=%u t=%u }", _debug("- Fid { vl=%08x n=%u u=%u } CB { v=%u x=%u t=%u }",
...@@ -107,14 +106,15 @@ int SRXAFSCM_CallBack(afs_server_t *server, size_t count, afs_callback_t callbac ...@@ -107,14 +106,15 @@ int SRXAFSCM_CallBack(afs_server_t *server, size_t count, afs_callback_t callbac
/* find the inode for this fid */ /* find the inode for this fid */
spin_lock(&afs_cb_hash_lock); spin_lock(&afs_cb_hash_lock);
list_for_each(_p,&afs_cb_hash(server,&callbacks->fid)) { list_for_each_entry(vnode,
vnode = list_entry(_p,afs_vnode_t,cb_hash_link); &afs_cb_hash(server, &callbacks->fid),
cb_hash_link) {
if (memcmp(&vnode->fid,&callbacks->fid,sizeof(afs_fid_t))!=0) if (memcmp(&vnode->fid, &callbacks->fid,
sizeof(struct afs_fid)) != 0)
continue; continue;
/* right vnode, but is it same server? */ /* right vnode, but is it same server? */
if (vnode->cb_server!=server) if (vnode->cb_server != server)
break; /* no */ break; /* no */
/* try and nail the inode down */ /* try and nail the inode down */
...@@ -127,7 +127,7 @@ int SRXAFSCM_CallBack(afs_server_t *server, size_t count, afs_callback_t callbac ...@@ -127,7 +127,7 @@ int SRXAFSCM_CallBack(afs_server_t *server, size_t count, afs_callback_t callbac
if (inode) { if (inode) {
/* we've found the record for this vnode */ /* we've found the record for this vnode */
spin_lock(&vnode->lock); spin_lock(&vnode->lock);
if (vnode->cb_server==server) { if (vnode->cb_server == server) {
/* the callback _is_ on the calling server */ /* the callback _is_ on the calling server */
vnode->cb_server = NULL; vnode->cb_server = NULL;
valid = 1; valid = 1;
...@@ -161,8 +161,8 @@ int SRXAFSCM_CallBack(afs_server_t *server, size_t count, afs_callback_t callbac ...@@ -161,8 +161,8 @@ int SRXAFSCM_CallBack(afs_server_t *server, size_t count, afs_callback_t callbac
/* /*
* allow the fileserver to see if the cache manager is still alive * allow the fileserver to see if the cache manager is still alive
*/ */
int SRXAFSCM_Probe(afs_server_t *server) int SRXAFSCM_Probe(struct afs_server *server)
{ {
_debug("SRXAFSCM_Probe(%p)\n",server); _debug("SRXAFSCM_Probe(%p)\n", server);
return 0; return 0;
} /* end SRXAFSCM_Probe() */ } /* end SRXAFSCM_Probe() */
...@@ -29,20 +29,16 @@ LIST_HEAD(afs_proc_cells); ...@@ -29,20 +29,16 @@ LIST_HEAD(afs_proc_cells);
static struct list_head afs_cells = LIST_HEAD_INIT(afs_cells); static struct list_head afs_cells = LIST_HEAD_INIT(afs_cells);
static rwlock_t afs_cells_lock = RW_LOCK_UNLOCKED; static rwlock_t afs_cells_lock = RW_LOCK_UNLOCKED;
static DECLARE_RWSEM(afs_cells_sem); /* add/remove serialisation */ static DECLARE_RWSEM(afs_cells_sem); /* add/remove serialisation */
static afs_cell_t *afs_cell_root; static struct afs_cell *afs_cell_root;
static char *rootcell;
MODULE_PARM(rootcell,"s");
MODULE_PARM_DESC(rootcell,"root AFS cell name and VL server IP addr list");
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
static cachefs_match_val_t afs_cell_cache_match(void *target, const void *entry); static cachefs_match_val_t afs_cell_cache_match(void *target,
const void *entry);
static void afs_cell_cache_update(void *source, void *entry); static void afs_cell_cache_update(void *source, void *entry);
struct cachefs_index_def afs_cache_cell_index_def = { struct cachefs_index_def afs_cache_cell_index_def = {
.name = "cell_ix", .name = "cell_ix",
.data_size = sizeof(afs_cell_t), .data_size = sizeof(struct afs_cache_cell),
.keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 }, .keys[0] = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
.match = afs_cell_cache_match, .match = afs_cell_cache_match,
.update = afs_cell_cache_update, .update = afs_cell_cache_update,
...@@ -55,27 +51,27 @@ struct cachefs_index_def afs_cache_cell_index_def = { ...@@ -55,27 +51,27 @@ struct cachefs_index_def afs_cache_cell_index_def = {
* - "name" is the name of the cell * - "name" is the name of the cell
* - "vllist" is a colon separated list of IP addresses in "a.b.c.d" format * - "vllist" is a colon separated list of IP addresses in "a.b.c.d" format
*/ */
int afs_cell_create(const char *name, char *vllist, afs_cell_t **_cell) int afs_cell_create(const char *name, char *vllist, struct afs_cell **_cell)
{ {
afs_cell_t *cell; struct afs_cell *cell;
char *next; char *next;
int ret; int ret;
_enter("%s",name); _enter("%s", name);
if (!name) BUG(); /* TODO: want to look up "this cell" in the cache */ BUG_ON(!name); /* TODO: want to look up "this cell" in the cache */
down_write(&afs_cells_sem);
/* allocate and initialise a cell record */ /* allocate and initialise a cell record */
cell = kmalloc(sizeof(afs_cell_t) + strlen(name) + 1,GFP_KERNEL); cell = kmalloc(sizeof(struct afs_cell) + strlen(name) + 1, GFP_KERNEL);
if (!cell) { if (!cell) {
_leave(" = -ENOMEM"); _leave(" = -ENOMEM");
return -ENOMEM; return -ENOMEM;
} }
memset(cell,0,sizeof(afs_cell_t)); down_write(&afs_cells_sem);
atomic_set(&cell->usage,0);
memset(cell, 0, sizeof(struct afs_cell));
atomic_set(&cell->usage, 0);
INIT_LIST_HEAD(&cell->link); INIT_LIST_HEAD(&cell->link);
...@@ -96,26 +92,27 @@ int afs_cell_create(const char *name, char *vllist, afs_cell_t **_cell) ...@@ -96,26 +92,27 @@ int afs_cell_create(const char *name, char *vllist, afs_cell_t **_cell)
do { do {
unsigned a, b, c, d; unsigned a, b, c, d;
next = strchr(vllist,':'); next = strchr(vllist, ':');
if (next) *next++ = 0; if (next)
*next++ = 0;
if (sscanf(vllist,"%u.%u.%u.%u",&a,&b,&c,&d)!=4) if (sscanf(vllist, "%u.%u.%u.%u", &a, &b, &c, &d) != 4)
goto badaddr; goto badaddr;
if (a>255 || b>255 || c>255 || d>255) if (a > 255 || b > 255 || c > 255 || d > 255)
goto badaddr; goto badaddr;
cell->vl_addrs[cell->vl_naddrs++].s_addr = cell->vl_addrs[cell->vl_naddrs++].s_addr =
htonl((a<<24)|(b<<16)|(c<<8)|d); htonl((a << 24) | (b << 16) | (c << 8) | d);
if (cell->vl_naddrs >= AFS_CELL_MAX_ADDRS) if (cell->vl_naddrs >= AFS_CELL_MAX_ADDRS)
break; break;
} while(vllist=next, vllist); } while(vllist = next, vllist);
/* add a proc dir for this cell */ /* add a proc dir for this cell */
ret = afs_proc_cell_setup(cell); ret = afs_proc_cell_setup(cell);
if (ret<0) if (ret < 0)
goto error; goto error;
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
...@@ -128,24 +125,25 @@ int afs_cell_create(const char *name, char *vllist, afs_cell_t **_cell) ...@@ -128,24 +125,25 @@ int afs_cell_create(const char *name, char *vllist, afs_cell_t **_cell)
/* add to the cell lists */ /* add to the cell lists */
write_lock(&afs_cells_lock); write_lock(&afs_cells_lock);
list_add_tail(&cell->link,&afs_cells); list_add_tail(&cell->link, &afs_cells);
write_unlock(&afs_cells_lock); write_unlock(&afs_cells_lock);
down_write(&afs_proc_cells_sem); down_write(&afs_proc_cells_sem);
list_add_tail(&cell->proc_link,&afs_proc_cells); list_add_tail(&cell->proc_link, &afs_proc_cells);
up_write(&afs_proc_cells_sem); up_write(&afs_proc_cells_sem);
*_cell = cell; *_cell = cell;
up_write(&afs_cells_sem); up_write(&afs_cells_sem);
_leave(" = 0 (%p)",cell); _leave(" = 0 (%p)", cell);
return 0; return 0;
badaddr: badaddr:
printk("kAFS: bad VL server IP address: '%s'\n",vllist); printk(KERN_ERR "kAFS: bad VL server IP address: '%s'\n", vllist);
error: error:
up_write(&afs_cells_sem); up_write(&afs_cells_sem);
kfree(afs_cell_root); kfree(cell);
_leave(" = %d", ret);
return ret; return ret;
} /* end afs_cell_create() */ } /* end afs_cell_create() */
...@@ -153,31 +151,54 @@ int afs_cell_create(const char *name, char *vllist, afs_cell_t **_cell) ...@@ -153,31 +151,54 @@ int afs_cell_create(const char *name, char *vllist, afs_cell_t **_cell)
/* /*
* initialise the cell database from module parameters * initialise the cell database from module parameters
*/ */
int afs_cell_init(void) int afs_cell_init(char *rootcell)
{ {
struct afs_cell *old_root, *new_root;
char *cp; char *cp;
int ret; int ret;
_enter(""); _enter("");
if (!rootcell) { if (!rootcell) {
printk("kAFS: no root cell specified\n"); /* module is loaded with no parameters, or built statically.
return -EINVAL; * - in the future we might initialize cell DB here.
*/
_leave(" = 0 (but no root)");
return 0;
} }
cp = strchr(rootcell,':'); cp = strchr(rootcell, ':');
if (!cp) { if (!cp) {
printk("kAFS: no VL server IP addresses specified\n"); printk(KERN_ERR "kAFS: no VL server IP addresses specified\n");
_leave(" = %d (no colon)", -EINVAL);
return -EINVAL; return -EINVAL;
} }
/* allocate a cell record for the root cell */ /* allocate a cell record for the root cell */
*cp++ = 0; *cp++ = 0;
ret = afs_cell_create(rootcell,cp,&afs_cell_root); ret = afs_cell_create(rootcell, cp, &new_root);
if (ret==0) if (ret < 0) {
afs_get_cell(afs_cell_root); _leave(" = %d", ret);
return ret;
}
/* as afs_put_cell() takes locks by itself, we have to do
* a little gymnastics to be race-free.
*/
afs_get_cell(new_root);
write_lock(&afs_cells_lock);
while (afs_cell_root) {
old_root = afs_cell_root;
afs_cell_root = NULL;
write_unlock(&afs_cells_lock);
afs_put_cell(old_root);
write_lock(&afs_cells_lock);
}
afs_cell_root = new_root;
write_unlock(&afs_cells_lock);
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_cell_init() */ } /* end afs_cell_init() */
...@@ -188,8 +209,7 @@ int afs_cell_init(void) ...@@ -188,8 +209,7 @@ int afs_cell_init(void)
*/ */
int afs_cell_lookup(const char *name, unsigned namesz, struct afs_cell **_cell) int afs_cell_lookup(const char *name, unsigned namesz, struct afs_cell **_cell)
{ {
struct list_head *_p; struct afs_cell *cell;
afs_cell_t *cell;
int ret; int ret;
_enter("\"%*.*s\",", namesz, namesz, name ? name : ""); _enter("\"%*.*s\",", namesz, namesz, name ? name : "");
...@@ -202,14 +222,14 @@ int afs_cell_lookup(const char *name, unsigned namesz, struct afs_cell **_cell) ...@@ -202,14 +222,14 @@ int afs_cell_lookup(const char *name, unsigned namesz, struct afs_cell **_cell)
cell = NULL; cell = NULL;
read_lock(&afs_cells_lock); read_lock(&afs_cells_lock);
list_for_each(_p,&afs_cells) { list_for_each_entry(cell, &afs_cells, link) {
cell = list_entry(_p, struct afs_cell, link);
if (strncmp(cell->name, name, namesz) == 0) { if (strncmp(cell->name, name, namesz) == 0) {
afs_get_cell(cell); afs_get_cell(cell);
break; goto found;
} }
cell = NULL;
} }
cell = NULL;
found:
read_unlock(&afs_cells_lock); read_unlock(&afs_cells_lock);
...@@ -217,11 +237,26 @@ int afs_cell_lookup(const char *name, unsigned namesz, struct afs_cell **_cell) ...@@ -217,11 +237,26 @@ int afs_cell_lookup(const char *name, unsigned namesz, struct afs_cell **_cell)
ret = 0; ret = 0;
} }
else { else {
read_lock(&afs_cells_lock);
cell = afs_cell_root; cell = afs_cell_root;
if (!cell) {
/* this should not happen unless user tries to mount
* when root cell is not set. Return an impossibly
* bizzare errno to alert the user. Things like
* ENOENT might be "more appropriate" but they happen
* for other reasons.
*/
ret = -EDESTADDRREQ;
}
else {
afs_get_cell(cell); afs_get_cell(cell);
ret = 0; ret = 0;
} }
read_unlock(&afs_cells_lock);
}
*_cell = cell; *_cell = cell;
_leave(" = %d (%p)", ret, cell); _leave(" = %d (%p)", ret, cell);
return ret; return ret;
...@@ -232,9 +267,9 @@ int afs_cell_lookup(const char *name, unsigned namesz, struct afs_cell **_cell) ...@@ -232,9 +267,9 @@ int afs_cell_lookup(const char *name, unsigned namesz, struct afs_cell **_cell)
/* /*
* try and get a cell record * try and get a cell record
*/ */
afs_cell_t *afs_get_cell_maybe(afs_cell_t **_cell) struct afs_cell *afs_get_cell_maybe(struct afs_cell **_cell)
{ {
afs_cell_t *cell; struct afs_cell *cell;
write_lock(&afs_cells_lock); write_lock(&afs_cells_lock);
...@@ -253,18 +288,18 @@ afs_cell_t *afs_get_cell_maybe(afs_cell_t **_cell) ...@@ -253,18 +288,18 @@ afs_cell_t *afs_get_cell_maybe(afs_cell_t **_cell)
/* /*
* destroy a cell record * destroy a cell record
*/ */
void afs_put_cell(afs_cell_t *cell) void afs_put_cell(struct afs_cell *cell)
{ {
if (!cell) if (!cell)
return; return;
_enter("%p{%d,%s}",cell,atomic_read(&cell->usage),cell->name); _enter("%p{%d,%s}", cell, atomic_read(&cell->usage), cell->name);
/* sanity check */ /* sanity check */
if (atomic_read(&cell->usage)<=0) BUG_ON(atomic_read(&cell->usage) <= 0);
BUG();
/* to prevent a race, the decrement and the dequeue must be effectively atomic */ /* to prevent a race, the decrement and the dequeue must be effectively
* atomic */
write_lock(&afs_cells_lock); write_lock(&afs_cells_lock);
if (likely(!atomic_dec_and_test(&cell->usage))) { if (likely(!atomic_dec_and_test(&cell->usage))) {
...@@ -275,10 +310,10 @@ void afs_put_cell(afs_cell_t *cell) ...@@ -275,10 +310,10 @@ void afs_put_cell(afs_cell_t *cell)
write_unlock(&afs_cells_lock); write_unlock(&afs_cells_lock);
if (!list_empty(&cell->sv_list)) BUG(); BUG_ON(!list_empty(&cell->sv_list));
if (!list_empty(&cell->sv_graveyard)) BUG(); BUG_ON(!list_empty(&cell->sv_graveyard));
if (!list_empty(&cell->vl_list)) BUG(); BUG_ON(!list_empty(&cell->vl_list));
if (!list_empty(&cell->vl_graveyard)) BUG(); BUG_ON(!list_empty(&cell->vl_graveyard));
_leave(" [unused]"); _leave(" [unused]");
} /* end afs_put_cell() */ } /* end afs_put_cell() */
...@@ -287,16 +322,16 @@ void afs_put_cell(afs_cell_t *cell) ...@@ -287,16 +322,16 @@ void afs_put_cell(afs_cell_t *cell)
/* /*
* destroy a cell record * destroy a cell record
*/ */
static void afs_cell_destroy(afs_cell_t *cell) static void afs_cell_destroy(struct afs_cell *cell)
{ {
_enter("%p{%d,%s}",cell,atomic_read(&cell->usage),cell->name); _enter("%p{%d,%s}", cell, atomic_read(&cell->usage), cell->name);
/* to prevent a race, the decrement and the dequeue must be effectively atomic */ /* to prevent a race, the decrement and the dequeue must be effectively
* atomic */
write_lock(&afs_cells_lock); write_lock(&afs_cells_lock);
/* sanity check */ /* sanity check */
if (atomic_read(&cell->usage)!=0) BUG_ON(atomic_read(&cell->usage) != 0);
BUG();
list_del_init(&cell->link); list_del_init(&cell->link);
...@@ -311,15 +346,15 @@ static void afs_cell_destroy(afs_cell_t *cell) ...@@ -311,15 +346,15 @@ static void afs_cell_destroy(afs_cell_t *cell)
up_write(&afs_proc_cells_sem); up_write(&afs_proc_cells_sem);
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
cachefs_relinquish_cookie(cell->cache,0); cachefs_relinquish_cookie(cell->cache, 0);
#endif #endif
up_write(&afs_cells_sem); up_write(&afs_cells_sem);
if (!list_empty(&cell->sv_list)) BUG(); BUG_ON(!list_empty(&cell->sv_list));
if (!list_empty(&cell->sv_graveyard)) BUG(); BUG_ON(!list_empty(&cell->sv_graveyard));
if (!list_empty(&cell->vl_list)) BUG(); BUG_ON(!list_empty(&cell->vl_list));
if (!list_empty(&cell->vl_graveyard)) BUG(); BUG_ON(!list_empty(&cell->vl_graveyard));
/* finish cleaning up the cell */ /* finish cleaning up the cell */
kfree(cell); kfree(cell);
...@@ -331,42 +366,40 @@ static void afs_cell_destroy(afs_cell_t *cell) ...@@ -331,42 +366,40 @@ static void afs_cell_destroy(afs_cell_t *cell)
/* /*
* lookup the server record corresponding to an Rx RPC peer * lookup the server record corresponding to an Rx RPC peer
*/ */
int afs_server_find_by_peer(const struct rxrpc_peer *peer, afs_server_t **_server) int afs_server_find_by_peer(const struct rxrpc_peer *peer,
struct afs_server **_server)
{ {
struct list_head *_pc, *_ps; struct afs_server *server;
afs_server_t *server; struct afs_cell *cell;
afs_cell_t *cell;
_enter("%p{a=%08x},",peer,ntohl(peer->addr.s_addr)); _enter("%p{a=%08x},", peer, ntohl(peer->addr.s_addr));
/* search the cell list */ /* search the cell list */
read_lock(&afs_cells_lock); read_lock(&afs_cells_lock);
list_for_each(_pc,&afs_cells) { list_for_each_entry(cell, &afs_cells, link) {
cell = list_entry(_pc,afs_cell_t,link);
_debug("? cell %s",cell->name); _debug("? cell %s",cell->name);
write_lock(&cell->sv_lock); write_lock(&cell->sv_lock);
/* check the active list */ /* check the active list */
list_for_each(_ps,&cell->sv_list) { list_for_each_entry(server, &cell->sv_list, link) {
server = list_entry(_ps,afs_server_t,link); _debug("?? server %08x", ntohl(server->addr.s_addr));
_debug("?? server %08x",ntohl(server->addr.s_addr)); if (memcmp(&server->addr, &peer->addr,
sizeof(struct in_addr)) == 0)
if (memcmp(&server->addr,&peer->addr,sizeof(struct in_addr))==0)
goto found_server; goto found_server;
} }
/* check the inactive list */ /* check the inactive list */
spin_lock(&cell->sv_gylock); spin_lock(&cell->sv_gylock);
list_for_each(_ps,&cell->sv_graveyard) { list_for_each_entry(server, &cell->sv_graveyard, link) {
server = list_entry(_ps,afs_server_t,link); _debug("?? dead server %08x",
ntohl(server->addr.s_addr));
_debug("?? dead server %08x",ntohl(server->addr.s_addr));
if (memcmp(&server->addr,&peer->addr,sizeof(struct in_addr))==0) if (memcmp(&server->addr, &peer->addr,
sizeof(struct in_addr)) == 0)
goto found_dead_server; goto found_dead_server;
} }
spin_unlock(&cell->sv_gylock); spin_unlock(&cell->sv_gylock);
...@@ -381,7 +414,7 @@ int afs_server_find_by_peer(const struct rxrpc_peer *peer, afs_server_t **_serve ...@@ -381,7 +414,7 @@ int afs_server_find_by_peer(const struct rxrpc_peer *peer, afs_server_t **_serve
/* we found it in the graveyard - resurrect it */ /* we found it in the graveyard - resurrect it */
found_dead_server: found_dead_server:
list_del(&server->link); list_del(&server->link);
list_add_tail(&server->link,&cell->sv_list); list_add_tail(&server->link, &cell->sv_list);
afs_get_server(server); afs_get_server(server);
afs_kafstimod_del_timer(&server->timeout); afs_kafstimod_del_timer(&server->timeout);
spin_unlock(&cell->sv_gylock); spin_unlock(&cell->sv_gylock);
...@@ -396,20 +429,20 @@ int afs_server_find_by_peer(const struct rxrpc_peer *peer, afs_server_t **_serve ...@@ -396,20 +429,20 @@ int afs_server_find_by_peer(const struct rxrpc_peer *peer, afs_server_t **_serve
read_unlock(&afs_cells_lock); read_unlock(&afs_cells_lock);
*_server = server; *_server = server;
_leave(" = 0 (s=%p c=%p)",server,cell); _leave(" = 0 (s=%p c=%p)", server, cell);
return 0; return 0;
} /* end afs_server_find_by_peer() */ } /* end afs_server_find_by_peer() */
/*****************************************************************************/ /*****************************************************************************/
/* /*
* purge in-memory cell database on module unload * purge in-memory cell database on module unload or afs_init() failure
* - the timeout daemon is stopped before calling this * - the timeout daemon is stopped before calling this
*/ */
void afs_cell_purge(void) void afs_cell_purge(void)
{ {
afs_vlocation_t *vlocation; struct afs_vlocation *vlocation;
afs_cell_t *cell; struct afs_cell *cell;
_enter(""); _enter("");
...@@ -422,17 +455,19 @@ void afs_cell_purge(void) ...@@ -422,17 +455,19 @@ void afs_cell_purge(void)
write_lock(&afs_cells_lock); write_lock(&afs_cells_lock);
if (!list_empty(&afs_cells)) { if (!list_empty(&afs_cells)) {
cell = list_entry(afs_cells.next,afs_cell_t,link); cell = list_entry(afs_cells.next,
struct afs_cell, link);
list_del_init(&cell->link); list_del_init(&cell->link);
} }
write_unlock(&afs_cells_lock); write_unlock(&afs_cells_lock);
if (cell) { if (cell) {
_debug("PURGING CELL %s (%d)",cell->name,atomic_read(&cell->usage)); _debug("PURGING CELL %s (%d)",
cell->name, atomic_read(&cell->usage));
if (!list_empty(&cell->sv_list)) BUG(); BUG_ON(!list_empty(&cell->sv_list));
if (!list_empty(&cell->vl_list)) BUG(); BUG_ON(!list_empty(&cell->vl_list));
/* purge the cell's VL graveyard list */ /* purge the cell's VL graveyard list */
_debug(" - clearing VL graveyard"); _debug(" - clearing VL graveyard");
...@@ -441,7 +476,8 @@ void afs_cell_purge(void) ...@@ -441,7 +476,8 @@ void afs_cell_purge(void)
while (!list_empty(&cell->vl_graveyard)) { while (!list_empty(&cell->vl_graveyard)) {
vlocation = list_entry(cell->vl_graveyard.next, vlocation = list_entry(cell->vl_graveyard.next,
afs_vlocation_t,link); struct afs_vlocation,
link);
list_del_init(&vlocation->link); list_del_init(&vlocation->link);
afs_kafstimod_del_timer(&vlocation->timeout); afs_kafstimod_del_timer(&vlocation->timeout);
...@@ -449,7 +485,8 @@ void afs_cell_purge(void) ...@@ -449,7 +485,8 @@ void afs_cell_purge(void)
spin_unlock(&cell->vl_gylock); spin_unlock(&cell->vl_gylock);
afs_vlocation_do_timeout(vlocation); afs_vlocation_do_timeout(vlocation);
/* TODO: race if move to use krxtimod instead of kafstimod */ /* TODO: race if move to use krxtimod instead
* of kafstimod */
spin_lock(&cell->vl_gylock); spin_lock(&cell->vl_gylock);
} }
...@@ -462,9 +499,10 @@ void afs_cell_purge(void) ...@@ -462,9 +499,10 @@ void afs_cell_purge(void)
spin_lock(&cell->sv_gylock); spin_lock(&cell->sv_gylock);
while (!list_empty(&cell->sv_graveyard)) { while (!list_empty(&cell->sv_graveyard)) {
afs_server_t *server; struct afs_server *server;
server = list_entry(cell->sv_graveyard.next,afs_server_t,link); server = list_entry(cell->sv_graveyard.next,
struct afs_server, link);
list_del_init(&server->link); list_del_init(&server->link);
afs_kafstimod_del_timer(&server->timeout); afs_kafstimod_del_timer(&server->timeout);
...@@ -491,7 +529,8 @@ void afs_cell_purge(void) ...@@ -491,7 +529,8 @@ void afs_cell_purge(void)
* match a cell record obtained from the cache * match a cell record obtained from the cache
*/ */
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
static cachefs_match_val_t afs_cell_cache_match(void *target, const void *entry) static cachefs_match_val_t afs_cell_cache_match(void *target,
const void *entry)
{ {
const struct afs_cache_cell *ccell = entry; const struct afs_cache_cell *ccell = entry;
struct afs_cell *cell = target; struct afs_cell *cell = target;
......
...@@ -61,7 +61,7 @@ struct afs_cell ...@@ -61,7 +61,7 @@ struct afs_cell
char name[0]; /* cell name - must go last */ char name[0]; /* cell name - must go last */
}; };
extern int afs_cell_init(void); extern int afs_cell_init(char *rootcell);
extern int afs_cell_create(const char *name, char *vllist, struct afs_cell **_cell); extern int afs_cell_create(const char *name, char *vllist, struct afs_cell **_cell);
......
...@@ -94,7 +94,7 @@ static struct rxrpc_service AFSCM_service = { ...@@ -94,7 +94,7 @@ static struct rxrpc_service AFSCM_service = {
.error_func = afscm_error, .error_func = afscm_error,
.aemap_func = afscm_aemap, .aemap_func = afscm_aemap,
.ops_begin = &AFSCM_ops[0], .ops_begin = &AFSCM_ops[0],
.ops_end = &AFSCM_ops[sizeof(AFSCM_ops)/sizeof(AFSCM_ops[0])], .ops_end = &AFSCM_ops[sizeof(AFSCM_ops) / sizeof(AFSCM_ops[0])],
}; };
static DECLARE_COMPLETION(kafscmd_alive); static DECLARE_COMPLETION(kafscmd_alive);
...@@ -112,13 +112,13 @@ static int kafscmd_die; ...@@ -112,13 +112,13 @@ static int kafscmd_die;
*/ */
static int kafscmd(void *arg) static int kafscmd(void *arg)
{ {
DECLARE_WAITQUEUE(myself,current); DECLARE_WAITQUEUE(myself, current);
struct rxrpc_call *call; struct rxrpc_call *call;
_SRXAFSCM_xxxx_t func; _SRXAFSCM_xxxx_t func;
int die; int die;
printk("kAFS: Started kafscmd %d\n",current->pid); printk("kAFS: Started kafscmd %d\n", current->pid);
daemonize("kafscmd"); daemonize("kafscmd");
...@@ -128,7 +128,7 @@ static int kafscmd(void *arg) ...@@ -128,7 +128,7 @@ static int kafscmd(void *arg)
do { do {
if (list_empty(&kafscmd_attention_list)) { if (list_empty(&kafscmd_attention_list)) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&kafscmd_sleepq,&myself); add_wait_queue(&kafscmd_sleepq, &myself);
for (;;) { for (;;) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
...@@ -140,7 +140,7 @@ static int kafscmd(void *arg) ...@@ -140,7 +140,7 @@ static int kafscmd(void *arg)
schedule(); schedule();
} }
remove_wait_queue(&kafscmd_sleepq,&myself); remove_wait_queue(&kafscmd_sleepq, &myself);
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
} }
...@@ -162,7 +162,7 @@ static int kafscmd(void *arg) ...@@ -162,7 +162,7 @@ static int kafscmd(void *arg)
if (call) { if (call) {
/* act upon it */ /* act upon it */
_debug("@@@ Begin Attend Call %p",call); _debug("@@@ Begin Attend Call %p", call);
func = call->app_user; func = call->app_user;
if (func) if (func)
...@@ -170,13 +170,13 @@ static int kafscmd(void *arg) ...@@ -170,13 +170,13 @@ static int kafscmd(void *arg)
rxrpc_put_call(call); rxrpc_put_call(call);
_debug("@@@ End Attend Call %p",call); _debug("@@@ End Attend Call %p", call);
} }
} while(!die); } while(!die);
/* and that's all */ /* and that's all */
complete_and_exit(&kafscmd_dead,0); complete_and_exit(&kafscmd_dead, 0);
} /* end kafscmd() */ } /* end kafscmd() */
...@@ -184,12 +184,14 @@ static int kafscmd(void *arg) ...@@ -184,12 +184,14 @@ static int kafscmd(void *arg)
/* /*
* handle a call coming in to the cache manager * handle a call coming in to the cache manager
* - if I want to keep the call, I must increment its usage count * - if I want to keep the call, I must increment its usage count
* - the return value will be negated and passed back in an abort packet if non-zero * - the return value will be negated and passed back in an abort packet if
* non-zero
* - serialised by virtue of there only being one krxiod * - serialised by virtue of there only being one krxiod
*/ */
static int afscm_new_call(struct rxrpc_call *call) static int afscm_new_call(struct rxrpc_call *call)
{ {
_enter("%p{cid=%u u=%d}",call,ntohl(call->call_id),atomic_read(&call->usage)); _enter("%p{cid=%u u=%d}",
call, ntohl(call->call_id), atomic_read(&call->usage));
rxrpc_get_call(call); rxrpc_get_call(call);
...@@ -209,12 +211,13 @@ static int afscm_new_call(struct rxrpc_call *call) ...@@ -209,12 +211,13 @@ static int afscm_new_call(struct rxrpc_call *call)
*/ */
static void afscm_attention(struct rxrpc_call *call) static void afscm_attention(struct rxrpc_call *call)
{ {
_enter("%p{cid=%u u=%d}",call,ntohl(call->call_id),atomic_read(&call->usage)); _enter("%p{cid=%u u=%d}",
call, ntohl(call->call_id), atomic_read(&call->usage));
spin_lock(&kafscmd_attention_lock); spin_lock(&kafscmd_attention_lock);
if (list_empty(&call->app_attn_link)) { if (list_empty(&call->app_attn_link)) {
list_add_tail(&call->app_attn_link,&kafscmd_attention_list); list_add_tail(&call->app_attn_link, &kafscmd_attention_list);
rxrpc_get_call(call); rxrpc_get_call(call);
} }
...@@ -222,7 +225,7 @@ static void afscm_attention(struct rxrpc_call *call) ...@@ -222,7 +225,7 @@ static void afscm_attention(struct rxrpc_call *call)
wake_up(&kafscmd_sleepq); wake_up(&kafscmd_sleepq);
_leave(" {u=%d}",atomic_read(&call->usage)); _leave(" {u=%d}", atomic_read(&call->usage));
} /* end afscm_attention() */ } /* end afscm_attention() */
/*****************************************************************************/ /*****************************************************************************/
...@@ -243,7 +246,7 @@ static void afscm_error(struct rxrpc_call *call) ...@@ -243,7 +246,7 @@ static void afscm_error(struct rxrpc_call *call)
spin_lock(&kafscmd_attention_lock); spin_lock(&kafscmd_attention_lock);
if (list_empty(&call->app_attn_link)) { if (list_empty(&call->app_attn_link)) {
list_add_tail(&call->app_attn_link,&kafscmd_attention_list); list_add_tail(&call->app_attn_link, &kafscmd_attention_list);
rxrpc_get_call(call); rxrpc_get_call(call);
} }
...@@ -301,7 +304,7 @@ int afscm_start(void) ...@@ -301,7 +304,7 @@ int afscm_start(void)
wait_for_completion(&kafscmd_alive); wait_for_completion(&kafscmd_alive);
ret = rxrpc_add_service(afs_transport, &AFSCM_service); ret = rxrpc_add_service(afs_transport, &AFSCM_service);
if (ret<0) if (ret < 0)
goto kill; goto kill;
#ifdef AFS_AUTOMOUNT_SUPPORT #ifdef AFS_AUTOMOUNT_SUPPORT
...@@ -336,14 +339,15 @@ void afscm_stop(void) ...@@ -336,14 +339,15 @@ void afscm_stop(void)
down_write(&afscm_sem); down_write(&afscm_sem);
if (afscm_usage == 0) BUG(); BUG_ON(afscm_usage == 0);
afscm_usage--; afscm_usage--;
if (afscm_usage == 0) { if (afscm_usage == 0) {
/* don't want more incoming calls */ /* don't want more incoming calls */
rxrpc_del_service(afs_transport, &AFSCM_service); rxrpc_del_service(afs_transport, &AFSCM_service);
/* abort any calls I've still got open (the afscm_error() will dequeue them) */ /* abort any calls I've still got open (the afscm_error() will
* dequeue them) */
spin_lock(&afscm_calls_lock); spin_lock(&afscm_calls_lock);
while (!list_empty(&afscm_calls)) { while (!list_empty(&afscm_calls)) {
call = list_entry(afscm_calls.next, call = list_entry(afscm_calls.next,
...@@ -354,7 +358,8 @@ void afscm_stop(void) ...@@ -354,7 +358,8 @@ void afscm_stop(void)
rxrpc_get_call(call); rxrpc_get_call(call);
spin_unlock(&afscm_calls_lock); spin_unlock(&afscm_calls_lock);
rxrpc_call_abort(call,-ESRCH); /* abort, dequeue and put */ rxrpc_call_abort(call, -ESRCH); /* abort, dequeue and
* put */
_debug("nuking active call %08x.%d", _debug("nuking active call %08x.%d",
ntohl(call->conn->conn_id), ntohl(call->conn->conn_id),
...@@ -402,11 +407,11 @@ void afscm_stop(void) ...@@ -402,11 +407,11 @@ void afscm_stop(void)
*/ */
static void _SRXAFSCM_CallBack(struct rxrpc_call *call) static void _SRXAFSCM_CallBack(struct rxrpc_call *call)
{ {
afs_server_t *server; struct afs_server *server;
size_t count, qty, tmp; size_t count, qty, tmp;
int ret = 0, removed; int ret = 0, removed;
_enter("%p{acs=%s}",call,rxrpc_call_states[call->app_call_state]); _enter("%p{acs=%s}", call, rxrpc_call_states[call->app_call_state]);
server = afs_server_get_from_peer(call->conn->peer); server = afs_server_get_from_peer(call->conn->peer);
...@@ -417,38 +422,41 @@ static void _SRXAFSCM_CallBack(struct rxrpc_call *call) ...@@ -417,38 +422,41 @@ static void _SRXAFSCM_CallBack(struct rxrpc_call *call)
case RXRPC_CSTATE_SRVR_GOT_ARGS: case RXRPC_CSTATE_SRVR_GOT_ARGS:
ret = -EBADMSG; ret = -EBADMSG;
qty = call->app_ready_qty; qty = call->app_ready_qty;
if (qty<8 || qty>50*(6*4)+8) if (qty < 8 || qty > 50 * (6 * 4) + 8)
break; break;
{ {
afs_callback_t *cb, *pcb; struct afs_callback *cb, *pcb;
int loop; int loop;
u32 *fp, *bp; u32 *fp, *bp;
fp = rxrpc_call_alloc_scratch(call,qty); fp = rxrpc_call_alloc_scratch(call, qty);
/* drag the entire argument block out to the scratch space */ /* drag the entire argument block out to the scratch
ret = rxrpc_call_read_data(call,fp,qty,0); * space */
if (ret<0) ret = rxrpc_call_read_data(call, fp, qty, 0);
if (ret < 0)
break; break;
/* and unmarshall the parameter block */ /* and unmarshall the parameter block */
ret = -EBADMSG; ret = -EBADMSG;
count = ntohl(*fp++); count = ntohl(*fp++);
if (count>AFSCBMAX || if (count>AFSCBMAX ||
(count*(3*4)+8 != qty && count*(6*4)+8 != qty)) (count * (3 * 4) + 8 != qty &&
count * (6 * 4) + 8 != qty))
break; break;
bp = fp + count*3; bp = fp + count*3;
tmp = ntohl(*bp++); tmp = ntohl(*bp++);
if (tmp>0 && tmp!=count) if (tmp > 0 && tmp != count)
break; break;
if (tmp==0) if (tmp == 0)
bp = NULL; bp = NULL;
pcb = cb = rxrpc_call_alloc_scratch_s(call,afs_callback_t); pcb = cb = rxrpc_call_alloc_scratch_s(
call, struct afs_callback);
for (loop=count-1; loop>=0; loop--) { for (loop = count - 1; loop >= 0; loop--) {
pcb->fid.vid = ntohl(*fp++); pcb->fid.vid = ntohl(*fp++);
pcb->fid.vnode = ntohl(*fp++); pcb->fid.vnode = ntohl(*fp++);
pcb->fid.unique = ntohl(*fp++); pcb->fid.unique = ntohl(*fp++);
...@@ -466,14 +474,15 @@ static void _SRXAFSCM_CallBack(struct rxrpc_call *call) ...@@ -466,14 +474,15 @@ static void _SRXAFSCM_CallBack(struct rxrpc_call *call)
} }
/* invoke the actual service routine */ /* invoke the actual service routine */
ret = SRXAFSCM_CallBack(server,count,cb); ret = SRXAFSCM_CallBack(server, count, cb);
if (ret<0) if (ret < 0)
break; break;
} }
/* send the reply */ /* send the reply */
ret = rxrpc_call_write_data(call,0,NULL,RXRPC_LAST_PACKET,GFP_KERNEL,0,&count); ret = rxrpc_call_write_data(call, 0, NULL, RXRPC_LAST_PACKET,
if (ret<0) GFP_KERNEL, 0, &count);
if (ret < 0)
break; break;
break; break;
...@@ -501,12 +510,12 @@ static void _SRXAFSCM_CallBack(struct rxrpc_call *call) ...@@ -501,12 +510,12 @@ static void _SRXAFSCM_CallBack(struct rxrpc_call *call)
break; break;
} }
if (ret<0) if (ret < 0)
rxrpc_call_abort(call,ret); rxrpc_call_abort(call, ret);
afs_put_server(server); afs_put_server(server);
_leave(" = %d",ret); _leave(" = %d", ret);
} /* end _SRXAFSCM_CallBack() */ } /* end _SRXAFSCM_CallBack() */
...@@ -516,16 +525,17 @@ static void _SRXAFSCM_CallBack(struct rxrpc_call *call) ...@@ -516,16 +525,17 @@ static void _SRXAFSCM_CallBack(struct rxrpc_call *call)
*/ */
static void _SRXAFSCM_InitCallBackState(struct rxrpc_call *call) static void _SRXAFSCM_InitCallBackState(struct rxrpc_call *call)
{ {
afs_server_t *server; struct afs_server *server;
size_t count; size_t count;
int ret = 0, removed; int ret = 0, removed;
_enter("%p{acs=%s}",call,rxrpc_call_states[call->app_call_state]); _enter("%p{acs=%s}", call, rxrpc_call_states[call->app_call_state]);
server = afs_server_get_from_peer(call->conn->peer); server = afs_server_get_from_peer(call->conn->peer);
switch (call->app_call_state) { switch (call->app_call_state) {
/* we've received the last packet - drain all the data from the call */ /* we've received the last packet - drain all the data from the
* call */
case RXRPC_CSTATE_SRVR_GOT_ARGS: case RXRPC_CSTATE_SRVR_GOT_ARGS:
/* shouldn't be any args */ /* shouldn't be any args */
ret = -EBADMSG; ret = -EBADMSG;
...@@ -535,11 +545,12 @@ static void _SRXAFSCM_InitCallBackState(struct rxrpc_call *call) ...@@ -535,11 +545,12 @@ static void _SRXAFSCM_InitCallBackState(struct rxrpc_call *call)
case RXRPC_CSTATE_SRVR_SND_REPLY: case RXRPC_CSTATE_SRVR_SND_REPLY:
/* invoke the actual service routine */ /* invoke the actual service routine */
ret = SRXAFSCM_InitCallBackState(server); ret = SRXAFSCM_InitCallBackState(server);
if (ret<0) if (ret < 0)
break; break;
ret = rxrpc_call_write_data(call,0,NULL,RXRPC_LAST_PACKET,GFP_KERNEL,0,&count); ret = rxrpc_call_write_data(call, 0, NULL, RXRPC_LAST_PACKET,
if (ret<0) GFP_KERNEL, 0, &count);
if (ret < 0)
break; break;
break; break;
...@@ -567,12 +578,12 @@ static void _SRXAFSCM_InitCallBackState(struct rxrpc_call *call) ...@@ -567,12 +578,12 @@ static void _SRXAFSCM_InitCallBackState(struct rxrpc_call *call)
break; break;
} }
if (ret<0) if (ret < 0)
rxrpc_call_abort(call,ret); rxrpc_call_abort(call, ret);
afs_put_server(server); afs_put_server(server);
_leave(" = %d",ret); _leave(" = %d", ret);
} /* end _SRXAFSCM_InitCallBackState() */ } /* end _SRXAFSCM_InitCallBackState() */
...@@ -582,16 +593,17 @@ static void _SRXAFSCM_InitCallBackState(struct rxrpc_call *call) ...@@ -582,16 +593,17 @@ static void _SRXAFSCM_InitCallBackState(struct rxrpc_call *call)
*/ */
static void _SRXAFSCM_Probe(struct rxrpc_call *call) static void _SRXAFSCM_Probe(struct rxrpc_call *call)
{ {
afs_server_t *server; struct afs_server *server;
size_t count; size_t count;
int ret = 0, removed; int ret = 0, removed;
_enter("%p{acs=%s}",call,rxrpc_call_states[call->app_call_state]); _enter("%p{acs=%s}", call, rxrpc_call_states[call->app_call_state]);
server = afs_server_get_from_peer(call->conn->peer); server = afs_server_get_from_peer(call->conn->peer);
switch (call->app_call_state) { switch (call->app_call_state) {
/* we've received the last packet - drain all the data from the call */ /* we've received the last packet - drain all the data from the
* call */
case RXRPC_CSTATE_SRVR_GOT_ARGS: case RXRPC_CSTATE_SRVR_GOT_ARGS:
/* shouldn't be any args */ /* shouldn't be any args */
ret = -EBADMSG; ret = -EBADMSG;
...@@ -601,11 +613,12 @@ static void _SRXAFSCM_Probe(struct rxrpc_call *call) ...@@ -601,11 +613,12 @@ static void _SRXAFSCM_Probe(struct rxrpc_call *call)
case RXRPC_CSTATE_SRVR_SND_REPLY: case RXRPC_CSTATE_SRVR_SND_REPLY:
/* invoke the actual service routine */ /* invoke the actual service routine */
ret = SRXAFSCM_Probe(server); ret = SRXAFSCM_Probe(server);
if (ret<0) if (ret < 0)
break; break;
ret = rxrpc_call_write_data(call,0,NULL,RXRPC_LAST_PACKET,GFP_KERNEL,0,&count); ret = rxrpc_call_write_data(call, 0, NULL, RXRPC_LAST_PACKET,
if (ret<0) GFP_KERNEL, 0, &count);
if (ret < 0)
break; break;
break; break;
...@@ -633,11 +646,11 @@ static void _SRXAFSCM_Probe(struct rxrpc_call *call) ...@@ -633,11 +646,11 @@ static void _SRXAFSCM_Probe(struct rxrpc_call *call)
break; break;
} }
if (ret<0) if (ret < 0)
rxrpc_call_abort(call,ret); rxrpc_call_abort(call, ret);
afs_put_server(server); afs_put_server(server);
_leave(" = %d",ret); _leave(" = %d", ret);
} /* end _SRXAFSCM_Probe() */ } /* end _SRXAFSCM_Probe() */
...@@ -20,8 +20,10 @@ extern int afscm_start(void); ...@@ -20,8 +20,10 @@ extern int afscm_start(void);
extern void afscm_stop(void); extern void afscm_stop(void);
/* cache manager server functions */ /* cache manager server functions */
extern int SRXAFSCM_InitCallBackState(afs_server_t *server); extern int SRXAFSCM_InitCallBackState(struct afs_server *server);
extern int SRXAFSCM_CallBack(afs_server_t *server, size_t count, afs_callback_t callbacks[]); extern int SRXAFSCM_CallBack(struct afs_server *server,
extern int SRXAFSCM_Probe(afs_server_t *server); size_t count,
struct afs_callback callbacks[]);
extern int SRXAFSCM_Probe(struct afs_server *server);
#endif /* _LINUX_AFS_CMSERVICE_H */ #endif /* _LINUX_AFS_CMSERVICE_H */
...@@ -29,8 +29,8 @@ static int afs_dir_open(struct inode *inode, struct file *file); ...@@ -29,8 +29,8 @@ static int afs_dir_open(struct inode *inode, struct file *file);
static int afs_dir_readdir(struct file *file, void *dirent, filldir_t filldir); static int afs_dir_readdir(struct file *file, void *dirent, filldir_t filldir);
static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd); static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd);
static int afs_d_delete(struct dentry *dentry); static int afs_d_delete(struct dentry *dentry);
static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, loff_t fpos, static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen,
ino_t ino, unsigned dtype); loff_t fpos, ino_t ino, unsigned dtype);
struct file_operations afs_dir_file_operations = { struct file_operations afs_dir_file_operations = {
.open = afs_dir_open, .open = afs_dir_open,
...@@ -61,51 +61,53 @@ static struct dentry_operations afs_fs_dentry_operations = { ...@@ -61,51 +61,53 @@ static struct dentry_operations afs_fs_dentry_operations = {
#define AFS_DIR_DIRENT_SIZE 32 #define AFS_DIR_DIRENT_SIZE 32
#define AFS_DIRENT_PER_BLOCK 64 #define AFS_DIRENT_PER_BLOCK 64
typedef union afs_dirent { union afs_dirent {
struct { struct {
u8 valid; uint8_t valid;
u8 unused[1]; uint8_t unused[1];
u16 hash_next; uint16_t hash_next;
u32 vnode; uint32_t vnode;
u32 unique; uint32_t unique;
u8 name[16]; uint8_t name[16];
u8 overflow[4]; /* if any char of the name (inc NUL) reaches here, consume uint8_t overflow[4]; /* if any char of the name (inc
* NUL) reaches here, consume
* the next dirent too */ * the next dirent too */
} u; } u;
u8 extended_name[32]; uint8_t extended_name[32];
} afs_dirent_t; };
/* AFS directory page header (one at the beginning of every 2048-byte chunk) */ /* AFS directory page header (one at the beginning of every 2048-byte chunk) */
typedef struct afs_dir_pagehdr { struct afs_dir_pagehdr {
u16 npages; uint16_t npages;
u16 magic; uint16_t magic;
#define AFS_DIR_MAGIC htons(1234) #define AFS_DIR_MAGIC htons(1234)
u8 nentries; uint8_t nentries;
u8 bitmap[8]; uint8_t bitmap[8];
u8 pad[19]; uint8_t pad[19];
} afs_dir_pagehdr_t; };
/* directory block layout */ /* directory block layout */
typedef union afs_dir_block { union afs_dir_block {
afs_dir_pagehdr_t pagehdr; struct afs_dir_pagehdr pagehdr;
struct { struct {
afs_dir_pagehdr_t pagehdr; struct afs_dir_pagehdr pagehdr;
u8 alloc_ctrs[128]; uint8_t alloc_ctrs[128];
u16 hashtable[AFS_DIR_HASHTBL_SIZE]; /* dir hash table */ /* dir hash table */
uint16_t hashtable[AFS_DIR_HASHTBL_SIZE];
} hdr; } hdr;
afs_dirent_t dirents[AFS_DIRENT_PER_BLOCK]; union afs_dirent dirents[AFS_DIRENT_PER_BLOCK];
} afs_dir_block_t; };
/* layout on a linux VM page */ /* layout on a linux VM page */
typedef struct afs_dir_page { struct afs_dir_page {
afs_dir_block_t blocks[PAGE_SIZE/sizeof(afs_dir_block_t)]; union afs_dir_block blocks[PAGE_SIZE / sizeof(union afs_dir_block)];
} afs_dir_page_t; };
struct afs_dir_lookup_cookie { struct afs_dir_lookup_cookie {
afs_fid_t fid; struct afs_fid fid;
const char *name; const char *name;
size_t nlen; size_t nlen;
int found; int found;
...@@ -117,14 +119,14 @@ struct afs_dir_lookup_cookie { ...@@ -117,14 +119,14 @@ struct afs_dir_lookup_cookie {
*/ */
static inline void afs_dir_check_page(struct inode *dir, struct page *page) static inline void afs_dir_check_page(struct inode *dir, struct page *page)
{ {
afs_dir_page_t *dbuf; struct afs_dir_page *dbuf;
loff_t latter; loff_t latter;
int tmp, qty; int tmp, qty;
#if 0 #if 0
/* check the page count */ /* check the page count */
qty = desc.size/sizeof(dbuf->blocks[0]); qty = desc.size / sizeof(dbuf->blocks[0]);
if (qty==0) if (qty == 0)
goto error; goto error;
if (page->index==0 && qty!=ntohs(dbuf->blocks[0].pagehdr.npages)) { if (page->index==0 && qty!=ntohs(dbuf->blocks[0].pagehdr.npages)) {
...@@ -140,15 +142,15 @@ static inline void afs_dir_check_page(struct inode *dir, struct page *page) ...@@ -140,15 +142,15 @@ static inline void afs_dir_check_page(struct inode *dir, struct page *page)
qty = PAGE_SIZE; qty = PAGE_SIZE;
else else
qty = latter; qty = latter;
qty /= sizeof(afs_dir_block_t); qty /= sizeof(union afs_dir_block);
/* check them */ /* check them */
dbuf = page_address(page); dbuf = page_address(page);
for (tmp=0; tmp<qty; tmp++) { for (tmp = 0; tmp < qty; tmp++) {
if (dbuf->blocks[tmp].pagehdr.magic != AFS_DIR_MAGIC) { if (dbuf->blocks[tmp].pagehdr.magic != AFS_DIR_MAGIC) {
printk("kAFS: %s(%lu): bad magic %d/%d is %04hx\n", printk("kAFS: %s(%lu): bad magic %d/%d is %04hx\n",
__FUNCTION__,dir->i_ino,tmp, __FUNCTION__, dir->i_ino, tmp, qty,
qty,ntohs(dbuf->blocks[tmp].pagehdr.magic)); ntohs(dbuf->blocks[tmp].pagehdr.magic));
goto error; goto error;
} }
} }
...@@ -181,17 +183,18 @@ static struct page *afs_dir_get_page(struct inode *dir, unsigned long index) ...@@ -181,17 +183,18 @@ static struct page *afs_dir_get_page(struct inode *dir, unsigned long index)
{ {
struct page *page; struct page *page;
_enter("{%lu},%lu",dir->i_ino,index); _enter("{%lu},%lu", dir->i_ino, index);
page = read_cache_page(dir->i_mapping,index, page = read_cache_page(dir->i_mapping,index,
(filler_t*)dir->i_mapping->a_ops->readpage,NULL); (filler_t *) dir->i_mapping->a_ops->readpage,
NULL);
if (!IS_ERR(page)) { if (!IS_ERR(page)) {
wait_on_page_locked(page); wait_on_page_locked(page);
kmap(page); kmap(page);
if (!PageUptodate(page)) if (!PageUptodate(page))
goto fail; goto fail;
if (!PageChecked(page)) if (!PageChecked(page))
afs_dir_check_page(dir,page); afs_dir_check_page(dir, page);
if (PageError(page)) if (PageError(page))
goto fail; goto fail;
} }
...@@ -208,10 +211,10 @@ static struct page *afs_dir_get_page(struct inode *dir, unsigned long index) ...@@ -208,10 +211,10 @@ static struct page *afs_dir_get_page(struct inode *dir, unsigned long index)
*/ */
static int afs_dir_open(struct inode *inode, struct file *file) static int afs_dir_open(struct inode *inode, struct file *file)
{ {
_enter("{%lu}",inode->i_ino); _enter("{%lu}", inode->i_ino);
if (sizeof(afs_dir_block_t) != 2048) BUG(); BUG_ON(sizeof(union afs_dir_block) != 2048);
if (sizeof(afs_dirent_t) != 32) BUG(); BUG_ON(sizeof(union afs_dirent) != 32);
if (AFS_FS_I(inode)->flags & AFS_VNODE_DELETED) if (AFS_FS_I(inode)->flags & AFS_VNODE_DELETED)
return -ENOENT; return -ENOENT;
...@@ -226,19 +229,19 @@ static int afs_dir_open(struct inode *inode, struct file *file) ...@@ -226,19 +229,19 @@ static int afs_dir_open(struct inode *inode, struct file *file)
* deal with one block in an AFS directory * deal with one block in an AFS directory
*/ */
static int afs_dir_iterate_block(unsigned *fpos, static int afs_dir_iterate_block(unsigned *fpos,
afs_dir_block_t *block, union afs_dir_block *block,
unsigned blkoff, unsigned blkoff,
void *cookie, void *cookie,
filldir_t filldir) filldir_t filldir)
{ {
afs_dirent_t *dire; union afs_dirent *dire;
unsigned offset, next, curr; unsigned offset, next, curr;
size_t nlen; size_t nlen;
int tmp, ret; int tmp, ret;
_enter("%u,%x,%p,,",*fpos,blkoff,block); _enter("%u,%x,%p,,",*fpos,blkoff,block);
curr = (*fpos - blkoff) / sizeof(afs_dirent_t); curr = (*fpos - blkoff) / sizeof(union afs_dirent);
/* walk through the block, an entry at a time */ /* walk through the block, an entry at a time */
for (offset = AFS_DIRENT_PER_BLOCK - block->pagehdr.nentries; for (offset = AFS_DIRENT_PER_BLOCK - block->pagehdr.nentries;
...@@ -248,58 +251,70 @@ static int afs_dir_iterate_block(unsigned *fpos, ...@@ -248,58 +251,70 @@ static int afs_dir_iterate_block(unsigned *fpos,
next = offset + 1; next = offset + 1;
/* skip entries marked unused in the bitmap */ /* skip entries marked unused in the bitmap */
if (!(block->pagehdr.bitmap[offset/8] & (1 << (offset % 8)))) { if (!(block->pagehdr.bitmap[offset / 8] &
_debug("ENT[%Zu.%u]: unused\n",blkoff/sizeof(afs_dir_block_t),offset); (1 << (offset % 8)))) {
if (offset>=curr) _debug("ENT[%Zu.%u]: unused\n",
*fpos = blkoff + next * sizeof(afs_dirent_t); blkoff / sizeof(union afs_dir_block), offset);
if (offset >= curr)
*fpos = blkoff +
next * sizeof(union afs_dirent);
continue; continue;
} }
/* got a valid entry */ /* got a valid entry */
dire = &block->dirents[offset]; dire = &block->dirents[offset];
nlen = strnlen(dire->u.name,sizeof(*block) - offset*sizeof(afs_dirent_t)); nlen = strnlen(dire->u.name,
sizeof(*block) -
offset * sizeof(union afs_dirent));
_debug("ENT[%Zu.%u]: %s %Zu \"%s\"\n", _debug("ENT[%Zu.%u]: %s %Zu \"%s\"\n",
blkoff/sizeof(afs_dir_block_t),offset, blkoff / sizeof(union afs_dir_block), offset,
(offset<curr ? "skip" : "fill"), (offset < curr ? "skip" : "fill"),
nlen,dire->u.name); nlen, dire->u.name);
/* work out where the next possible entry is */ /* work out where the next possible entry is */
for (tmp=nlen; tmp>15; tmp-=sizeof(afs_dirent_t)) { for (tmp = nlen; tmp > 15; tmp -= sizeof(union afs_dirent)) {
if (next>=AFS_DIRENT_PER_BLOCK) { if (next >= AFS_DIRENT_PER_BLOCK) {
_debug("ENT[%Zu.%u]:" _debug("ENT[%Zu.%u]:"
" %u travelled beyond end dir block (len %u/%Zu)\n", " %u travelled beyond end dir block"
blkoff/sizeof(afs_dir_block_t),offset,next,tmp,nlen); " (len %u/%Zu)\n",
blkoff / sizeof(union afs_dir_block),
offset, next, tmp, nlen);
return -EIO; return -EIO;
} }
if (!(block->pagehdr.bitmap[next/8] & (1 << (next % 8)))) { if (!(block->pagehdr.bitmap[next / 8] &
_debug("ENT[%Zu.%u]: %u unmarked extension (len %u/%Zu)\n", (1 << (next % 8)))) {
blkoff/sizeof(afs_dir_block_t),offset,next,tmp,nlen); _debug("ENT[%Zu.%u]:"
" %u unmarked extension (len %u/%Zu)\n",
blkoff / sizeof(union afs_dir_block),
offset, next, tmp, nlen);
return -EIO; return -EIO;
} }
_debug("ENT[%Zu.%u]: ext %u/%Zu\n", _debug("ENT[%Zu.%u]: ext %u/%Zu\n",
blkoff/sizeof(afs_dir_block_t),next,tmp,nlen); blkoff / sizeof(union afs_dir_block),
next, tmp, nlen);
next++; next++;
} }
/* skip if starts before the current position */ /* skip if starts before the current position */
if (offset<curr) if (offset < curr)
continue; continue;
/* found the next entry */ /* found the next entry */
ret = filldir(cookie, ret = filldir(cookie,
dire->u.name, dire->u.name,
nlen, nlen,
blkoff + offset * sizeof(afs_dirent_t), blkoff + offset * sizeof(union afs_dirent),
ntohl(dire->u.vnode), ntohl(dire->u.vnode),
filldir==afs_dir_lookup_filldir ? dire->u.unique : DT_UNKNOWN); filldir == afs_dir_lookup_filldir ?
if (ret<0) { dire->u.unique : DT_UNKNOWN);
if (ret < 0) {
_leave(" = 0 [full]"); _leave(" = 0 [full]");
return 0; return 0;
} }
*fpos = blkoff + next * sizeof(afs_dirent_t); *fpos = blkoff + next * sizeof(union afs_dirent);
} }
_leave(" = 1 [more]"); _leave(" = 1 [more]");
...@@ -310,15 +325,16 @@ static int afs_dir_iterate_block(unsigned *fpos, ...@@ -310,15 +325,16 @@ static int afs_dir_iterate_block(unsigned *fpos,
/* /*
* read an AFS directory * read an AFS directory
*/ */
static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie, filldir_t filldir) static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie,
filldir_t filldir)
{ {
afs_dir_block_t *dblock; union afs_dir_block *dblock;
afs_dir_page_t *dbuf; struct afs_dir_page *dbuf;
struct page *page; struct page *page;
unsigned blkoff, limit; unsigned blkoff, limit;
int ret; int ret;
_enter("{%lu},%u,,",dir->i_ino,*fpos); _enter("{%lu},%u,,", dir->i_ino, *fpos);
if (AFS_FS_I(dir)->flags & AFS_VNODE_DELETED) { if (AFS_FS_I(dir)->flags & AFS_VNODE_DELETED) {
_leave(" = -ESTALE"); _leave(" = -ESTALE");
...@@ -326,35 +342,37 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie, fill ...@@ -326,35 +342,37 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie, fill
} }
/* round the file position up to the next entry boundary */ /* round the file position up to the next entry boundary */
*fpos += sizeof(afs_dirent_t) - 1; *fpos += sizeof(union afs_dirent) - 1;
*fpos &= ~(sizeof(afs_dirent_t) - 1); *fpos &= ~(sizeof(union afs_dirent) - 1);
/* walk through the blocks in sequence */ /* walk through the blocks in sequence */
ret = 0; ret = 0;
while (*fpos < dir->i_size) { while (*fpos < dir->i_size) {
blkoff = *fpos & ~(sizeof(afs_dir_block_t) - 1); blkoff = *fpos & ~(sizeof(union afs_dir_block) - 1);
/* fetch the appropriate page from the directory */ /* fetch the appropriate page from the directory */
page = afs_dir_get_page(dir,blkoff/PAGE_SIZE); page = afs_dir_get_page(dir, blkoff / PAGE_SIZE);
if (IS_ERR(page)) { if (IS_ERR(page)) {
ret = PTR_ERR(page); ret = PTR_ERR(page);
break; break;
} }
limit = blkoff & ~(PAGE_SIZE-1); limit = blkoff & ~(PAGE_SIZE - 1);
dbuf = page_address(page); dbuf = page_address(page);
/* deal with the individual blocks stashed on this page */ /* deal with the individual blocks stashed on this page */
do { do {
dblock = &dbuf->blocks[(blkoff % PAGE_SIZE) / sizeof(afs_dir_block_t)]; dblock = &dbuf->blocks[(blkoff % PAGE_SIZE) /
ret = afs_dir_iterate_block(fpos,dblock,blkoff,cookie,filldir); sizeof(union afs_dir_block)];
if (ret!=1) { ret = afs_dir_iterate_block(fpos, dblock, blkoff,
cookie, filldir);
if (ret != 1) {
afs_dir_put_page(page); afs_dir_put_page(page);
goto out; goto out;
} }
blkoff += sizeof(afs_dir_block_t); blkoff += sizeof(union afs_dir_block);
} while (*fpos < dir->i_size && blkoff < limit); } while (*fpos < dir->i_size && blkoff < limit);
...@@ -363,7 +381,7 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie, fill ...@@ -363,7 +381,7 @@ static int afs_dir_iterate(struct inode *dir, unsigned *fpos, void *cookie, fill
} }
out: out:
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_dir_iterate() */ } /* end afs_dir_iterate() */
...@@ -376,29 +394,31 @@ static int afs_dir_readdir(struct file *file, void *cookie, filldir_t filldir) ...@@ -376,29 +394,31 @@ static int afs_dir_readdir(struct file *file, void *cookie, filldir_t filldir)
unsigned fpos; unsigned fpos;
int ret; int ret;
_enter("{%Ld,{%lu}}",file->f_pos,file->f_dentry->d_inode->i_ino); _enter("{%Ld,{%lu}}", file->f_pos, file->f_dentry->d_inode->i_ino);
fpos = file->f_pos; fpos = file->f_pos;
ret = afs_dir_iterate(file->f_dentry->d_inode,&fpos,cookie,filldir); ret = afs_dir_iterate(file->f_dentry->d_inode, &fpos, cookie, filldir);
file->f_pos = fpos; file->f_pos = fpos;
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_dir_readdir() */ } /* end afs_dir_readdir() */
/*****************************************************************************/ /*****************************************************************************/
/* /*
* search the directory for a name * search the directory for a name
* - if afs_dir_iterate_block() spots this function, it'll pass the FID uniquifier through dtype * - if afs_dir_iterate_block() spots this function, it'll pass the FID
* uniquifier through dtype
*/ */
static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen, loff_t fpos, static int afs_dir_lookup_filldir(void *_cookie, const char *name, int nlen,
ino_t ino, unsigned dtype) loff_t fpos, ino_t ino, unsigned dtype)
{ {
struct afs_dir_lookup_cookie *cookie = _cookie; struct afs_dir_lookup_cookie *cookie = _cookie;
_enter("{%s,%Zu},%s,%u,,%lu,%u",cookie->name,cookie->nlen,name,nlen,ino,ntohl(dtype)); _enter("{%s,%Zu},%s,%u,,%lu,%u",
cookie->name, cookie->nlen, name, nlen, ino, ntohl(dtype));
if (cookie->nlen != nlen || memcmp(cookie->name,name,nlen)!=0) { if (cookie->nlen != nlen || memcmp(cookie->name, name, nlen) != 0) {
_leave(" = 0 [no]"); _leave(" = 0 [no]");
return 0; return 0;
} }
...@@ -420,16 +440,16 @@ static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry, ...@@ -420,16 +440,16 @@ static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry,
{ {
struct afs_dir_lookup_cookie cookie; struct afs_dir_lookup_cookie cookie;
struct afs_super_info *as; struct afs_super_info *as;
struct afs_vnode *vnode;
struct inode *inode; struct inode *inode;
afs_vnode_t *vnode;
unsigned fpos; unsigned fpos;
int ret; int ret;
_enter("{%lu},%p{%s}",dir->i_ino,dentry,dentry->d_name.name); _enter("{%lu},%p{%s}", dir->i_ino, dentry, dentry->d_name.name);
/* insanity checks first */ /* insanity checks first */
BUG_ON(sizeof(afs_dir_block_t) != 2048); BUG_ON(sizeof(union afs_dir_block) != 2048);
BUG_ON(sizeof(afs_dirent_t) != 32); BUG_ON(sizeof(union afs_dirent) != 32);
if (dentry->d_name.len > 255) { if (dentry->d_name.len > 255) {
_leave(" = -ENAMETOOLONG"); _leave(" = -ENAMETOOLONG");
...@@ -451,29 +471,29 @@ static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry, ...@@ -451,29 +471,29 @@ static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry,
cookie.found = 0; cookie.found = 0;
fpos = 0; fpos = 0;
ret = afs_dir_iterate(dir,&fpos,&cookie,afs_dir_lookup_filldir); ret = afs_dir_iterate(dir, &fpos, &cookie, afs_dir_lookup_filldir);
if (ret<0) { if (ret < 0) {
_leave(" = %d",ret); _leave(" = %d", ret);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
ret = -ENOENT; ret = -ENOENT;
if (!cookie.found) { if (!cookie.found) {
_leave(" = %d",ret); _leave(" = %d", ret);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
/* instantiate the dentry */ /* instantiate the dentry */
ret = afs_iget(dir->i_sb,&cookie.fid,&inode); ret = afs_iget(dir->i_sb, &cookie.fid, &inode);
if (ret<0) { if (ret < 0) {
_leave(" = %d",ret); _leave(" = %d", ret);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
dentry->d_op = &afs_fs_dentry_operations; dentry->d_op = &afs_fs_dentry_operations;
dentry->d_fsdata = (void*) (unsigned long) vnode->status.version; dentry->d_fsdata = (void *) (unsigned long) vnode->status.version;
d_add(dentry,inode); d_add(dentry, inode);
_leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%lu }", _leave(" = 0 { vn=%u u=%u } -> { ino=%lu v=%lu }",
cookie.fid.vnode, cookie.fid.vnode,
cookie.fid.unique, cookie.fid.unique,
...@@ -486,7 +506,8 @@ static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry, ...@@ -486,7 +506,8 @@ static struct dentry *afs_dir_lookup(struct inode *dir, struct dentry *dentry,
/*****************************************************************************/ /*****************************************************************************/
/* /*
* check that a dentry lookup hit has found a valid entry * check that a dentry lookup hit has found a valid entry
* - NOTE! the hit can be a negative hit too, so we can't assume we have an inode * - NOTE! the hit can be a negative hit too, so we can't assume we have an
* inode
* (derived from nfs_lookup_revalidate) * (derived from nfs_lookup_revalidate)
*/ */
static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
...@@ -497,7 +518,7 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) ...@@ -497,7 +518,7 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
unsigned fpos; unsigned fpos;
int ret; int ret;
_enter("{sb=%p n=%s},",dentry->d_sb,dentry->d_name.name); _enter("{sb=%p n=%s},", dentry->d_sb, dentry->d_name.name);
/* lock down the parent dentry so we can peer at it */ /* lock down the parent dentry so we can peer at it */
parent = dget_parent(dentry->d_parent); parent = dget_parent(dentry->d_parent);
...@@ -505,39 +526,41 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) ...@@ -505,39 +526,41 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
dir = parent->d_inode; dir = parent->d_inode;
inode = dentry->d_inode; inode = dentry->d_inode;
/* handle a negative inode */ /* handle a negative dentry */
if (!inode) if (!inode)
goto out_bad; goto out_bad;
/* handle a bad inode */ /* handle a bad inode */
if (is_bad_inode(inode)) { if (is_bad_inode(inode)) {
printk("kAFS: afs_d_revalidate: %s/%s has bad inode\n", printk("kAFS: afs_d_revalidate: %s/%s has bad inode\n",
dentry->d_parent->d_name.name,dentry->d_name.name); dentry->d_parent->d_name.name, dentry->d_name.name);
goto out_bad; goto out_bad;
} }
/* force a full look up if the parent directory changed since last the server was consulted /* force a full look up if the parent directory changed since last the
* - otherwise this inode must still exist, even if the inode details themselves have * server was consulted
* changed * - otherwise this inode must still exist, even if the inode details
* themselves have changed
*/ */
if (AFS_FS_I(dir)->flags & AFS_VNODE_CHANGED) if (AFS_FS_I(dir)->flags & AFS_VNODE_CHANGED)
afs_vnode_fetch_status(AFS_FS_I(dir)); afs_vnode_fetch_status(AFS_FS_I(dir));
if (AFS_FS_I(dir)->flags & AFS_VNODE_DELETED) { if (AFS_FS_I(dir)->flags & AFS_VNODE_DELETED) {
_debug("%s: parent dir deleted",dentry->d_name.name); _debug("%s: parent dir deleted", dentry->d_name.name);
goto out_bad; goto out_bad;
} }
if (AFS_FS_I(inode)->flags & AFS_VNODE_DELETED) { if (AFS_FS_I(inode)->flags & AFS_VNODE_DELETED) {
_debug("%s: file already deleted",dentry->d_name.name); _debug("%s: file already deleted", dentry->d_name.name);
goto out_bad; goto out_bad;
} }
if ((unsigned long)dentry->d_fsdata != (unsigned long)AFS_FS_I(dir)->status.version) { if ((unsigned long) dentry->d_fsdata !=
(unsigned long) AFS_FS_I(dir)->status.version) {
_debug("%s: parent changed %lu -> %u", _debug("%s: parent changed %lu -> %u",
dentry->d_name.name, dentry->d_name.name,
(unsigned long)dentry->d_fsdata, (unsigned long) dentry->d_fsdata,
(unsigned)AFS_FS_I(dir)->status.version); (unsigned) AFS_FS_I(dir)->status.version);
/* search the directory for this vnode */ /* search the directory for this vnode */
cookie.name = dentry->d_name.name; cookie.name = dentry->d_name.name;
...@@ -546,25 +569,29 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) ...@@ -546,25 +569,29 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
cookie.found = 0; cookie.found = 0;
fpos = 0; fpos = 0;
ret = afs_dir_iterate(dir,&fpos,&cookie,afs_dir_lookup_filldir); ret = afs_dir_iterate(dir, &fpos, &cookie,
if (ret<0) { afs_dir_lookup_filldir);
_debug("failed to iterate dir %s: %d",parent->d_name.name,ret); if (ret < 0) {
_debug("failed to iterate dir %s: %d",
parent->d_name.name, ret);
goto out_bad; goto out_bad;
} }
if (!cookie.found) { if (!cookie.found) {
_debug("%s: dirent not found",dentry->d_name.name); _debug("%s: dirent not found", dentry->d_name.name);
goto not_found; goto not_found;
} }
/* if the vnode ID has changed, then the dirent points to a different file */ /* if the vnode ID has changed, then the dirent points to a
if (cookie.fid.vnode!=AFS_FS_I(inode)->fid.vnode) { * different file */
_debug("%s: dirent changed",dentry->d_name.name); if (cookie.fid.vnode != AFS_FS_I(inode)->fid.vnode) {
_debug("%s: dirent changed", dentry->d_name.name);
goto not_found; goto not_found;
} }
/* if the vnode ID uniqifier has changed, then the file has been deleted */ /* if the vnode ID uniqifier has changed, then the file has
if (cookie.fid.unique!=AFS_FS_I(inode)->fid.unique) { * been deleted */
if (cookie.fid.unique != AFS_FS_I(inode)->fid.unique) {
_debug("%s: file deleted (uq %u -> %u I:%lu)", _debug("%s: file deleted (uq %u -> %u I:%lu)",
dentry->d_name.name, dentry->d_name.name,
cookie.fid.unique, cookie.fid.unique,
...@@ -577,7 +604,8 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) ...@@ -577,7 +604,8 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
goto out_bad; goto out_bad;
} }
dentry->d_fsdata = (void*) (unsigned long) AFS_FS_I(dir)->status.version; dentry->d_fsdata =
(void *) (unsigned long) AFS_FS_I(dir)->status.version;
} }
out_valid: out_valid:
...@@ -598,7 +626,8 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) ...@@ -598,7 +626,8 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
shrink_dcache_parent(dentry); shrink_dcache_parent(dentry);
_debug("dropping dentry %s/%s",dentry->d_parent->d_name.name,dentry->d_name.name); _debug("dropping dentry %s/%s",
dentry->d_parent->d_name.name, dentry->d_name.name);
d_drop(dentry); d_drop(dentry);
dput(parent); dput(parent);
...@@ -609,13 +638,14 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd) ...@@ -609,13 +638,14 @@ static int afs_d_revalidate(struct dentry *dentry, struct nameidata *nd)
/*****************************************************************************/ /*****************************************************************************/
/* /*
* allow the VFS to enquire as to whether a dentry should be unhashed (mustn't sleep) * allow the VFS to enquire as to whether a dentry should be unhashed (mustn't
* sleep)
* - called from dput() when d_count is going to 0. * - called from dput() when d_count is going to 0.
* - return 1 to request dentry be unhashed, 0 otherwise * - return 1 to request dentry be unhashed, 0 otherwise
*/ */
static int afs_d_delete(struct dentry *dentry) static int afs_d_delete(struct dentry *dentry)
{ {
_enter("%s",dentry->d_name.name); _enter("%s", dentry->d_name.name);
if (dentry->d_flags & DCACHE_NFSFS_RENAMED) if (dentry->d_flags & DCACHE_NFSFS_RENAMED)
goto zap; goto zap;
......
...@@ -31,7 +31,8 @@ static int afs_file_readpage(struct file *file, struct page *page); ...@@ -31,7 +31,8 @@ static int afs_file_readpage(struct file *file, struct page *page);
static int afs_file_invalidatepage(struct page *page, unsigned long offset); static int afs_file_invalidatepage(struct page *page, unsigned long offset);
static int afs_file_releasepage(struct page *page, int gfp_flags); static int afs_file_releasepage(struct page *page, int gfp_flags);
static ssize_t afs_file_write(struct file *file, const char *buf, size_t size, loff_t *off); static ssize_t afs_file_write(struct file *file, const char *buf, size_t size,
loff_t *off);
struct inode_operations afs_file_inode_operations = { struct inode_operations afs_file_inode_operations = {
.getattr = afs_inode_getattr, .getattr = afs_inode_getattr,
...@@ -60,9 +61,10 @@ struct address_space_operations afs_fs_aops = { ...@@ -60,9 +61,10 @@ struct address_space_operations afs_fs_aops = {
/* /*
* AFS file write * AFS file write
*/ */
static ssize_t afs_file_write(struct file *file, const char *buf, size_t size, loff_t *off) static ssize_t afs_file_write(struct file *file, const char *buf, size_t size,
loff_t *off)
{ {
afs_vnode_t *vnode; struct afs_vnode *vnode;
vnode = AFS_FS_I(file->f_dentry->d_inode); vnode = AFS_FS_I(file->f_dentry->d_inode);
if (vnode->flags & AFS_VNODE_DELETED) if (vnode->flags & AFS_VNODE_DELETED)
...@@ -76,10 +78,12 @@ static ssize_t afs_file_write(struct file *file, const char *buf, size_t size, l ...@@ -76,10 +78,12 @@ static ssize_t afs_file_write(struct file *file, const char *buf, size_t size, l
* deal with notification that a page was read from the cache * deal with notification that a page was read from the cache
*/ */
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
static void afs_file_readpage_read_complete(void *cookie_data, struct page *page, void *data, static void afs_file_readpage_read_complete(void *cookie_data,
struct page *page,
void *data,
int error) int error)
{ {
_enter("%p,%p,%p,%d",cookie_data,page,data,error); _enter("%p,%p,%p,%d", cookie_data, page, data, error);
if (error) if (error)
SetPageError(page); SetPageError(page);
...@@ -95,10 +99,12 @@ static void afs_file_readpage_read_complete(void *cookie_data, struct page *page ...@@ -95,10 +99,12 @@ static void afs_file_readpage_read_complete(void *cookie_data, struct page *page
* deal with notification that a page was written to the cache * deal with notification that a page was written to the cache
*/ */
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
static void afs_file_readpage_write_complete(void *cookie_data, struct page *page, void *data, static void afs_file_readpage_write_complete(void *cookie_data,
struct page *page,
void *data,
int error) int error)
{ {
_enter("%p,%p,%p,%d",cookie_data,page,data,error); _enter("%p,%p,%p,%d", cookie_data, page, data, error);
unlock_page(page); unlock_page(page);
...@@ -115,13 +121,13 @@ static int afs_file_readpage(struct file *file, struct page *page) ...@@ -115,13 +121,13 @@ static int afs_file_readpage(struct file *file, struct page *page)
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
struct cachefs_page *pageio; struct cachefs_page *pageio;
#endif #endif
struct afs_vnode *vnode;
struct inode *inode; struct inode *inode;
afs_vnode_t *vnode;
int ret; int ret;
inode = page->mapping->host; inode = page->mapping->host;
_enter("{%lu},{%lu}",inode->i_ino,page->index); _enter("{%lu},{%lu}", inode->i_ino, page->index);
vnode = AFS_FS_I(inode); vnode = AFS_FS_I(inode);
...@@ -133,8 +139,8 @@ static int afs_file_readpage(struct file *file, struct page *page) ...@@ -133,8 +139,8 @@ static int afs_file_readpage(struct file *file, struct page *page)
goto error; goto error;
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
ret = cachefs_page_get_private(page,&pageio,GFP_NOIO); ret = cachefs_page_get_private(page, &pageio, GFP_NOIO);
if (ret<0) if (ret < 0)
goto error; goto error;
/* is it cached? */ /* is it cached? */
...@@ -162,23 +168,26 @@ static int afs_file_readpage(struct file *file, struct page *page) ...@@ -162,23 +168,26 @@ static int afs_file_readpage(struct file *file, struct page *page)
default: default:
desc.fid = vnode->fid; desc.fid = vnode->fid;
desc.offset = page->index << PAGE_CACHE_SHIFT; desc.offset = page->index << PAGE_CACHE_SHIFT;
desc.size = min((size_t)(inode->i_size - desc.offset),(size_t)PAGE_SIZE); desc.size = min((size_t) (inode->i_size - desc.offset),
(size_t) PAGE_SIZE);
desc.buffer = kmap(page); desc.buffer = kmap(page);
clear_page(desc.buffer); clear_page(desc.buffer);
/* read the contents of the file from the server into the page */ /* read the contents of the file from the server into the
ret = afs_vnode_fetch_data(vnode,&desc); * page */
ret = afs_vnode_fetch_data(vnode, &desc);
kunmap(page); kunmap(page);
if (ret<0) { if (ret < 0) {
if (ret==-ENOENT) { if (ret==-ENOENT) {
_debug("got NOENT from server - marking file deleted and stale"); _debug("got NOENT from server"
" - marking file deleted and stale");
vnode->flags |= AFS_VNODE_DELETED; vnode->flags |= AFS_VNODE_DELETED;
ret = -ESTALE; ret = -ESTALE;
} }
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
cachefs_uncache_page(vnode->cache,page); cachefs_uncache_page(vnode->cache, page);
#endif #endif
goto error; goto error;
} }
...@@ -192,7 +201,7 @@ static int afs_file_readpage(struct file *file, struct page *page) ...@@ -192,7 +201,7 @@ static int afs_file_readpage(struct file *file, struct page *page)
NULL, NULL,
GFP_KERNEL) != 0 GFP_KERNEL) != 0
) { ) {
cachefs_uncache_page(vnode->cache,page); cachefs_uncache_page(vnode->cache, page);
unlock_page(page); unlock_page(page);
} }
#else #else
...@@ -207,7 +216,7 @@ static int afs_file_readpage(struct file *file, struct page *page) ...@@ -207,7 +216,7 @@ static int afs_file_readpage(struct file *file, struct page *page)
SetPageError(page); SetPageError(page);
unlock_page(page); unlock_page(page);
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_file_readpage() */ } /* end afs_file_readpage() */
...@@ -217,14 +226,15 @@ static int afs_file_readpage(struct file *file, struct page *page) ...@@ -217,14 +226,15 @@ static int afs_file_readpage(struct file *file, struct page *page)
* get a page cookie for the specified page * get a page cookie for the specified page
*/ */
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
int afs_cache_get_page_cookie(struct page *page, struct cachefs_page **_page_cookie) int afs_cache_get_page_cookie(struct page *page,
struct cachefs_page **_page_cookie)
{ {
int ret; int ret;
_enter(""); _enter("");
ret = cachefs_page_get_private(page,_page_cookie,GFP_NOIO); ret = cachefs_page_get_private(page,_page_cookie, GFP_NOIO);
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_cache_get_page_cookie() */ } /* end afs_cache_get_page_cookie() */
#endif #endif
...@@ -237,30 +247,32 @@ static int afs_file_invalidatepage(struct page *page, unsigned long offset) ...@@ -237,30 +247,32 @@ static int afs_file_invalidatepage(struct page *page, unsigned long offset)
{ {
int ret = 1; int ret = 1;
_enter("{%lu},%lu",page->index,offset); _enter("{%lu},%lu", page->index, offset);
BUG_ON(!PageLocked(page)); BUG_ON(!PageLocked(page));
if (PagePrivate(page)) { if (PagePrivate(page)) {
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
cachefs_uncache_page(vnode->cache,page); cachefs_uncache_page(vnode->cache,page);
#endif #endif
/* /* We release buffers only if the entire page is being
* We release buffers only if the entire page is being invalidated. * invalidated.
* The get_block cached value has been unconditionally invalidated, * The get_block cached value has been unconditionally
* so real IO is not possible anymore. * invalidated, so real IO is not possible anymore.
*/ */
if (offset == 0) { if (offset == 0) {
BUG_ON(!PageLocked(page)); BUG_ON(!PageLocked(page));
ret = 0; ret = 0;
if (!PageWriteback(page)) if (!PageWriteback(page))
ret = page->mapping->a_ops->releasepage(page, 0); ret = page->mapping->a_ops->releasepage(page,
0);
} }
} }
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_file_invalidatepage() */ } /* end afs_file_invalidatepage() */
...@@ -272,12 +284,12 @@ static int afs_file_releasepage(struct page *page, int gfp_flags) ...@@ -272,12 +284,12 @@ static int afs_file_releasepage(struct page *page, int gfp_flags)
{ {
struct cachefs_page *pageio; struct cachefs_page *pageio;
_enter("{%lu},%x",page->index,gfp_flags); _enter("{%lu},%x", page->index, gfp_flags);
if (PagePrivate(page)) { if (PagePrivate(page)) {
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
struct afs_vnode *vnode = AFS_FS_I(page->mapping->host); struct afs_vnode *vnode = AFS_FS_I(page->mapping->host);
cachefs_uncache_page(vnode->cache,page); cachefs_uncache_page(vnode->cache, page);
#endif #endif
pageio = (struct cachefs_page *) page->private; pageio = (struct cachefs_page *) page->private;
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#define FSFETCHSTATUS 132 /* AFS Fetch file status */ #define FSFETCHSTATUS 132 /* AFS Fetch file status */
#define FSFETCHDATA 130 /* AFS Fetch file data */ #define FSFETCHDATA 130 /* AFS Fetch file data */
#define FSGIVEUPCALLBACKS 147 /* AFS Discard server callback promises */ #define FSGIVEUPCALLBACKS 147 /* AFS Discard callback promises */
#define FSGETVOLUMEINFO 148 /* AFS Get root volume information */ #define FSGETVOLUMEINFO 148 /* AFS Get root volume information */
#define FSGETROOTVOLUME 151 /* AFS Get root volume name */ #define FSGETROOTVOLUME 151 /* AFS Get root volume name */
#define FSLOOKUP 161 /* AFS lookup file in directory */ #define FSLOOKUP 161 /* AFS lookup file in directory */
...@@ -54,10 +54,9 @@ static void afs_rxfs_aemap(struct rxrpc_call *call) ...@@ -54,10 +54,9 @@ static void afs_rxfs_aemap(struct rxrpc_call *call)
* - this operation doesn't seem to work correctly in OpenAFS server 1.2.2 * - this operation doesn't seem to work correctly in OpenAFS server 1.2.2
*/ */
#if 0 #if 0
int afs_rxfs_get_root_volume(afs_server_t *server, char *buf, size_t *buflen) int afs_rxfs_get_root_volume(struct afs_server *server,
char *buf, size_t *buflen)
{ {
DECLARE_WAITQUEUE(myself,current);
struct rxrpc_connection *conn; struct rxrpc_connection *conn;
struct rxrpc_call *call; struct rxrpc_call *call;
struct iovec piov[2]; struct iovec piov[2];
...@@ -65,23 +64,25 @@ int afs_rxfs_get_root_volume(afs_server_t *server, char *buf, size_t *buflen) ...@@ -65,23 +64,25 @@ int afs_rxfs_get_root_volume(afs_server_t *server, char *buf, size_t *buflen)
int ret; int ret;
u32 param[1]; u32 param[1];
kenter("%p,%p,%u",server,buf,*buflen); DECLARE_WAITQUEUE(myself, current);
kenter("%p,%p,%u",server, buf, *buflen);
/* get hold of the fileserver connection */ /* get hold of the fileserver connection */
ret = afs_server_get_fsconn(server,&conn); ret = afs_server_get_fsconn(server, &conn);
if (ret<0) if (ret < 0)
goto out; goto out;
/* create a call through that connection */ /* create a call through that connection */
ret = rxrpc_create_call(conn,NULL,NULL,afs_rxfs_aemap,&call); ret = rxrpc_create_call(conn, NULL, NULL, afs_rxfs_aemap, &call);
if (ret<0) { if (ret < 0) {
printk("kAFS: Unable to create call: %d\n",ret); printk("kAFS: Unable to create call: %d\n", ret);
goto out_put_conn; goto out_put_conn;
} }
call->app_opcode = FSGETROOTVOLUME; call->app_opcode = FSGETROOTVOLUME;
/* we want to get event notifications from the call */ /* we want to get event notifications from the call */
add_wait_queue(&call->waitq,&myself); add_wait_queue(&call->waitq, &myself);
/* marshall the parameters */ /* marshall the parameters */
param[0] = htonl(FSGETROOTVOLUME); param[0] = htonl(FSGETROOTVOLUME);
...@@ -90,14 +91,15 @@ int afs_rxfs_get_root_volume(afs_server_t *server, char *buf, size_t *buflen) ...@@ -90,14 +91,15 @@ int afs_rxfs_get_root_volume(afs_server_t *server, char *buf, size_t *buflen)
piov[0].iov_base = param; piov[0].iov_base = param;
/* send the parameters to the server */ /* send the parameters to the server */
ret = rxrpc_call_write_data(call,1,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent); ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS,
if (ret<0) 0, &sent);
if (ret < 0)
goto abort; goto abort;
/* wait for the reply to completely arrive */ /* wait for the reply to completely arrive */
for (;;) { for (;;) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
if (call->app_call_state!=RXRPC_CSTATE_CLNT_RCV_REPLY || if (call->app_call_state != RXRPC_CSTATE_CLNT_RCV_REPLY ||
signal_pending(current)) signal_pending(current))
break; break;
schedule(); schedule();
...@@ -111,41 +113,41 @@ int afs_rxfs_get_root_volume(afs_server_t *server, char *buf, size_t *buflen) ...@@ -111,41 +113,41 @@ int afs_rxfs_get_root_volume(afs_server_t *server, char *buf, size_t *buflen)
switch (call->app_call_state) { switch (call->app_call_state) {
case RXRPC_CSTATE_ERROR: case RXRPC_CSTATE_ERROR:
ret = call->app_errno; ret = call->app_errno;
kdebug("Got Error: %d",ret); kdebug("Got Error: %d", ret);
goto out_unwait; goto out_unwait;
case RXRPC_CSTATE_CLNT_GOT_REPLY: case RXRPC_CSTATE_CLNT_GOT_REPLY:
/* read the reply */ /* read the reply */
kdebug("Got Reply: qty=%d",call->app_ready_qty); kdebug("Got Reply: qty=%d", call->app_ready_qty);
ret = -EBADMSG; ret = -EBADMSG;
if (call->app_ready_qty <= 4) if (call->app_ready_qty <= 4)
goto abort; goto abort;
ret = rxrpc_call_read_data(call,NULL,call->app_ready_qty,0); ret = rxrpc_call_read_data(call, NULL, call->app_ready_qty, 0);
if (ret<0) if (ret < 0)
goto abort; goto abort;
#if 0 #if 0
/* unmarshall the reply */ /* unmarshall the reply */
bp = buffer; bp = buffer;
for (loop=0; loop<65; loop++) for (loop = 0; loop < 65; loop++)
entry->name[loop] = ntohl(*bp++); entry->name[loop] = ntohl(*bp++);
entry->name[64] = 0; entry->name[64] = 0;
entry->type = ntohl(*bp++); entry->type = ntohl(*bp++);
entry->num_servers = ntohl(*bp++); entry->num_servers = ntohl(*bp++);
for (loop=0; loop<8; loop++) for (loop = 0; loop < 8; loop++)
entry->servers[loop].addr.s_addr = *bp++; entry->servers[loop].addr.s_addr = *bp++;
for (loop=0; loop<8; loop++) for (loop = 0; loop < 8; loop++)
entry->servers[loop].partition = ntohl(*bp++); entry->servers[loop].partition = ntohl(*bp++);
for (loop=0; loop<8; loop++) for (loop = 0; loop < 8; loop++)
entry->servers[loop].flags = ntohl(*bp++); entry->servers[loop].flags = ntohl(*bp++);
for (loop=0; loop<3; loop++) for (loop = 0; loop < 3; loop++)
entry->volume_ids[loop] = ntohl(*bp++); entry->volume_ids[loop] = ntohl(*bp++);
entry->clone_id = ntohl(*bp++); entry->clone_id = ntohl(*bp++);
...@@ -162,14 +164,14 @@ int afs_rxfs_get_root_volume(afs_server_t *server, char *buf, size_t *buflen) ...@@ -162,14 +164,14 @@ int afs_rxfs_get_root_volume(afs_server_t *server, char *buf, size_t *buflen)
abort: abort:
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
rxrpc_call_abort(call,ret); rxrpc_call_abort(call, ret);
schedule(); schedule();
out_unwait: out_unwait:
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
remove_wait_queue(&call->waitq,&myself); remove_wait_queue(&call->waitq, &myself);
rxrpc_put_call(call); rxrpc_put_call(call);
out_put_conn: out_put_conn:
afs_server_release_fsconn(server,conn); afs_server_release_fsconn(server, conn);
out: out:
kleave(""); kleave("");
return ret; return ret;
...@@ -181,12 +183,10 @@ int afs_rxfs_get_root_volume(afs_server_t *server, char *buf, size_t *buflen) ...@@ -181,12 +183,10 @@ int afs_rxfs_get_root_volume(afs_server_t *server, char *buf, size_t *buflen)
* get information about a volume * get information about a volume
*/ */
#if 0 #if 0
int afs_rxfs_get_volume_info(afs_server_t *server, int afs_rxfs_get_volume_info(struct afs_server *server,
const char *name, const char *name,
afs_volume_info_t *vinfo) struct afs_volume_info *vinfo)
{ {
DECLARE_WAITQUEUE(myself,current);
struct rxrpc_connection *conn; struct rxrpc_connection *conn;
struct rxrpc_call *call; struct rxrpc_call *call;
struct iovec piov[3]; struct iovec piov[3];
...@@ -194,27 +194,29 @@ int afs_rxfs_get_volume_info(afs_server_t *server, ...@@ -194,27 +194,29 @@ int afs_rxfs_get_volume_info(afs_server_t *server,
int ret; int ret;
u32 param[2], *bp, zero; u32 param[2], *bp, zero;
_enter("%p,%s,%p",server,name,vinfo); DECLARE_WAITQUEUE(myself, current);
_enter("%p,%s,%p", server, name, vinfo);
/* get hold of the fileserver connection */ /* get hold of the fileserver connection */
ret = afs_server_get_fsconn(server,&conn); ret = afs_server_get_fsconn(server, &conn);
if (ret<0) if (ret < 0)
goto out; goto out;
/* create a call through that connection */ /* create a call through that connection */
ret = rxrpc_create_call(conn,NULL,NULL,afs_rxfs_aemap,&call); ret = rxrpc_create_call(conn, NULL, NULL, afs_rxfs_aemap, &call);
if (ret<0) { if (ret < 0) {
printk("kAFS: Unable to create call: %d\n",ret); printk("kAFS: Unable to create call: %d\n", ret);
goto out_put_conn; goto out_put_conn;
} }
call->app_opcode = FSGETVOLUMEINFO; call->app_opcode = FSGETVOLUMEINFO;
/* we want to get event notifications from the call */ /* we want to get event notifications from the call */
add_wait_queue(&call->waitq,&myself); add_wait_queue(&call->waitq, &myself);
/* marshall the parameters */ /* marshall the parameters */
piov[1].iov_len = strlen(name); piov[1].iov_len = strlen(name);
piov[1].iov_base = (char*)name; piov[1].iov_base = (char *) name;
zero = 0; zero = 0;
piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3; piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3;
...@@ -227,16 +229,19 @@ int afs_rxfs_get_volume_info(afs_server_t *server, ...@@ -227,16 +229,19 @@ int afs_rxfs_get_volume_info(afs_server_t *server,
piov[0].iov_base = param; piov[0].iov_base = param;
/* send the parameters to the server */ /* send the parameters to the server */
ret = rxrpc_call_write_data(call,3,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent); ret = rxrpc_call_write_data(call, 3, piov, RXRPC_LAST_PACKET, GFP_NOFS,
if (ret<0) 0, &sent);
if (ret < 0)
goto abort; goto abort;
/* wait for the reply to completely arrive */ /* wait for the reply to completely arrive */
bp = rxrpc_call_alloc_scratch(call,64); bp = rxrpc_call_alloc_scratch(call, 64);
ret = rxrpc_call_read_data(call,bp,64,RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL); ret = rxrpc_call_read_data(call, bp, 64,
if (ret<0) { RXRPC_CALL_READ_BLOCK |
if (ret==-ECONNABORTED) { RXRPC_CALL_READ_ALL);
if (ret < 0) {
if (ret == -ECONNABORTED) {
ret = call->app_errno; ret = call->app_errno;
goto out_unwait; goto out_unwait;
} }
...@@ -264,7 +269,7 @@ int afs_rxfs_get_volume_info(afs_server_t *server, ...@@ -264,7 +269,7 @@ int afs_rxfs_get_volume_info(afs_server_t *server,
vinfo->servers[7].addr.s_addr = *bp++; vinfo->servers[7].addr.s_addr = *bp++;
ret = -EBADMSG; ret = -EBADMSG;
if (vinfo->nservers>8) if (vinfo->nservers > 8)
goto abort; goto abort;
/* success */ /* success */
...@@ -272,17 +277,17 @@ int afs_rxfs_get_volume_info(afs_server_t *server, ...@@ -272,17 +277,17 @@ int afs_rxfs_get_volume_info(afs_server_t *server,
out_unwait: out_unwait:
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
remove_wait_queue(&call->waitq,&myself); remove_wait_queue(&call->waitq, &myself);
rxrpc_put_call(call); rxrpc_put_call(call);
out_put_conn: out_put_conn:
afs_server_release_fsconn(server,conn); afs_server_release_fsconn(server, conn);
out: out:
_leave(""); _leave("");
return ret; return ret;
abort: abort:
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
rxrpc_call_abort(call,ret); rxrpc_call_abort(call, ret);
schedule(); schedule();
goto out_unwait; goto out_unwait;
...@@ -293,12 +298,10 @@ int afs_rxfs_get_volume_info(afs_server_t *server, ...@@ -293,12 +298,10 @@ int afs_rxfs_get_volume_info(afs_server_t *server,
/* /*
* fetch the status information for a file * fetch the status information for a file
*/ */
int afs_rxfs_fetch_file_status(afs_server_t *server, int afs_rxfs_fetch_file_status(struct afs_server *server,
afs_vnode_t *vnode, struct afs_vnode *vnode,
afs_volsync_t *volsync) struct afs_volsync *volsync)
{ {
DECLARE_WAITQUEUE(myself,current);
struct afs_server_callslot callslot; struct afs_server_callslot callslot;
struct rxrpc_call *call; struct rxrpc_call *call;
struct iovec piov[1]; struct iovec piov[1];
...@@ -306,26 +309,30 @@ int afs_rxfs_fetch_file_status(afs_server_t *server, ...@@ -306,26 +309,30 @@ int afs_rxfs_fetch_file_status(afs_server_t *server,
int ret; int ret;
u32 *bp; u32 *bp;
_enter("%p,{%u,%u,%u}",server,vnode->fid.vid,vnode->fid.vnode,vnode->fid.unique); DECLARE_WAITQUEUE(myself, current);
_enter("%p,{%u,%u,%u}",
server, vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique);
/* get hold of the fileserver connection */ /* get hold of the fileserver connection */
ret = afs_server_request_callslot(server,&callslot); ret = afs_server_request_callslot(server, &callslot);
if (ret<0) if (ret < 0)
goto out; goto out;
/* create a call through that connection */ /* create a call through that connection */
ret = rxrpc_create_call(callslot.conn,NULL,NULL,afs_rxfs_aemap,&call); ret = rxrpc_create_call(callslot.conn, NULL, NULL, afs_rxfs_aemap,
if (ret<0) { &call);
printk("kAFS: Unable to create call: %d\n",ret); if (ret < 0) {
printk("kAFS: Unable to create call: %d\n", ret);
goto out_put_conn; goto out_put_conn;
} }
call->app_opcode = FSFETCHSTATUS; call->app_opcode = FSFETCHSTATUS;
/* we want to get event notifications from the call */ /* we want to get event notifications from the call */
add_wait_queue(&call->waitq,&myself); add_wait_queue(&call->waitq, &myself);
/* marshall the parameters */ /* marshall the parameters */
bp = rxrpc_call_alloc_scratch(call,16); bp = rxrpc_call_alloc_scratch(call, 16);
bp[0] = htonl(FSFETCHSTATUS); bp[0] = htonl(FSFETCHSTATUS);
bp[1] = htonl(vnode->fid.vid); bp[1] = htonl(vnode->fid.vid);
bp[2] = htonl(vnode->fid.vnode); bp[2] = htonl(vnode->fid.vnode);
...@@ -335,16 +342,19 @@ int afs_rxfs_fetch_file_status(afs_server_t *server, ...@@ -335,16 +342,19 @@ int afs_rxfs_fetch_file_status(afs_server_t *server,
piov[0].iov_base = bp; piov[0].iov_base = bp;
/* send the parameters to the server */ /* send the parameters to the server */
ret = rxrpc_call_write_data(call,1,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent); ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS,
if (ret<0) 0, &sent);
if (ret < 0)
goto abort; goto abort;
/* wait for the reply to completely arrive */ /* wait for the reply to completely arrive */
bp = rxrpc_call_alloc_scratch(call,120); bp = rxrpc_call_alloc_scratch(call, 120);
ret = rxrpc_call_read_data(call,bp,120,RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL); ret = rxrpc_call_read_data(call, bp, 120,
if (ret<0) { RXRPC_CALL_READ_BLOCK |
if (ret==-ECONNABORTED) { RXRPC_CALL_READ_ALL);
if (ret < 0) {
if (ret == -ECONNABORTED) {
ret = call->app_errno; ret = call->app_errno;
goto out_unwait; goto out_unwait;
} }
...@@ -393,17 +403,17 @@ int afs_rxfs_fetch_file_status(afs_server_t *server, ...@@ -393,17 +403,17 @@ int afs_rxfs_fetch_file_status(afs_server_t *server,
out_unwait: out_unwait:
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
remove_wait_queue(&call->waitq,&myself); remove_wait_queue(&call->waitq, &myself);
rxrpc_put_call(call); rxrpc_put_call(call);
out_put_conn: out_put_conn:
afs_server_release_callslot(server,&callslot); afs_server_release_callslot(server, &callslot);
out: out:
_leave(""); _leave("");
return ret; return ret;
abort: abort:
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
rxrpc_call_abort(call,ret); rxrpc_call_abort(call, ret);
schedule(); schedule();
goto out_unwait; goto out_unwait;
} /* end afs_rxfs_fetch_file_status() */ } /* end afs_rxfs_fetch_file_status() */
...@@ -412,13 +422,11 @@ int afs_rxfs_fetch_file_status(afs_server_t *server, ...@@ -412,13 +422,11 @@ int afs_rxfs_fetch_file_status(afs_server_t *server,
/* /*
* fetch the contents of a file or directory * fetch the contents of a file or directory
*/ */
int afs_rxfs_fetch_file_data(afs_server_t *server, int afs_rxfs_fetch_file_data(struct afs_server *server,
afs_vnode_t *vnode, struct afs_vnode *vnode,
struct afs_rxfs_fetch_descriptor *desc, struct afs_rxfs_fetch_descriptor *desc,
afs_volsync_t *volsync) struct afs_volsync *volsync)
{ {
DECLARE_WAITQUEUE(myself,current);
struct afs_server_callslot callslot; struct afs_server_callslot callslot;
struct rxrpc_call *call; struct rxrpc_call *call;
struct iovec piov[1]; struct iovec piov[1];
...@@ -426,6 +434,8 @@ int afs_rxfs_fetch_file_data(afs_server_t *server, ...@@ -426,6 +434,8 @@ int afs_rxfs_fetch_file_data(afs_server_t *server,
int ret; int ret;
u32 *bp; u32 *bp;
DECLARE_WAITQUEUE(myself, current);
_enter("%p,{fid={%u,%u,%u},sz=%Zu,of=%lu}", _enter("%p,{fid={%u,%u,%u},sz=%Zu,of=%lu}",
server, server,
desc->fid.vid, desc->fid.vid,
...@@ -435,23 +445,23 @@ int afs_rxfs_fetch_file_data(afs_server_t *server, ...@@ -435,23 +445,23 @@ int afs_rxfs_fetch_file_data(afs_server_t *server,
desc->offset); desc->offset);
/* get hold of the fileserver connection */ /* get hold of the fileserver connection */
ret = afs_server_request_callslot(server,&callslot); ret = afs_server_request_callslot(server, &callslot);
if (ret<0) if (ret < 0)
goto out; goto out;
/* create a call through that connection */ /* create a call through that connection */
ret = rxrpc_create_call(callslot.conn,NULL,NULL,afs_rxfs_aemap,&call); ret = rxrpc_create_call(callslot.conn, NULL, NULL, afs_rxfs_aemap, &call);
if (ret<0) { if (ret < 0) {
printk("kAFS: Unable to create call: %d\n",ret); printk("kAFS: Unable to create call: %d\n", ret);
goto out_put_conn; goto out_put_conn;
} }
call->app_opcode = FSFETCHDATA; call->app_opcode = FSFETCHDATA;
/* we want to get event notifications from the call */ /* we want to get event notifications from the call */
add_wait_queue(&call->waitq,&myself); add_wait_queue(&call->waitq, &myself);
/* marshall the parameters */ /* marshall the parameters */
bp = rxrpc_call_alloc_scratch(call,24); bp = rxrpc_call_alloc_scratch(call, 24);
bp[0] = htonl(FSFETCHDATA); bp[0] = htonl(FSFETCHDATA);
bp[1] = htonl(desc->fid.vid); bp[1] = htonl(desc->fid.vid);
bp[2] = htonl(desc->fid.vnode); bp[2] = htonl(desc->fid.vnode);
...@@ -463,17 +473,18 @@ int afs_rxfs_fetch_file_data(afs_server_t *server, ...@@ -463,17 +473,18 @@ int afs_rxfs_fetch_file_data(afs_server_t *server,
piov[0].iov_base = bp; piov[0].iov_base = bp;
/* send the parameters to the server */ /* send the parameters to the server */
ret = rxrpc_call_write_data(call,1,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent); ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS,
if (ret<0) 0, &sent);
if (ret < 0)
goto abort; goto abort;
/* wait for the data count to arrive */ /* wait for the data count to arrive */
ret = rxrpc_call_read_data(call,bp,4,RXRPC_CALL_READ_BLOCK); ret = rxrpc_call_read_data(call, bp, 4, RXRPC_CALL_READ_BLOCK);
if (ret<0) if (ret < 0)
goto read_failed; goto read_failed;
desc->actual = ntohl(bp[0]); desc->actual = ntohl(bp[0]);
if (desc->actual!=desc->size) { if (desc->actual != desc->size) {
ret = -EBADMSG; ret = -EBADMSG;
goto abort; goto abort;
} }
...@@ -481,16 +492,19 @@ int afs_rxfs_fetch_file_data(afs_server_t *server, ...@@ -481,16 +492,19 @@ int afs_rxfs_fetch_file_data(afs_server_t *server,
/* call the app to read the actual data */ /* call the app to read the actual data */
rxrpc_call_reset_scratch(call); rxrpc_call_reset_scratch(call);
ret = rxrpc_call_read_data(call,desc->buffer,desc->actual,RXRPC_CALL_READ_BLOCK); ret = rxrpc_call_read_data(call, desc->buffer, desc->actual,
if (ret<0) RXRPC_CALL_READ_BLOCK);
if (ret < 0)
goto read_failed; goto read_failed;
/* wait for the rest of the reply to completely arrive */ /* wait for the rest of the reply to completely arrive */
rxrpc_call_reset_scratch(call); rxrpc_call_reset_scratch(call);
bp = rxrpc_call_alloc_scratch(call,120); bp = rxrpc_call_alloc_scratch(call, 120);
ret = rxrpc_call_read_data(call,bp,120,RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL); ret = rxrpc_call_read_data(call, bp, 120,
if (ret<0) RXRPC_CALL_READ_BLOCK |
RXRPC_CALL_READ_ALL);
if (ret < 0)
goto read_failed; goto read_failed;
/* unmarshall the reply */ /* unmarshall the reply */
...@@ -538,20 +552,20 @@ int afs_rxfs_fetch_file_data(afs_server_t *server, ...@@ -538,20 +552,20 @@ int afs_rxfs_fetch_file_data(afs_server_t *server,
remove_wait_queue(&call->waitq,&myself); remove_wait_queue(&call->waitq,&myself);
rxrpc_put_call(call); rxrpc_put_call(call);
out_put_conn: out_put_conn:
afs_server_release_callslot(server,&callslot); afs_server_release_callslot(server, &callslot);
out: out:
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
read_failed: read_failed:
if (ret==-ECONNABORTED) { if (ret == -ECONNABORTED) {
ret = call->app_errno; ret = call->app_errno;
goto out_unwait; goto out_unwait;
} }
abort: abort:
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
rxrpc_call_abort(call,ret); rxrpc_call_abort(call, ret);
schedule(); schedule();
goto out_unwait; goto out_unwait;
...@@ -561,10 +575,9 @@ int afs_rxfs_fetch_file_data(afs_server_t *server, ...@@ -561,10 +575,9 @@ int afs_rxfs_fetch_file_data(afs_server_t *server,
/* /*
* ask the AFS fileserver to discard a callback request on a file * ask the AFS fileserver to discard a callback request on a file
*/ */
int afs_rxfs_give_up_callback(afs_server_t *server, afs_vnode_t *vnode) int afs_rxfs_give_up_callback(struct afs_server *server,
struct afs_vnode *vnode)
{ {
DECLARE_WAITQUEUE(myself,current);
struct afs_server_callslot callslot; struct afs_server_callslot callslot;
struct rxrpc_call *call; struct rxrpc_call *call;
struct iovec piov[1]; struct iovec piov[1];
...@@ -572,28 +585,31 @@ int afs_rxfs_give_up_callback(afs_server_t *server, afs_vnode_t *vnode) ...@@ -572,28 +585,31 @@ int afs_rxfs_give_up_callback(afs_server_t *server, afs_vnode_t *vnode)
int ret; int ret;
u32 *bp; u32 *bp;
_enter("%p,{%u,%u,%u}",server,vnode->fid.vid,vnode->fid.vnode,vnode->fid.unique); DECLARE_WAITQUEUE(myself, current);
_enter("%p,{%u,%u,%u}",
server, vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique);
/* get hold of the fileserver connection */ /* get hold of the fileserver connection */
ret = afs_server_request_callslot(server,&callslot); ret = afs_server_request_callslot(server, &callslot);
if (ret<0) if (ret < 0)
goto out; goto out;
/* create a call through that connection */ /* create a call through that connection */
ret = rxrpc_create_call(callslot.conn,NULL,NULL,afs_rxfs_aemap,&call); ret = rxrpc_create_call(callslot.conn, NULL, NULL, afs_rxfs_aemap, &call);
if (ret<0) { if (ret < 0) {
printk("kAFS: Unable to create call: %d\n",ret); printk("kAFS: Unable to create call: %d\n", ret);
goto out_put_conn; goto out_put_conn;
} }
call->app_opcode = FSGIVEUPCALLBACKS; call->app_opcode = FSGIVEUPCALLBACKS;
/* we want to get event notifications from the call */ /* we want to get event notifications from the call */
add_wait_queue(&call->waitq,&myself); add_wait_queue(&call->waitq, &myself);
/* marshall the parameters */ /* marshall the parameters */
bp = rxrpc_call_alloc_scratch(call,(1+4+4)*4); bp = rxrpc_call_alloc_scratch(call, (1 + 4 + 4) * 4);
piov[0].iov_len = (1+4+4)*4; piov[0].iov_len = (1 + 4 + 4) * 4;
piov[0].iov_base = bp; piov[0].iov_base = bp;
*bp++ = htonl(FSGIVEUPCALLBACKS); *bp++ = htonl(FSGIVEUPCALLBACKS);
...@@ -607,14 +623,15 @@ int afs_rxfs_give_up_callback(afs_server_t *server, afs_vnode_t *vnode) ...@@ -607,14 +623,15 @@ int afs_rxfs_give_up_callback(afs_server_t *server, afs_vnode_t *vnode)
*bp++ = htonl(vnode->cb_type); *bp++ = htonl(vnode->cb_type);
/* send the parameters to the server */ /* send the parameters to the server */
ret = rxrpc_call_write_data(call,1,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent); ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS,
if (ret<0) 0, &sent);
if (ret < 0)
goto abort; goto abort;
/* wait for the reply to completely arrive */ /* wait for the reply to completely arrive */
for (;;) { for (;;) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
if (call->app_call_state!=RXRPC_CSTATE_CLNT_RCV_REPLY || if (call->app_call_state != RXRPC_CSTATE_CLNT_RCV_REPLY ||
signal_pending(current)) signal_pending(current))
break; break;
schedule(); schedule();
...@@ -640,17 +657,17 @@ int afs_rxfs_give_up_callback(afs_server_t *server, afs_vnode_t *vnode) ...@@ -640,17 +657,17 @@ int afs_rxfs_give_up_callback(afs_server_t *server, afs_vnode_t *vnode)
out_unwait: out_unwait:
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
remove_wait_queue(&call->waitq,&myself); remove_wait_queue(&call->waitq, &myself);
rxrpc_put_call(call); rxrpc_put_call(call);
out_put_conn: out_put_conn:
afs_server_release_callslot(server,&callslot); afs_server_release_callslot(server, &callslot);
out: out:
_leave(""); _leave("");
return ret; return ret;
abort: abort:
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
rxrpc_call_abort(call,ret); rxrpc_call_abort(call, ret);
schedule(); schedule();
goto out_unwait; goto out_unwait;
} /* end afs_rxfs_give_up_callback() */ } /* end afs_rxfs_give_up_callback() */
...@@ -661,14 +678,12 @@ int afs_rxfs_give_up_callback(afs_server_t *server, afs_vnode_t *vnode) ...@@ -661,14 +678,12 @@ int afs_rxfs_give_up_callback(afs_server_t *server, afs_vnode_t *vnode)
* - this operation doesn't seem to work correctly in OpenAFS server 1.2.2 * - this operation doesn't seem to work correctly in OpenAFS server 1.2.2
*/ */
#if 0 #if 0
int afs_rxfs_lookup(afs_server_t *server, int afs_rxfs_lookup(struct afs_server *server,
afs_vnode_t *dir, struct afs_vnode *dir,
const char *filename, const char *filename,
afs_vnode_t *vnode, struct afs_vnode *vnode,
afs_volsync_t *volsync) struct afs_volsync *volsync)
{ {
DECLARE_WAITQUEUE(myself,current);
struct rxrpc_connection *conn; struct rxrpc_connection *conn;
struct rxrpc_call *call; struct rxrpc_call *call;
struct iovec piov[3]; struct iovec piov[3];
...@@ -676,17 +691,20 @@ int afs_rxfs_lookup(afs_server_t *server, ...@@ -676,17 +691,20 @@ int afs_rxfs_lookup(afs_server_t *server,
int ret; int ret;
u32 *bp, zero; u32 *bp, zero;
kenter("%p,{%u,%u,%u},%s",server,fid->vid,fid->vnode,fid->unique,filename); DECLARE_WAITQUEUE(myself, current);
kenter("%p,{%u,%u,%u},%s",
server, fid->vid, fid->vnode, fid->unique, filename);
/* get hold of the fileserver connection */ /* get hold of the fileserver connection */
ret = afs_server_get_fsconn(server,&conn); ret = afs_server_get_fsconn(server, &conn);
if (ret<0) if (ret < 0)
goto out; goto out;
/* create a call through that connection */ /* create a call through that connection */
ret = rxrpc_create_call(conn,NULL,NULL,afs_rxfs_aemap,&call); ret = rxrpc_create_call(conn, NULL, NULL, afs_rxfs_aemap, &call);
if (ret<0) { if (ret < 0) {
printk("kAFS: Unable to create call: %d\n",ret); printk("kAFS: Unable to create call: %d\n", ret);
goto out_put_conn; goto out_put_conn;
} }
call->app_opcode = FSLOOKUP; call->app_opcode = FSLOOKUP;
...@@ -695,14 +713,14 @@ int afs_rxfs_lookup(afs_server_t *server, ...@@ -695,14 +713,14 @@ int afs_rxfs_lookup(afs_server_t *server,
add_wait_queue(&call->waitq,&myself); add_wait_queue(&call->waitq,&myself);
/* marshall the parameters */ /* marshall the parameters */
bp = rxrpc_call_alloc_scratch(call,20); bp = rxrpc_call_alloc_scratch(call, 20);
zero = 0; zero = 0;
piov[0].iov_len = 20; piov[0].iov_len = 20;
piov[0].iov_base = bp; piov[0].iov_base = bp;
piov[1].iov_len = strlen(filename); piov[1].iov_len = strlen(filename);
piov[1].iov_base = (char*) filename; piov[1].iov_base = (char *) filename;
piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3; piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3;
piov[2].iov_base = &zero; piov[2].iov_base = &zero;
...@@ -713,16 +731,19 @@ int afs_rxfs_lookup(afs_server_t *server, ...@@ -713,16 +731,19 @@ int afs_rxfs_lookup(afs_server_t *server,
*bp++ = htonl(piov[1].iov_len); *bp++ = htonl(piov[1].iov_len);
/* send the parameters to the server */ /* send the parameters to the server */
ret = rxrpc_call_write_data(call,3,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent); ret = rxrpc_call_write_data(call, 3, piov, RXRPC_LAST_PACKET, GFP_NOFS,
if (ret<0) 0, &sent);
if (ret < 0)
goto abort; goto abort;
/* wait for the reply to completely arrive */ /* wait for the reply to completely arrive */
bp = rxrpc_call_alloc_scratch(call,220); bp = rxrpc_call_alloc_scratch(call, 220);
ret = rxrpc_call_read_data(call,bp,220,RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL); ret = rxrpc_call_read_data(call, bp, 220,
if (ret<0) { RXRPC_CALL_READ_BLOCK |
if (ret==-ECONNABORTED) { RXRPC_CALL_READ_ALL);
if (ret < 0) {
if (ret == -ECONNABORTED) {
ret = call->app_errno; ret = call->app_errno;
goto out_unwait; goto out_unwait;
} }
...@@ -799,17 +820,17 @@ int afs_rxfs_lookup(afs_server_t *server, ...@@ -799,17 +820,17 @@ int afs_rxfs_lookup(afs_server_t *server,
out_unwait: out_unwait:
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
remove_wait_queue(&call->waitq,&myself); remove_wait_queue(&call->waitq, &myself);
rxrpc_put_call(call); rxrpc_put_call(call);
out_put_conn: out_put_conn:
afs_server_release_fsconn(server,conn); afs_server_release_fsconn(server, conn);
out: out:
kleave(""); kleave("");
return ret; return ret;
abort: abort:
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
rxrpc_call_abort(call,ret); rxrpc_call_abort(call, ret);
schedule(); schedule();
goto out_unwait; goto out_unwait;
} /* end afs_rxfs_lookup() */ } /* end afs_rxfs_lookup() */
......
...@@ -14,38 +14,39 @@ ...@@ -14,38 +14,39 @@
#include "server.h" #include "server.h"
extern int afs_rxfs_get_volume_info(afs_server_t *server, extern int afs_rxfs_get_volume_info(struct afs_server *server,
const char *name, const char *name,
afs_volume_info_t *vinfo); struct afs_volume_info *vinfo);
extern int afs_rxfs_fetch_file_status(afs_server_t *server, extern int afs_rxfs_fetch_file_status(struct afs_server *server,
afs_vnode_t *vnode, struct afs_vnode *vnode,
afs_volsync_t *volsync); struct afs_volsync *volsync);
struct afs_rxfs_fetch_descriptor { struct afs_rxfs_fetch_descriptor {
afs_fid_t fid; /* file ID to fetch */ struct afs_fid fid; /* file ID to fetch */
size_t size; /* total number of bytes to fetch */ size_t size; /* total number of bytes to fetch */
off_t offset; /* offset in file to start from */ off_t offset; /* offset in file to start from */
void *buffer; /* read buffer */ void *buffer; /* read buffer */
size_t actual; /* actual size sent back by server */ size_t actual; /* actual size sent back by server */
}; };
extern int afs_rxfs_fetch_file_data(afs_server_t *server, extern int afs_rxfs_fetch_file_data(struct afs_server *server,
afs_vnode_t *vnode, struct afs_vnode *vnode,
struct afs_rxfs_fetch_descriptor *desc, struct afs_rxfs_fetch_descriptor *desc,
afs_volsync_t *volsync); struct afs_volsync *volsync);
extern int afs_rxfs_give_up_callback(afs_server_t *server, afs_vnode_t *vnode); extern int afs_rxfs_give_up_callback(struct afs_server *server,
struct afs_vnode *vnode);
/* this doesn't appear to work in OpenAFS server */ /* this doesn't appear to work in OpenAFS server */
extern int afs_rxfs_lookup(afs_server_t *server, extern int afs_rxfs_lookup(struct afs_server *server,
afs_vnode_t *dir, struct afs_vnode *dir,
const char *filename, const char *filename,
afs_vnode_t *vnode, struct afs_vnode *vnode,
afs_volsync_t *volsync); struct afs_volsync *volsync);
/* this is apparently mis-implemented in OpenAFS server */ /* this is apparently mis-implemented in OpenAFS server */
extern int afs_rxfs_get_root_volume(afs_server_t *server, extern int afs_rxfs_get_root_volume(struct afs_server *server,
char *buf, char *buf,
size_t *buflen); size_t *buflen);
......
...@@ -26,15 +26,15 @@ ...@@ -26,15 +26,15 @@
#include "internal.h" #include "internal.h"
struct afs_iget_data { struct afs_iget_data {
afs_fid_t fid; struct afs_fid fid;
afs_volume_t *volume; /* volume on which resides */ struct afs_volume *volume; /* volume on which resides */
}; };
/*****************************************************************************/ /*****************************************************************************/
/* /*
* map the AFS file status to the inode member variables * map the AFS file status to the inode member variables
*/ */
static int afs_inode_map_status(afs_vnode_t *vnode) static int afs_inode_map_status(struct afs_vnode *vnode)
{ {
struct inode *inode = AFS_VNODE_TO_I(vnode); struct inode *inode = AFS_VNODE_TO_I(vnode);
...@@ -97,7 +97,7 @@ static int afs_inode_map_status(afs_vnode_t *vnode) ...@@ -97,7 +97,7 @@ static int afs_inode_map_status(afs_vnode_t *vnode)
*/ */
int afs_inode_fetch_status(struct inode *inode) int afs_inode_fetch_status(struct inode *inode)
{ {
afs_vnode_t *vnode; struct afs_vnode *vnode;
int ret; int ret;
vnode = AFS_FS_I(inode); vnode = AFS_FS_I(inode);
...@@ -130,7 +130,7 @@ static int afs_iget5_test(struct inode *inode, void *opaque) ...@@ -130,7 +130,7 @@ static int afs_iget5_test(struct inode *inode, void *opaque)
static int afs_iget5_set(struct inode *inode, void *opaque) static int afs_iget5_set(struct inode *inode, void *opaque)
{ {
struct afs_iget_data *data = opaque; struct afs_iget_data *data = opaque;
afs_vnode_t *vnode = AFS_FS_I(inode); struct afs_vnode *vnode = AFS_FS_I(inode);
inode->i_ino = data->fid.vnode; inode->i_ino = data->fid.vnode;
inode->i_version = data->fid.unique; inode->i_version = data->fid.unique;
...@@ -144,7 +144,7 @@ static int afs_iget5_set(struct inode *inode, void *opaque) ...@@ -144,7 +144,7 @@ static int afs_iget5_set(struct inode *inode, void *opaque)
/* /*
* inode retrieval * inode retrieval
*/ */
inline int afs_iget(struct super_block *sb, afs_fid_t *fid, inline int afs_iget(struct super_block *sb, struct afs_fid *fid,
struct inode **_inode) struct inode **_inode)
{ {
struct afs_iget_data data = { fid: *fid }; struct afs_iget_data data = { fid: *fid };
...@@ -201,7 +201,11 @@ inline int afs_iget(struct super_block *sb, afs_fid_t *fid, ...@@ -201,7 +201,11 @@ inline int afs_iget(struct super_block *sb, afs_fid_t *fid,
vnode->cb_version, vnode->cb_version,
vnode->cb_timeout.timo_jif, vnode->cb_timeout.timo_jif,
vnode->cb_type, vnode->cb_type,
#ifdef AFS_CACHING_SUPPORT
vnode->cache vnode->cache
#else
NULL
#endif
); );
return 0; return 0;
...@@ -222,8 +226,8 @@ inline int afs_iget(struct super_block *sb, afs_fid_t *fid, ...@@ -222,8 +226,8 @@ inline int afs_iget(struct super_block *sb, afs_fid_t *fid,
int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat) struct kstat *stat)
{ {
struct afs_vnode *vnode;
struct inode *inode; struct inode *inode;
afs_vnode_t *vnode;
int ret; int ret;
inode = dentry->d_inode; inode = dentry->d_inode;
...@@ -262,7 +266,7 @@ int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, ...@@ -262,7 +266,7 @@ int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry,
*/ */
void afs_clear_inode(struct inode *inode) void afs_clear_inode(struct inode *inode)
{ {
afs_vnode_t *vnode; struct afs_vnode *vnode;
vnode = AFS_FS_I(inode); vnode = AFS_FS_I(inode);
......
...@@ -46,7 +46,7 @@ static inline void afs_discard_my_signals(void) ...@@ -46,7 +46,7 @@ static inline void afs_discard_my_signals(void)
siginfo_t sinfo; siginfo_t sinfo;
spin_lock_irq(&current->sighand->siglock); spin_lock_irq(&current->sighand->siglock);
dequeue_signal(current,&current->blocked,&sinfo); dequeue_signal(current,&current->blocked, &sinfo);
spin_unlock_irq(&current->sighand->siglock); spin_unlock_irq(&current->sighand->siglock);
} }
} }
...@@ -74,16 +74,27 @@ extern struct inode_operations afs_file_inode_operations; ...@@ -74,16 +74,27 @@ extern struct inode_operations afs_file_inode_operations;
extern struct file_operations afs_file_file_operations; extern struct file_operations afs_file_file_operations;
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
extern int afs_cache_get_page_cookie(struct page *page, struct cachefs_page **_page_cookie); extern int afs_cache_get_page_cookie(struct page *page,
struct cachefs_page **_page_cookie);
#endif #endif
/* /*
* inode.c * inode.c
*/ */
extern int afs_iget(struct super_block *sb, afs_fid_t *fid, struct inode **_inode); extern int afs_iget(struct super_block *sb, struct afs_fid *fid,
extern int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); struct inode **_inode);
extern int afs_inode_getattr(struct vfsmount *mnt, struct dentry *dentry,
struct kstat *stat);
extern void afs_clear_inode(struct inode *inode); extern void afs_clear_inode(struct inode *inode);
/*
* key_afs.c
*/
#ifdef CONFIG_KEYS
extern int afs_key_register(void);
extern void afs_key_unregister(void);
#endif
/* /*
* main.c * main.c
*/ */
...@@ -102,7 +113,7 @@ extern struct afs_timer_ops afs_mntpt_expiry_timer_ops; ...@@ -102,7 +113,7 @@ extern struct afs_timer_ops afs_mntpt_expiry_timer_ops;
extern unsigned long afs_mntpt_expiry_timeout; extern unsigned long afs_mntpt_expiry_timeout;
#endif #endif
extern int afs_mntpt_check_symlink(afs_vnode_t *vnode); extern int afs_mntpt_check_symlink(struct afs_vnode *vnode);
/* /*
* super.c * super.c
...@@ -110,13 +121,14 @@ extern int afs_mntpt_check_symlink(afs_vnode_t *vnode); ...@@ -110,13 +121,14 @@ extern int afs_mntpt_check_symlink(afs_vnode_t *vnode);
extern int afs_fs_init(void); extern int afs_fs_init(void);
extern void afs_fs_exit(void); extern void afs_fs_exit(void);
#define AFS_CB_HASH_COUNT (PAGE_SIZE/sizeof(struct list_head)) #define AFS_CB_HASH_COUNT (PAGE_SIZE / sizeof(struct list_head))
extern struct list_head afs_cb_hash_tbl[]; extern struct list_head afs_cb_hash_tbl[];
extern spinlock_t afs_cb_hash_lock; extern spinlock_t afs_cb_hash_lock;
#define afs_cb_hash(SRV,FID) \ #define afs_cb_hash(SRV,FID) \
afs_cb_hash_tbl[((unsigned long)(SRV) + (FID)->vid + (FID)->vnode + (FID)->unique) % \ afs_cb_hash_tbl[((unsigned long)(SRV) + \
(FID)->vid + (FID)->vnode + (FID)->unique) % \
AFS_CB_HASH_COUNT] AFS_CB_HASH_COUNT]
/* /*
...@@ -124,7 +136,7 @@ extern spinlock_t afs_cb_hash_lock; ...@@ -124,7 +136,7 @@ extern spinlock_t afs_cb_hash_lock;
*/ */
extern int afs_proc_init(void); extern int afs_proc_init(void);
extern void afs_proc_cleanup(void); extern void afs_proc_cleanup(void);
extern int afs_proc_cell_setup(afs_cell_t *cell); extern int afs_proc_cell_setup(struct afs_cell *cell);
extern void afs_proc_cell_remove(afs_cell_t *cell); extern void afs_proc_cell_remove(struct afs_cell *cell);
#endif /* AFS_INTERNAL_H */ #endif /* AFS_INTERNAL_H */
...@@ -57,8 +57,8 @@ int afs_kafsasyncd_start(void) ...@@ -57,8 +57,8 @@ int afs_kafsasyncd_start(void)
{ {
int ret; int ret;
ret = kernel_thread(kafsasyncd,NULL,0); ret = kernel_thread(kafsasyncd, NULL, 0);
if (ret<0) if (ret < 0)
return ret; return ret;
wait_for_completion(&kafsasyncd_alive); wait_for_completion(&kafsasyncd_alive);
...@@ -85,14 +85,14 @@ void afs_kafsasyncd_stop(void) ...@@ -85,14 +85,14 @@ void afs_kafsasyncd_stop(void)
*/ */
static int kafsasyncd(void *arg) static int kafsasyncd(void *arg)
{ {
DECLARE_WAITQUEUE(myself,current); struct afs_async_op *op;
struct list_head *_p;
int die; int die;
DECLARE_WAITQUEUE(myself, current);
kafsasyncd_task = current; kafsasyncd_task = current;
printk("kAFS: Started kafsasyncd %d\n",current->pid); printk("kAFS: Started kafsasyncd %d\n", current->pid);
daemonize("kafsasyncd"); daemonize("kafsasyncd");
...@@ -101,7 +101,7 @@ static int kafsasyncd(void *arg) ...@@ -101,7 +101,7 @@ static int kafsasyncd(void *arg)
/* loop around looking for things to attend to */ /* loop around looking for things to attend to */
do { do {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&kafsasyncd_sleepq,&myself); add_wait_queue(&kafsasyncd_sleepq, &myself);
for (;;) { for (;;) {
if (!list_empty(&kafsasyncd_async_attnq) || if (!list_empty(&kafsasyncd_async_attnq) ||
...@@ -113,7 +113,7 @@ static int kafsasyncd(void *arg) ...@@ -113,7 +113,7 @@ static int kafsasyncd(void *arg)
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
} }
remove_wait_queue(&kafsasyncd_sleepq,&myself); remove_wait_queue(&kafsasyncd_sleepq, &myself);
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
/* discard pending signals */ /* discard pending signals */
...@@ -121,7 +121,8 @@ static int kafsasyncd(void *arg) ...@@ -121,7 +121,8 @@ static int kafsasyncd(void *arg)
die = kafsasyncd_die; die = kafsasyncd_die;
/* deal with the next asynchronous operation requiring attention */ /* deal with the next asynchronous operation requiring
* attention */
if (!list_empty(&kafsasyncd_async_attnq)) { if (!list_empty(&kafsasyncd_async_attnq)) {
struct afs_async_op *op; struct afs_async_op *op;
...@@ -131,14 +132,17 @@ static int kafsasyncd(void *arg) ...@@ -131,14 +132,17 @@ static int kafsasyncd(void *arg)
spin_lock(&kafsasyncd_async_lock); spin_lock(&kafsasyncd_async_lock);
if (!list_empty(&kafsasyncd_async_attnq)) { if (!list_empty(&kafsasyncd_async_attnq)) {
op = list_entry(kafsasyncd_async_attnq.next,afs_async_op_t,link); op = list_entry(kafsasyncd_async_attnq.next,
struct afs_async_op, link);
list_del(&op->link); list_del(&op->link);
list_add_tail(&op->link,&kafsasyncd_async_busyq); list_add_tail(&op->link,
&kafsasyncd_async_busyq);
} }
spin_unlock(&kafsasyncd_async_lock); spin_unlock(&kafsasyncd_async_lock);
_debug("@@@ Operation %p {%p}\n",op,op?op->ops:NULL); _debug("@@@ Operation %p {%p}\n",
op, op ? op->ops : NULL);
if (op) if (op)
op->ops->attend(op); op->ops->attend(op);
...@@ -148,30 +152,30 @@ static int kafsasyncd(void *arg) ...@@ -148,30 +152,30 @@ static int kafsasyncd(void *arg)
} while(!die); } while(!die);
/* need to kill all outstanding asynchronous operations before exiting */ /* need to kill all outstanding asynchronous operations before
* exiting */
kafsasyncd_task = NULL; kafsasyncd_task = NULL;
spin_lock(&kafsasyncd_async_lock); spin_lock(&kafsasyncd_async_lock);
/* fold the busy and attention queues together */ /* fold the busy and attention queues together */
list_splice_init(&kafsasyncd_async_busyq,&kafsasyncd_async_attnq); list_splice_init(&kafsasyncd_async_busyq,
&kafsasyncd_async_attnq);
/* dequeue kafsasyncd from all their wait queues */ /* dequeue kafsasyncd from all their wait queues */
list_for_each(_p,&kafsasyncd_async_attnq) { list_for_each_entry(op, &kafsasyncd_async_attnq, link) {
afs_async_op_t *op = list_entry(_p,afs_async_op_t,link);
op->call->app_attn_func = kafsasyncd_null_call_attn_func; op->call->app_attn_func = kafsasyncd_null_call_attn_func;
op->call->app_error_func = kafsasyncd_null_call_error_func; op->call->app_error_func = kafsasyncd_null_call_error_func;
remove_wait_queue(&op->call->waitq,&op->waiter); remove_wait_queue(&op->call->waitq, &op->waiter);
} }
spin_unlock(&kafsasyncd_async_lock); spin_unlock(&kafsasyncd_async_lock);
/* abort all the operations */ /* abort all the operations */
while (!list_empty(&kafsasyncd_async_attnq)) { while (!list_empty(&kafsasyncd_async_attnq)) {
afs_async_op_t *op = list_entry(_p,afs_async_op_t,link); op = list_entry(kafsasyncd_async_attnq.next, struct afs_async_op, link);
list_del_init(&op->link); list_del_init(&op->link);
rxrpc_call_abort(op->call,-EIO); rxrpc_call_abort(op->call, -EIO);
rxrpc_put_call(op->call); rxrpc_put_call(op->call);
op->call = NULL; op->call = NULL;
...@@ -180,7 +184,7 @@ static int kafsasyncd(void *arg) ...@@ -180,7 +184,7 @@ static int kafsasyncd(void *arg)
/* and that's all */ /* and that's all */
_leave(""); _leave("");
complete_and_exit(&kafsasyncd_dead,0); complete_and_exit(&kafsasyncd_dead, 0);
} /* end kafsasyncd() */ } /* end kafsasyncd() */
...@@ -189,17 +193,17 @@ static int kafsasyncd(void *arg) ...@@ -189,17 +193,17 @@ static int kafsasyncd(void *arg)
* begin an operation * begin an operation
* - place operation on busy queue * - place operation on busy queue
*/ */
void afs_kafsasyncd_begin_op(afs_async_op_t *op) void afs_kafsasyncd_begin_op(struct afs_async_op *op)
{ {
_enter(""); _enter("");
spin_lock(&kafsasyncd_async_lock); spin_lock(&kafsasyncd_async_lock);
init_waitqueue_entry(&op->waiter,kafsasyncd_task); init_waitqueue_entry(&op->waiter, kafsasyncd_task);
add_wait_queue(&op->call->waitq,&op->waiter); add_wait_queue(&op->call->waitq, &op->waiter);
list_del(&op->link); list_del(&op->link);
list_add_tail(&op->link,&kafsasyncd_async_busyq); list_add_tail(&op->link, &kafsasyncd_async_busyq);
spin_unlock(&kafsasyncd_async_lock); spin_unlock(&kafsasyncd_async_lock);
...@@ -211,14 +215,14 @@ void afs_kafsasyncd_begin_op(afs_async_op_t *op) ...@@ -211,14 +215,14 @@ void afs_kafsasyncd_begin_op(afs_async_op_t *op)
* request attention for an operation * request attention for an operation
* - move to attention queue * - move to attention queue
*/ */
void afs_kafsasyncd_attend_op(afs_async_op_t *op) void afs_kafsasyncd_attend_op(struct afs_async_op *op)
{ {
_enter(""); _enter("");
spin_lock(&kafsasyncd_async_lock); spin_lock(&kafsasyncd_async_lock);
list_del(&op->link); list_del(&op->link);
list_add_tail(&op->link,&kafsasyncd_async_attnq); list_add_tail(&op->link, &kafsasyncd_async_attnq);
spin_unlock(&kafsasyncd_async_lock); spin_unlock(&kafsasyncd_async_lock);
...@@ -232,7 +236,7 @@ void afs_kafsasyncd_attend_op(afs_async_op_t *op) ...@@ -232,7 +236,7 @@ void afs_kafsasyncd_attend_op(afs_async_op_t *op)
* terminate an operation * terminate an operation
* - remove from either queue * - remove from either queue
*/ */
void afs_kafsasyncd_terminate_op(afs_async_op_t *op) void afs_kafsasyncd_terminate_op(struct afs_async_op *op)
{ {
_enter(""); _enter("");
...@@ -240,7 +244,7 @@ void afs_kafsasyncd_terminate_op(afs_async_op_t *op) ...@@ -240,7 +244,7 @@ void afs_kafsasyncd_terminate_op(afs_async_op_t *op)
if (!list_empty(&op->link)) { if (!list_empty(&op->link)) {
list_del_init(&op->link); list_del_init(&op->link);
remove_wait_queue(&op->call->waitq,&op->waiter); remove_wait_queue(&op->call->waitq, &op->waiter);
} }
spin_unlock(&kafsasyncd_async_lock); spin_unlock(&kafsasyncd_async_lock);
......
...@@ -14,9 +14,11 @@ ...@@ -14,9 +14,11 @@
#include "types.h" #include "types.h"
struct afs_async_op;
struct afs_async_op_ops { struct afs_async_op_ops {
void (*attend)(afs_async_op_t *op); void (*attend)(struct afs_async_op *op);
void (*discard)(afs_async_op_t *op); void (*discard)(struct afs_async_op *op);
}; };
/*****************************************************************************/ /*****************************************************************************/
...@@ -26,13 +28,14 @@ struct afs_async_op_ops { ...@@ -26,13 +28,14 @@ struct afs_async_op_ops {
struct afs_async_op struct afs_async_op
{ {
struct list_head link; struct list_head link;
afs_server_t *server; /* server being contacted */ struct afs_server *server; /* server being contacted */
struct rxrpc_call *call; /* RxRPC call performing op */ struct rxrpc_call *call; /* RxRPC call performing op */
wait_queue_t waiter; /* wait queue for kafsasyncd */ wait_queue_t waiter; /* wait queue for kafsasyncd */
const struct afs_async_op_ops *ops; /* operations */ const struct afs_async_op_ops *ops; /* operations */
}; };
static inline void afs_async_op_init(afs_async_op_t *op, const struct afs_async_op_ops *ops) static inline void afs_async_op_init(struct afs_async_op *op,
const struct afs_async_op_ops *ops)
{ {
INIT_LIST_HEAD(&op->link); INIT_LIST_HEAD(&op->link);
op->call = NULL; op->call = NULL;
...@@ -42,8 +45,8 @@ static inline void afs_async_op_init(afs_async_op_t *op, const struct afs_async_ ...@@ -42,8 +45,8 @@ static inline void afs_async_op_init(afs_async_op_t *op, const struct afs_async_
extern int afs_kafsasyncd_start(void); extern int afs_kafsasyncd_start(void);
extern void afs_kafsasyncd_stop(void); extern void afs_kafsasyncd_stop(void);
extern void afs_kafsasyncd_begin_op(afs_async_op_t *op); extern void afs_kafsasyncd_begin_op(struct afs_async_op *op);
extern void afs_kafsasyncd_attend_op(afs_async_op_t *op); extern void afs_kafsasyncd_attend_op(struct afs_async_op *op);
extern void afs_kafsasyncd_terminate_op(afs_async_op_t *op); extern void afs_kafsasyncd_terminate_op(struct afs_async_op *op);
#endif /* _LINUX_AFS_KAFSASYNCD_H */ #endif /* _LINUX_AFS_KAFSASYNCD_H */
...@@ -37,8 +37,8 @@ int afs_kafstimod_start(void) ...@@ -37,8 +37,8 @@ int afs_kafstimod_start(void)
{ {
int ret; int ret;
ret = kernel_thread(kafstimod,NULL,0); ret = kernel_thread(kafstimod, NULL, 0);
if (ret<0) if (ret < 0)
return ret; return ret;
wait_for_completion(&kafstimod_alive); wait_for_completion(&kafstimod_alive);
...@@ -65,11 +65,11 @@ void afs_kafstimod_stop(void) ...@@ -65,11 +65,11 @@ void afs_kafstimod_stop(void)
*/ */
static int kafstimod(void *arg) static int kafstimod(void *arg)
{ {
DECLARE_WAITQUEUE(myself,current); struct afs_timer *timer;
afs_timer_t *timer; DECLARE_WAITQUEUE(myself, current);
printk("kAFS: Started kafstimod %d\n",current->pid); printk("kAFS: Started kafstimod %d\n", current->pid);
daemonize("kafstimod"); daemonize("kafstimod");
...@@ -78,7 +78,7 @@ static int kafstimod(void *arg) ...@@ -78,7 +78,7 @@ static int kafstimod(void *arg)
/* loop around looking for things to attend to */ /* loop around looking for things to attend to */
loop: loop:
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&kafstimod_sleepq,&myself); add_wait_queue(&kafstimod_sleepq, &myself);
for (;;) { for (;;) {
unsigned long jif; unsigned long jif;
...@@ -86,9 +86,9 @@ static int kafstimod(void *arg) ...@@ -86,9 +86,9 @@ static int kafstimod(void *arg)
/* deal with the server being asked to die */ /* deal with the server being asked to die */
if (kafstimod_die) { if (kafstimod_die) {
remove_wait_queue(&kafstimod_sleepq,&myself); remove_wait_queue(&kafstimod_sleepq, &myself);
_leave(""); _leave("");
complete_and_exit(&kafstimod_dead,0); complete_and_exit(&kafstimod_dead, 0);
} }
/* discard pending signals */ /* discard pending signals */
...@@ -100,15 +100,16 @@ static int kafstimod(void *arg) ...@@ -100,15 +100,16 @@ static int kafstimod(void *arg)
timeout = MAX_SCHEDULE_TIMEOUT; timeout = MAX_SCHEDULE_TIMEOUT;
} }
else { else {
timer = list_entry(kafstimod_list.next,afs_timer_t,link); timer = list_entry(kafstimod_list.next,
struct afs_timer, link);
timeout = timer->timo_jif; timeout = timer->timo_jif;
jif = jiffies; jif = jiffies;
if (time_before_eq((unsigned long)timeout,jif)) if (time_before_eq((unsigned long) timeout, jif))
goto immediate; goto immediate;
else { else {
timeout = (long)timeout - (long)jiffies; timeout = (long) timeout - (long) jiffies;
} }
} }
spin_unlock(&kafstimod_lock); spin_unlock(&kafstimod_lock);
...@@ -119,13 +120,14 @@ static int kafstimod(void *arg) ...@@ -119,13 +120,14 @@ static int kafstimod(void *arg)
} }
/* the thing on the front of the queue needs processing /* the thing on the front of the queue needs processing
* - we come here with the lock held and timer pointing to the expired entry * - we come here with the lock held and timer pointing to the expired
* entry
*/ */
immediate: immediate:
remove_wait_queue(&kafstimod_sleepq,&myself); remove_wait_queue(&kafstimod_sleepq, &myself);
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
_debug("@@@ Begin Timeout of %p",timer); _debug("@@@ Begin Timeout of %p", timer);
/* dequeue the timer */ /* dequeue the timer */
list_del_init(&timer->link); list_del_init(&timer->link);
...@@ -143,27 +145,28 @@ static int kafstimod(void *arg) ...@@ -143,27 +145,28 @@ static int kafstimod(void *arg)
/* /*
* (re-)queue a timer * (re-)queue a timer
*/ */
void afs_kafstimod_add_timer(afs_timer_t *timer, unsigned long timeout) void afs_kafstimod_add_timer(struct afs_timer *timer, unsigned long timeout)
{ {
struct afs_timer *ptimer;
struct list_head *_p; struct list_head *_p;
afs_timer_t *ptimer;
_enter("%p,%lu",timer,timeout); _enter("%p,%lu", timer, timeout);
spin_lock(&kafstimod_lock); spin_lock(&kafstimod_lock);
list_del(&timer->link); list_del(&timer->link);
/* the timer was deferred or reset - put it back in the queue at the right place */ /* the timer was deferred or reset - put it back in the queue at the
* right place */
timer->timo_jif = jiffies + timeout; timer->timo_jif = jiffies + timeout;
list_for_each(_p,&kafstimod_list) { list_for_each(_p, &kafstimod_list) {
ptimer = list_entry(_p,afs_timer_t,link); ptimer = list_entry(_p, struct afs_timer, link);
if (time_before(timer->timo_jif,ptimer->timo_jif)) if (time_before(timer->timo_jif, ptimer->timo_jif))
break; break;
} }
list_add_tail(&timer->link,_p); /* insert before stopping point */ list_add_tail(&timer->link, _p); /* insert before stopping point */
spin_unlock(&kafstimod_lock); spin_unlock(&kafstimod_lock);
...@@ -177,11 +180,11 @@ void afs_kafstimod_add_timer(afs_timer_t *timer, unsigned long timeout) ...@@ -177,11 +180,11 @@ void afs_kafstimod_add_timer(afs_timer_t *timer, unsigned long timeout)
* dequeue a timer * dequeue a timer
* - returns 0 if the timer was deleted or -ENOENT if it wasn't queued * - returns 0 if the timer was deleted or -ENOENT if it wasn't queued
*/ */
int afs_kafstimod_del_timer(afs_timer_t *timer) int afs_kafstimod_del_timer(struct afs_timer *timer)
{ {
int ret = 0; int ret = 0;
_enter("%p",timer); _enter("%p", timer);
spin_lock(&kafstimod_lock); spin_lock(&kafstimod_lock);
...@@ -194,6 +197,6 @@ int afs_kafstimod_del_timer(afs_timer_t *timer) ...@@ -194,6 +197,6 @@ int afs_kafstimod_del_timer(afs_timer_t *timer)
wake_up(&kafstimod_sleepq); wake_up(&kafstimod_sleepq);
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_kafstimod_del_timer() */ } /* end afs_kafstimod_del_timer() */
...@@ -14,6 +14,8 @@ ...@@ -14,6 +14,8 @@
#include "types.h" #include "types.h"
struct afs_timer;
struct afs_timer_ops { struct afs_timer_ops {
/* called when the front of the timer queue has timed out */ /* called when the front of the timer queue has timed out */
void (*timed_out)(struct afs_timer *timer); void (*timed_out)(struct afs_timer *timer);
...@@ -30,7 +32,8 @@ struct afs_timer ...@@ -30,7 +32,8 @@ struct afs_timer
const struct afs_timer_ops *ops; /* timeout expiry function */ const struct afs_timer_ops *ops; /* timeout expiry function */
}; };
static inline void afs_timer_init(afs_timer_t *timer, const struct afs_timer_ops *ops) static inline void afs_timer_init(struct afs_timer *timer,
const struct afs_timer_ops *ops)
{ {
INIT_LIST_HEAD(&timer->link); INIT_LIST_HEAD(&timer->link);
timer->ops = ops; timer->ops = ops;
...@@ -39,7 +42,8 @@ static inline void afs_timer_init(afs_timer_t *timer, const struct afs_timer_ops ...@@ -39,7 +42,8 @@ static inline void afs_timer_init(afs_timer_t *timer, const struct afs_timer_ops
extern int afs_kafstimod_start(void); extern int afs_kafstimod_start(void);
extern void afs_kafstimod_stop(void); extern void afs_kafstimod_stop(void);
extern void afs_kafstimod_add_timer(afs_timer_t *timer, unsigned long timeout); extern void afs_kafstimod_add_timer(struct afs_timer *timer,
extern int afs_kafstimod_del_timer(afs_timer_t *timer); unsigned long timeout);
extern int afs_kafstimod_del_timer(struct afs_timer *timer);
#endif /* _LINUX_AFS_KAFSTIMOD_H */ #endif /* _LINUX_AFS_KAFSTIMOD_H */
...@@ -33,13 +33,24 @@ static void afs_exit(void); ...@@ -33,13 +33,24 @@ static void afs_exit(void);
static int afs_adding_peer(struct rxrpc_peer *peer); static int afs_adding_peer(struct rxrpc_peer *peer);
static void afs_discarding_peer(struct rxrpc_peer *peer); static void afs_discarding_peer(struct rxrpc_peer *peer);
module_init(afs_init); /* XXX late_initcall is kludgy, but the only alternative seems to create
* a transport upon the first mount, which is worse. Or is it?
*/
/* module_init(afs_init); */
late_initcall(afs_init); /* must be called after net/ to create socket */
module_exit(afs_exit); module_exit(afs_exit);
MODULE_DESCRIPTION("AFS Client File System"); MODULE_DESCRIPTION("AFS Client File System");
MODULE_AUTHOR("Red Hat, Inc."); MODULE_AUTHOR("Red Hat, Inc.");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
static char *rootcell;
MODULE_PARM(rootcell, "s");
MODULE_PARM_DESC(rootcell, "root AFS cell name and VL server IP addr list");
static struct rxrpc_peer_ops afs_peer_ops = { static struct rxrpc_peer_ops afs_peer_ops = {
.adding = afs_adding_peer, .adding = afs_adding_peer,
.discarding = afs_discarding_peer, .discarding = afs_discarding_peer,
...@@ -72,7 +83,7 @@ static int afs_init(void) ...@@ -72,7 +83,7 @@ static int afs_init(void)
/* initialise the callback hash table */ /* initialise the callback hash table */
spin_lock_init(&afs_cb_hash_lock); spin_lock_init(&afs_cb_hash_lock);
for (loop=AFS_CB_HASH_COUNT-1; loop>=0; loop--) for (loop = AFS_CB_HASH_COUNT - 1; loop >= 0; loop--)
INIT_LIST_HEAD(&afs_cb_hash_tbl[loop]); INIT_LIST_HEAD(&afs_cb_hash_tbl[loop]);
/* register the /proc stuff */ /* register the /proc stuff */
...@@ -82,20 +93,27 @@ static int afs_init(void) ...@@ -82,20 +93,27 @@ static int afs_init(void)
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
/* we want to be able to cache */ /* we want to be able to cache */
ret = cachefs_register_netfs(&afs_cache_netfs,&afs_cache_cell_index_def); ret = cachefs_register_netfs(&afs_cache_netfs,
&afs_cache_cell_index_def);
if (ret < 0) if (ret < 0)
goto error; goto error;
#endif #endif
/* initialise the cell DB */ #ifdef CONFIG_KEYS
ret = afs_cell_init(); ret = afs_key_register();
if (ret < 0) if (ret < 0)
goto error_cache; goto error_cache;
#endif
/* initialise the cell DB */
ret = afs_cell_init(rootcell);
if (ret < 0)
goto error_keys;
/* start the timeout daemon */ /* start the timeout daemon */
ret = afs_kafstimod_start(); ret = afs_kafstimod_start();
if (ret < 0) if (ret < 0)
goto error_cache; goto error_keys;
/* start the async operation daemon */ /* start the async operation daemon */
ret = afs_kafsasyncd_start(); ret = afs_kafsasyncd_start();
...@@ -103,7 +121,7 @@ static int afs_init(void) ...@@ -103,7 +121,7 @@ static int afs_init(void)
goto error_kafstimod; goto error_kafstimod;
/* create the RxRPC transport */ /* create the RxRPC transport */
ret = rxrpc_create_transport(7001,&afs_transport); ret = rxrpc_create_transport(7001, &afs_transport);
if (ret < 0) if (ret < 0)
goto error_kafsasyncd; goto error_kafsasyncd;
...@@ -122,14 +140,18 @@ static int afs_init(void) ...@@ -122,14 +140,18 @@ static int afs_init(void)
afs_kafsasyncd_stop(); afs_kafsasyncd_stop();
error_kafstimod: error_kafstimod:
afs_kafstimod_stop(); afs_kafstimod_stop();
error_keys:
#ifdef CONFIG_KEYS
afs_key_unregister();
error_cache: error_cache:
#endif
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
cachefs_unregister_netfs(&afs_cache_netfs); cachefs_unregister_netfs(&afs_cache_netfs);
error: error:
#endif #endif
afs_cell_purge(); afs_cell_purge();
afs_proc_cleanup(); afs_proc_cleanup();
printk(KERN_ERR "kAFS: failed to register: %d\n",ret); printk(KERN_ERR "kAFS: failed to register: %d\n", ret);
return ret; return ret;
} /* end afs_init() */ } /* end afs_init() */
...@@ -146,6 +168,9 @@ static void __exit afs_exit(void) ...@@ -146,6 +168,9 @@ static void __exit afs_exit(void)
afs_kafstimod_stop(); afs_kafstimod_stop();
afs_kafsasyncd_stop(); afs_kafsasyncd_stop();
afs_cell_purge(); afs_cell_purge();
#ifdef CONFIG_KEYS
afs_key_unregister();
#endif
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
cachefs_unregister_netfs(&afs_cache_netfs); cachefs_unregister_netfs(&afs_cache_netfs);
#endif #endif
...@@ -162,19 +187,20 @@ static void __exit afs_exit(void) ...@@ -162,19 +187,20 @@ static void __exit afs_exit(void)
*/ */
static int afs_adding_peer(struct rxrpc_peer *peer) static int afs_adding_peer(struct rxrpc_peer *peer)
{ {
afs_server_t *server; struct afs_server *server;
int ret; int ret;
_debug("kAFS: Adding new peer %08x\n",ntohl(peer->addr.s_addr)); _debug("kAFS: Adding new peer %08x\n", ntohl(peer->addr.s_addr));
/* determine which server the peer resides in (if any) */ /* determine which server the peer resides in (if any) */
ret = afs_server_find_by_peer(peer,&server); ret = afs_server_find_by_peer(peer, &server);
if (ret < 0) if (ret < 0)
return ret; /* none that we recognise, so abort */ return ret; /* none that we recognise, so abort */
_debug("Server %p{u=%d}\n",server,atomic_read(&server->usage)); _debug("Server %p{u=%d}\n", server, atomic_read(&server->usage));
_debug("Cell %p{u=%d}\n",server->cell,atomic_read(&server->cell->usage)); _debug("Cell %p{u=%d}\n",
server->cell, atomic_read(&server->cell->usage));
/* cross-point the structs under a global lock */ /* cross-point the structs under a global lock */
spin_lock(&afs_server_peer_lock); spin_lock(&afs_server_peer_lock);
...@@ -194,14 +220,14 @@ static int afs_adding_peer(struct rxrpc_peer *peer) ...@@ -194,14 +220,14 @@ static int afs_adding_peer(struct rxrpc_peer *peer)
*/ */
static void afs_discarding_peer(struct rxrpc_peer *peer) static void afs_discarding_peer(struct rxrpc_peer *peer)
{ {
afs_server_t *server; struct afs_server *server;
_enter("%p",peer); _enter("%p",peer);
_debug("Discarding peer %08x (rtt=%lu.%lumS)\n", _debug("Discarding peer %08x (rtt=%lu.%lumS)\n",
ntohl(peer->addr.s_addr), ntohl(peer->addr.s_addr),
(long)(peer->rtt/1000), (long) (peer->rtt / 1000),
(long)(peer->rtt%1000)); (long) (peer->rtt % 1000));
/* uncross-point the structs under a global lock */ /* uncross-point the structs under a global lock */
spin_lock(&afs_server_peer_lock); spin_lock(&afs_server_peer_lock);
...@@ -209,9 +235,6 @@ static void afs_discarding_peer(struct rxrpc_peer *peer) ...@@ -209,9 +235,6 @@ static void afs_discarding_peer(struct rxrpc_peer *peer)
if (server) { if (server) {
peer->user = NULL; peer->user = NULL;
server->peer = NULL; server->peer = NULL;
//_debug("Server %p{u=%d}\n",server,atomic_read(&server->usage));
//_debug("Cell %p{u=%d}\n",server->cell,atomic_read(&server->cell->usage));
} }
spin_unlock(&afs_server_peer_lock); spin_unlock(&afs_server_peer_lock);
...@@ -239,7 +262,7 @@ void __cyg_profile_func_enter (void *this_fn, void *call_site) ...@@ -239,7 +262,7 @@ void __cyg_profile_func_enter (void *this_fn, void *call_site)
" movl $0xedededed,%%eax \n" " movl $0xedededed,%%eax \n"
" rep stosl \n" " rep stosl \n"
: :
: "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info)) : "i"(~(THREAD_SIZE - 1)), "i"(sizeof(struct thread_info))
: "eax", "ecx", "edi", "memory", "cc" : "eax", "ecx", "edi", "memory", "cc"
); );
} }
...@@ -258,7 +281,7 @@ void __cyg_profile_func_exit(void *this_fn, void *call_site) ...@@ -258,7 +281,7 @@ void __cyg_profile_func_exit(void *this_fn, void *call_site)
" movl $0xdadadada,%%eax \n" " movl $0xdadadada,%%eax \n"
" rep stosl \n" " rep stosl \n"
: :
: "i"(~(THREAD_SIZE-1)), "i"(sizeof(struct thread_info)) : "i"(~(THREAD_SIZE - 1)), "i"(sizeof(struct thread_info))
: "eax", "ecx", "edi", "memory", "cc" : "eax", "ecx", "edi", "memory", "cc"
); );
} }
......
...@@ -67,18 +67,21 @@ unsigned long afs_mntpt_expiry_timeout = 20; ...@@ -67,18 +67,21 @@ unsigned long afs_mntpt_expiry_timeout = 20;
* check a symbolic link to see whether it actually encodes a mountpoint * check a symbolic link to see whether it actually encodes a mountpoint
* - sets the AFS_VNODE_MOUNTPOINT flag on the vnode appropriately * - sets the AFS_VNODE_MOUNTPOINT flag on the vnode appropriately
*/ */
int afs_mntpt_check_symlink(afs_vnode_t *vnode) int afs_mntpt_check_symlink(struct afs_vnode *vnode)
{ {
struct page *page; struct page *page;
filler_t *filler;
size_t size; size_t size;
char *buf; char *buf;
int ret; int ret;
_enter("{%u,%u}",vnode->fid.vnode,vnode->fid.unique); _enter("{%u,%u}", vnode->fid.vnode, vnode->fid.unique);
/* read the contents of the symlink into the pagecache */ /* read the contents of the symlink into the pagecache */
page = read_cache_page(AFS_VNODE_TO_I(vnode)->i_mapping,0, filler = (filler_t *) AFS_VNODE_TO_I(vnode)->i_mapping->a_ops->readpage;
(filler_t*)AFS_VNODE_TO_I(vnode)->i_mapping->a_ops->readpage,NULL);
page = read_cache_page(AFS_VNODE_TO_I(vnode)->i_mapping, 0,
filler, NULL);
if (IS_ERR(page)) { if (IS_ERR(page)) {
ret = PTR_ERR(page); ret = PTR_ERR(page);
goto out; goto out;
...@@ -94,11 +97,11 @@ int afs_mntpt_check_symlink(afs_vnode_t *vnode) ...@@ -94,11 +97,11 @@ int afs_mntpt_check_symlink(afs_vnode_t *vnode)
/* examine the symlink's contents */ /* examine the symlink's contents */
size = vnode->status.size; size = vnode->status.size;
_debug("symlink to %*.*s",size,(int)size,buf); _debug("symlink to %*.*s", size, (int) size, buf);
if (size>2 && if (size > 2 &&
(buf[0]=='%' || buf[0]=='#') && (buf[0] == '%' || buf[0] == '#') &&
buf[size-1]=='.' buf[size - 1] == '.'
) { ) {
_debug("symlink is a mountpoint"); _debug("symlink is a mountpoint");
spin_lock(&vnode->lock); spin_lock(&vnode->lock);
...@@ -112,7 +115,7 @@ int afs_mntpt_check_symlink(afs_vnode_t *vnode) ...@@ -112,7 +115,7 @@ int afs_mntpt_check_symlink(afs_vnode_t *vnode)
kunmap(page); kunmap(page);
page_cache_release(page); page_cache_release(page);
out: out:
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_mntpt_check_symlink() */ } /* end afs_mntpt_check_symlink() */
...@@ -129,7 +132,8 @@ static struct dentry *afs_mntpt_lookup(struct inode *dir, ...@@ -129,7 +132,8 @@ static struct dentry *afs_mntpt_lookup(struct inode *dir,
dir, dir,
dentry, dentry,
dentry->d_parent, dentry->d_parent,
dentry->d_parent ? dentry->d_parent->d_name.name : (const unsigned char*)"", dentry->d_parent ?
dentry->d_parent->d_name.name : (const unsigned char *) "",
dentry->d_name.name); dentry->d_name.name);
return ERR_PTR(-EREMOTE); return ERR_PTR(-EREMOTE);
...@@ -144,7 +148,9 @@ static int afs_mntpt_open(struct inode *inode, struct file *file) ...@@ -144,7 +148,9 @@ static int afs_mntpt_open(struct inode *inode, struct file *file)
kenter("%p,%p{%p{%s},%s}", kenter("%p,%p{%p{%s},%s}",
inode, file, inode, file,
file->f_dentry->d_parent, file->f_dentry->d_parent,
file->f_dentry->d_parent ? file->f_dentry->d_parent->d_name.name : (const unsigned char*)"", file->f_dentry->d_parent ?
file->f_dentry->d_parent->d_name.name :
(const unsigned char *) "",
file->f_dentry->d_name.name); file->f_dentry->d_name.name);
return -EREMOTE; return -EREMOTE;
...@@ -183,10 +189,9 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt) ...@@ -183,10 +189,9 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
goto error; goto error;
/* read the contents of the AFS special symlink */ /* read the contents of the AFS special symlink */
page = read_cache_page(mntpt->d_inode->i_mapping, filler_t *filler = mntpt->d_inode->i_mapping->a_ops->readpage;
0,
(filler_t*)mntpt->d_inode->i_mapping->a_ops->readpage, page = read_cache_page(mntpt->d_inode->i_mapping, 0, filler, NULL);
NULL);
if (IS_ERR(page)) { if (IS_ERR(page)) {
ret = PTR_ERR(page); ret = PTR_ERR(page);
goto error; goto error;
...@@ -208,26 +213,26 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt) ...@@ -208,26 +213,26 @@ static struct vfsmount *afs_mntpt_do_automount(struct dentry *mntpt)
memcpy(options, "cell=", 5); memcpy(options, "cell=", 5);
strcpy(options + 5, super->volume->cell->name); strcpy(options + 5, super->volume->cell->name);
if (super->volume->type == AFSVL_RWVOL) if (super->volume->type == AFSVL_RWVOL)
strcat(options,",rwpath"); strcat(options, ",rwpath");
/* try and do the mount */ /* try and do the mount */
kdebug("--- attempting mount %s -o %s ---", devname, options); kdebug("--- attempting mount %s -o %s ---", devname, options);
mnt = do_kern_mount("afs", 0, devname, options); mnt = do_kern_mount("afs", 0, devname, options);
kdebug("--- mount result %p ---", mnt); kdebug("--- mount result %p ---", mnt);
free_page((unsigned long)devname); free_page((unsigned long) devname);
free_page((unsigned long)options); free_page((unsigned long) options);
kleave(" = %p",mnt); kleave(" = %p", mnt);
return mnt; return mnt;
error: error:
if (page) if (page)
page_cache_release(page); page_cache_release(page);
if (devname) if (devname)
free_page((unsigned long)devname); free_page((unsigned long) devname);
if (options) if (options)
free_page((unsigned long)options); free_page((unsigned long) options);
kleave(" = %d",ret); kleave(" = %d", ret);
return ERR_PTR(ret); return ERR_PTR(ret);
} /* end afs_mntpt_do_automount() */ } /* end afs_mntpt_do_automount() */
...@@ -252,7 +257,7 @@ static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd) ...@@ -252,7 +257,7 @@ static int afs_mntpt_follow_link(struct dentry *dentry, struct nameidata *nd)
if (IS_ERR(newmnt)) if (IS_ERR(newmnt))
return PTR_ERR(newmnt); return PTR_ERR(newmnt);
struct_cpy(&newnd,nd); struct_cpy(&newnd, nd);
newnd.dentry = dentry; newnd.dentry = dentry;
err = do_add_mount(newmnt, &newnd, 0, &afs_vfsmounts); err = do_add_mount(newmnt, &newnd, 0, &afs_vfsmounts);
......
...@@ -27,7 +27,8 @@ static void *afs_proc_cells_start(struct seq_file *p, loff_t *pos); ...@@ -27,7 +27,8 @@ static void *afs_proc_cells_start(struct seq_file *p, loff_t *pos);
static void *afs_proc_cells_next(struct seq_file *p, void *v, loff_t *pos); static void *afs_proc_cells_next(struct seq_file *p, void *v, loff_t *pos);
static void afs_proc_cells_stop(struct seq_file *p, void *v); static void afs_proc_cells_stop(struct seq_file *p, void *v);
static int afs_proc_cells_show(struct seq_file *m, void *v); static int afs_proc_cells_show(struct seq_file *m, void *v);
static ssize_t afs_proc_cells_write(struct file *file, const char *buf, size_t size, loff_t *_pos); static ssize_t afs_proc_cells_write(struct file *file, const char *buf,
size_t size, loff_t *_pos);
static struct seq_operations afs_proc_cells_ops = { static struct seq_operations afs_proc_cells_ops = {
.start = afs_proc_cells_start, .start = afs_proc_cells_start,
...@@ -44,10 +45,27 @@ static struct file_operations afs_proc_cells_fops = { ...@@ -44,10 +45,27 @@ static struct file_operations afs_proc_cells_fops = {
.release = seq_release, .release = seq_release,
}; };
static int afs_proc_rootcell_open(struct inode *inode, struct file *file);
static int afs_proc_rootcell_release(struct inode *inode, struct file *file);
static ssize_t afs_proc_rootcell_read(struct file *file, char *buf,
size_t size, loff_t *_pos);
static ssize_t afs_proc_rootcell_write(struct file *file, const char *buf,
size_t size, loff_t *_pos);
static struct file_operations afs_proc_rootcell_fops = {
.open = afs_proc_rootcell_open,
.read = afs_proc_rootcell_read,
.write = afs_proc_rootcell_write,
.llseek = no_llseek,
.release = afs_proc_rootcell_release
};
static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file); static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file);
static int afs_proc_cell_volumes_release(struct inode *inode, struct file *file); static int afs_proc_cell_volumes_release(struct inode *inode,
struct file *file);
static void *afs_proc_cell_volumes_start(struct seq_file *p, loff_t *pos); static void *afs_proc_cell_volumes_start(struct seq_file *p, loff_t *pos);
static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v, loff_t *pos); static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v,
loff_t *pos);
static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v); static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v);
static int afs_proc_cell_volumes_show(struct seq_file *m, void *v); static int afs_proc_cell_volumes_show(struct seq_file *m, void *v);
...@@ -65,10 +83,13 @@ static struct file_operations afs_proc_cell_volumes_fops = { ...@@ -65,10 +83,13 @@ static struct file_operations afs_proc_cell_volumes_fops = {
.release = afs_proc_cell_volumes_release, .release = afs_proc_cell_volumes_release,
}; };
static int afs_proc_cell_vlservers_open(struct inode *inode, struct file *file); static int afs_proc_cell_vlservers_open(struct inode *inode,
static int afs_proc_cell_vlservers_release(struct inode *inode, struct file *file); struct file *file);
static int afs_proc_cell_vlservers_release(struct inode *inode,
struct file *file);
static void *afs_proc_cell_vlservers_start(struct seq_file *p, loff_t *pos); static void *afs_proc_cell_vlservers_start(struct seq_file *p, loff_t *pos);
static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v, loff_t *pos); static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v,
loff_t *pos);
static void afs_proc_cell_vlservers_stop(struct seq_file *p, void *v); static void afs_proc_cell_vlservers_stop(struct seq_file *p, void *v);
static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v); static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v);
...@@ -87,9 +108,11 @@ static struct file_operations afs_proc_cell_vlservers_fops = { ...@@ -87,9 +108,11 @@ static struct file_operations afs_proc_cell_vlservers_fops = {
}; };
static int afs_proc_cell_servers_open(struct inode *inode, struct file *file); static int afs_proc_cell_servers_open(struct inode *inode, struct file *file);
static int afs_proc_cell_servers_release(struct inode *inode, struct file *file); static int afs_proc_cell_servers_release(struct inode *inode,
struct file *file);
static void *afs_proc_cell_servers_start(struct seq_file *p, loff_t *pos); static void *afs_proc_cell_servers_start(struct seq_file *p, loff_t *pos);
static void *afs_proc_cell_servers_next(struct seq_file *p, void *v, loff_t *pos); static void *afs_proc_cell_servers_next(struct seq_file *p, void *v,
loff_t *pos);
static void afs_proc_cell_servers_stop(struct seq_file *p, void *v); static void afs_proc_cell_servers_stop(struct seq_file *p, void *v);
static int afs_proc_cell_servers_show(struct seq_file *m, void *v); static int afs_proc_cell_servers_show(struct seq_file *m, void *v);
...@@ -117,26 +140,30 @@ int afs_proc_init(void) ...@@ -117,26 +140,30 @@ int afs_proc_init(void)
_enter(""); _enter("");
proc_afs = proc_mkdir("fs/afs",NULL); proc_afs = proc_mkdir("fs/afs", NULL);
if (!proc_afs) if (!proc_afs)
goto error; goto error;
proc_afs->owner = THIS_MODULE; proc_afs->owner = THIS_MODULE;
p = create_proc_entry("cells",0,proc_afs); p = create_proc_entry("cells", 0, proc_afs);
if (!p) if (!p)
goto error_proc; goto error_proc;
p->proc_fops = &afs_proc_cells_fops; p->proc_fops = &afs_proc_cells_fops;
p->owner = THIS_MODULE; p->owner = THIS_MODULE;
p = create_proc_entry("rootcell", 0, proc_afs);
if (!p)
goto error_cells;
p->proc_fops = &afs_proc_rootcell_fops;
p->owner = THIS_MODULE;
_leave(" = 0"); _leave(" = 0");
return 0; return 0;
#if 0
error_cells: error_cells:
remove_proc_entry("cells",proc_afs); remove_proc_entry("cells", proc_afs);
#endif
error_proc: error_proc:
remove_proc_entry("fs/afs",NULL); remove_proc_entry("fs/afs", NULL);
error: error:
_leave(" = -ENOMEM"); _leave(" = -ENOMEM");
return -ENOMEM; return -ENOMEM;
...@@ -149,9 +176,9 @@ int afs_proc_init(void) ...@@ -149,9 +176,9 @@ int afs_proc_init(void)
*/ */
void afs_proc_cleanup(void) void afs_proc_cleanup(void)
{ {
remove_proc_entry("cells",proc_afs); remove_proc_entry("cells", proc_afs);
remove_proc_entry("fs/afs",NULL); remove_proc_entry("fs/afs", NULL);
} /* end afs_proc_cleanup() */ } /* end afs_proc_cleanup() */
...@@ -164,8 +191,8 @@ static int afs_proc_cells_open(struct inode *inode, struct file *file) ...@@ -164,8 +191,8 @@ static int afs_proc_cells_open(struct inode *inode, struct file *file)
struct seq_file *m; struct seq_file *m;
int ret; int ret;
ret = seq_open(file,&afs_proc_cells_ops); ret = seq_open(file, &afs_proc_cells_ops);
if (ret<0) if (ret < 0)
return ret; return ret;
m = file->private_data; m = file->private_data;
...@@ -176,7 +203,8 @@ static int afs_proc_cells_open(struct inode *inode, struct file *file) ...@@ -176,7 +203,8 @@ static int afs_proc_cells_open(struct inode *inode, struct file *file)
/*****************************************************************************/ /*****************************************************************************/
/* /*
* set up the iterator to start reading from the cells list and return the first item * set up the iterator to start reading from the cells list and return the
* first item
*/ */
static void *afs_proc_cells_start(struct seq_file *m, loff_t *_pos) static void *afs_proc_cells_start(struct seq_file *m, loff_t *_pos)
{ {
...@@ -188,15 +216,15 @@ static void *afs_proc_cells_start(struct seq_file *m, loff_t *_pos) ...@@ -188,15 +216,15 @@ static void *afs_proc_cells_start(struct seq_file *m, loff_t *_pos)
/* allow for the header line */ /* allow for the header line */
if (!pos) if (!pos)
return (void *)1; return (void *) 1;
pos--; pos--;
/* find the n'th element in the list */ /* find the n'th element in the list */
list_for_each(_p,&afs_proc_cells) list_for_each(_p, &afs_proc_cells)
if (!pos--) if (!pos--)
break; break;
return _p!=&afs_proc_cells ? _p : NULL; return _p != &afs_proc_cells ? _p : NULL;
} /* end afs_proc_cells_start() */ } /* end afs_proc_cells_start() */
/*****************************************************************************/ /*****************************************************************************/
...@@ -210,9 +238,9 @@ static void *afs_proc_cells_next(struct seq_file *p, void *v, loff_t *pos) ...@@ -210,9 +238,9 @@ static void *afs_proc_cells_next(struct seq_file *p, void *v, loff_t *pos)
(*pos)++; (*pos)++;
_p = v; _p = v;
_p = v==(void*)1 ? afs_proc_cells.next : _p->next; _p = v == (void *) 1 ? afs_proc_cells.next : _p->next;
return _p!=&afs_proc_cells ? _p : NULL; return _p != &afs_proc_cells ? _p : NULL;
} /* end afs_proc_cells_next() */ } /* end afs_proc_cells_next() */
/*****************************************************************************/ /*****************************************************************************/
...@@ -231,16 +259,16 @@ static void afs_proc_cells_stop(struct seq_file *p, void *v) ...@@ -231,16 +259,16 @@ static void afs_proc_cells_stop(struct seq_file *p, void *v)
*/ */
static int afs_proc_cells_show(struct seq_file *m, void *v) static int afs_proc_cells_show(struct seq_file *m, void *v)
{ {
afs_cell_t *cell = list_entry(v,afs_cell_t,proc_link); struct afs_cell *cell = list_entry(v, struct afs_cell, proc_link);
/* display header on line 1 */ /* display header on line 1 */
if (v == (void *)1) { if (v == (void *) 1) {
seq_puts(m, "USE NAME\n"); seq_puts(m, "USE NAME\n");
return 0; return 0;
} }
/* display one cell per line on subsequent lines */ /* display one cell per line on subsequent lines */
seq_printf(m,"%3d %s\n",atomic_read(&cell->usage),cell->name); seq_printf(m, "%3d %s\n", atomic_read(&cell->usage), cell->name);
return 0; return 0;
} /* end afs_proc_cells_show() */ } /* end afs_proc_cells_show() */
...@@ -248,51 +276,61 @@ static int afs_proc_cells_show(struct seq_file *m, void *v) ...@@ -248,51 +276,61 @@ static int afs_proc_cells_show(struct seq_file *m, void *v)
/*****************************************************************************/ /*****************************************************************************/
/* /*
* handle writes to /proc/fs/afs/cells * handle writes to /proc/fs/afs/cells
* - to add cells: echo "add <cellname> <IP>[:<IP>][:<IP>]* * - to add cells: echo "add <cellname> <IP>[:<IP>][:<IP>]"
*/ */
static ssize_t afs_proc_cells_write(struct file *file, const char *buf, size_t size, loff_t *_pos) static ssize_t afs_proc_cells_write(struct file *file, const char *buf,
size_t size, loff_t *_pos)
{ {
char *kbuf, *name, *args; char *kbuf, *name, *args;
int ret; int ret;
/* start by dragging the command into memory */ /* start by dragging the command into memory */
if (size<=1 || size>=PAGE_SIZE) if (size <= 1 || size >= PAGE_SIZE)
return -EINVAL; return -EINVAL;
kbuf = kmalloc(size+1,GFP_KERNEL); kbuf = kmalloc(size + 1, GFP_KERNEL);
if (!kbuf) if (!kbuf)
return -ENOMEM; return -ENOMEM;
ret = -EFAULT; ret = -EFAULT;
if (copy_from_user(kbuf,buf,size)!=0) if (copy_from_user(kbuf, buf, size) != 0)
goto done; goto done;
kbuf[size] = 0; kbuf[size] = 0;
/* trim to first NL */ /* trim to first NL */
name = memchr(kbuf,'\n',size); name = memchr(kbuf, '\n', size);
if (name) *name = 0; if (name)
*name = 0;
/* split into command, name and argslist */ /* split into command, name and argslist */
name = strchr(kbuf,' '); name = strchr(kbuf, ' ');
if (!name) goto inval; if (!name)
do { *name++ = 0; } while(*name==' '); goto inval;
if (!*name) goto inval; do {
*name++ = 0;
} while(*name == ' ');
if (!*name)
goto inval;
args = strchr(name,' '); args = strchr(name, ' ');
if (!args) goto inval; if (!args)
do { *args++ = 0; } while(*args==' '); goto inval;
if (!*args) goto inval; do {
*args++ = 0;
} while(*args == ' ');
if (!*args)
goto inval;
/* determine command to perform */ /* determine command to perform */
_debug("cmd=%s name=%s args=%s",kbuf,name,args); _debug("cmd=%s name=%s args=%s", kbuf, name, args);
if (strcmp(kbuf,"add")==0) { if (strcmp(kbuf, "add") == 0) {
afs_cell_t *cell; struct afs_cell *cell;
ret = afs_cell_create(name,args,&cell); ret = afs_cell_create(name, args, &cell);
if (ret<0) if (ret < 0)
goto done; goto done;
printk("kAFS: Added new cell '%s'\n",name); printk("kAFS: Added new cell '%s'\n", name);
} }
else { else {
goto inval; goto inval;
...@@ -302,7 +340,7 @@ static ssize_t afs_proc_cells_write(struct file *file, const char *buf, size_t s ...@@ -302,7 +340,7 @@ static ssize_t afs_proc_cells_write(struct file *file, const char *buf, size_t s
done: done:
kfree(kbuf); kfree(kbuf);
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
inval: inval:
...@@ -311,35 +349,99 @@ static ssize_t afs_proc_cells_write(struct file *file, const char *buf, size_t s ...@@ -311,35 +349,99 @@ static ssize_t afs_proc_cells_write(struct file *file, const char *buf, size_t s
goto done; goto done;
} /* end afs_proc_cells_write() */ } /* end afs_proc_cells_write() */
/*****************************************************************************/
/*
* Stubs for /proc/fs/afs/rootcell
*/
static int afs_proc_rootcell_open(struct inode *inode, struct file *file)
{
return 0;
}
static int afs_proc_rootcell_release(struct inode *inode, struct file *file)
{
return 0;
}
static ssize_t afs_proc_rootcell_read(struct file *file, char *buf,
size_t size, loff_t *_pos)
{
return 0;
}
/*****************************************************************************/
/*
* handle writes to /proc/fs/afs/rootcell
* - to initialize rootcell: echo "cell.name:192.168.231.14"
*/
static ssize_t afs_proc_rootcell_write(struct file *file, const char *buf,
size_t size, loff_t *_pos)
{
char *kbuf, *s;
int ret;
/* start by dragging the command into memory */
if (size <= 1 || size >= PAGE_SIZE)
return -EINVAL;
ret = -ENOMEM;
kbuf = kmalloc(size + 1, GFP_KERNEL);
if (!kbuf)
goto nomem;
ret = -EFAULT;
if (copy_from_user(kbuf, buf, size) != 0)
goto infault;
kbuf[size] = 0;
/* trim to first NL */
s = memchr(kbuf, '\n', size);
if (s)
*s = 0;
/* determine command to perform */
_debug("rootcell=%s", kbuf);
ret = afs_cell_init(kbuf);
if (ret >= 0)
ret = size; /* consume everything, always */
infault:
kfree(kbuf);
nomem:
_leave(" = %d", ret);
return ret;
} /* end afs_proc_rootcell_write() */
/*****************************************************************************/ /*****************************************************************************/
/* /*
* initialise /proc/fs/afs/<cell>/ * initialise /proc/fs/afs/<cell>/
*/ */
int afs_proc_cell_setup(afs_cell_t *cell) int afs_proc_cell_setup(struct afs_cell *cell)
{ {
struct proc_dir_entry *p; struct proc_dir_entry *p;
_enter("%p{%s}",cell,cell->name); _enter("%p{%s}", cell, cell->name);
cell->proc_dir = proc_mkdir(cell->name,proc_afs); cell->proc_dir = proc_mkdir(cell->name, proc_afs);
if (!cell->proc_dir) if (!cell->proc_dir)
return -ENOMEM; return -ENOMEM;
p = create_proc_entry("servers",0,cell->proc_dir); p = create_proc_entry("servers", 0, cell->proc_dir);
if (!p) if (!p)
goto error_proc; goto error_proc;
p->proc_fops = &afs_proc_cell_servers_fops; p->proc_fops = &afs_proc_cell_servers_fops;
p->owner = THIS_MODULE; p->owner = THIS_MODULE;
p->data = cell; p->data = cell;
p = create_proc_entry("vlservers",0,cell->proc_dir); p = create_proc_entry("vlservers", 0, cell->proc_dir);
if (!p) if (!p)
goto error_servers; goto error_servers;
p->proc_fops = &afs_proc_cell_vlservers_fops; p->proc_fops = &afs_proc_cell_vlservers_fops;
p->owner = THIS_MODULE; p->owner = THIS_MODULE;
p->data = cell; p->data = cell;
p = create_proc_entry("volumes",0,cell->proc_dir); p = create_proc_entry("volumes", 0, cell->proc_dir);
if (!p) if (!p)
goto error_vlservers; goto error_vlservers;
p->proc_fops = &afs_proc_cell_volumes_fops; p->proc_fops = &afs_proc_cell_volumes_fops;
...@@ -350,11 +452,11 @@ int afs_proc_cell_setup(afs_cell_t *cell) ...@@ -350,11 +452,11 @@ int afs_proc_cell_setup(afs_cell_t *cell)
return 0; return 0;
error_vlservers: error_vlservers:
remove_proc_entry("vlservers",cell->proc_dir); remove_proc_entry("vlservers", cell->proc_dir);
error_servers: error_servers:
remove_proc_entry("servers",cell->proc_dir); remove_proc_entry("servers", cell->proc_dir);
error_proc: error_proc:
remove_proc_entry(cell->name,proc_afs); remove_proc_entry(cell->name, proc_afs);
_leave(" = -ENOMEM"); _leave(" = -ENOMEM");
return -ENOMEM; return -ENOMEM;
} /* end afs_proc_cell_setup() */ } /* end afs_proc_cell_setup() */
...@@ -363,14 +465,14 @@ int afs_proc_cell_setup(afs_cell_t *cell) ...@@ -363,14 +465,14 @@ int afs_proc_cell_setup(afs_cell_t *cell)
/* /*
* remove /proc/fs/afs/<cell>/ * remove /proc/fs/afs/<cell>/
*/ */
void afs_proc_cell_remove(afs_cell_t *cell) void afs_proc_cell_remove(struct afs_cell *cell)
{ {
_enter(""); _enter("");
remove_proc_entry("volumes",cell->proc_dir); remove_proc_entry("volumes", cell->proc_dir);
remove_proc_entry("vlservers",cell->proc_dir); remove_proc_entry("vlservers", cell->proc_dir);
remove_proc_entry("servers",cell->proc_dir); remove_proc_entry("servers", cell->proc_dir);
remove_proc_entry(cell->name,proc_afs); remove_proc_entry(cell->name, proc_afs);
_leave(""); _leave("");
} /* end afs_proc_cell_remove() */ } /* end afs_proc_cell_remove() */
...@@ -381,16 +483,16 @@ void afs_proc_cell_remove(afs_cell_t *cell) ...@@ -381,16 +483,16 @@ void afs_proc_cell_remove(afs_cell_t *cell)
*/ */
static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file) static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file)
{ {
struct afs_cell *cell;
struct seq_file *m; struct seq_file *m;
afs_cell_t *cell;
int ret; int ret;
cell = afs_get_cell_maybe((afs_cell_t**)&PDE(inode)->data); cell = afs_get_cell_maybe((struct afs_cell **) &PDE(inode)->data);
if (!cell) if (!cell)
return -ENOENT; return -ENOENT;
ret = seq_open(file,&afs_proc_cell_volumes_ops); ret = seq_open(file, &afs_proc_cell_volumes_ops);
if (ret<0) if (ret < 0)
return ret; return ret;
m = file->private_data; m = file->private_data;
...@@ -405,7 +507,7 @@ static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file) ...@@ -405,7 +507,7 @@ static int afs_proc_cell_volumes_open(struct inode *inode, struct file *file)
*/ */
static int afs_proc_cell_volumes_release(struct inode *inode, struct file *file) static int afs_proc_cell_volumes_release(struct inode *inode, struct file *file)
{ {
afs_cell_t *cell = PDE(inode)->data; struct afs_cell *cell = PDE(inode)->data;
int ret; int ret;
ret = seq_release(inode,file); ret = seq_release(inode,file);
...@@ -417,49 +519,51 @@ static int afs_proc_cell_volumes_release(struct inode *inode, struct file *file) ...@@ -417,49 +519,51 @@ static int afs_proc_cell_volumes_release(struct inode *inode, struct file *file)
/*****************************************************************************/ /*****************************************************************************/
/* /*
* set up the iterator to start reading from the cells list and return the first item * set up the iterator to start reading from the cells list and return the
* first item
*/ */
static void *afs_proc_cell_volumes_start(struct seq_file *m, loff_t *_pos) static void *afs_proc_cell_volumes_start(struct seq_file *m, loff_t *_pos)
{ {
struct list_head *_p; struct list_head *_p;
afs_cell_t *cell = m->private; struct afs_cell *cell = m->private;
loff_t pos = *_pos; loff_t pos = *_pos;
_enter("cell=%p pos=%Ld",cell,*_pos); _enter("cell=%p pos=%Ld", cell, *_pos);
/* lock the list against modification */ /* lock the list against modification */
down_read(&cell->vl_sem); down_read(&cell->vl_sem);
/* allow for the header line */ /* allow for the header line */
if (!pos) if (!pos)
return (void *)1; return (void *) 1;
pos--; pos--;
/* find the n'th element in the list */ /* find the n'th element in the list */
list_for_each(_p,&cell->vl_list) list_for_each(_p, &cell->vl_list)
if (!pos--) if (!pos--)
break; break;
return _p!=&cell->vl_list ? _p : NULL; return _p != &cell->vl_list ? _p : NULL;
} /* end afs_proc_cell_volumes_start() */ } /* end afs_proc_cell_volumes_start() */
/*****************************************************************************/ /*****************************************************************************/
/* /*
* move to next cell in cells list * move to next cell in cells list
*/ */
static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v, loff_t *_pos) static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v,
loff_t *_pos)
{ {
struct list_head *_p; struct list_head *_p;
afs_cell_t *cell = p->private; struct afs_cell *cell = p->private;
_enter("cell=%p pos=%Ld",cell,*_pos); _enter("cell=%p pos=%Ld", cell, *_pos);
(*_pos)++; (*_pos)++;
_p = v; _p = v;
_p = v==(void*)1 ? cell->vl_list.next : _p->next; _p = v == (void *) 1 ? cell->vl_list.next : _p->next;
return _p!=&cell->vl_list ? _p : NULL; return _p != &cell->vl_list ? _p : NULL;
} /* end afs_proc_cell_volumes_next() */ } /* end afs_proc_cell_volumes_next() */
/*****************************************************************************/ /*****************************************************************************/
...@@ -468,7 +572,7 @@ static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v, loff_t *_po ...@@ -468,7 +572,7 @@ static void *afs_proc_cell_volumes_next(struct seq_file *p, void *v, loff_t *_po
*/ */
static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v) static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v)
{ {
afs_cell_t *cell = p->private; struct afs_cell *cell = p->private;
up_read(&cell->vl_sem); up_read(&cell->vl_sem);
...@@ -480,16 +584,17 @@ static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v) ...@@ -480,16 +584,17 @@ static void afs_proc_cell_volumes_stop(struct seq_file *p, void *v)
*/ */
static int afs_proc_cell_volumes_show(struct seq_file *m, void *v) static int afs_proc_cell_volumes_show(struct seq_file *m, void *v)
{ {
afs_vlocation_t *vlocation = list_entry(v,afs_vlocation_t,link); struct afs_vlocation *vlocation =
list_entry(v, struct afs_vlocation, link);
/* display header on line 1 */ /* display header on line 1 */
if (v == (void *)1) { if (v == (void *) 1) {
seq_puts(m, "USE VLID[0] VLID[1] VLID[2] NAME\n"); seq_puts(m, "USE VLID[0] VLID[1] VLID[2] NAME\n");
return 0; return 0;
} }
/* display one cell per line on subsequent lines */ /* display one cell per line on subsequent lines */
seq_printf(m,"%3d %08x %08x %08x %s\n", seq_printf(m, "%3d %08x %08x %08x %s\n",
atomic_read(&vlocation->usage), atomic_read(&vlocation->usage),
vlocation->vldb.vid[0], vlocation->vldb.vid[0],
vlocation->vldb.vid[1], vlocation->vldb.vid[1],
...@@ -502,15 +607,16 @@ static int afs_proc_cell_volumes_show(struct seq_file *m, void *v) ...@@ -502,15 +607,16 @@ static int afs_proc_cell_volumes_show(struct seq_file *m, void *v)
/*****************************************************************************/ /*****************************************************************************/
/* /*
* open "/proc/fs/afs/<cell>/vlservers" which provides a list of volume location server * open "/proc/fs/afs/<cell>/vlservers" which provides a list of volume
* location server
*/ */
static int afs_proc_cell_vlservers_open(struct inode *inode, struct file *file) static int afs_proc_cell_vlservers_open(struct inode *inode, struct file *file)
{ {
struct afs_cell *cell;
struct seq_file *m; struct seq_file *m;
afs_cell_t *cell;
int ret; int ret;
cell = afs_get_cell_maybe((afs_cell_t**)&PDE(inode)->data); cell = afs_get_cell_maybe((struct afs_cell**)&PDE(inode)->data);
if (!cell) if (!cell)
return -ENOENT; return -ENOENT;
...@@ -528,9 +634,10 @@ static int afs_proc_cell_vlservers_open(struct inode *inode, struct file *file) ...@@ -528,9 +634,10 @@ static int afs_proc_cell_vlservers_open(struct inode *inode, struct file *file)
/* /*
* close the file and release the ref to the cell * close the file and release the ref to the cell
*/ */
static int afs_proc_cell_vlservers_release(struct inode *inode, struct file *file) static int afs_proc_cell_vlservers_release(struct inode *inode,
struct file *file)
{ {
afs_cell_t *cell = PDE(inode)->data; struct afs_cell *cell = PDE(inode)->data;
int ret; int ret;
ret = seq_release(inode,file); ret = seq_release(inode,file);
...@@ -542,24 +649,25 @@ static int afs_proc_cell_vlservers_release(struct inode *inode, struct file *fil ...@@ -542,24 +649,25 @@ static int afs_proc_cell_vlservers_release(struct inode *inode, struct file *fil
/*****************************************************************************/ /*****************************************************************************/
/* /*
* set up the iterator to start reading from the cells list and return the first item * set up the iterator to start reading from the cells list and return the
* first item
*/ */
static void *afs_proc_cell_vlservers_start(struct seq_file *m, loff_t *_pos) static void *afs_proc_cell_vlservers_start(struct seq_file *m, loff_t *_pos)
{ {
afs_cell_t *cell = m->private; struct afs_cell *cell = m->private;
loff_t pos = *_pos; loff_t pos = *_pos;
_enter("cell=%p pos=%Ld",cell,*_pos); _enter("cell=%p pos=%Ld", cell, *_pos);
/* lock the list against modification */ /* lock the list against modification */
down_read(&cell->vl_sem); down_read(&cell->vl_sem);
/* allow for the header line */ /* allow for the header line */
if (!pos) if (!pos)
return (void *)1; return (void *) 1;
pos--; pos--;
if (pos>=cell->vl_naddrs) if (pos >= cell->vl_naddrs)
return NULL; return NULL;
return &cell->vl_addrs[pos]; return &cell->vl_addrs[pos];
...@@ -569,16 +677,17 @@ static void *afs_proc_cell_vlservers_start(struct seq_file *m, loff_t *_pos) ...@@ -569,16 +677,17 @@ static void *afs_proc_cell_vlservers_start(struct seq_file *m, loff_t *_pos)
/* /*
* move to next cell in cells list * move to next cell in cells list
*/ */
static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v, loff_t *_pos) static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v,
loff_t *_pos)
{ {
afs_cell_t *cell = p->private; struct afs_cell *cell = p->private;
loff_t pos; loff_t pos;
_enter("cell=%p{nad=%u} pos=%Ld",cell,cell->vl_naddrs,*_pos); _enter("cell=%p{nad=%u} pos=%Ld", cell, cell->vl_naddrs, *_pos);
pos = *_pos; pos = *_pos;
(*_pos)++; (*_pos)++;
if (pos>=cell->vl_naddrs) if (pos >= cell->vl_naddrs)
return NULL; return NULL;
return &cell->vl_addrs[pos]; return &cell->vl_addrs[pos];
...@@ -590,7 +699,7 @@ static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v, loff_t *_ ...@@ -590,7 +699,7 @@ static void *afs_proc_cell_vlservers_next(struct seq_file *p, void *v, loff_t *_
*/ */
static void afs_proc_cell_vlservers_stop(struct seq_file *p, void *v) static void afs_proc_cell_vlservers_stop(struct seq_file *p, void *v)
{ {
afs_cell_t *cell = p->private; struct afs_cell *cell = p->private;
up_read(&cell->vl_sem); up_read(&cell->vl_sem);
...@@ -605,33 +714,34 @@ static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v) ...@@ -605,33 +714,34 @@ static int afs_proc_cell_vlservers_show(struct seq_file *m, void *v)
struct in_addr *addr = v; struct in_addr *addr = v;
/* display header on line 1 */ /* display header on line 1 */
if (v == (struct in_addr *)1) { if (v == (struct in_addr *) 1) {
seq_puts(m,"ADDRESS\n"); seq_puts(m, "ADDRESS\n");
return 0; return 0;
} }
/* display one cell per line on subsequent lines */ /* display one cell per line on subsequent lines */
seq_printf(m,"%u.%u.%u.%u\n",NIPQUAD(addr->s_addr)); seq_printf(m, "%u.%u.%u.%u\n", NIPQUAD(addr->s_addr));
return 0; return 0;
} /* end afs_proc_cell_vlservers_show() */ } /* end afs_proc_cell_vlservers_show() */
/*****************************************************************************/ /*****************************************************************************/
/* /*
* open "/proc/fs/afs/<cell>/servers" which provides a summary of active servers * open "/proc/fs/afs/<cell>/servers" which provides a summary of active
* servers
*/ */
static int afs_proc_cell_servers_open(struct inode *inode, struct file *file) static int afs_proc_cell_servers_open(struct inode *inode, struct file *file)
{ {
struct afs_cell *cell;
struct seq_file *m; struct seq_file *m;
afs_cell_t *cell;
int ret; int ret;
cell = afs_get_cell_maybe((afs_cell_t**)&PDE(inode)->data); cell = afs_get_cell_maybe((struct afs_cell **) &PDE(inode)->data);
if (!cell) if (!cell)
return -ENOENT; return -ENOENT;
ret = seq_open(file,&afs_proc_cell_servers_ops); ret = seq_open(file, &afs_proc_cell_servers_ops);
if (ret<0) if (ret < 0)
return ret; return ret;
m = file->private_data; m = file->private_data;
...@@ -644,12 +754,13 @@ static int afs_proc_cell_servers_open(struct inode *inode, struct file *file) ...@@ -644,12 +754,13 @@ static int afs_proc_cell_servers_open(struct inode *inode, struct file *file)
/* /*
* close the file and release the ref to the cell * close the file and release the ref to the cell
*/ */
static int afs_proc_cell_servers_release(struct inode *inode, struct file *file) static int afs_proc_cell_servers_release(struct inode *inode,
struct file *file)
{ {
afs_cell_t *cell = PDE(inode)->data; struct afs_cell *cell = PDE(inode)->data;
int ret; int ret;
ret = seq_release(inode,file); ret = seq_release(inode, file);
afs_put_cell(cell); afs_put_cell(cell);
...@@ -658,49 +769,51 @@ static int afs_proc_cell_servers_release(struct inode *inode, struct file *file) ...@@ -658,49 +769,51 @@ static int afs_proc_cell_servers_release(struct inode *inode, struct file *file)
/*****************************************************************************/ /*****************************************************************************/
/* /*
* set up the iterator to start reading from the cells list and return the first item * set up the iterator to start reading from the cells list and return the
* first item
*/ */
static void *afs_proc_cell_servers_start(struct seq_file *m, loff_t *_pos) static void *afs_proc_cell_servers_start(struct seq_file *m, loff_t *_pos)
{ {
struct list_head *_p; struct list_head *_p;
afs_cell_t *cell = m->private; struct afs_cell *cell = m->private;
loff_t pos = *_pos; loff_t pos = *_pos;
_enter("cell=%p pos=%Ld",cell,*_pos); _enter("cell=%p pos=%Ld", cell, *_pos);
/* lock the list against modification */ /* lock the list against modification */
read_lock(&cell->sv_lock); read_lock(&cell->sv_lock);
/* allow for the header line */ /* allow for the header line */
if (!pos) if (!pos)
return (void *)1; return (void *) 1;
pos--; pos--;
/* find the n'th element in the list */ /* find the n'th element in the list */
list_for_each(_p,&cell->sv_list) list_for_each(_p, &cell->sv_list)
if (!pos--) if (!pos--)
break; break;
return _p!=&cell->sv_list ? _p : NULL; return _p != &cell->sv_list ? _p : NULL;
} /* end afs_proc_cell_servers_start() */ } /* end afs_proc_cell_servers_start() */
/*****************************************************************************/ /*****************************************************************************/
/* /*
* move to next cell in cells list * move to next cell in cells list
*/ */
static void *afs_proc_cell_servers_next(struct seq_file *p, void *v, loff_t *_pos) static void *afs_proc_cell_servers_next(struct seq_file *p, void *v,
loff_t *_pos)
{ {
struct list_head *_p; struct list_head *_p;
afs_cell_t *cell = p->private; struct afs_cell *cell = p->private;
_enter("cell=%p pos=%Ld",cell,*_pos); _enter("cell=%p pos=%Ld", cell, *_pos);
(*_pos)++; (*_pos)++;
_p = v; _p = v;
_p = v==(void*)1 ? cell->sv_list.next : _p->next; _p = v == (void *) 1 ? cell->sv_list.next : _p->next;
return _p!=&cell->sv_list ? _p : NULL; return _p != &cell->sv_list ? _p : NULL;
} /* end afs_proc_cell_servers_next() */ } /* end afs_proc_cell_servers_next() */
/*****************************************************************************/ /*****************************************************************************/
...@@ -709,7 +822,7 @@ static void *afs_proc_cell_servers_next(struct seq_file *p, void *v, loff_t *_po ...@@ -709,7 +822,7 @@ static void *afs_proc_cell_servers_next(struct seq_file *p, void *v, loff_t *_po
*/ */
static void afs_proc_cell_servers_stop(struct seq_file *p, void *v) static void afs_proc_cell_servers_stop(struct seq_file *p, void *v)
{ {
afs_cell_t *cell = p->private; struct afs_cell *cell = p->private;
read_unlock(&cell->sv_lock); read_unlock(&cell->sv_lock);
...@@ -721,18 +834,18 @@ static void afs_proc_cell_servers_stop(struct seq_file *p, void *v) ...@@ -721,18 +834,18 @@ static void afs_proc_cell_servers_stop(struct seq_file *p, void *v)
*/ */
static int afs_proc_cell_servers_show(struct seq_file *m, void *v) static int afs_proc_cell_servers_show(struct seq_file *m, void *v)
{ {
afs_server_t *server = list_entry(v,afs_server_t,link); struct afs_server *server = list_entry(v, struct afs_server, link);
char ipaddr[20]; char ipaddr[20];
/* display header on line 1 */ /* display header on line 1 */
if (v == (void *)1) { if (v == (void *) 1) {
seq_puts(m, "USE ADDR STATE\n"); seq_puts(m, "USE ADDR STATE\n");
return 0; return 0;
} }
/* display one cell per line on subsequent lines */ /* display one cell per line on subsequent lines */
sprintf(ipaddr,"%u.%u.%u.%u",NIPQUAD(server->addr)); sprintf(ipaddr, "%u.%u.%u.%u", NIPQUAD(server->addr));
seq_printf(m,"%3d %-15.15s %5d\n", seq_printf(m, "%3d %-15.15s %5d\n",
atomic_read(&server->usage), atomic_read(&server->usage),
ipaddr, ipaddr,
server->fs_state server->fs_state
......
...@@ -26,11 +26,13 @@ spinlock_t afs_server_peer_lock = SPIN_LOCK_UNLOCKED; ...@@ -26,11 +26,13 @@ spinlock_t afs_server_peer_lock = SPIN_LOCK_UNLOCKED;
#define FS_SERVICE_ID 1 /* AFS Volume Location Service ID */ #define FS_SERVICE_ID 1 /* AFS Volume Location Service ID */
#define VL_SERVICE_ID 52 /* AFS Volume Location Service ID */ #define VL_SERVICE_ID 52 /* AFS Volume Location Service ID */
static void __afs_server_timeout(afs_timer_t *timer) static void __afs_server_timeout(struct afs_timer *timer)
{ {
afs_server_t *server = list_entry(timer,afs_server_t,timeout); struct afs_server *server =
list_entry(timer, struct afs_server, timeout);
_debug("SERVER TIMEOUT [%p{u=%d}]",server,atomic_read(&server->usage)); _debug("SERVER TIMEOUT [%p{u=%d}]",
server, atomic_read(&server->usage));
afs_server_do_timeout(server); afs_server_do_timeout(server);
} }
...@@ -44,23 +46,23 @@ static const struct afs_timer_ops afs_server_timer_ops = { ...@@ -44,23 +46,23 @@ static const struct afs_timer_ops afs_server_timer_ops = {
* lookup a server record in a cell * lookup a server record in a cell
* - TODO: search the cell's server list * - TODO: search the cell's server list
*/ */
int afs_server_lookup(afs_cell_t *cell, const struct in_addr *addr, afs_server_t **_server) int afs_server_lookup(struct afs_cell *cell, const struct in_addr *addr,
struct afs_server **_server)
{ {
struct list_head *_p; struct afs_server *server, *active, *zombie;
afs_server_t *server, *active, *zombie;
int loop; int loop;
_enter("%p,%08x,",cell,ntohl(addr->s_addr)); _enter("%p,%08x,", cell, ntohl(addr->s_addr));
/* allocate and initialise a server record */ /* allocate and initialise a server record */
server = kmalloc(sizeof(afs_server_t),GFP_KERNEL); server = kmalloc(sizeof(struct afs_server), GFP_KERNEL);
if (!server) { if (!server) {
_leave(" = -ENOMEM"); _leave(" = -ENOMEM");
return -ENOMEM; return -ENOMEM;
} }
memset(server,0,sizeof(afs_server_t)); memset(server, 0, sizeof(struct afs_server));
atomic_set(&server->usage,1); atomic_set(&server->usage, 1);
INIT_LIST_HEAD(&server->link); INIT_LIST_HEAD(&server->link);
init_rwsem(&server->sem); init_rwsem(&server->sem);
...@@ -69,43 +71,39 @@ int afs_server_lookup(afs_cell_t *cell, const struct in_addr *addr, afs_server_t ...@@ -69,43 +71,39 @@ int afs_server_lookup(afs_cell_t *cell, const struct in_addr *addr, afs_server_t
INIT_LIST_HEAD(&server->cb_promises); INIT_LIST_HEAD(&server->cb_promises);
spin_lock_init(&server->cb_lock); spin_lock_init(&server->cb_lock);
for (loop=0; loop<AFS_SERVER_CONN_LIST_SIZE; loop++) for (loop = 0; loop < AFS_SERVER_CONN_LIST_SIZE; loop++)
server->fs_conn_cnt[loop] = 4; server->fs_conn_cnt[loop] = 4;
memcpy(&server->addr,addr,sizeof(struct in_addr)); memcpy(&server->addr, addr, sizeof(struct in_addr));
server->addr.s_addr = addr->s_addr; server->addr.s_addr = addr->s_addr;
afs_timer_init(&server->timeout,&afs_server_timer_ops); afs_timer_init(&server->timeout, &afs_server_timer_ops);
/* add to the cell */ /* add to the cell */
write_lock(&cell->sv_lock); write_lock(&cell->sv_lock);
/* check the active list */ /* check the active list */
list_for_each(_p,&cell->sv_list) { list_for_each_entry(active, &cell->sv_list, link) {
active = list_entry(_p,afs_server_t,link); if (active->addr.s_addr == addr->s_addr)
if (active->addr.s_addr==addr->s_addr)
goto use_active_server; goto use_active_server;
} }
/* check the inactive list */ /* check the inactive list */
spin_lock(&cell->sv_gylock); spin_lock(&cell->sv_gylock);
list_for_each(_p,&cell->sv_graveyard) { list_for_each_entry(zombie, &cell->sv_graveyard, link) {
zombie = list_entry(_p,afs_server_t,link); if (zombie->addr.s_addr == addr->s_addr)
if (zombie->addr.s_addr==addr->s_addr)
goto resurrect_server; goto resurrect_server;
} }
spin_unlock(&cell->sv_gylock); spin_unlock(&cell->sv_gylock);
afs_get_cell(cell); afs_get_cell(cell);
server->cell = cell; server->cell = cell;
list_add_tail(&server->link,&cell->sv_list); list_add_tail(&server->link, &cell->sv_list);
write_unlock(&cell->sv_lock); write_unlock(&cell->sv_lock);
*_server = server; *_server = server;
_leave(" = 0 (%p)",server); _leave(" = 0 (%p)", server);
return 0; return 0;
/* found a matching active server */ /* found a matching active server */
...@@ -117,15 +115,16 @@ int afs_server_lookup(afs_cell_t *cell, const struct in_addr *addr, afs_server_t ...@@ -117,15 +115,16 @@ int afs_server_lookup(afs_cell_t *cell, const struct in_addr *addr, afs_server_t
kfree(server); kfree(server);
*_server = active; *_server = active;
_leave(" = 0 (%p)",active); _leave(" = 0 (%p)", active);
return 0; return 0;
/* found a matching server in the graveyard, so resurrect it and dispose of the new rec */ /* found a matching server in the graveyard, so resurrect it and
* dispose of the new record */
resurrect_server: resurrect_server:
_debug("resurrecting server"); _debug("resurrecting server");
list_del(&zombie->link); list_del(&zombie->link);
list_add_tail(&zombie->link,&cell->sv_list); list_add_tail(&zombie->link, &cell->sv_list);
afs_get_server(zombie); afs_get_server(zombie);
afs_kafstimod_del_timer(&zombie->timeout); afs_kafstimod_del_timer(&zombie->timeout);
spin_unlock(&cell->sv_gylock); spin_unlock(&cell->sv_gylock);
...@@ -134,7 +133,7 @@ int afs_server_lookup(afs_cell_t *cell, const struct in_addr *addr, afs_server_t ...@@ -134,7 +133,7 @@ int afs_server_lookup(afs_cell_t *cell, const struct in_addr *addr, afs_server_t
kfree(server); kfree(server);
*_server = zombie; *_server = zombie;
_leave(" = 0 (%p)",zombie); _leave(" = 0 (%p)", zombie);
return 0; return 0;
} /* end afs_server_lookup() */ } /* end afs_server_lookup() */
...@@ -144,22 +143,22 @@ int afs_server_lookup(afs_cell_t *cell, const struct in_addr *addr, afs_server_t ...@@ -144,22 +143,22 @@ int afs_server_lookup(afs_cell_t *cell, const struct in_addr *addr, afs_server_t
* destroy a server record * destroy a server record
* - removes from the cell list * - removes from the cell list
*/ */
void afs_put_server(afs_server_t *server) void afs_put_server(struct afs_server *server)
{ {
afs_cell_t *cell; struct afs_cell *cell;
if (!server) if (!server)
return; return;
_enter("%p",server); _enter("%p", server);
cell = server->cell; cell = server->cell;
/* sanity check */ /* sanity check */
if (atomic_read(&server->usage)<=0) BUG_ON(atomic_read(&server->usage) <= 0);
BUG();
/* to prevent a race, the decrement and the dequeue must be effectively atomic */ /* to prevent a race, the decrement and the dequeue must be effectively
* atomic */
write_lock(&cell->sv_lock); write_lock(&cell->sv_lock);
if (likely(!atomic_dec_and_test(&server->usage))) { if (likely(!atomic_dec_and_test(&server->usage))) {
...@@ -170,10 +169,10 @@ void afs_put_server(afs_server_t *server) ...@@ -170,10 +169,10 @@ void afs_put_server(afs_server_t *server)
spin_lock(&cell->sv_gylock); spin_lock(&cell->sv_gylock);
list_del(&server->link); list_del(&server->link);
list_add_tail(&server->link,&cell->sv_graveyard); list_add_tail(&server->link, &cell->sv_graveyard);
/* time out in 10 secs */ /* time out in 10 secs */
afs_kafstimod_add_timer(&server->timeout,10*HZ); afs_kafstimod_add_timer(&server->timeout, 10 * HZ);
spin_unlock(&cell->sv_gylock); spin_unlock(&cell->sv_gylock);
write_unlock(&cell->sv_lock); write_unlock(&cell->sv_lock);
...@@ -186,21 +185,21 @@ void afs_put_server(afs_server_t *server) ...@@ -186,21 +185,21 @@ void afs_put_server(afs_server_t *server)
* timeout server record * timeout server record
* - removes from the cell's graveyard if the usage count is zero * - removes from the cell's graveyard if the usage count is zero
*/ */
void afs_server_do_timeout(afs_server_t *server) void afs_server_do_timeout(struct afs_server *server)
{ {
struct rxrpc_peer *peer; struct rxrpc_peer *peer;
afs_cell_t *cell; struct afs_cell *cell;
int loop; int loop;
_enter("%p",server); _enter("%p", server);
cell = server->cell; cell = server->cell;
if (atomic_read(&server->usage)<0) BUG(); BUG_ON(atomic_read(&server->usage) < 0);
/* remove from graveyard if still dead */ /* remove from graveyard if still dead */
spin_lock(&cell->vl_gylock); spin_lock(&cell->vl_gylock);
if (atomic_read(&server->usage)==0) if (atomic_read(&server->usage) == 0)
list_del_init(&server->link); list_del_init(&server->link);
else else
server = NULL; server = NULL;
...@@ -224,7 +223,7 @@ void afs_server_do_timeout(afs_server_t *server) ...@@ -224,7 +223,7 @@ void afs_server_do_timeout(afs_server_t *server)
spin_unlock(&afs_server_peer_lock); spin_unlock(&afs_server_peer_lock);
/* finish cleaning up the server */ /* finish cleaning up the server */
for (loop=AFS_SERVER_CONN_LIST_SIZE-1; loop>=0; loop--) for (loop = AFS_SERVER_CONN_LIST_SIZE - 1; loop >= 0; loop--)
if (server->fs_conn[loop]) if (server->fs_conn[loop])
rxrpc_put_connection(server->fs_conn[loop]); rxrpc_put_connection(server->fs_conn[loop]);
...@@ -240,7 +239,8 @@ void afs_server_do_timeout(afs_server_t *server) ...@@ -240,7 +239,8 @@ void afs_server_do_timeout(afs_server_t *server)
/* /*
* get a callslot on a connection to the fileserver on the specified server * get a callslot on a connection to the fileserver on the specified server
*/ */
int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot *callslot) int afs_server_request_callslot(struct afs_server *server,
struct afs_server_callslot *callslot)
{ {
struct afs_server_callslot *pcallslot; struct afs_server_callslot *pcallslot;
struct rxrpc_connection *conn; struct rxrpc_connection *conn;
...@@ -262,10 +262,10 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot ...@@ -262,10 +262,10 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot
/* resurrect the server if it's death timeout has expired */ /* resurrect the server if it's death timeout has expired */
if (server->fs_state) { if (server->fs_state) {
if (time_before(jiffies,server->fs_dead_jif)) { if (time_before(jiffies, server->fs_dead_jif)) {
ret = server->fs_state; ret = server->fs_state;
spin_unlock(&server->fs_lock); spin_unlock(&server->fs_lock);
_leave(" = %d [still dead]",ret); _leave(" = %d [still dead]", ret);
return ret; return ret;
} }
...@@ -273,8 +273,8 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot ...@@ -273,8 +273,8 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot
} }
/* try and find a connection that has spare callslots */ /* try and find a connection that has spare callslots */
for (nconn=0; nconn<AFS_SERVER_CONN_LIST_SIZE; nconn++) { for (nconn = 0; nconn < AFS_SERVER_CONN_LIST_SIZE; nconn++) {
if (server->fs_conn_cnt[nconn]>0) { if (server->fs_conn_cnt[nconn] > 0) {
server->fs_conn_cnt[nconn]--; server->fs_conn_cnt[nconn]--;
spin_unlock(&server->fs_lock); spin_unlock(&server->fs_lock);
callslot->nconn = nconn; callslot->nconn = nconn;
...@@ -282,9 +282,10 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot ...@@ -282,9 +282,10 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot
} }
} }
/* none were available - wait interruptibly for one to become available */ /* none were available - wait interruptibly for one to become
* available */
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
list_add_tail(&callslot->link,&server->fs_callq); list_add_tail(&callslot->link, &server->fs_callq);
spin_unlock(&server->fs_lock); spin_unlock(&server->fs_lock);
while (!callslot->ready && !signal_pending(current)) { while (!callslot->ready && !signal_pending(current)) {
...@@ -303,22 +304,24 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot ...@@ -303,22 +304,24 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot
nconn = callslot->nconn; nconn = callslot->nconn;
/* if interrupted, we must release any slot we also got before returning an error */ /* if interrupted, we must release any slot we also got before
* returning an error */
if (signal_pending(current)) { if (signal_pending(current)) {
ret = -EINTR; ret = -EINTR;
goto error_release; goto error_release;
} }
/* if we were woken up with an error, then pass that error back to the called */ /* if we were woken up with an error, then pass that error back to the
if (nconn<0) { * called */
_leave(" = %d",callslot->errno); if (nconn < 0) {
_leave(" = %d", callslot->errno);
return callslot->errno; return callslot->errno;
} }
/* were we given a connection directly? */ /* were we given a connection directly? */
if (callslot->conn) { if (callslot->conn) {
/* yes - use it */ /* yes - use it */
_leave(" = 0 (nc=%d)",nconn); _leave(" = 0 (nc=%d)", nconn);
return 0; return 0;
} }
...@@ -347,7 +350,7 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot ...@@ -347,7 +350,7 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot
NULL, NULL,
&server->fs_conn[nconn]); &server->fs_conn[nconn]);
if (ret<0) if (ret < 0)
goto error_release_upw; goto error_release_upw;
callslot->conn = server->fs_conn[0]; callslot->conn = server->fs_conn[0];
...@@ -364,10 +367,11 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot ...@@ -364,10 +367,11 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot
up_write(&server->sem); up_write(&server->sem);
error_release: error_release:
/* either release the callslot or pass it along to another deserving task */ /* either release the callslot or pass it along to another deserving
* task */
spin_lock(&server->fs_lock); spin_lock(&server->fs_lock);
if (nconn<0) { if (nconn < 0) {
/* no callslot allocated */ /* no callslot allocated */
} }
else if (list_empty(&server->fs_callq)) { else if (list_empty(&server->fs_callq)) {
...@@ -377,13 +381,15 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot ...@@ -377,13 +381,15 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot
} }
else { else {
/* someone's waiting - dequeue them and wake them up */ /* someone's waiting - dequeue them and wake them up */
pcallslot = list_entry(server->fs_callq.next,struct afs_server_callslot,link); pcallslot = list_entry(server->fs_callq.next,
struct afs_server_callslot, link);
list_del_init(&pcallslot->link); list_del_init(&pcallslot->link);
pcallslot->errno = server->fs_state; pcallslot->errno = server->fs_state;
if (!pcallslot->errno) { if (!pcallslot->errno) {
/* pass them out callslot details */ /* pass them out callslot details */
callslot->conn = xchg(&pcallslot->conn,callslot->conn); callslot->conn = xchg(&pcallslot->conn,
callslot->conn);
pcallslot->nconn = nconn; pcallslot->nconn = nconn;
callslot->nconn = nconn = -1; callslot->nconn = nconn = -1;
} }
...@@ -392,10 +398,10 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot ...@@ -392,10 +398,10 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot
spin_unlock(&server->fs_lock); spin_unlock(&server->fs_lock);
} }
if (callslot->conn) rxrpc_put_connection(callslot->conn); rxrpc_put_connection(callslot->conn);
callslot->conn = NULL; callslot->conn = NULL;
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_server_request_callslot() */ } /* end afs_server_request_callslot() */
...@@ -405,7 +411,8 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot ...@@ -405,7 +411,8 @@ int afs_server_request_callslot(afs_server_t *server, struct afs_server_callslot
* release a callslot back to the server * release a callslot back to the server
* - transfers the RxRPC connection to the next pending callslot if possible * - transfers the RxRPC connection to the next pending callslot if possible
*/ */
void afs_server_release_callslot(afs_server_t *server, struct afs_server_callslot *callslot) void afs_server_release_callslot(struct afs_server *server,
struct afs_server_callslot *callslot)
{ {
struct afs_server_callslot *pcallslot; struct afs_server_callslot *pcallslot;
...@@ -414,7 +421,7 @@ void afs_server_release_callslot(afs_server_t *server, struct afs_server_callslo ...@@ -414,7 +421,7 @@ void afs_server_release_callslot(afs_server_t *server, struct afs_server_callslo
server->fs_conn_cnt[callslot->nconn], server->fs_conn_cnt[callslot->nconn],
callslot->nconn); callslot->nconn);
if (callslot->nconn<0) BUG(); BUG_ON(callslot->nconn < 0);
spin_lock(&server->fs_lock); spin_lock(&server->fs_lock);
...@@ -425,13 +432,14 @@ void afs_server_release_callslot(afs_server_t *server, struct afs_server_callslo ...@@ -425,13 +432,14 @@ void afs_server_release_callslot(afs_server_t *server, struct afs_server_callslo
} }
else { else {
/* someone's waiting - dequeue them and wake them up */ /* someone's waiting - dequeue them and wake them up */
pcallslot = list_entry(server->fs_callq.next,struct afs_server_callslot,link); pcallslot = list_entry(server->fs_callq.next,
struct afs_server_callslot, link);
list_del_init(&pcallslot->link); list_del_init(&pcallslot->link);
pcallslot->errno = server->fs_state; pcallslot->errno = server->fs_state;
if (!pcallslot->errno) { if (!pcallslot->errno) {
/* pass them out callslot details */ /* pass them out callslot details */
callslot->conn = xchg(&pcallslot->conn,callslot->conn); callslot->conn = xchg(&pcallslot->conn, callslot->conn);
pcallslot->nconn = callslot->nconn; pcallslot->nconn = callslot->nconn;
callslot->nconn = -1; callslot->nconn = -1;
} }
...@@ -441,21 +449,23 @@ void afs_server_release_callslot(afs_server_t *server, struct afs_server_callslo ...@@ -441,21 +449,23 @@ void afs_server_release_callslot(afs_server_t *server, struct afs_server_callslo
spin_unlock(&server->fs_lock); spin_unlock(&server->fs_lock);
} }
if (callslot->conn) rxrpc_put_connection(callslot->conn); rxrpc_put_connection(callslot->conn);
_leave(""); _leave("");
} /* end afs_server_release_callslot() */ } /* end afs_server_release_callslot() */
/*****************************************************************************/ /*****************************************************************************/
/* /*
* get a handle to a connection to the vlserver (volume location) on the specified server * get a handle to a connection to the vlserver (volume location) on the
* specified server
*/ */
int afs_server_get_vlconn(afs_server_t *server, struct rxrpc_connection **_conn) int afs_server_get_vlconn(struct afs_server *server,
struct rxrpc_connection **_conn)
{ {
struct rxrpc_connection *conn; struct rxrpc_connection *conn;
int ret; int ret;
_enter("%p,",server); _enter("%p,", server);
ret = 0; ret = 0;
conn = NULL; conn = NULL;
...@@ -479,7 +489,7 @@ int afs_server_get_vlconn(afs_server_t *server, struct rxrpc_connection **_conn) ...@@ -479,7 +489,7 @@ int afs_server_get_vlconn(afs_server_t *server, struct rxrpc_connection **_conn)
NULL, NULL,
&server->vlserver); &server->vlserver);
} }
if (ret==0) { if (ret == 0) {
rxrpc_get_connection(server->vlserver); rxrpc_get_connection(server->vlserver);
conn = server->vlserver; conn = server->vlserver;
} }
...@@ -487,6 +497,6 @@ int afs_server_get_vlconn(afs_server_t *server, struct rxrpc_connection **_conn) ...@@ -487,6 +497,6 @@ int afs_server_get_vlconn(afs_server_t *server, struct rxrpc_connection **_conn)
} }
*_conn = conn; *_conn = conn;
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_server_get_vlconn() */ } /* end afs_server_get_vlconn() */
...@@ -26,10 +26,10 @@ extern spinlock_t afs_server_peer_lock; ...@@ -26,10 +26,10 @@ extern spinlock_t afs_server_peer_lock;
struct afs_server struct afs_server
{ {
atomic_t usage; atomic_t usage;
afs_cell_t *cell; /* cell in which server resides */ struct afs_cell *cell; /* cell in which server resides */
struct list_head link; /* link in cell's server list */ struct list_head link; /* link in cell's server list */
struct rw_semaphore sem; /* access lock */ struct rw_semaphore sem; /* access lock */
afs_timer_t timeout; /* graveyard timeout */ struct afs_timer timeout; /* graveyard timeout */
struct in_addr addr; /* server address */ struct in_addr addr; /* server address */
struct rxrpc_peer *peer; /* peer record for this server */ struct rxrpc_peer *peer; /* peer record for this server */
struct rxrpc_connection *vlserver; /* connection to the volume location service */ struct rxrpc_connection *vlserver; /* connection to the volume location service */
...@@ -50,20 +50,25 @@ struct afs_server ...@@ -50,20 +50,25 @@ struct afs_server
spinlock_t cb_lock; /* access lock */ spinlock_t cb_lock; /* access lock */
}; };
extern int afs_server_lookup(afs_cell_t *cell, const struct in_addr *addr, afs_server_t **_server); extern int afs_server_lookup(struct afs_cell *cell,
const struct in_addr *addr,
struct afs_server **_server);
#define afs_get_server(S) do { atomic_inc(&(S)->usage); } while(0) #define afs_get_server(S) do { atomic_inc(&(S)->usage); } while(0)
extern void afs_put_server(afs_server_t *server); extern void afs_put_server(struct afs_server *server);
extern void afs_server_do_timeout(afs_server_t *server); extern void afs_server_do_timeout(struct afs_server *server);
extern int afs_server_find_by_peer(const struct rxrpc_peer *peer, afs_server_t **_server); extern int afs_server_find_by_peer(const struct rxrpc_peer *peer,
struct afs_server **_server);
extern int afs_server_get_vlconn(afs_server_t *server, struct rxrpc_connection **_conn); extern int afs_server_get_vlconn(struct afs_server *server,
struct rxrpc_connection **_conn);
static inline afs_server_t *afs_server_get_from_peer(struct rxrpc_peer *peer) static inline
struct afs_server *afs_server_get_from_peer(struct rxrpc_peer *peer)
{ {
afs_server_t *server; struct afs_server *server;
spin_lock(&afs_server_peer_lock); spin_lock(&afs_server_peer_lock);
server = peer->user; server = peer->user;
...@@ -88,10 +93,10 @@ struct afs_server_callslot ...@@ -88,10 +93,10 @@ struct afs_server_callslot
int errno; /* error number if nconn==-1 */ int errno; /* error number if nconn==-1 */
}; };
extern int afs_server_request_callslot(afs_server_t *server, extern int afs_server_request_callslot(struct afs_server *server,
struct afs_server_callslot *callslot); struct afs_server_callslot *callslot);
extern void afs_server_release_callslot(afs_server_t *server, extern void afs_server_release_callslot(struct afs_server *server,
struct afs_server_callslot *callslot); struct afs_server_callslot *callslot);
#endif /* _LINUX_AFS_SERVER_H */ #endif /* _LINUX_AFS_SERVER_H */
...@@ -86,7 +86,7 @@ int __init afs_fs_init(void) ...@@ -86,7 +86,7 @@ int __init afs_fs_init(void)
ret = -ENOMEM; ret = -ENOMEM;
afs_inode_cachep = kmem_cache_create("afs_inode_cache", afs_inode_cachep = kmem_cache_create("afs_inode_cache",
sizeof(afs_vnode_t), sizeof(struct afs_vnode),
0, 0,
SLAB_HWCACHE_ALIGN, SLAB_HWCACHE_ALIGN,
afs_i_init_once, afs_i_init_once,
...@@ -156,8 +156,8 @@ static int want_no_value(char *const *_value, const char *option) ...@@ -156,8 +156,8 @@ static int want_no_value(char *const *_value, const char *option)
/*****************************************************************************/ /*****************************************************************************/
/* /*
* parse the mount options * parse the mount options
* - this function has been shamelessly adapted from the ext3 fs which shamelessly adapted it from * - this function has been shamelessly adapted from the ext3 fs which
* the msdos fs * shamelessly adapted it from the msdos fs
*/ */
static int afs_super_parse_options(struct afs_mount_params *params, static int afs_super_parse_options(struct afs_mount_params *params,
char *options, char *options,
...@@ -235,9 +235,9 @@ static int afs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -235,9 +235,9 @@ static int afs_fill_super(struct super_block *sb, void *data, int silent)
{ {
struct afs_mount_params *params = data; struct afs_mount_params *params = data;
struct afs_super_info *as = NULL; struct afs_super_info *as = NULL;
struct afs_fid fid;
struct dentry *root = NULL; struct dentry *root = NULL;
struct inode *inode = NULL; struct inode *inode = NULL;
afs_fid_t fid;
int ret; int ret;
kenter(""); kenter("");
...@@ -387,7 +387,7 @@ static void afs_put_super(struct super_block *sb) ...@@ -387,7 +387,7 @@ static void afs_put_super(struct super_block *sb)
static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep, static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep,
unsigned long flags) unsigned long flags)
{ {
afs_vnode_t *vnode = (afs_vnode_t *) _vnode; struct afs_vnode *vnode = (struct afs_vnode *) _vnode;
if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) == if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
SLAB_CTOR_CONSTRUCTOR) { SLAB_CTOR_CONSTRUCTOR) {
...@@ -409,9 +409,9 @@ static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep, ...@@ -409,9 +409,9 @@ static void afs_i_init_once(void *_vnode, kmem_cache_t *cachep,
*/ */
static struct inode *afs_alloc_inode(struct super_block *sb) static struct inode *afs_alloc_inode(struct super_block *sb)
{ {
afs_vnode_t *vnode; struct afs_vnode *vnode;
vnode = (afs_vnode_t *) vnode = (struct afs_vnode *)
kmem_cache_alloc(afs_inode_cachep, SLAB_KERNEL); kmem_cache_alloc(afs_inode_cachep, SLAB_KERNEL);
if (!vnode) if (!vnode)
return NULL; return NULL;
......
...@@ -20,21 +20,6 @@ typedef unsigned afs_volid_t; ...@@ -20,21 +20,6 @@ typedef unsigned afs_volid_t;
typedef unsigned afs_vnodeid_t; typedef unsigned afs_vnodeid_t;
typedef unsigned long long afs_dataversion_t; typedef unsigned long long afs_dataversion_t;
typedef struct afs_async_op afs_async_op_t;
typedef struct afs_callback afs_callback_t;
typedef struct afs_cell afs_cell_t;
typedef struct afs_fid afs_fid_t;
typedef struct afs_file_status afs_file_status_t;
typedef struct afs_server afs_server_t;
typedef struct afs_timer afs_timer_t;
typedef struct afs_vlocation afs_vlocation_t;
typedef struct afs_vnode afs_vnode_t;
typedef struct afs_volsync afs_volsync_t;
typedef struct afs_volume afs_volume_t;
typedef struct afs_volume_info afs_volume_info_t;
typedef struct afsvl_dbentry afsvl_dbentry_t;
typedef enum { typedef enum {
AFSVL_RWVOL, /* read/write volume */ AFSVL_RWVOL, /* read/write volume */
AFSVL_ROVOL, /* read-only volume */ AFSVL_ROVOL, /* read-only volume */
...@@ -52,6 +37,9 @@ typedef enum { ...@@ -52,6 +37,9 @@ typedef enum {
#ifdef __KERNEL__ #ifdef __KERNEL__
struct afs_cell;
struct afs_vnode;
/*****************************************************************************/ /*****************************************************************************/
/* /*
* AFS file identifier * AFS file identifier
...@@ -76,8 +64,8 @@ typedef enum { ...@@ -76,8 +64,8 @@ typedef enum {
struct afs_callback struct afs_callback
{ {
afs_server_t *server; /* server that made the promise */ struct afs_server *server; /* server that made the promise */
afs_fid_t fid; /* file identifier */ struct afs_fid fid; /* file identifier */
unsigned version; /* callback version */ unsigned version; /* callback version */
unsigned expiry; /* time at which expires */ unsigned expiry; /* time at which expires */
afs_callback_type_t type; /* type of callback */ afs_callback_type_t type; /* type of callback */
...@@ -120,7 +108,7 @@ struct afs_file_status ...@@ -120,7 +108,7 @@ struct afs_file_status
unsigned caller_access; /* access rights for authenticated caller */ unsigned caller_access; /* access rights for authenticated caller */
unsigned anon_access; /* access rights for unauthenticated caller */ unsigned anon_access; /* access rights for unauthenticated caller */
umode_t mode; /* UNIX mode */ umode_t mode; /* UNIX mode */
afs_fid_t parent; /* parent file ID */ struct afs_fid parent; /* parent file ID */
time_t mtime_client; /* last time client changed data */ time_t mtime_client; /* last time client changed data */
time_t mtime_server; /* last time server changed data */ time_t mtime_server; /* last time server changed data */
}; };
......
...@@ -39,7 +39,8 @@ static void afs_rxvl_aemap(struct rxrpc_call *call) ...@@ -39,7 +39,8 @@ static void afs_rxvl_aemap(struct rxrpc_call *call)
{ {
int err; int err;
_enter("{%u,%u,%d}",call->app_err_state,call->app_abort_code,call->app_errno); _enter("{%u,%u,%d}",
call->app_err_state, call->app_abort_code, call->app_errno);
switch (call->app_err_state) { switch (call->app_err_state) {
case RXRPC_ESTATE_LOCAL_ABORT: case RXRPC_ESTATE_LOCAL_ABORT:
...@@ -92,10 +93,8 @@ static void afs_rxvl_aemap(struct rxrpc_call *call) ...@@ -92,10 +93,8 @@ static void afs_rxvl_aemap(struct rxrpc_call *call)
/* /*
* probe a volume location server to see if it is still alive * probe a volume location server to see if it is still alive
*/ */
int afs_rxvl_probe(afs_server_t *server, int alloc_flags) int afs_rxvl_probe(struct afs_server *server, int alloc_flags)
{ {
DECLARE_WAITQUEUE(myself,current);
struct rxrpc_connection *conn; struct rxrpc_connection *conn;
struct rxrpc_call *call; struct rxrpc_call *call;
struct iovec piov[1]; struct iovec piov[1];
...@@ -103,21 +102,23 @@ int afs_rxvl_probe(afs_server_t *server, int alloc_flags) ...@@ -103,21 +102,23 @@ int afs_rxvl_probe(afs_server_t *server, int alloc_flags)
int ret; int ret;
u32 param[1]; u32 param[1];
DECLARE_WAITQUEUE(myself, current);
/* get hold of the vlserver connection */ /* get hold of the vlserver connection */
ret = afs_server_get_vlconn(server,&conn); ret = afs_server_get_vlconn(server, &conn);
if (ret<0) if (ret < 0)
goto out; goto out;
/* create a call through that connection */ /* create a call through that connection */
ret = rxrpc_create_call(conn,NULL,NULL,afs_rxvl_aemap,&call); ret = rxrpc_create_call(conn, NULL, NULL, afs_rxvl_aemap, &call);
if (ret<0) { if (ret < 0) {
printk("kAFS: Unable to create call: %d\n",ret); printk("kAFS: Unable to create call: %d\n", ret);
goto out_put_conn; goto out_put_conn;
} }
call->app_opcode = VLPROBE; call->app_opcode = VLPROBE;
/* we want to get event notifications from the call */ /* we want to get event notifications from the call */
add_wait_queue(&call->waitq,&myself); add_wait_queue(&call->waitq, &myself);
/* marshall the parameters */ /* marshall the parameters */
param[0] = htonl(VLPROBE); param[0] = htonl(VLPROBE);
...@@ -125,14 +126,15 @@ int afs_rxvl_probe(afs_server_t *server, int alloc_flags) ...@@ -125,14 +126,15 @@ int afs_rxvl_probe(afs_server_t *server, int alloc_flags)
piov[0].iov_base = param; piov[0].iov_base = param;
/* send the parameters to the server */ /* send the parameters to the server */
ret = rxrpc_call_write_data(call,1,piov,RXRPC_LAST_PACKET,alloc_flags,0,&sent); ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET,
if (ret<0) alloc_flags, 0, &sent);
if (ret < 0)
goto abort; goto abort;
/* wait for the reply to completely arrive */ /* wait for the reply to completely arrive */
for (;;) { for (;;) {
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
if (call->app_call_state!=RXRPC_CSTATE_CLNT_RCV_REPLY || if (call->app_call_state != RXRPC_CSTATE_CLNT_RCV_REPLY ||
signal_pending(current)) signal_pending(current))
break; break;
schedule(); schedule();
...@@ -158,12 +160,12 @@ int afs_rxvl_probe(afs_server_t *server, int alloc_flags) ...@@ -158,12 +160,12 @@ int afs_rxvl_probe(afs_server_t *server, int alloc_flags)
abort: abort:
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
rxrpc_call_abort(call,ret); rxrpc_call_abort(call, ret);
schedule(); schedule();
out_unwait: out_unwait:
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
remove_wait_queue(&call->waitq,&myself); remove_wait_queue(&call->waitq, &myself);
rxrpc_put_call(call); rxrpc_put_call(call);
out_put_conn: out_put_conn:
rxrpc_put_connection(conn); rxrpc_put_connection(conn);
...@@ -176,10 +178,12 @@ int afs_rxvl_probe(afs_server_t *server, int alloc_flags) ...@@ -176,10 +178,12 @@ int afs_rxvl_probe(afs_server_t *server, int alloc_flags)
/* /*
* look up a volume location database entry by name * look up a volume location database entry by name
*/ */
int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsigned volnamesz, int afs_rxvl_get_entry_by_name(struct afs_server *server,
const char *volname,
unsigned volnamesz,
struct afs_cache_vlocation *entry) struct afs_cache_vlocation *entry)
{ {
DECLARE_WAITQUEUE(myself,current); DECLARE_WAITQUEUE(myself, current);
struct rxrpc_connection *conn; struct rxrpc_connection *conn;
struct rxrpc_call *call; struct rxrpc_call *call;
...@@ -195,7 +199,7 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsign ...@@ -195,7 +199,7 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsign
/* get hold of the vlserver connection */ /* get hold of the vlserver connection */
ret = afs_server_get_vlconn(server, &conn); ret = afs_server_get_vlconn(server, &conn);
if (ret<0) if (ret < 0)
goto out; goto out;
/* create a call through that connection */ /* create a call through that connection */
...@@ -211,7 +215,7 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsign ...@@ -211,7 +215,7 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsign
/* marshall the parameters */ /* marshall the parameters */
piov[1].iov_len = volnamesz; piov[1].iov_len = volnamesz;
piov[1].iov_base = (char*) volname; piov[1].iov_base = (char *) volname;
zero = 0; zero = 0;
piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3; piov[2].iov_len = (4 - (piov[1].iov_len & 3)) & 3;
...@@ -224,14 +228,17 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsign ...@@ -224,14 +228,17 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsign
piov[0].iov_base = param; piov[0].iov_base = param;
/* send the parameters to the server */ /* send the parameters to the server */
ret = rxrpc_call_write_data(call, 3, piov, RXRPC_LAST_PACKET, GFP_NOFS, 0, &sent); ret = rxrpc_call_write_data(call, 3, piov, RXRPC_LAST_PACKET, GFP_NOFS,
if (ret<0) 0, &sent);
if (ret < 0)
goto abort; goto abort;
/* wait for the reply to completely arrive */ /* wait for the reply to completely arrive */
bp = rxrpc_call_alloc_scratch(call, 384); bp = rxrpc_call_alloc_scratch(call, 384);
ret = rxrpc_call_read_data(call, bp, 384, RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL); ret = rxrpc_call_read_data(call, bp, 384,
RXRPC_CALL_READ_BLOCK |
RXRPC_CALL_READ_ALL);
if (ret < 0) { if (ret < 0) {
if (ret == -ECONNABORTED) { if (ret == -ECONNABORTED) {
ret = call->app_errno; ret = call->app_errno;
...@@ -241,23 +248,26 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsign ...@@ -241,23 +248,26 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsign
} }
/* unmarshall the reply */ /* unmarshall the reply */
for (loop=0; loop<64; loop++) for (loop = 0; loop < 64; loop++)
entry->name[loop] = ntohl(*bp++); entry->name[loop] = ntohl(*bp++);
bp++; /* final NUL */ bp++; /* final NUL */
bp++; /* type */ bp++; /* type */
entry->nservers = ntohl(*bp++); entry->nservers = ntohl(*bp++);
for (loop=0; loop<8; loop++) for (loop = 0; loop < 8; loop++)
entry->servers[loop].s_addr = *bp++; entry->servers[loop].s_addr = *bp++;
bp += 8; /* partition IDs */ bp += 8; /* partition IDs */
for (loop=0; loop<8; loop++) { for (loop = 0; loop < 8; loop++) {
tmp = ntohl(*bp++); tmp = ntohl(*bp++);
if (tmp & AFS_VLSF_RWVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RW; if (tmp & AFS_VLSF_RWVOL)
if (tmp & AFS_VLSF_ROVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RO; entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFS_VOL_VTM_BAK; if (tmp & AFS_VLSF_ROVOL)
entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
if (tmp & AFS_VLSF_BACKVOL)
entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
} }
entry->vid[0] = ntohl(*bp++); entry->vid[0] = ntohl(*bp++);
...@@ -267,9 +277,12 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsign ...@@ -267,9 +277,12 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsign
bp++; /* clone ID */ bp++; /* clone ID */
tmp = ntohl(*bp++); /* flags */ tmp = ntohl(*bp++); /* flags */
if (tmp & AFS_VLF_RWEXISTS ) entry->vidmask |= AFS_VOL_VTM_RW; if (tmp & AFS_VLF_RWEXISTS)
if (tmp & AFS_VLF_ROEXISTS ) entry->vidmask |= AFS_VOL_VTM_RO; entry->vidmask |= AFS_VOL_VTM_RW;
if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFS_VOL_VTM_BAK; if (tmp & AFS_VLF_ROEXISTS)
entry->vidmask |= AFS_VOL_VTM_RO;
if (tmp & AFS_VLF_BACKEXISTS)
entry->vidmask |= AFS_VOL_VTM_BAK;
ret = -ENOMEDIUM; ret = -ENOMEDIUM;
if (!entry->vidmask) if (!entry->vidmask)
...@@ -291,7 +304,7 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsign ...@@ -291,7 +304,7 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsign
abort: abort:
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
rxrpc_call_abort(call,ret); rxrpc_call_abort(call, ret);
schedule(); schedule();
goto out_unwait; goto out_unwait;
} /* end afs_rxvl_get_entry_by_name() */ } /* end afs_rxvl_get_entry_by_name() */
...@@ -300,12 +313,12 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsign ...@@ -300,12 +313,12 @@ int afs_rxvl_get_entry_by_name(afs_server_t *server, const char *volname, unsign
/* /*
* look up a volume location database entry by ID * look up a volume location database entry by ID
*/ */
int afs_rxvl_get_entry_by_id(afs_server_t *server, int afs_rxvl_get_entry_by_id(struct afs_server *server,
afs_volid_t volid, afs_volid_t volid,
afs_voltype_t voltype, afs_voltype_t voltype,
struct afs_cache_vlocation *entry) struct afs_cache_vlocation *entry)
{ {
DECLARE_WAITQUEUE(myself,current); DECLARE_WAITQUEUE(myself, current);
struct rxrpc_connection *conn; struct rxrpc_connection *conn;
struct rxrpc_call *call; struct rxrpc_call *call;
...@@ -315,25 +328,25 @@ int afs_rxvl_get_entry_by_id(afs_server_t *server, ...@@ -315,25 +328,25 @@ int afs_rxvl_get_entry_by_id(afs_server_t *server,
int ret, loop; int ret, loop;
u32 *bp, param[3]; u32 *bp, param[3];
_enter(",%x,%d,",volid,voltype); _enter(",%x,%d,", volid, voltype);
memset(entry,0,sizeof(*entry)); memset(entry, 0, sizeof(*entry));
/* get hold of the vlserver connection */ /* get hold of the vlserver connection */
ret = afs_server_get_vlconn(server,&conn); ret = afs_server_get_vlconn(server, &conn);
if (ret<0) if (ret < 0)
goto out; goto out;
/* create a call through that connection */ /* create a call through that connection */
ret = rxrpc_create_call(conn,NULL,NULL,afs_rxvl_aemap,&call); ret = rxrpc_create_call(conn, NULL, NULL, afs_rxvl_aemap, &call);
if (ret<0) { if (ret < 0) {
printk("kAFS: Unable to create call: %d\n",ret); printk("kAFS: Unable to create call: %d\n", ret);
goto out_put_conn; goto out_put_conn;
} }
call->app_opcode = VLGETENTRYBYID; call->app_opcode = VLGETENTRYBYID;
/* we want to get event notifications from the call */ /* we want to get event notifications from the call */
add_wait_queue(&call->waitq,&myself); add_wait_queue(&call->waitq, &myself);
/* marshall the parameters */ /* marshall the parameters */
param[0] = htonl(VLGETENTRYBYID); param[0] = htonl(VLGETENTRYBYID);
...@@ -344,16 +357,19 @@ int afs_rxvl_get_entry_by_id(afs_server_t *server, ...@@ -344,16 +357,19 @@ int afs_rxvl_get_entry_by_id(afs_server_t *server,
piov[0].iov_base = param; piov[0].iov_base = param;
/* send the parameters to the server */ /* send the parameters to the server */
ret = rxrpc_call_write_data(call,1,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent); ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS,
if (ret<0) 0, &sent);
if (ret < 0)
goto abort; goto abort;
/* wait for the reply to completely arrive */ /* wait for the reply to completely arrive */
bp = rxrpc_call_alloc_scratch(call,384); bp = rxrpc_call_alloc_scratch(call, 384);
ret = rxrpc_call_read_data(call,bp,384,RXRPC_CALL_READ_BLOCK|RXRPC_CALL_READ_ALL); ret = rxrpc_call_read_data(call, bp, 384,
if (ret<0) { RXRPC_CALL_READ_BLOCK |
if (ret==-ECONNABORTED) { RXRPC_CALL_READ_ALL);
if (ret < 0) {
if (ret == -ECONNABORTED) {
ret = call->app_errno; ret = call->app_errno;
goto out_unwait; goto out_unwait;
} }
...@@ -361,23 +377,26 @@ int afs_rxvl_get_entry_by_id(afs_server_t *server, ...@@ -361,23 +377,26 @@ int afs_rxvl_get_entry_by_id(afs_server_t *server,
} }
/* unmarshall the reply */ /* unmarshall the reply */
for (loop=0; loop<64; loop++) for (loop = 0; loop < 64; loop++)
entry->name[loop] = ntohl(*bp++); entry->name[loop] = ntohl(*bp++);
bp++; /* final NUL */ bp++; /* final NUL */
bp++; /* type */ bp++; /* type */
entry->nservers = ntohl(*bp++); entry->nservers = ntohl(*bp++);
for (loop=0; loop<8; loop++) for (loop = 0; loop < 8; loop++)
entry->servers[loop].s_addr = *bp++; entry->servers[loop].s_addr = *bp++;
bp += 8; /* partition IDs */ bp += 8; /* partition IDs */
for (loop=0; loop<8; loop++) { for (loop = 0; loop < 8; loop++) {
tmp = ntohl(*bp++); tmp = ntohl(*bp++);
if (tmp & AFS_VLSF_RWVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RW; if (tmp & AFS_VLSF_RWVOL)
if (tmp & AFS_VLSF_ROVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RO; entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFS_VOL_VTM_BAK; if (tmp & AFS_VLSF_ROVOL)
entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
if (tmp & AFS_VLSF_BACKVOL)
entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
} }
entry->vid[0] = ntohl(*bp++); entry->vid[0] = ntohl(*bp++);
...@@ -387,9 +406,12 @@ int afs_rxvl_get_entry_by_id(afs_server_t *server, ...@@ -387,9 +406,12 @@ int afs_rxvl_get_entry_by_id(afs_server_t *server,
bp++; /* clone ID */ bp++; /* clone ID */
tmp = ntohl(*bp++); /* flags */ tmp = ntohl(*bp++); /* flags */
if (tmp & AFS_VLF_RWEXISTS ) entry->vidmask |= AFS_VOL_VTM_RW; if (tmp & AFS_VLF_RWEXISTS)
if (tmp & AFS_VLF_ROEXISTS ) entry->vidmask |= AFS_VOL_VTM_RO; entry->vidmask |= AFS_VOL_VTM_RW;
if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFS_VOL_VTM_BAK; if (tmp & AFS_VLF_ROEXISTS)
entry->vidmask |= AFS_VOL_VTM_RO;
if (tmp & AFS_VLF_BACKEXISTS)
entry->vidmask |= AFS_VOL_VTM_BAK;
ret = -ENOMEDIUM; ret = -ENOMEDIUM;
if (!entry->vidmask) if (!entry->vidmask)
...@@ -412,17 +434,17 @@ int afs_rxvl_get_entry_by_id(afs_server_t *server, ...@@ -412,17 +434,17 @@ int afs_rxvl_get_entry_by_id(afs_server_t *server,
out_unwait: out_unwait:
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
remove_wait_queue(&call->waitq,&myself); remove_wait_queue(&call->waitq, &myself);
rxrpc_put_call(call); rxrpc_put_call(call);
out_put_conn: out_put_conn:
rxrpc_put_connection(conn); rxrpc_put_connection(conn);
out: out:
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
abort: abort:
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
rxrpc_call_abort(call,ret); rxrpc_call_abort(call, ret);
schedule(); schedule();
goto out_unwait; goto out_unwait;
} /* end afs_rxvl_get_entry_by_id() */ } /* end afs_rxvl_get_entry_by_id() */
...@@ -431,7 +453,7 @@ int afs_rxvl_get_entry_by_id(afs_server_t *server, ...@@ -431,7 +453,7 @@ int afs_rxvl_get_entry_by_id(afs_server_t *server,
/* /*
* look up a volume location database entry by ID asynchronously * look up a volume location database entry by ID asynchronously
*/ */
int afs_rxvl_get_entry_by_id_async(afs_async_op_t *op, int afs_rxvl_get_entry_by_id_async(struct afs_async_op *op,
afs_volid_t volid, afs_volid_t volid,
afs_voltype_t voltype) afs_voltype_t voltype)
{ {
...@@ -442,12 +464,12 @@ int afs_rxvl_get_entry_by_id_async(afs_async_op_t *op, ...@@ -442,12 +464,12 @@ int afs_rxvl_get_entry_by_id_async(afs_async_op_t *op,
int ret; int ret;
u32 param[3]; u32 param[3];
_enter(",%x,%d,",volid,voltype); _enter(",%x,%d,", volid, voltype);
/* get hold of the vlserver connection */ /* get hold of the vlserver connection */
ret = afs_server_get_vlconn(op->server,&conn); ret = afs_server_get_vlconn(op->server, &conn);
if (ret<0) { if (ret < 0) {
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} }
...@@ -459,9 +481,9 @@ int afs_rxvl_get_entry_by_id_async(afs_async_op_t *op, ...@@ -459,9 +481,9 @@ int afs_rxvl_get_entry_by_id_async(afs_async_op_t *op,
&op->call); &op->call);
rxrpc_put_connection(conn); rxrpc_put_connection(conn);
if (ret<0) { if (ret < 0) {
printk("kAFS: Unable to create call: %d\n",ret); printk("kAFS: Unable to create call: %d\n", ret);
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} }
...@@ -483,18 +505,19 @@ int afs_rxvl_get_entry_by_id_async(afs_async_op_t *op, ...@@ -483,18 +505,19 @@ int afs_rxvl_get_entry_by_id_async(afs_async_op_t *op,
piov[0].iov_base = param; piov[0].iov_base = param;
/* allocate result read buffer in scratch space */ /* allocate result read buffer in scratch space */
call->app_scr_ptr = rxrpc_call_alloc_scratch(op->call,384); call->app_scr_ptr = rxrpc_call_alloc_scratch(op->call, 384);
/* send the parameters to the server */ /* send the parameters to the server */
ret = rxrpc_call_write_data(call,1,piov,RXRPC_LAST_PACKET,GFP_NOFS,0,&sent); ret = rxrpc_call_write_data(call, 1, piov, RXRPC_LAST_PACKET, GFP_NOFS,
if (ret<0) { 0, &sent);
rxrpc_call_abort(call,ret); /* handle from kafsasyncd */ if (ret < 0) {
rxrpc_call_abort(call, ret); /* handle from kafsasyncd */
ret = 0; ret = 0;
goto out; goto out;
} }
/* wait for the reply to completely arrive */ /* wait for the reply to completely arrive */
ret = rxrpc_call_read_data(call,call->app_scr_ptr,384,0); ret = rxrpc_call_read_data(call, call->app_scr_ptr, 384, 0);
switch (ret) { switch (ret) {
case 0: case 0:
case -EAGAIN: case -EAGAIN:
...@@ -503,14 +526,14 @@ int afs_rxvl_get_entry_by_id_async(afs_async_op_t *op, ...@@ -503,14 +526,14 @@ int afs_rxvl_get_entry_by_id_async(afs_async_op_t *op,
break; /* all handled by kafsasyncd */ break; /* all handled by kafsasyncd */
default: default:
rxrpc_call_abort(call,ret); /* force kafsasyncd to handle it */ rxrpc_call_abort(call, ret); /* make kafsasyncd handle it */
ret = 0; ret = 0;
break; break;
} }
out: out:
rxrpc_put_call(call); rxrpc_put_call(call);
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_rxvl_get_entry_by_id_async() */ } /* end afs_rxvl_get_entry_by_id_async() */
...@@ -519,40 +542,43 @@ int afs_rxvl_get_entry_by_id_async(afs_async_op_t *op, ...@@ -519,40 +542,43 @@ int afs_rxvl_get_entry_by_id_async(afs_async_op_t *op,
/* /*
* attend to the asynchronous get VLDB entry by ID * attend to the asynchronous get VLDB entry by ID
*/ */
int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op, int afs_rxvl_get_entry_by_id_async2(struct afs_async_op *op,
struct afs_cache_vlocation *entry) struct afs_cache_vlocation *entry)
{ {
unsigned *bp, tmp; unsigned *bp, tmp;
int loop, ret; int loop, ret;
_enter("{op=%p cst=%u}",op,op->call->app_call_state); _enter("{op=%p cst=%u}", op, op->call->app_call_state);
memset(entry,0,sizeof(*entry)); memset(entry, 0, sizeof(*entry));
if (op->call->app_call_state==RXRPC_CSTATE_COMPLETE) { if (op->call->app_call_state == RXRPC_CSTATE_COMPLETE) {
/* operation finished */ /* operation finished */
afs_kafsasyncd_terminate_op(op); afs_kafsasyncd_terminate_op(op);
bp = op->call->app_scr_ptr; bp = op->call->app_scr_ptr;
/* unmarshall the reply */ /* unmarshall the reply */
for (loop=0; loop<64; loop++) for (loop = 0; loop < 64; loop++)
entry->name[loop] = ntohl(*bp++); entry->name[loop] = ntohl(*bp++);
bp++; /* final NUL */ bp++; /* final NUL */
bp++; /* type */ bp++; /* type */
entry->nservers = ntohl(*bp++); entry->nservers = ntohl(*bp++);
for (loop=0; loop<8; loop++) for (loop = 0; loop < 8; loop++)
entry->servers[loop].s_addr = *bp++; entry->servers[loop].s_addr = *bp++;
bp += 8; /* partition IDs */ bp += 8; /* partition IDs */
for (loop=0; loop<8; loop++) { for (loop = 0; loop < 8; loop++) {
tmp = ntohl(*bp++); tmp = ntohl(*bp++);
if (tmp & AFS_VLSF_RWVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RW; if (tmp & AFS_VLSF_RWVOL)
if (tmp & AFS_VLSF_ROVOL ) entry->srvtmask[loop] |= AFS_VOL_VTM_RO; entry->srvtmask[loop] |= AFS_VOL_VTM_RW;
if (tmp & AFS_VLSF_BACKVOL) entry->srvtmask[loop] |= AFS_VOL_VTM_BAK; if (tmp & AFS_VLSF_ROVOL)
entry->srvtmask[loop] |= AFS_VOL_VTM_RO;
if (tmp & AFS_VLSF_BACKVOL)
entry->srvtmask[loop] |= AFS_VOL_VTM_BAK;
} }
entry->vid[0] = ntohl(*bp++); entry->vid[0] = ntohl(*bp++);
...@@ -562,13 +588,16 @@ int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op, ...@@ -562,13 +588,16 @@ int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op,
bp++; /* clone ID */ bp++; /* clone ID */
tmp = ntohl(*bp++); /* flags */ tmp = ntohl(*bp++); /* flags */
if (tmp & AFS_VLF_RWEXISTS ) entry->vidmask |= AFS_VOL_VTM_RW; if (tmp & AFS_VLF_RWEXISTS)
if (tmp & AFS_VLF_ROEXISTS ) entry->vidmask |= AFS_VOL_VTM_RO; entry->vidmask |= AFS_VOL_VTM_RW;
if (tmp & AFS_VLF_BACKEXISTS) entry->vidmask |= AFS_VOL_VTM_BAK; if (tmp & AFS_VLF_ROEXISTS)
entry->vidmask |= AFS_VOL_VTM_RO;
if (tmp & AFS_VLF_BACKEXISTS)
entry->vidmask |= AFS_VOL_VTM_BAK;
ret = -ENOMEDIUM; ret = -ENOMEDIUM;
if (!entry->vidmask) { if (!entry->vidmask) {
rxrpc_call_abort(op->call,ret); rxrpc_call_abort(op->call, ret);
goto done; goto done;
} }
...@@ -589,7 +618,7 @@ int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op, ...@@ -589,7 +618,7 @@ int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op,
goto done; goto done;
} }
if (op->call->app_call_state==RXRPC_CSTATE_ERROR) { if (op->call->app_call_state == RXRPC_CSTATE_ERROR) {
/* operation error */ /* operation error */
ret = op->call->app_errno; ret = op->call->app_errno;
goto done; goto done;
...@@ -601,7 +630,7 @@ int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op, ...@@ -601,7 +630,7 @@ int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op,
done: done:
rxrpc_put_call(op->call); rxrpc_put_call(op->call);
op->call = NULL; op->call = NULL;
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_rxvl_get_entry_by_id_async2() */ } /* end afs_rxvl_get_entry_by_id_async2() */
...@@ -612,9 +641,9 @@ int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op, ...@@ -612,9 +641,9 @@ int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op,
*/ */
static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call) static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call)
{ {
afs_async_op_t *op = call->app_user; struct afs_async_op *op = call->app_user;
_enter("{op=%p cst=%u}",op,call->app_call_state); _enter("{op=%p cst=%u}", op, call->app_call_state);
switch (call->app_call_state) { switch (call->app_call_state) {
case RXRPC_CSTATE_COMPLETE: case RXRPC_CSTATE_COMPLETE:
...@@ -624,7 +653,7 @@ static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call) ...@@ -624,7 +653,7 @@ static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call)
if (call->app_async_read) if (call->app_async_read)
break; break;
case RXRPC_CSTATE_CLNT_GOT_REPLY: case RXRPC_CSTATE_CLNT_GOT_REPLY:
if (call->app_read_count==0) if (call->app_read_count == 0)
break; break;
printk("kAFS: Reply bigger than expected" printk("kAFS: Reply bigger than expected"
" {cst=%u asyn=%d mark=%Zu rdy=%Zu pr=%u%s}", " {cst=%u asyn=%d mark=%Zu rdy=%Zu pr=%u%s}",
...@@ -635,7 +664,7 @@ static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call) ...@@ -635,7 +664,7 @@ static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call)
call->pkt_rcv_count, call->pkt_rcv_count,
call->app_last_rcv ? " last" : ""); call->app_last_rcv ? " last" : "");
rxrpc_call_abort(call,-EBADMSG); rxrpc_call_abort(call, -EBADMSG);
break; break;
default: default:
BUG(); BUG();
...@@ -652,9 +681,9 @@ static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call) ...@@ -652,9 +681,9 @@ static void afs_rxvl_get_entry_by_id_attn(struct rxrpc_call *call)
*/ */
static void afs_rxvl_get_entry_by_id_error(struct rxrpc_call *call) static void afs_rxvl_get_entry_by_id_error(struct rxrpc_call *call)
{ {
afs_async_op_t *op = call->app_user; struct afs_async_op *op = call->app_user;
_enter("{op=%p cst=%u}",op,call->app_call_state); _enter("{op=%p cst=%u}", op, call->app_call_state);
afs_kafsasyncd_attend_op(op); afs_kafsasyncd_attend_op(op);
......
...@@ -72,25 +72,25 @@ struct afs_vldbentry { ...@@ -72,25 +72,25 @@ struct afs_vldbentry {
}; };
/* probe a volume location server to see if it is still alive */ /* probe a volume location server to see if it is still alive */
extern int afs_rxvl_probe(afs_server_t *server, int alloc_flags); extern int afs_rxvl_probe(struct afs_server *server, int alloc_flags);
/* look up a volume location database entry by name */ /* look up a volume location database entry by name */
extern int afs_rxvl_get_entry_by_name(afs_server_t *server, extern int afs_rxvl_get_entry_by_name(struct afs_server *server,
const char *volname, const char *volname,
unsigned volnamesz, unsigned volnamesz,
struct afs_cache_vlocation *entry); struct afs_cache_vlocation *entry);
/* look up a volume location database entry by ID */ /* look up a volume location database entry by ID */
extern int afs_rxvl_get_entry_by_id(afs_server_t *server, extern int afs_rxvl_get_entry_by_id(struct afs_server *server,
afs_volid_t volid, afs_volid_t volid,
afs_voltype_t voltype, afs_voltype_t voltype,
struct afs_cache_vlocation *entry); struct afs_cache_vlocation *entry);
extern int afs_rxvl_get_entry_by_id_async(afs_async_op_t *op, extern int afs_rxvl_get_entry_by_id_async(struct afs_async_op *op,
afs_volid_t volid, afs_volid_t volid,
afs_voltype_t voltype); afs_voltype_t voltype);
extern int afs_rxvl_get_entry_by_id_async2(afs_async_op_t *op, extern int afs_rxvl_get_entry_by_id_async2(struct afs_async_op *op,
struct afs_cache_vlocation *entry); struct afs_cache_vlocation *entry);
#endif /* _LINUX_AFS_VLCLIENT_H */ #endif /* _LINUX_AFS_VLCLIENT_H */
...@@ -26,15 +26,17 @@ ...@@ -26,15 +26,17 @@
#define AFS_VLDB_TIMEOUT HZ*1000 #define AFS_VLDB_TIMEOUT HZ*1000
static void afs_vlocation_update_timer(afs_timer_t *timer); static void afs_vlocation_update_timer(struct afs_timer *timer);
static void afs_vlocation_update_attend(afs_async_op_t *op); static void afs_vlocation_update_attend(struct afs_async_op *op);
static void afs_vlocation_update_discard(afs_async_op_t *op); static void afs_vlocation_update_discard(struct afs_async_op *op);
static void __afs_vlocation_timeout(afs_timer_t *timer) static void __afs_vlocation_timeout(struct afs_timer *timer)
{ {
afs_vlocation_t *vlocation = list_entry(timer,afs_vlocation_t,timeout); struct afs_vlocation *vlocation =
list_entry(timer, struct afs_vlocation, timeout);
_debug("VL TIMEOUT [%s{u=%d}]",vlocation->vldb.name,atomic_read(&vlocation->usage)); _debug("VL TIMEOUT [%s{u=%d}]",
vlocation->vldb.name, atomic_read(&vlocation->usage));
afs_vlocation_do_timeout(vlocation); afs_vlocation_do_timeout(vlocation);
} }
...@@ -53,11 +55,12 @@ static const struct afs_async_op_ops afs_vlocation_update_op_ops = { ...@@ -53,11 +55,12 @@ static const struct afs_async_op_ops afs_vlocation_update_op_ops = {
}; };
static LIST_HEAD(afs_vlocation_update_pendq); /* queue of VLs awaiting update */ static LIST_HEAD(afs_vlocation_update_pendq); /* queue of VLs awaiting update */
static afs_vlocation_t *afs_vlocation_update; /* VL currently being updated */ static struct afs_vlocation *afs_vlocation_update; /* VL currently being updated */
static spinlock_t afs_vlocation_update_lock = SPIN_LOCK_UNLOCKED; /* lock guarding update queue */ static spinlock_t afs_vlocation_update_lock = SPIN_LOCK_UNLOCKED; /* lock guarding update queue */
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
static cachefs_match_val_t afs_vlocation_cache_match(void *target, const void *entry); static cachefs_match_val_t afs_vlocation_cache_match(void *target,
const void *entry);
static void afs_vlocation_cache_update(void *source, void *entry); static void afs_vlocation_cache_update(void *source, void *entry);
struct cachefs_index_def afs_vlocation_cache_index_def = { struct cachefs_index_def afs_vlocation_cache_index_def = {
...@@ -71,29 +74,31 @@ struct cachefs_index_def afs_vlocation_cache_index_def = { ...@@ -71,29 +74,31 @@ struct cachefs_index_def afs_vlocation_cache_index_def = {
/*****************************************************************************/ /*****************************************************************************/
/* /*
* iterate through the VL servers in a cell until one of them admits knowing about the volume in * iterate through the VL servers in a cell until one of them admits knowing
* question * about the volume in question
* - caller must have cell->vl_sem write-locked * - caller must have cell->vl_sem write-locked
*/ */
static int afs_vlocation_access_vl_by_name(afs_vlocation_t *vlocation, static int afs_vlocation_access_vl_by_name(struct afs_vlocation *vlocation,
const char *name, const char *name,
unsigned namesz, unsigned namesz,
struct afs_cache_vlocation *vldb) struct afs_cache_vlocation *vldb)
{ {
afs_server_t *server = NULL; struct afs_server *server = NULL;
afs_cell_t *cell = vlocation->cell; struct afs_cell *cell = vlocation->cell;
int count, ret; int count, ret;
_enter("%s,%*.*s,%u", cell->name, namesz, namesz, name, namesz); _enter("%s,%*.*s,%u", cell->name, namesz, namesz, name, namesz);
ret = -ENOMEDIUM; ret = -ENOMEDIUM;
for (count=cell->vl_naddrs; count>0; count--) { for (count = cell->vl_naddrs; count > 0; count--) {
_debug("CellServ[%hu]: %08x", _debug("CellServ[%hu]: %08x",
cell->vl_curr_svix, cell->vl_curr_svix,
cell->vl_addrs[cell->vl_curr_svix].s_addr); cell->vl_addrs[cell->vl_curr_svix].s_addr);
/* try and create a server */ /* try and create a server */
ret = afs_server_lookup(cell, &cell->vl_addrs[cell->vl_curr_svix], &server); ret = afs_server_lookup(cell,
&cell->vl_addrs[cell->vl_curr_svix],
&server);
switch (ret) { switch (ret) {
case 0: case 0:
break; break;
...@@ -141,36 +146,38 @@ static int afs_vlocation_access_vl_by_name(afs_vlocation_t *vlocation, ...@@ -141,36 +146,38 @@ static int afs_vlocation_access_vl_by_name(afs_vlocation_t *vlocation,
} }
out: out:
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_vlocation_access_vl_by_name() */ } /* end afs_vlocation_access_vl_by_name() */
/*****************************************************************************/ /*****************************************************************************/
/* /*
* iterate through the VL servers in a cell until one of them admits knowing about the volume in * iterate through the VL servers in a cell until one of them admits knowing
* question * about the volume in question
* - caller must have cell->vl_sem write-locked * - caller must have cell->vl_sem write-locked
*/ */
static int afs_vlocation_access_vl_by_id(afs_vlocation_t *vlocation, static int afs_vlocation_access_vl_by_id(struct afs_vlocation *vlocation,
afs_volid_t volid, afs_volid_t volid,
afs_voltype_t voltype, afs_voltype_t voltype,
struct afs_cache_vlocation *vldb) struct afs_cache_vlocation *vldb)
{ {
afs_server_t *server = NULL; struct afs_server *server = NULL;
afs_cell_t *cell = vlocation->cell; struct afs_cell *cell = vlocation->cell;
int count, ret; int count, ret;
_enter("%s,%x,%d,", cell->name, volid, voltype); _enter("%s,%x,%d,", cell->name, volid, voltype);
ret = -ENOMEDIUM; ret = -ENOMEDIUM;
for (count=cell->vl_naddrs; count>0; count--) { for (count = cell->vl_naddrs; count > 0; count--) {
_debug("CellServ[%hu]: %08x", _debug("CellServ[%hu]: %08x",
cell->vl_curr_svix, cell->vl_curr_svix,
cell->vl_addrs[cell->vl_curr_svix].s_addr); cell->vl_addrs[cell->vl_curr_svix].s_addr);
/* try and create a server */ /* try and create a server */
ret = afs_server_lookup(cell, &cell->vl_addrs[cell->vl_curr_svix], &server); ret = afs_server_lookup(cell,
&cell->vl_addrs[cell->vl_curr_svix],
&server);
switch (ret) { switch (ret) {
case 0: case 0:
break; break;
...@@ -218,7 +225,7 @@ static int afs_vlocation_access_vl_by_id(afs_vlocation_t *vlocation, ...@@ -218,7 +225,7 @@ static int afs_vlocation_access_vl_by_id(afs_vlocation_t *vlocation,
} }
out: out:
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_vlocation_access_vl_by_id() */ } /* end afs_vlocation_access_vl_by_id() */
...@@ -227,17 +234,18 @@ static int afs_vlocation_access_vl_by_id(afs_vlocation_t *vlocation, ...@@ -227,17 +234,18 @@ static int afs_vlocation_access_vl_by_id(afs_vlocation_t *vlocation,
/* /*
* lookup volume location * lookup volume location
* - caller must have cell->vol_sem write-locked * - caller must have cell->vol_sem write-locked
* - iterate through the VL servers in a cell until one of them admits knowing about the volume in * - iterate through the VL servers in a cell until one of them admits knowing
* question * about the volume in question
* - lookup in the local cache if not able to find on the VL server * - lookup in the local cache if not able to find on the VL server
* - insert/update in the local cache if did get a VL response * - insert/update in the local cache if did get a VL response
*/ */
int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz, int afs_vlocation_lookup(struct afs_cell *cell,
afs_vlocation_t **_vlocation) const char *name,
unsigned namesz,
struct afs_vlocation **_vlocation)
{ {
struct afs_cache_vlocation vldb; struct afs_cache_vlocation vldb;
struct list_head *_p; struct afs_vlocation *vlocation;
afs_vlocation_t *vlocation;
afs_voltype_t voltype; afs_voltype_t voltype;
afs_volid_t vid; afs_volid_t vid;
int active = 0, ret; int active = 0, ret;
...@@ -250,8 +258,7 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz, ...@@ -250,8 +258,7 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz,
} }
/* search the cell's active list first */ /* search the cell's active list first */
list_for_each(_p, &cell->vl_list) { list_for_each_entry(vlocation, &cell->vl_list, link) {
vlocation = list_entry(_p, afs_vlocation_t, link);
if (namesz < sizeof(vlocation->vldb.name) && if (namesz < sizeof(vlocation->vldb.name) &&
vlocation->vldb.name[namesz] != '\0') vlocation->vldb.name[namesz] != '\0')
continue; continue;
...@@ -262,8 +269,7 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz, ...@@ -262,8 +269,7 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz,
/* search the cell's graveyard list second */ /* search the cell's graveyard list second */
spin_lock(&cell->vl_gylock); spin_lock(&cell->vl_gylock);
list_for_each(_p, &cell->vl_graveyard) { list_for_each_entry(vlocation, &cell->vl_graveyard, link) {
vlocation = list_entry(_p, afs_vlocation_t, link);
if (namesz < sizeof(vlocation->vldb.name) && if (namesz < sizeof(vlocation->vldb.name) &&
vlocation->vldb.name[namesz] != '\0') vlocation->vldb.name[namesz] != '\0')
continue; continue;
...@@ -274,11 +280,11 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz, ...@@ -274,11 +280,11 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz,
spin_unlock(&cell->vl_gylock); spin_unlock(&cell->vl_gylock);
/* not in the cell's in-memory lists - create a new record */ /* not in the cell's in-memory lists - create a new record */
vlocation = kmalloc(sizeof(afs_vlocation_t), GFP_KERNEL); vlocation = kmalloc(sizeof(struct afs_vlocation), GFP_KERNEL);
if (!vlocation) if (!vlocation)
return -ENOMEM; return -ENOMEM;
memset(vlocation, 0, sizeof(afs_vlocation_t)); memset(vlocation, 0, sizeof(struct afs_vlocation));
atomic_set(&vlocation->usage, 1); atomic_set(&vlocation->usage, 1);
INIT_LIST_HEAD(&vlocation->link); INIT_LIST_HEAD(&vlocation->link);
rwlock_init(&vlocation->lock); rwlock_init(&vlocation->lock);
...@@ -294,7 +300,8 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz, ...@@ -294,7 +300,8 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz,
list_add_tail(&vlocation->link, &cell->vl_list); list_add_tail(&vlocation->link, &cell->vl_list);
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
/* we want to store it in the cache, plus it might already be encached */ /* we want to store it in the cache, plus it might already be
* encached */
cachefs_acquire_cookie(cell->cache, cachefs_acquire_cookie(cell->cache,
&afs_volume_cache_index_def, &afs_volume_cache_index_def,
vlocation, vlocation,
...@@ -306,7 +313,7 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz, ...@@ -306,7 +313,7 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz,
/* try to look up an unknown volume in the cell VL databases by name */ /* try to look up an unknown volume in the cell VL databases by name */
ret = afs_vlocation_access_vl_by_name(vlocation, name, namesz, &vldb); ret = afs_vlocation_access_vl_by_name(vlocation, name, namesz, &vldb);
if (ret<0) { if (ret < 0) {
printk("kAFS: failed to locate '%*.*s' in cell '%s'\n", printk("kAFS: failed to locate '%*.*s' in cell '%s'\n",
namesz, namesz, name, cell->name); namesz, namesz, name, cell->name);
goto error; goto error;
...@@ -342,13 +349,18 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz, ...@@ -342,13 +349,18 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz,
_debug("Locally Cached: %s %02x { %08x(%x) %08x(%x) %08x(%x) }", _debug("Locally Cached: %s %02x { %08x(%x) %08x(%x) %08x(%x) }",
vlocation->vldb.name, vlocation->vldb.name,
vlocation->vldb.vidmask, vlocation->vldb.vidmask,
ntohl(vlocation->vldb.servers[0].s_addr), vlocation->vldb.srvtmask[0], ntohl(vlocation->vldb.servers[0].s_addr),
ntohl(vlocation->vldb.servers[1].s_addr), vlocation->vldb.srvtmask[1], vlocation->vldb.srvtmask[0],
ntohl(vlocation->vldb.servers[2].s_addr), vlocation->vldb.srvtmask[2] ntohl(vlocation->vldb.servers[1].s_addr),
vlocation->vldb.srvtmask[1],
ntohl(vlocation->vldb.servers[2].s_addr),
vlocation->vldb.srvtmask[2]
); );
_debug("Vids: %08x %08x %08x", _debug("Vids: %08x %08x %08x",
vlocation->vldb.vid[0], vlocation->vldb.vid[1], vlocation->vldb.vid[2]); vlocation->vldb.vid[0],
vlocation->vldb.vid[1],
vlocation->vldb.vid[2]);
if (vlocation->vldb.vidmask & AFS_VOL_VTM_RW) { if (vlocation->vldb.vidmask & AFS_VOL_VTM_RW) {
vid = vlocation->vldb.vid[0]; vid = vlocation->vldb.vid[0];
...@@ -400,21 +412,20 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz, ...@@ -400,21 +412,20 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz,
_debug("Vids: %08x %08x %08x", vldb.vid[0], vldb.vid[1], vldb.vid[2]); _debug("Vids: %08x %08x %08x", vldb.vid[0], vldb.vid[1], vldb.vid[2]);
if ((namesz < sizeof(vlocation->vldb.name) && vlocation->vldb.name[namesz] != '\0') || if ((namesz < sizeof(vlocation->vldb.name) &&
vlocation->vldb.name[namesz] != '\0') ||
memcmp(vldb.name, name, namesz) != 0) memcmp(vldb.name, name, namesz) != 0)
printk("kAFS: name of volume '%*.*s' changed to '%s' on server\n", printk("kAFS: name of volume '%*.*s' changed to '%s' on server\n",
namesz, namesz, name, vldb.name); namesz, namesz, name, vldb.name);
memcpy(&vlocation->vldb, &vldb, sizeof(vlocation->vldb)); memcpy(&vlocation->vldb, &vldb, sizeof(vlocation->vldb));
#if 0 afs_kafstimod_add_timer(&vlocation->upd_timer, 10 * HZ);
/* add volume entry to local cache */
ret = afsc_update_vlocation(vlocation);
if (ret<0)
goto error;
#endif
afs_kafstimod_add_timer(&vlocation->upd_timer, 10*HZ); #ifdef AFS_CACHING_SUPPORT
/* update volume entry in local cache */
cachefs_update_cookie(vlocation->cache);
#endif
*_vlocation = vlocation; *_vlocation = vlocation;
_leave(" = 0 (%p)",vlocation); _leave(" = 0 (%p)",vlocation);
...@@ -435,7 +446,7 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz, ...@@ -435,7 +446,7 @@ int afs_vlocation_lookup(afs_cell_t *cell, const char *name, unsigned namesz,
} }
} }
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_vlocation_lookup() */ } /* end afs_vlocation_lookup() */
...@@ -451,13 +462,12 @@ void __afs_put_vlocation(struct afs_vlocation *vlocation) ...@@ -451,13 +462,12 @@ void __afs_put_vlocation(struct afs_vlocation *vlocation)
if (!vlocation) if (!vlocation)
return; return;
_enter("%s",vlocation->vldb.name); _enter("%s", vlocation->vldb.name);
cell = vlocation->cell; cell = vlocation->cell;
/* sanity check */ /* sanity check */
if (atomic_read(&vlocation->usage)<=0) BUG_ON(atomic_read(&vlocation->usage) <= 0);
BUG();
spin_lock(&cell->vl_gylock); spin_lock(&cell->vl_gylock);
if (likely(!atomic_dec_and_test(&vlocation->usage))) { if (likely(!atomic_dec_and_test(&vlocation->usage))) {
...@@ -470,12 +480,13 @@ void __afs_put_vlocation(struct afs_vlocation *vlocation) ...@@ -470,12 +480,13 @@ void __afs_put_vlocation(struct afs_vlocation *vlocation)
list_del(&vlocation->link); list_del(&vlocation->link);
list_add_tail(&vlocation->link,&cell->vl_graveyard); list_add_tail(&vlocation->link,&cell->vl_graveyard);
/* remove from pending timeout queue (refcounted if actually being updated) */ /* remove from pending timeout queue (refcounted if actually being
* updated) */
list_del_init(&vlocation->upd_op.link); list_del_init(&vlocation->upd_op.link);
/* time out in 10 secs */ /* time out in 10 secs */
afs_kafstimod_del_timer(&vlocation->upd_timer); afs_kafstimod_del_timer(&vlocation->upd_timer);
afs_kafstimod_add_timer(&vlocation->timeout,10*HZ); afs_kafstimod_add_timer(&vlocation->timeout, 10 * HZ);
spin_unlock(&cell->vl_gylock); spin_unlock(&cell->vl_gylock);
...@@ -486,7 +497,7 @@ void __afs_put_vlocation(struct afs_vlocation *vlocation) ...@@ -486,7 +497,7 @@ void __afs_put_vlocation(struct afs_vlocation *vlocation)
/* /*
* finish using a volume location record * finish using a volume location record
*/ */
void afs_put_vlocation(afs_vlocation_t *vlocation) void afs_put_vlocation(struct afs_vlocation *vlocation)
{ {
if (vlocation) { if (vlocation) {
struct afs_cell *cell = vlocation->cell; struct afs_cell *cell = vlocation->cell;
...@@ -502,19 +513,19 @@ void afs_put_vlocation(afs_vlocation_t *vlocation) ...@@ -502,19 +513,19 @@ void afs_put_vlocation(afs_vlocation_t *vlocation)
* timeout vlocation record * timeout vlocation record
* - removes from the cell's graveyard if the usage count is zero * - removes from the cell's graveyard if the usage count is zero
*/ */
void afs_vlocation_do_timeout(afs_vlocation_t *vlocation) void afs_vlocation_do_timeout(struct afs_vlocation *vlocation)
{ {
afs_cell_t *cell; struct afs_cell *cell;
_enter("%s",vlocation->vldb.name); _enter("%s", vlocation->vldb.name);
cell = vlocation->cell; cell = vlocation->cell;
if (atomic_read(&vlocation->usage)<0) BUG(); BUG_ON(atomic_read(&vlocation->usage) < 0);
/* remove from graveyard if still dead */ /* remove from graveyard if still dead */
spin_lock(&cell->vl_gylock); spin_lock(&cell->vl_gylock);
if (atomic_read(&vlocation->usage)==0) if (atomic_read(&vlocation->usage) == 0)
list_del_init(&vlocation->link); list_del_init(&vlocation->link);
else else
vlocation = NULL; vlocation = NULL;
...@@ -527,7 +538,7 @@ void afs_vlocation_do_timeout(afs_vlocation_t *vlocation) ...@@ -527,7 +538,7 @@ void afs_vlocation_do_timeout(afs_vlocation_t *vlocation)
/* we can now destroy it properly */ /* we can now destroy it properly */
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
cachefs_relinquish_cookie(vlocation->cache,0); cachefs_relinquish_cookie(vlocation->cache, 0);
#endif #endif
afs_put_cell(cell); afs_put_cell(cell);
...@@ -540,14 +551,16 @@ void afs_vlocation_do_timeout(afs_vlocation_t *vlocation) ...@@ -540,14 +551,16 @@ void afs_vlocation_do_timeout(afs_vlocation_t *vlocation)
/* /*
* send an update operation to the currently selected server * send an update operation to the currently selected server
*/ */
static int afs_vlocation_update_begin(afs_vlocation_t *vlocation) static int afs_vlocation_update_begin(struct afs_vlocation *vlocation)
{ {
afs_voltype_t voltype; afs_voltype_t voltype;
afs_volid_t vid; afs_volid_t vid;
int ret; int ret;
_enter("%s{ufs=%u ucs=%u}", _enter("%s{ufs=%u ucs=%u}",
vlocation->vldb.name,vlocation->upd_first_svix,vlocation->upd_curr_svix); vlocation->vldb.name,
vlocation->upd_first_svix,
vlocation->upd_curr_svix);
/* try to look up a cached volume in the cell VL databases by ID */ /* try to look up a cached volume in the cell VL databases by ID */
if (vlocation->vldb.vidmask & AFS_VOL_VTM_RW) { if (vlocation->vldb.vidmask & AFS_VOL_VTM_RW) {
...@@ -569,27 +582,29 @@ static int afs_vlocation_update_begin(afs_vlocation_t *vlocation) ...@@ -569,27 +582,29 @@ static int afs_vlocation_update_begin(afs_vlocation_t *vlocation)
} }
/* contact the chosen server */ /* contact the chosen server */
ret = afs_server_lookup(vlocation->cell, ret = afs_server_lookup(
vlocation->cell,
&vlocation->cell->vl_addrs[vlocation->upd_curr_svix], &vlocation->cell->vl_addrs[vlocation->upd_curr_svix],
&vlocation->upd_op.server); &vlocation->upd_op.server);
switch (ret) { switch (ret) {
case 0: case 0:
break; break;
case -ENOMEM: case -ENOMEM:
case -ENONET: case -ENONET:
default: default:
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} }
/* initiate the update operation */ /* initiate the update operation */
ret = afs_rxvl_get_entry_by_id_async(&vlocation->upd_op,vid,voltype); ret = afs_rxvl_get_entry_by_id_async(&vlocation->upd_op, vid, voltype);
if (ret<0) { if (ret < 0) {
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} }
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_vlocation_update_begin() */ } /* end afs_vlocation_update_begin() */
...@@ -598,14 +613,15 @@ static int afs_vlocation_update_begin(afs_vlocation_t *vlocation) ...@@ -598,14 +613,15 @@ static int afs_vlocation_update_begin(afs_vlocation_t *vlocation)
* abandon updating a VL record * abandon updating a VL record
* - does not restart the update timer * - does not restart the update timer
*/ */
static void afs_vlocation_update_abandon(afs_vlocation_t *vlocation, static void afs_vlocation_update_abandon(struct afs_vlocation *vlocation,
afs_vlocation_upd_t state, afs_vlocation_upd_t state,
int ret) int ret)
{ {
_enter("%s,%u",vlocation->vldb.name,state); _enter("%s,%u", vlocation->vldb.name, state);
if (ret<0) if (ret < 0)
printk("kAFS: Abandoning VL update '%s': %d\n",vlocation->vldb.name,ret); printk("kAFS: Abandoning VL update '%s': %d\n",
vlocation->vldb.name, ret);
/* discard the server record */ /* discard the server record */
afs_put_server(vlocation->upd_op.server); afs_put_server(vlocation->upd_op.server);
...@@ -627,12 +643,13 @@ static void afs_vlocation_update_abandon(afs_vlocation_t *vlocation, ...@@ -627,12 +643,13 @@ static void afs_vlocation_update_abandon(afs_vlocation_t *vlocation,
* handle periodic update timeouts and busy retry timeouts * handle periodic update timeouts and busy retry timeouts
* - called from kafstimod * - called from kafstimod
*/ */
static void afs_vlocation_update_timer(afs_timer_t *timer) static void afs_vlocation_update_timer(struct afs_timer *timer)
{ {
afs_vlocation_t *vlocation = list_entry(timer,afs_vlocation_t,upd_timer); struct afs_vlocation *vlocation =
list_entry(timer, struct afs_vlocation, upd_timer);
int ret; int ret;
_enter("%s",vlocation->vldb.name); _enter("%s", vlocation->vldb.name);
/* only update if not in the graveyard (defend against putting too) */ /* only update if not in the graveyard (defend against putting too) */
spin_lock(&vlocation->cell->vl_gylock); spin_lock(&vlocation->cell->vl_gylock);
...@@ -642,11 +659,12 @@ static void afs_vlocation_update_timer(afs_timer_t *timer) ...@@ -642,11 +659,12 @@ static void afs_vlocation_update_timer(afs_timer_t *timer)
spin_lock(&afs_vlocation_update_lock); spin_lock(&afs_vlocation_update_lock);
/* if we were woken up due to EBUSY sleep then restart immediately if possible or else jump /* if we were woken up due to EBUSY sleep then restart immediately if
* to front of pending queue */ * possible or else jump to front of pending queue */
if (vlocation->upd_state==AFS_VLUPD_BUSYSLEEP) { if (vlocation->upd_state == AFS_VLUPD_BUSYSLEEP) {
if (afs_vlocation_update) { if (afs_vlocation_update) {
list_add(&vlocation->upd_op.link,&afs_vlocation_update_pendq); list_add(&vlocation->upd_op.link,
&afs_vlocation_update_pendq);
} }
else { else {
afs_get_vlocation(vlocation); afs_get_vlocation(vlocation);
...@@ -659,7 +677,8 @@ static void afs_vlocation_update_timer(afs_timer_t *timer) ...@@ -659,7 +677,8 @@ static void afs_vlocation_update_timer(afs_timer_t *timer)
/* put on pending queue if there's already another update in progress */ /* put on pending queue if there's already another update in progress */
if (afs_vlocation_update) { if (afs_vlocation_update) {
vlocation->upd_state = AFS_VLUPD_PENDING; vlocation->upd_state = AFS_VLUPD_PENDING;
list_add_tail(&vlocation->upd_op.link,&afs_vlocation_update_pendq); list_add_tail(&vlocation->upd_op.link,
&afs_vlocation_update_pendq);
goto out_unlock2; goto out_unlock2;
} }
...@@ -672,16 +691,17 @@ static void afs_vlocation_update_timer(afs_timer_t *timer) ...@@ -672,16 +691,17 @@ static void afs_vlocation_update_timer(afs_timer_t *timer)
spin_unlock(&vlocation->cell->vl_gylock); spin_unlock(&vlocation->cell->vl_gylock);
/* okay... we can start the update */ /* okay... we can start the update */
_debug("BEGIN VL UPDATE [%s]",vlocation->vldb.name); _debug("BEGIN VL UPDATE [%s]", vlocation->vldb.name);
vlocation->upd_first_svix = vlocation->cell->vl_curr_svix; vlocation->upd_first_svix = vlocation->cell->vl_curr_svix;
vlocation->upd_curr_svix = vlocation->upd_first_svix; vlocation->upd_curr_svix = vlocation->upd_first_svix;
vlocation->upd_rej_cnt = 0; vlocation->upd_rej_cnt = 0;
vlocation->upd_busy_cnt = 0; vlocation->upd_busy_cnt = 0;
ret = afs_vlocation_update_begin(vlocation); ret = afs_vlocation_update_begin(vlocation);
if (ret<0) { if (ret < 0) {
afs_vlocation_update_abandon(vlocation,AFS_VLUPD_SLEEP,ret); afs_vlocation_update_abandon(vlocation, AFS_VLUPD_SLEEP, ret);
afs_kafstimod_add_timer(&vlocation->upd_timer,AFS_VLDB_TIMEOUT); afs_kafstimod_add_timer(&vlocation->upd_timer,
AFS_VLDB_TIMEOUT);
afs_put_vlocation(vlocation); afs_put_vlocation(vlocation);
} }
...@@ -702,56 +722,60 @@ static void afs_vlocation_update_timer(afs_timer_t *timer) ...@@ -702,56 +722,60 @@ static void afs_vlocation_update_timer(afs_timer_t *timer)
* attend to an update operation upon which an event happened * attend to an update operation upon which an event happened
* - called in kafsasyncd context * - called in kafsasyncd context
*/ */
static void afs_vlocation_update_attend(afs_async_op_t *op) static void afs_vlocation_update_attend(struct afs_async_op *op)
{ {
struct afs_cache_vlocation vldb; struct afs_cache_vlocation vldb;
afs_vlocation_t *vlocation = list_entry(op,afs_vlocation_t,upd_op); struct afs_vlocation *vlocation =
list_entry(op, struct afs_vlocation, upd_op);
unsigned tmp; unsigned tmp;
int ret; int ret;
_enter("%s",vlocation->vldb.name); _enter("%s", vlocation->vldb.name);
ret = afs_rxvl_get_entry_by_id_async2(op,&vldb); ret = afs_rxvl_get_entry_by_id_async2(op, &vldb);
switch (ret) { switch (ret) {
case -EAGAIN: case -EAGAIN:
_leave(" [unfinished]"); _leave(" [unfinished]");
return; return;
case 0: case 0:
_debug("END VL UPDATE: %d\n",ret); _debug("END VL UPDATE: %d\n", ret);
vlocation->valid = 1; vlocation->valid = 1;
_debug("Done VL Lookup: %02x { %08x(%x) %08x(%x) %08x(%x) }", _debug("Done VL Lookup: %02x { %08x(%x) %08x(%x) %08x(%x) }",
vldb.vidmask, vldb.vidmask,
ntohl(vldb.servers[0].s_addr),vldb.srvtmask[0], ntohl(vldb.servers[0].s_addr), vldb.srvtmask[0],
ntohl(vldb.servers[1].s_addr),vldb.srvtmask[1], ntohl(vldb.servers[1].s_addr), vldb.srvtmask[1],
ntohl(vldb.servers[2].s_addr),vldb.srvtmask[2] ntohl(vldb.servers[2].s_addr), vldb.srvtmask[2]
); );
_debug("Vids: %08x %08x %08x",vldb.vid[0],vldb.vid[1],vldb.vid[2]); _debug("Vids: %08x %08x %08x",
vldb.vid[0], vldb.vid[1], vldb.vid[2]);
afs_vlocation_update_abandon(vlocation,AFS_VLUPD_SLEEP,0); afs_vlocation_update_abandon(vlocation, AFS_VLUPD_SLEEP, 0);
down_write(&vlocation->cell->vl_sem); down_write(&vlocation->cell->vl_sem);
/* actually update the cache */ /* actually update the cache */
if (strncmp(vldb.name,vlocation->vldb.name,sizeof(vlocation->vldb.name))!=0) if (strncmp(vldb.name, vlocation->vldb.name,
printk("kAFS: name of volume '%s' changed to '%s' on server\n", sizeof(vlocation->vldb.name)) != 0)
vlocation->vldb.name,vldb.name); printk("kAFS: name of volume '%s'"
" changed to '%s' on server\n",
vlocation->vldb.name, vldb.name);
memcpy(&vlocation->vldb,&vldb,sizeof(vlocation->vldb)); memcpy(&vlocation->vldb, &vldb, sizeof(vlocation->vldb));
#if 0 #if 0
/* add volume entry to local cache */ /* TODO update volume entry in local cache */
ret = afsc_update_vlocation(vlocation);
#endif #endif
up_write(&vlocation->cell->vl_sem); up_write(&vlocation->cell->vl_sem);
if (ret<0) if (ret < 0)
printk("kAFS: failed to update local cache: %d\n",ret); printk("kAFS: failed to update local cache: %d\n", ret);
afs_kafstimod_add_timer(&vlocation->upd_timer,AFS_VLDB_TIMEOUT); afs_kafstimod_add_timer(&vlocation->upd_timer,
AFS_VLDB_TIMEOUT);
afs_put_vlocation(vlocation); afs_put_vlocation(vlocation);
_leave(" [found]"); _leave(" [found]");
return; return;
...@@ -763,11 +787,12 @@ static void afs_vlocation_update_attend(afs_async_op_t *op) ...@@ -763,11 +787,12 @@ static void afs_vlocation_update_attend(afs_async_op_t *op)
/* the server is locked - retry in a very short while */ /* the server is locked - retry in a very short while */
case -EBUSY: case -EBUSY:
vlocation->upd_busy_cnt++; vlocation->upd_busy_cnt++;
if (vlocation->upd_busy_cnt>3) if (vlocation->upd_busy_cnt > 3)
goto try_next; /* too many retries */ goto try_next; /* too many retries */
afs_vlocation_update_abandon(vlocation,AFS_VLUPD_BUSYSLEEP,0); afs_vlocation_update_abandon(vlocation,
afs_kafstimod_add_timer(&vlocation->upd_timer,HZ/2); AFS_VLUPD_BUSYSLEEP, 0);
afs_kafstimod_add_timer(&vlocation->upd_timer, HZ / 2);
afs_put_vlocation(vlocation); afs_put_vlocation(vlocation);
_leave(" [busy]"); _leave(" [busy]");
return; return;
...@@ -781,7 +806,8 @@ static void afs_vlocation_update_attend(afs_async_op_t *op) ...@@ -781,7 +806,8 @@ static void afs_vlocation_update_attend(afs_async_op_t *op)
*/ */
if (vlocation->upd_curr_svix == vlocation->cell->vl_curr_svix) if (vlocation->upd_curr_svix == vlocation->cell->vl_curr_svix)
vlocation->cell->vl_curr_svix = vlocation->cell->vl_curr_svix =
vlocation->cell->vl_curr_svix % vlocation->cell->vl_naddrs; vlocation->cell->vl_curr_svix %
vlocation->cell->vl_naddrs;
case -EBADRQC: case -EBADRQC:
case -EINVAL: case -EINVAL:
...@@ -802,26 +828,30 @@ static void afs_vlocation_update_attend(afs_async_op_t *op) ...@@ -802,26 +828,30 @@ static void afs_vlocation_update_attend(afs_async_op_t *op)
vlocation->upd_op.server = NULL; vlocation->upd_op.server = NULL;
tmp = vlocation->cell->vl_naddrs; tmp = vlocation->cell->vl_naddrs;
if (tmp==0) if (tmp == 0)
goto abandon; goto abandon;
vlocation->upd_curr_svix++; vlocation->upd_curr_svix++;
if (vlocation->upd_curr_svix >= tmp) vlocation->upd_curr_svix = 0; if (vlocation->upd_curr_svix >= tmp)
if (vlocation->upd_first_svix >= tmp) vlocation->upd_first_svix = tmp - 1; vlocation->upd_curr_svix = 0;
if (vlocation->upd_first_svix >= tmp)
vlocation->upd_first_svix = tmp - 1;
/* move to the next server */ /* move to the next server */
if (vlocation->upd_curr_svix!=vlocation->upd_first_svix) { if (vlocation->upd_curr_svix != vlocation->upd_first_svix) {
afs_vlocation_update_begin(vlocation); afs_vlocation_update_begin(vlocation);
_leave(" [next]"); _leave(" [next]");
return; return;
} }
/* run out of servers to try - was the volume rejected? */ /* run out of servers to try - was the volume rejected? */
if (vlocation->upd_rej_cnt>0) { if (vlocation->upd_rej_cnt > 0) {
printk("kAFS: Active volume no longer valid '%s'\n",vlocation->vldb.name); printk("kAFS: Active volume no longer valid '%s'\n",
vlocation->vldb.name);
vlocation->valid = 0; vlocation->valid = 0;
afs_vlocation_update_abandon(vlocation,AFS_VLUPD_SLEEP,0); afs_vlocation_update_abandon(vlocation, AFS_VLUPD_SLEEP, 0);
afs_kafstimod_add_timer(&vlocation->upd_timer,AFS_VLDB_TIMEOUT); afs_kafstimod_add_timer(&vlocation->upd_timer,
AFS_VLDB_TIMEOUT);
afs_put_vlocation(vlocation); afs_put_vlocation(vlocation);
_leave(" [invalidated]"); _leave(" [invalidated]");
return; return;
...@@ -829,8 +859,8 @@ static void afs_vlocation_update_attend(afs_async_op_t *op) ...@@ -829,8 +859,8 @@ static void afs_vlocation_update_attend(afs_async_op_t *op)
/* abandon the update */ /* abandon the update */
abandon: abandon:
afs_vlocation_update_abandon(vlocation,AFS_VLUPD_SLEEP,ret); afs_vlocation_update_abandon(vlocation, AFS_VLUPD_SLEEP, ret);
afs_kafstimod_add_timer(&vlocation->upd_timer,HZ*10); afs_kafstimod_add_timer(&vlocation->upd_timer, HZ * 10);
afs_put_vlocation(vlocation); afs_put_vlocation(vlocation);
_leave(" [abandoned]"); _leave(" [abandoned]");
...@@ -842,11 +872,12 @@ static void afs_vlocation_update_attend(afs_async_op_t *op) ...@@ -842,11 +872,12 @@ static void afs_vlocation_update_attend(afs_async_op_t *op)
* - called in kafsasyncd context when it's dying due to rmmod * - called in kafsasyncd context when it's dying due to rmmod
* - the call has already been aborted and put()'d * - the call has already been aborted and put()'d
*/ */
static void afs_vlocation_update_discard(afs_async_op_t *op) static void afs_vlocation_update_discard(struct afs_async_op *op)
{ {
afs_vlocation_t *vlocation = list_entry(op,afs_vlocation_t,upd_op); struct afs_vlocation *vlocation =
list_entry(op, struct afs_vlocation, upd_op);
_enter("%s",vlocation->vldb.name); _enter("%s", vlocation->vldb.name);
afs_put_server(op->server); afs_put_server(op->server);
op->server = NULL; op->server = NULL;
...@@ -870,11 +901,11 @@ static cachefs_match_val_t afs_vlocation_cache_match(void *target, ...@@ -870,11 +901,11 @@ static cachefs_match_val_t afs_vlocation_cache_match(void *target,
_enter("{%s},{%s}", vlocation->vldb.name, vldb->name); _enter("{%s},{%s}", vlocation->vldb.name, vldb->name);
if (strncmp(vlocation->vldb.name, if (strncmp(vlocation->vldb.name, vldb->name, sizeof(vldb->name)) == 0
vldb->name, ) {
sizeof(vldb->name)) == 0) {
if (!vlocation->valid || if (!vlocation->valid ||
vlocation->vldb.rtime == vldb->rtime) { vlocation->vldb.rtime == vldb->rtime
) {
struct_cpy(&vlocation->vldb, vldb); struct_cpy(&vlocation->vldb, vldb);
vlocation->valid = 1; vlocation->valid = 1;
_leave(" = SUCCESS [c->m]"); _leave(" = SUCCESS [c->m]");
......
...@@ -30,7 +30,8 @@ struct afs_timer_ops afs_vnode_cb_timed_out_ops = { ...@@ -30,7 +30,8 @@ struct afs_timer_ops afs_vnode_cb_timed_out_ops = {
}; };
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
static cachefs_match_val_t afs_vnode_cache_match(void *target, const void *entry); static cachefs_match_val_t afs_vnode_cache_match(void *target,
const void *entry);
static void afs_vnode_cache_update(void *source, void *entry); static void afs_vnode_cache_update(void *source, void *entry);
struct cachefs_index_def afs_vnode_cache_index_def = { struct cachefs_index_def afs_vnode_cache_index_def = {
...@@ -49,17 +50,17 @@ struct cachefs_index_def afs_vnode_cache_index_def = { ...@@ -49,17 +50,17 @@ struct cachefs_index_def afs_vnode_cache_index_def = {
*/ */
static void afs_vnode_cb_timed_out(struct afs_timer *timer) static void afs_vnode_cb_timed_out(struct afs_timer *timer)
{ {
afs_server_t *oldserver; struct afs_server *oldserver;
afs_vnode_t *vnode; struct afs_vnode *vnode;
vnode = list_entry(timer,afs_vnode_t,cb_timeout); vnode = list_entry(timer, struct afs_vnode, cb_timeout);
_enter("%p",vnode); _enter("%p", vnode);
/* set the changed flag in the vnode and release the server */ /* set the changed flag in the vnode and release the server */
spin_lock(&vnode->lock); spin_lock(&vnode->lock);
oldserver = xchg(&vnode->cb_server,NULL); oldserver = xchg(&vnode->cb_server, NULL);
if (oldserver) { if (oldserver) {
vnode->flags |= AFS_VNODE_CHANGED; vnode->flags |= AFS_VNODE_CHANGED;
...@@ -85,28 +86,33 @@ static void afs_vnode_cb_timed_out(struct afs_timer *timer) ...@@ -85,28 +86,33 @@ static void afs_vnode_cb_timed_out(struct afs_timer *timer)
* - starts callback expiry timer * - starts callback expiry timer
* - adds to server's callback list * - adds to server's callback list
*/ */
void afs_vnode_finalise_status_update(afs_vnode_t *vnode, afs_server_t *server, int ret) void afs_vnode_finalise_status_update(struct afs_vnode *vnode,
struct afs_server *server,
int ret)
{ {
afs_server_t *oldserver = NULL; struct afs_server *oldserver = NULL;
_enter("%p,%p,%d",vnode,server,ret); _enter("%p,%p,%d", vnode, server, ret);
spin_lock(&vnode->lock); spin_lock(&vnode->lock);
vnode->flags &= ~AFS_VNODE_CHANGED; vnode->flags &= ~AFS_VNODE_CHANGED;
if (ret==0) { if (ret == 0) {
/* adjust the callback timeout appropriately */ /* adjust the callback timeout appropriately */
afs_kafstimod_add_timer(&vnode->cb_timeout,vnode->cb_expiry*HZ); afs_kafstimod_add_timer(&vnode->cb_timeout,
vnode->cb_expiry * HZ);
spin_lock(&afs_cb_hash_lock); spin_lock(&afs_cb_hash_lock);
list_del(&vnode->cb_hash_link); list_del(&vnode->cb_hash_link);
list_add_tail(&vnode->cb_hash_link,&afs_cb_hash(server,&vnode->fid)); list_add_tail(&vnode->cb_hash_link,
&afs_cb_hash(server, &vnode->fid));
spin_unlock(&afs_cb_hash_lock); spin_unlock(&afs_cb_hash_lock);
/* swap ref to old callback server with that for new callback server */ /* swap ref to old callback server with that for new callback
oldserver = xchg(&vnode->cb_server,server); * server */
if (oldserver!=server) { oldserver = xchg(&vnode->cb_server, server);
if (oldserver != server) {
if (oldserver) { if (oldserver) {
spin_lock(&oldserver->cb_lock); spin_lock(&oldserver->cb_lock);
list_del_init(&vnode->cb_link); list_del_init(&vnode->cb_link);
...@@ -115,7 +121,7 @@ void afs_vnode_finalise_status_update(afs_vnode_t *vnode, afs_server_t *server, ...@@ -115,7 +121,7 @@ void afs_vnode_finalise_status_update(afs_vnode_t *vnode, afs_server_t *server,
afs_get_server(server); afs_get_server(server);
spin_lock(&server->cb_lock); spin_lock(&server->cb_lock);
list_add_tail(&vnode->cb_link,&server->cb_promises); list_add_tail(&vnode->cb_link, &server->cb_promises);
spin_unlock(&server->cb_lock); spin_unlock(&server->cb_lock);
} }
else { else {
...@@ -123,9 +129,9 @@ void afs_vnode_finalise_status_update(afs_vnode_t *vnode, afs_server_t *server, ...@@ -123,9 +129,9 @@ void afs_vnode_finalise_status_update(afs_vnode_t *vnode, afs_server_t *server,
oldserver = NULL; oldserver = NULL;
} }
} }
else if (ret==-ENOENT) { else if (ret == -ENOENT) {
/* the file was deleted - clear the callback timeout */ /* the file was deleted - clear the callback timeout */
oldserver = xchg(&vnode->cb_server,NULL); oldserver = xchg(&vnode->cb_server, NULL);
afs_kafstimod_del_timer(&vnode->cb_timeout); afs_kafstimod_del_timer(&vnode->cb_timeout);
_debug("got NOENT from server - marking file deleted"); _debug("got NOENT from server - marking file deleted");
...@@ -152,15 +158,16 @@ void afs_vnode_finalise_status_update(afs_vnode_t *vnode, afs_server_t *server, ...@@ -152,15 +158,16 @@ void afs_vnode_finalise_status_update(afs_vnode_t *vnode, afs_server_t *server,
* - there are any outstanding ops that will fetch the status * - there are any outstanding ops that will fetch the status
* - TODO implement local caching * - TODO implement local caching
*/ */
int afs_vnode_fetch_status(afs_vnode_t *vnode) int afs_vnode_fetch_status(struct afs_vnode *vnode)
{ {
afs_server_t *server; struct afs_server *server;
int ret; int ret;
DECLARE_WAITQUEUE(myself,current); DECLARE_WAITQUEUE(myself, current);
_enter("%s,{%u,%u,%u}",vnode->volume->vlocation->vldb.name, _enter("%s,{%u,%u,%u}",
vnode->fid.vid,vnode->fid.vnode,vnode->fid.unique); vnode->volume->vlocation->vldb.name,
vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique);
if (!(vnode->flags & AFS_VNODE_CHANGED) && vnode->cb_server) { if (!(vnode->flags & AFS_VNODE_CHANGED) && vnode->cb_server) {
_leave(" [unchanged]"); _leave(" [unchanged]");
...@@ -180,19 +187,23 @@ int afs_vnode_fetch_status(afs_vnode_t *vnode) ...@@ -180,19 +187,23 @@ int afs_vnode_fetch_status(afs_vnode_t *vnode)
return 0; return 0;
} }
if (vnode->update_cnt>0) { if (vnode->update_cnt > 0) {
/* someone else started a fetch */ /* someone else started a fetch */
set_current_state(TASK_UNINTERRUPTIBLE); set_current_state(TASK_UNINTERRUPTIBLE);
add_wait_queue(&vnode->update_waitq,&myself); add_wait_queue(&vnode->update_waitq, &myself);
/* wait for the status to be updated */ /* wait for the status to be updated */
for (;;) { for (;;) {
if (!(vnode->flags & AFS_VNODE_CHANGED)) break; if (!(vnode->flags & AFS_VNODE_CHANGED))
if (vnode->flags & AFS_VNODE_DELETED) break; break;
if (vnode->flags & AFS_VNODE_DELETED)
/* it got updated and invalidated all before we saw it */ break;
if (vnode->update_cnt==0) {
remove_wait_queue(&vnode->update_waitq,&myself); /* it got updated and invalidated all before we saw
* it */
if (vnode->update_cnt == 0) {
remove_wait_queue(&vnode->update_waitq,
&myself);
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
goto get_anyway; goto get_anyway;
} }
...@@ -205,7 +216,7 @@ int afs_vnode_fetch_status(afs_vnode_t *vnode) ...@@ -205,7 +216,7 @@ int afs_vnode_fetch_status(afs_vnode_t *vnode)
spin_lock(&vnode->lock); spin_lock(&vnode->lock);
} }
remove_wait_queue(&vnode->update_waitq,&myself); remove_wait_queue(&vnode->update_waitq, &myself);
spin_unlock(&vnode->lock); spin_unlock(&vnode->lock);
set_current_state(TASK_RUNNING); set_current_state(TASK_RUNNING);
...@@ -218,23 +229,24 @@ int afs_vnode_fetch_status(afs_vnode_t *vnode) ...@@ -218,23 +229,24 @@ int afs_vnode_fetch_status(afs_vnode_t *vnode)
spin_unlock(&vnode->lock); spin_unlock(&vnode->lock);
/* merge AFS status fetches and clear outstanding callback on this vnode */ /* merge AFS status fetches and clear outstanding callback on this
* vnode */
do { do {
/* pick a server to query */ /* pick a server to query */
ret = afs_volume_pick_fileserver(vnode->volume,&server); ret = afs_volume_pick_fileserver(vnode->volume, &server);
if (ret<0) if (ret<0)
return ret; return ret;
_debug("USING SERVER: %08x\n",ntohl(server->addr.s_addr)); _debug("USING SERVER: %08x\n", ntohl(server->addr.s_addr));
ret = afs_rxfs_fetch_file_status(server,vnode,NULL); ret = afs_rxfs_fetch_file_status(server, vnode, NULL);
} while (!afs_volume_release_fileserver(vnode->volume,server,ret)); } while (!afs_volume_release_fileserver(vnode->volume, server, ret));
/* adjust the flags */ /* adjust the flags */
afs_vnode_finalise_status_update(vnode,server,ret); afs_vnode_finalise_status_update(vnode, server, ret);
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_vnode_fetch_status() */ } /* end afs_vnode_fetch_status() */
...@@ -243,9 +255,10 @@ int afs_vnode_fetch_status(afs_vnode_t *vnode) ...@@ -243,9 +255,10 @@ int afs_vnode_fetch_status(afs_vnode_t *vnode)
* fetch file data from the volume * fetch file data from the volume
* - TODO implement caching and server failover * - TODO implement caching and server failover
*/ */
int afs_vnode_fetch_data(afs_vnode_t *vnode, struct afs_rxfs_fetch_descriptor *desc) int afs_vnode_fetch_data(struct afs_vnode *vnode,
struct afs_rxfs_fetch_descriptor *desc)
{ {
afs_server_t *server; struct afs_server *server;
int ret; int ret;
_enter("%s,{%u,%u,%u}", _enter("%s,{%u,%u,%u}",
...@@ -259,23 +272,24 @@ int afs_vnode_fetch_data(afs_vnode_t *vnode, struct afs_rxfs_fetch_descriptor *d ...@@ -259,23 +272,24 @@ int afs_vnode_fetch_data(afs_vnode_t *vnode, struct afs_rxfs_fetch_descriptor *d
vnode->update_cnt++; vnode->update_cnt++;
spin_unlock(&vnode->lock); spin_unlock(&vnode->lock);
/* merge in AFS status fetches and clear outstanding callback on this vnode */ /* merge in AFS status fetches and clear outstanding callback on this
* vnode */
do { do {
/* pick a server to query */ /* pick a server to query */
ret = afs_volume_pick_fileserver(vnode->volume,&server); ret = afs_volume_pick_fileserver(vnode->volume, &server);
if (ret<0) if (ret < 0)
return ret; return ret;
_debug("USING SERVER: %08x\n",ntohl(server->addr.s_addr)); _debug("USING SERVER: %08x\n", ntohl(server->addr.s_addr));
ret = afs_rxfs_fetch_file_data(server,vnode,desc,NULL); ret = afs_rxfs_fetch_file_data(server, vnode, desc, NULL);
} while (!afs_volume_release_fileserver(vnode->volume,server,ret)); } while (!afs_volume_release_fileserver(vnode->volume, server, ret));
/* adjust the flags */ /* adjust the flags */
afs_vnode_finalise_status_update(vnode,server,ret); afs_vnode_finalise_status_update(vnode, server, ret);
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_vnode_fetch_data() */ } /* end afs_vnode_fetch_data() */
...@@ -285,9 +299,9 @@ int afs_vnode_fetch_data(afs_vnode_t *vnode, struct afs_rxfs_fetch_descriptor *d ...@@ -285,9 +299,9 @@ int afs_vnode_fetch_data(afs_vnode_t *vnode, struct afs_rxfs_fetch_descriptor *d
* break any outstanding callback on a vnode * break any outstanding callback on a vnode
* - only relevent to server that issued it * - only relevent to server that issued it
*/ */
int afs_vnode_give_up_callback(afs_vnode_t *vnode) int afs_vnode_give_up_callback(struct afs_vnode *vnode)
{ {
afs_server_t *server; struct afs_server *server;
int ret; int ret;
_enter("%s,{%u,%u,%u}", _enter("%s,{%u,%u,%u}",
...@@ -305,7 +319,7 @@ int afs_vnode_give_up_callback(afs_vnode_t *vnode) ...@@ -305,7 +319,7 @@ int afs_vnode_give_up_callback(afs_vnode_t *vnode)
afs_kafstimod_del_timer(&vnode->cb_timeout); afs_kafstimod_del_timer(&vnode->cb_timeout);
server = xchg(&vnode->cb_server,NULL); server = xchg(&vnode->cb_server, NULL);
if (server) { if (server) {
vnode->flags |= AFS_VNODE_CHANGED; vnode->flags |= AFS_VNODE_CHANGED;
...@@ -318,11 +332,11 @@ int afs_vnode_give_up_callback(afs_vnode_t *vnode) ...@@ -318,11 +332,11 @@ int afs_vnode_give_up_callback(afs_vnode_t *vnode)
ret = 0; ret = 0;
if (server) { if (server) {
ret = afs_rxfs_give_up_callback(server,vnode); ret = afs_rxfs_give_up_callback(server, vnode);
afs_put_server(server); afs_put_server(server);
} }
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_vnode_give_up_callback() */ } /* end afs_vnode_give_up_callback() */
...@@ -331,7 +345,8 @@ int afs_vnode_give_up_callback(afs_vnode_t *vnode) ...@@ -331,7 +345,8 @@ int afs_vnode_give_up_callback(afs_vnode_t *vnode)
* match a vnode record stored in the cache * match a vnode record stored in the cache
*/ */
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
static cachefs_match_val_t afs_vnode_cache_match(void *target, const void *entry) static cachefs_match_val_t afs_vnode_cache_match(void *target,
const void *entry)
{ {
const struct afs_cache_vnode *cvnode = entry; const struct afs_cache_vnode *cvnode = entry;
struct afs_vnode *vnode = target; struct afs_vnode *vnode = target;
......
...@@ -70,21 +70,22 @@ struct afs_vnode ...@@ -70,21 +70,22 @@ struct afs_vnode
afs_callback_type_t cb_type; /* type of callback */ afs_callback_type_t cb_type; /* type of callback */
}; };
static inline afs_vnode_t *AFS_FS_I(struct inode *inode) static inline struct afs_vnode *AFS_FS_I(struct inode *inode)
{ {
return container_of(inode,afs_vnode_t,vfs_inode); return container_of(inode,struct afs_vnode,vfs_inode);
} }
static inline struct inode *AFS_VNODE_TO_I(afs_vnode_t *vnode) static inline struct inode *AFS_VNODE_TO_I(struct afs_vnode *vnode)
{ {
return &vnode->vfs_inode; return &vnode->vfs_inode;
} }
extern int afs_vnode_fetch_status(afs_vnode_t *vnode); extern int afs_vnode_fetch_status(struct afs_vnode *vnode);
extern int afs_vnode_fetch_data(afs_vnode_t *vnode, struct afs_rxfs_fetch_descriptor *desc); extern int afs_vnode_fetch_data(struct afs_vnode *vnode,
struct afs_rxfs_fetch_descriptor *desc);
extern int afs_vnode_give_up_callback(afs_vnode_t *vnode); extern int afs_vnode_give_up_callback(struct afs_vnode *vnode);
extern struct afs_timer_ops afs_vnode_cb_timed_out_ops; extern struct afs_timer_ops afs_vnode_cb_timed_out_ops;
......
...@@ -27,7 +27,8 @@ ...@@ -27,7 +27,8 @@
const char *afs_voltypes[] = { "R/W", "R/O", "BAK" }; const char *afs_voltypes[] = { "R/W", "R/O", "BAK" };
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
static cachefs_match_val_t afs_volume_cache_match(void *target, const void *entry); static cachefs_match_val_t afs_volume_cache_match(void *target,
const void *entry);
static void afs_volume_cache_update(void *source, void *entry); static void afs_volume_cache_update(void *source, void *entry);
struct cachefs_index_def afs_volume_cache_index_def = { struct cachefs_index_def afs_volume_cache_index_def = {
...@@ -45,7 +46,8 @@ struct cachefs_index_def afs_volume_cache_index_def = { ...@@ -45,7 +46,8 @@ struct cachefs_index_def afs_volume_cache_index_def = {
* lookup a volume by name * lookup a volume by name
* - this can be one of the following: * - this can be one of the following:
* "%[cell:]volume[.]" R/W volume * "%[cell:]volume[.]" R/W volume
* "#[cell:]volume[.]" R/O or R/W volume (rwparent=0), or R/W (rwparent=1) volume * "#[cell:]volume[.]" R/O or R/W volume (rwparent=0),
* or R/W (rwparent=1) volume
* "%[cell:]volume.readonly" R/O volume * "%[cell:]volume.readonly" R/O volume
* "#[cell:]volume.readonly" R/O volume * "#[cell:]volume.readonly" R/O volume
* "%[cell:]volume.backup" Backup volume * "%[cell:]volume.backup" Backup volume
...@@ -53,14 +55,17 @@ struct cachefs_index_def afs_volume_cache_index_def = { ...@@ -53,14 +55,17 @@ struct cachefs_index_def afs_volume_cache_index_def = {
* *
* The cell name is optional, and defaults to the current cell. * The cell name is optional, and defaults to the current cell.
* *
* See "The Rules of Mount Point Traversal" in Chapter 5 of the AFS SysAdmin Guide * See "The Rules of Mount Point Traversal" in Chapter 5 of the AFS SysAdmin
* Guide
* - Rule 1: Explicit type suffix forces access of that type or nothing * - Rule 1: Explicit type suffix forces access of that type or nothing
* (no suffix, then use Rule 2 & 3) * (no suffix, then use Rule 2 & 3)
* - Rule 2: If parent volume is R/O, then mount R/O volume by preference, R/W if not available * - Rule 2: If parent volume is R/O, then mount R/O volume by preference, R/W
* - Rule 3: If parent volume is R/W, then only mount R/W volume unless explicitly told otherwise * if not available
* - Rule 3: If parent volume is R/W, then only mount R/W volume unless
* explicitly told otherwise
*/ */
int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath, int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath,
afs_volume_t **_volume) struct afs_volume **_volume)
{ {
struct afs_vlocation *vlocation = NULL; struct afs_vlocation *vlocation = NULL;
struct afs_volume *volume = NULL; struct afs_volume *volume = NULL;
...@@ -108,6 +113,7 @@ int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath, ...@@ -108,6 +113,7 @@ int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath,
if (volname) { if (volname) {
cellname = name; cellname = name;
cellnamesz = volname - name; cellnamesz = volname - name;
volname++;
} }
else { else {
volname = name; volname = name;
...@@ -127,7 +133,8 @@ int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath, ...@@ -127,7 +133,8 @@ int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath,
if (cellname || !cell) { if (cellname || !cell) {
ret = afs_cell_lookup(cellname, cellnamesz, &cell); ret = afs_cell_lookup(cellname, cellnamesz, &cell);
if (ret<0) { if (ret<0) {
printk("kAFS: unable to lookup cell '%s'\n", cellname ?: ""); printk("kAFS: unable to lookup cell '%s'\n",
cellname ?: "");
goto error; goto error;
} }
} }
...@@ -146,7 +153,7 @@ int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath, ...@@ -146,7 +153,7 @@ int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath,
goto error; goto error;
srvtmask = 0; srvtmask = 0;
for (loop=0; loop<vlocation->vldb.nservers; loop++) for (loop = 0; loop < vlocation->vldb.nservers; loop++)
srvtmask |= vlocation->vldb.srvtmask[loop]; srvtmask |= vlocation->vldb.srvtmask[loop];
if (force) { if (force) {
...@@ -177,11 +184,11 @@ int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath, ...@@ -177,11 +184,11 @@ int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath,
_debug("creating new volume record"); _debug("creating new volume record");
ret = -ENOMEM; ret = -ENOMEM;
volume = kmalloc(sizeof(afs_volume_t), GFP_KERNEL); volume = kmalloc(sizeof(struct afs_volume), GFP_KERNEL);
if (!volume) if (!volume)
goto error_up; goto error_up;
memset(volume, 0, sizeof(afs_volume_t)); memset(volume, 0, sizeof(struct afs_volume));
atomic_set(&volume->usage, 1); atomic_set(&volume->usage, 1);
volume->type = type; volume->type = type;
volume->type_force = force; volume->type_force = force;
...@@ -191,12 +198,13 @@ int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath, ...@@ -191,12 +198,13 @@ int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath,
init_rwsem(&volume->server_sem); init_rwsem(&volume->server_sem);
/* look up all the applicable server records */ /* look up all the applicable server records */
for (loop=0; loop<8; loop++) { for (loop = 0; loop < 8; loop++) {
if (vlocation->vldb.srvtmask[loop] & (1 << volume->type)) { if (vlocation->vldb.srvtmask[loop] & (1 << volume->type)) {
ret = afs_server_lookup(volume->cell, ret = afs_server_lookup(
volume->cell,
&vlocation->vldb.servers[loop], &vlocation->vldb.servers[loop],
&volume->servers[volume->nservers]); &volume->servers[volume->nservers]);
if (ret<0) if (ret < 0)
goto error_discard; goto error_discard;
volume->nservers++; volume->nservers++;
...@@ -217,7 +225,8 @@ int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath, ...@@ -217,7 +225,8 @@ int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath,
vlocation->vols[type] = volume; vlocation->vols[type] = volume;
success: success:
_debug("kAFS selected %s volume %08x", afs_voltypes[volume->type], volume->vid); _debug("kAFS selected %s volume %08x",
afs_voltypes[volume->type], volume->vid);
*_volume = volume; *_volume = volume;
ret = 0; ret = 0;
...@@ -234,7 +243,7 @@ int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath, ...@@ -234,7 +243,7 @@ int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath,
error_discard: error_discard:
up_write(&cell->vl_sem); up_write(&cell->vl_sem);
for (loop=volume->nservers-1; loop>=0; loop--) for (loop = volume->nservers - 1; loop >= 0; loop--)
afs_put_server(volume->servers[loop]); afs_put_server(volume->servers[loop]);
kfree(volume); kfree(volume);
...@@ -245,23 +254,23 @@ int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath, ...@@ -245,23 +254,23 @@ int afs_volume_lookup(const char *name, struct afs_cell *cell, int rwpath,
/* /*
* destroy a volume record * destroy a volume record
*/ */
void afs_put_volume(afs_volume_t *volume) void afs_put_volume(struct afs_volume *volume)
{ {
afs_vlocation_t *vlocation; struct afs_vlocation *vlocation;
int loop; int loop;
if (!volume) if (!volume)
return; return;
_enter("%p",volume); _enter("%p", volume);
vlocation = volume->vlocation; vlocation = volume->vlocation;
/* sanity check */ /* sanity check */
if (atomic_read(&volume->usage)<=0) BUG_ON(atomic_read(&volume->usage) <= 0);
BUG();
/* to prevent a race, the decrement and the dequeue must be effectively atomic */ /* to prevent a race, the decrement and the dequeue must be effectively
* atomic */
down_write(&vlocation->cell->vl_sem); down_write(&vlocation->cell->vl_sem);
if (likely(!atomic_dec_and_test(&volume->usage))) { if (likely(!atomic_dec_and_test(&volume->usage))) {
...@@ -276,11 +285,11 @@ void afs_put_volume(afs_volume_t *volume) ...@@ -276,11 +285,11 @@ void afs_put_volume(afs_volume_t *volume)
/* finish cleaning up the volume */ /* finish cleaning up the volume */
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
cachefs_relinquish_cookie(volume->cache,0); cachefs_relinquish_cookie(volume->cache, 0);
#endif #endif
afs_put_vlocation(vlocation); afs_put_vlocation(vlocation);
for (loop=volume->nservers-1; loop>=0; loop--) for (loop = volume->nservers - 1; loop >= 0; loop--)
afs_put_server(volume->servers[loop]); afs_put_server(volume->servers[loop]);
kfree(volume); kfree(volume);
...@@ -293,26 +302,28 @@ void afs_put_volume(afs_volume_t *volume) ...@@ -293,26 +302,28 @@ void afs_put_volume(afs_volume_t *volume)
* pick a server to use to try accessing this volume * pick a server to use to try accessing this volume
* - returns with an elevated usage count on the server chosen * - returns with an elevated usage count on the server chosen
*/ */
int afs_volume_pick_fileserver(afs_volume_t *volume, afs_server_t **_server) int afs_volume_pick_fileserver(struct afs_volume *volume,
struct afs_server **_server)
{ {
afs_server_t *server; struct afs_server *server;
int ret, state, loop; int ret, state, loop;
_enter("%s",volume->vlocation->vldb.name); _enter("%s", volume->vlocation->vldb.name);
down_read(&volume->server_sem); down_read(&volume->server_sem);
/* handle the no-server case */ /* handle the no-server case */
if (volume->nservers==0) { if (volume->nservers == 0) {
ret = volume->rjservers ? -ENOMEDIUM : -ESTALE; ret = volume->rjservers ? -ENOMEDIUM : -ESTALE;
up_read(&volume->server_sem); up_read(&volume->server_sem);
_leave(" = %d [no servers]",ret); _leave(" = %d [no servers]", ret);
return ret; return ret;
} }
/* basically, just search the list for the first live server and use that */ /* basically, just search the list for the first live server and use
* that */
ret = 0; ret = 0;
for (loop=0; loop<volume->nservers; loop++) { for (loop = 0; loop < volume->nservers; loop++) {
server = volume->servers[loop]; server = volume->servers[loop];
state = server->fs_state; state = server->fs_state;
...@@ -322,30 +333,34 @@ int afs_volume_pick_fileserver(afs_volume_t *volume, afs_server_t **_server) ...@@ -322,30 +333,34 @@ int afs_volume_pick_fileserver(afs_volume_t *volume, afs_server_t **_server)
afs_get_server(server); afs_get_server(server);
up_read(&volume->server_sem); up_read(&volume->server_sem);
*_server = server; *_server = server;
_leave(" = 0 (picked %08x)",ntohl(server->addr.s_addr)); _leave(" = 0 (picked %08x)",
ntohl(server->addr.s_addr));
return 0; return 0;
case -ENETUNREACH: case -ENETUNREACH:
if (ret==0) if (ret == 0)
ret = state; ret = state;
break; break;
case -EHOSTUNREACH: case -EHOSTUNREACH:
if (ret==0 || ret==-ENETUNREACH) if (ret == 0 ||
ret == -ENETUNREACH)
ret = state; ret = state;
break; break;
case -ECONNREFUSED: case -ECONNREFUSED:
if (ret==0 || ret==-ENETUNREACH || ret==-EHOSTUNREACH) if (ret == 0 ||
ret == -ENETUNREACH ||
ret == -EHOSTUNREACH)
ret = state; ret = state;
break; break;
default: default:
case -EREMOTEIO: case -EREMOTEIO:
if (ret==0 || if (ret == 0 ||
ret==-ENETUNREACH || ret == -ENETUNREACH ||
ret==-EHOSTUNREACH || ret == -EHOSTUNREACH ||
ret==-ECONNREFUSED) ret == -ECONNREFUSED)
ret = state; ret = state;
break; break;
} }
...@@ -355,7 +370,7 @@ int afs_volume_pick_fileserver(afs_volume_t *volume, afs_server_t **_server) ...@@ -355,7 +370,7 @@ int afs_volume_pick_fileserver(afs_volume_t *volume, afs_server_t **_server)
* - TODO: handle the no active servers case better * - TODO: handle the no active servers case better
*/ */
up_read(&volume->server_sem); up_read(&volume->server_sem);
_leave(" = %d",ret); _leave(" = %d", ret);
return ret; return ret;
} /* end afs_volume_pick_fileserver() */ } /* end afs_volume_pick_fileserver() */
...@@ -366,11 +381,15 @@ int afs_volume_pick_fileserver(afs_volume_t *volume, afs_server_t **_server) ...@@ -366,11 +381,15 @@ int afs_volume_pick_fileserver(afs_volume_t *volume, afs_server_t **_server)
* - records result of using a particular server to access a volume * - records result of using a particular server to access a volume
* - return 0 to try again, 1 if okay or to issue error * - return 0 to try again, 1 if okay or to issue error
*/ */
int afs_volume_release_fileserver(afs_volume_t *volume, afs_server_t *server, int result) int afs_volume_release_fileserver(struct afs_volume *volume,
struct afs_server *server,
int result)
{ {
unsigned loop; unsigned loop;
_enter("%s,%08x,%d",volume->vlocation->vldb.name,ntohl(server->addr.s_addr),result); _enter("%s,%08x,%d",
volume->vlocation->vldb.name, ntohl(server->addr.s_addr),
result);
switch (result) { switch (result) {
/* success */ /* success */
...@@ -383,9 +402,10 @@ int afs_volume_release_fileserver(afs_volume_t *volume, afs_server_t *server, in ...@@ -383,9 +402,10 @@ int afs_volume_release_fileserver(afs_volume_t *volume, afs_server_t *server, in
server->fs_act_jif = jiffies; server->fs_act_jif = jiffies;
down_write(&volume->server_sem); down_write(&volume->server_sem);
/* first, find where the server is in the active list (if it is) */ /* first, find where the server is in the active list (if it
for (loop=0; loop<volume->nservers; loop++) * is) */
if (volume->servers[loop]==server) for (loop = 0; loop < volume->nservers; loop++)
if (volume->servers[loop] == server)
goto present; goto present;
/* no longer there - may have been discarded by another op */ /* no longer there - may have been discarded by another op */
...@@ -394,20 +414,22 @@ int afs_volume_release_fileserver(afs_volume_t *volume, afs_server_t *server, in ...@@ -394,20 +414,22 @@ int afs_volume_release_fileserver(afs_volume_t *volume, afs_server_t *server, in
present: present:
volume->nservers--; volume->nservers--;
memmove(&volume->servers[loop], memmove(&volume->servers[loop],
&volume->servers[loop+1], &volume->servers[loop + 1],
sizeof(volume->servers[loop]) * (volume->nservers - loop) sizeof(volume->servers[loop]) *
); (volume->nservers - loop));
volume->servers[volume->nservers] = NULL; volume->servers[volume->nservers] = NULL;
afs_put_server(server); afs_put_server(server);
volume->rjservers++; volume->rjservers++;
if (volume->nservers>0) if (volume->nservers > 0)
/* another server might acknowledge its existence */ /* another server might acknowledge its existence */
goto try_next_server_upw; goto try_next_server_upw;
/* handle the case where all the fileservers have rejected the volume /* handle the case where all the fileservers have rejected the
* volume
* - TODO: try asking the fileservers for volume information * - TODO: try asking the fileservers for volume information
* - TODO: contact the VL server again to see if the volume is no longer registered * - TODO: contact the VL server again to see if the volume is
* no longer registered
*/ */
up_write(&volume->server_sem); up_write(&volume->server_sem);
afs_put_server(server); afs_put_server(server);
...@@ -427,7 +449,7 @@ int afs_volume_release_fileserver(afs_volume_t *volume, afs_server_t *server, in ...@@ -427,7 +449,7 @@ int afs_volume_release_fileserver(afs_volume_t *volume, afs_server_t *server, in
if (!server->fs_state) { if (!server->fs_state) {
server->fs_dead_jif = jiffies + HZ * 10; server->fs_dead_jif = jiffies + HZ * 10;
server->fs_state = result; server->fs_state = result;
printk("kAFS: SERVER DEAD state=%d\n",result); printk("kAFS: SERVER DEAD state=%d\n", result);
} }
spin_unlock(&server->fs_lock); spin_unlock(&server->fs_lock);
goto try_next_server; goto try_next_server;
...@@ -460,7 +482,8 @@ int afs_volume_release_fileserver(afs_volume_t *volume, afs_server_t *server, in ...@@ -460,7 +482,8 @@ int afs_volume_release_fileserver(afs_volume_t *volume, afs_server_t *server, in
* match a volume hash record stored in the cache * match a volume hash record stored in the cache
*/ */
#ifdef AFS_CACHING_SUPPORT #ifdef AFS_CACHING_SUPPORT
static cachefs_match_val_t afs_volume_cache_match(void *target, const void *entry) static cachefs_match_val_t afs_volume_cache_match(void *target,
const void *entry)
{ {
const struct afs_cache_vhash *vhash = entry; const struct afs_cache_vhash *vhash = entry;
struct afs_volume *volume = target; struct afs_volume *volume = target;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment