#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/init.h>
+#include <linux/sched.h>
#include "internal.h"
-unsigned afs_vlocation_timeout = 10; /* volume location timeout in seconds */
-unsigned afs_vlocation_update_timeout = 10 * 60;
+static unsigned afs_vlocation_timeout = 10; /* volume location timeout in seconds */
+static unsigned afs_vlocation_update_timeout = 10 * 60;
static void afs_vlocation_reaper(struct work_struct *);
static void afs_vlocation_updater(struct work_struct *);
goto out;
goto rotate;
case -ENOMEDIUM:
+ case -EKEYREJECTED:
+ case -EKEYEXPIRED:
goto out;
default:
ret = -EIO;
INIT_LIST_HEAD(&vl->grave);
INIT_LIST_HEAD(&vl->update);
init_waitqueue_head(&vl->waitq);
- rwlock_init(&vl->lock);
+ spin_lock_init(&vl->lock);
memcpy(vl->vldb.name, name, namesz);
}
vl->vldb = *vldb;
-#ifdef AFS_CACHING_SUPPORT
- /* update volume entry in local cache */
- cachefs_update_cookie(vl->cache);
+#ifdef CONFIG_AFS_FSCACHE
+ fscache_update_cookie(vl->cache);
#endif
}
memset(&vldb, 0, sizeof(vldb));
/* see if we have an in-cache copy (will set vl->valid if there is) */
-#ifdef AFS_CACHING_SUPPORT
- cachefs_acquire_cookie(cell->cache,
- &afs_volume_cache_index_def,
- vlocation,
- &vl->cache);
+#ifdef CONFIG_AFS_FSCACHE
+ vl->cache = fscache_acquire_cookie(vl->cell->cache,
+ &afs_vlocation_cache_index_def, vl);
#endif
if (vl->valid) {
/*
* queue a vlocation record for updates
*/
-void afs_vlocation_queue_for_updates(struct afs_vlocation *vl)
+static void afs_vlocation_queue_for_updates(struct afs_vlocation *vl)
{
struct afs_vlocation *xvl;
cell->name, key_serial(key),
(int) namesz, (int) namesz, name, namesz);
- if (namesz > sizeof(vl->vldb.name)) {
+ if (namesz >= sizeof(vl->vldb.name)) {
_leave(" = -ENAMETOOLONG");
return ERR_PTR(-ENAMETOOLONG);
}
ret = afs_vlocation_fill_in_record(vl, key);
if (ret < 0)
goto error_abandon;
+ spin_lock(&vl->lock);
vl->state = AFS_VL_VALID;
+ spin_unlock(&vl->lock);
wake_up(&vl->waitq);
+ /* update volume entry in local cache */
+#ifdef CONFIG_AFS_FSCACHE
+ fscache_update_cookie(vl->cache);
+#endif
+
/* schedule for regular updates */
afs_vlocation_queue_for_updates(vl);
goto success;
up_write(&cell->vl_sem);
/* see if it was an abandoned record that we might try filling in */
+ spin_lock(&vl->lock);
while (vl->state != AFS_VL_VALID) {
afs_vlocation_state_t state = vl->state;
_debug("invalid [state %d]", state);
- if ((state == AFS_VL_NEW || state == AFS_VL_NO_VOLUME)) {
- if (cmpxchg(&vl->state, state, AFS_VL_CREATING) ==
- state)
- goto fill_in_record;
- continue;
+ if (state == AFS_VL_NEW || state == AFS_VL_NO_VOLUME) {
+ vl->state = AFS_VL_CREATING;
+ spin_unlock(&vl->lock);
+ goto fill_in_record;
}
/* must now wait for creation or update by someone else to
* complete */
_debug("wait");
- ret = wait_event_interruptible(
- vl->waitq,
- vl->state == AFS_VL_NEW ||
- vl->state == AFS_VL_VALID ||
- vl->state == AFS_VL_NO_VOLUME);
+ spin_unlock(&vl->lock);
+ ret = wait_event_interruptible(vl->waitq,
+ vl->state == AFS_VL_NEW ||
+ vl->state == AFS_VL_VALID ||
+ vl->state == AFS_VL_NO_VOLUME);
if (ret < 0)
goto error;
+ spin_lock(&vl->lock);
}
+ spin_unlock(&vl->lock);
success:
- _leave(" = %p",vl);
+ _leave(" = %p", vl);
return vl;
error_abandon:
+ spin_lock(&vl->lock);
vl->state = AFS_VL_NEW;
+ spin_unlock(&vl->lock);
wake_up(&vl->waitq);
error:
ASSERT(vl != NULL);
{
_enter("%p", vl);
-#ifdef AFS_CACHING_SUPPORT
- cachefs_relinquish_cookie(vl->cache, 0);
+#ifdef CONFIG_AFS_FSCACHE
+ fscache_relinquish_cookie(vl->cache, 0);
#endif
-
afs_put_cell(vl->cell);
kfree(vl);
}
/*
* discard all the volume location records for rmmod
*/
-void __exit afs_vlocation_purge(void)
+void afs_vlocation_purge(void)
{
afs_vlocation_timeout = 0;
vl->upd_busy_cnt = 0;
ret = afs_vlocation_update_record(vl, NULL, &vldb);
+ spin_lock(&vl->lock);
switch (ret) {
case 0:
afs_vlocation_apply_update(vl, &vldb);
vl->state = AFS_VL_UNCERTAIN;
break;
}
+ spin_unlock(&vl->lock);
+ wake_up(&vl->waitq);
/* and then reschedule */
_debug("reschedule");