/* * finish off updating the recorded status of a file * - starts callback expiry timer * - adds to server's callback list */ void afs_vnode_finalise_status_update(afs_vnode_t *vnode, afs_server_t *server, int ret) { afs_server_t *oldserver = NULL; _enter("%p,%p,%d",vnode,server,ret); spin_lock(&vnode->lock); vnode->flags &= ~AFS_VNODE_CHANGED; if (ret==0) { /* adjust the callback timeout appropriately */ afs_kafstimod_add_timer(&vnode->cb_timeout,vnode->cb_expiry*HZ); spin_lock(&afs_cb_hash_lock); list_del(&vnode->cb_hash_link); list_add_tail(&vnode->cb_hash_link,&afs_cb_hash(server,&vnode->fid)); spin_unlock(&afs_cb_hash_lock); /* swap ref to old callback server with that for new callback server */ oldserver = xchg(&vnode->cb_server,server); if (oldserver!=server) { if (oldserver) { spin_lock(&oldserver->cb_lock); list_del_init(&vnode->cb_link); spin_unlock(&oldserver->cb_lock); } afs_get_server(server); spin_lock(&server->cb_lock); list_add_tail(&vnode->cb_link,&server->cb_promises); spin_unlock(&server->cb_lock); } else { /* same server */ oldserver = NULL; } } else if (ret==-ENOENT) { /* the file was deleted - clear the callback timeout */ oldserver = xchg(&vnode->cb_server,NULL); afs_kafstimod_del_timer(&vnode->cb_timeout); _debug("got NOENT from server - marking file deleted"); vnode->flags |= AFS_VNODE_DELETED; } vnode->update_cnt--; spin_unlock(&vnode->lock); wake_up_all(&vnode->update_waitq); afs_put_server(oldserver); _leave(""); } /* end afs_vnode_finalise_status_update() */
/* * break any outstanding callback on a vnode * - only relevent to server that issued it */ int afs_vnode_give_up_callback(struct afs_vnode *vnode) { struct afs_server *server; int ret; _enter("%s,{%u,%u,%u}", vnode->volume->vlocation->vldb.name, vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique); spin_lock(&afs_cb_hash_lock); list_del_init(&vnode->cb_hash_link); spin_unlock(&afs_cb_hash_lock); /* set the changed flag in the vnode and release the server */ spin_lock(&vnode->lock); afs_kafstimod_del_timer(&vnode->cb_timeout); server = xchg(&vnode->cb_server, NULL); if (server) { vnode->flags |= AFS_VNODE_CHANGED; spin_lock(&server->cb_lock); list_del_init(&vnode->cb_link); spin_unlock(&server->cb_lock); } spin_unlock(&vnode->lock); ret = 0; if (server) { ret = afs_rxfs_give_up_callback(server, vnode); afs_put_server(server); } _leave(" = %d", ret); return ret; } /* end afs_vnode_give_up_callback() */