Merge to Fedora kernel-2.6.18-1.2224_FC5 patched with stable patch-2.6.18.1-vs2.0...
[linux-2.6.git] / fs / afs / vlocation.c
index eced206..20148bc 100644 (file)
@@ -59,17 +59,21 @@ static LIST_HEAD(afs_vlocation_update_pendq);       /* queue of VLs awaiting update */
 static struct afs_vlocation *afs_vlocation_update;     /* VL currently being updated */
 static DEFINE_SPINLOCK(afs_vlocation_update_lock); /* lock guarding update queue */
 
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_vlocation_cache_match(void *target,
-                                                    const void *entry);
-static void afs_vlocation_cache_update(void *source, void *entry);
-
-struct cachefs_index_def afs_vlocation_cache_index_def = {
-       .name           = "vldb",
-       .data_size      = sizeof(struct afs_cache_vlocation),
-       .keys[0]        = { CACHEFS_INDEX_KEYS_ASCIIZ, 64 },
-       .match          = afs_vlocation_cache_match,
-       .update         = afs_vlocation_cache_update,
+#ifdef CONFIG_AFS_FSCACHE
+static uint16_t afs_vlocation_cache_get_key(const void *cookie_netfs_data,
+                                           void *buffer, uint16_t buflen);
+static uint16_t afs_vlocation_cache_get_aux(const void *cookie_netfs_data,
+                                           void *buffer, uint16_t buflen);
+static fscache_checkaux_t afs_vlocation_cache_check_aux(void *cookie_netfs_data,
+                                                       const void *buffer,
+                                                       uint16_t buflen);
+
+static struct fscache_cookie_def afs_vlocation_cache_index_def = {
+       .name           = "AFS.vldb",
+       .type           = FSCACHE_COOKIE_TYPE_INDEX,
+       .get_key        = afs_vlocation_cache_get_key,
+       .get_aux        = afs_vlocation_cache_get_aux,
+       .check_aux      = afs_vlocation_cache_check_aux,
 };
 #endif
 
@@ -300,13 +304,12 @@ int afs_vlocation_lookup(struct afs_cell *cell,
 
        list_add_tail(&vlocation->link, &cell->vl_list);
 
-#ifdef AFS_CACHING_SUPPORT
+#ifdef CONFIG_AFS_FSCACHE
        /* we want to store it in the cache, plus it might already be
         * encached */
-       cachefs_acquire_cookie(cell->cache,
-                              &afs_volume_cache_index_def,
-                              vlocation,
-                              &vlocation->cache);
+       vlocation->cache = fscache_acquire_cookie(cell->cache,
+                                                 &afs_vlocation_cache_index_def,
+                                                 vlocation);
 
        if (vlocation->valid)
                goto found_in_cache;
@@ -326,8 +329,7 @@ int afs_vlocation_lookup(struct afs_cell *cell,
        /* found in the graveyard - resurrect */
        _debug("found in graveyard");
        atomic_inc(&vlocation->usage);
-       list_del(&vlocation->link);
-       list_add_tail(&vlocation->link, &cell->vl_list);
+       list_move_tail(&vlocation->link, &cell->vl_list);
        spin_unlock(&cell->vl_gylock);
 
        afs_kafstimod_del_timer(&vlocation->timeout);
@@ -341,7 +343,7 @@ int afs_vlocation_lookup(struct afs_cell *cell,
  active:
        active = 1;
 
-#ifdef AFS_CACHING_SUPPORT
+#ifdef CONFIG_AFS_FSCACHE
  found_in_cache:
 #endif
        /* try to look up a cached volume in the cell VL databases by ID */
@@ -423,9 +425,9 @@ int afs_vlocation_lookup(struct afs_cell *cell,
 
        afs_kafstimod_add_timer(&vlocation->upd_timer, 10 * HZ);
 
-#ifdef AFS_CACHING_SUPPORT
+#ifdef CONFIG_AFS_FSCACHE
        /* update volume entry in local cache */
-       cachefs_update_cookie(vlocation->cache);
+       fscache_update_cookie(vlocation->cache);
 #endif
 
        *_vlocation = vlocation;
@@ -439,8 +441,8 @@ int afs_vlocation_lookup(struct afs_cell *cell,
                }
                else {
                        list_del(&vlocation->link);
-#ifdef AFS_CACHING_SUPPORT
-                       cachefs_relinquish_cookie(vlocation->cache, 0);
+#ifdef CONFIG_AFS_FSCACHE
+                       fscache_relinquish_cookie(vlocation->cache, 0);
 #endif
                        afs_put_cell(vlocation->cell);
                        kfree(vlocation);
@@ -478,8 +480,7 @@ static void __afs_put_vlocation(struct afs_vlocation *vlocation)
        }
 
        /* move to graveyard queue */
-       list_del(&vlocation->link);
-       list_add_tail(&vlocation->link,&cell->vl_graveyard);
+       list_move_tail(&vlocation->link,&cell->vl_graveyard);
 
        /* remove from pending timeout queue (refcounted if actually being
         * updated) */
@@ -538,8 +539,8 @@ void afs_vlocation_do_timeout(struct afs_vlocation *vlocation)
        }
 
        /* we can now destroy it properly */
-#ifdef AFS_CACHING_SUPPORT
-       cachefs_relinquish_cookie(vlocation->cache, 0);
+#ifdef CONFIG_AFS_FSCACHE
+       fscache_relinquish_cookie(vlocation->cache, 0);
 #endif
        afs_put_cell(cell);
 
@@ -890,65 +891,103 @@ static void afs_vlocation_update_discard(struct afs_async_op *op)
 
 /*****************************************************************************/
 /*
- * match a VLDB record stored in the cache
- * - may also load target from entry
+ * set the key for the index entry
  */
-#ifdef AFS_CACHING_SUPPORT
-static cachefs_match_val_t afs_vlocation_cache_match(void *target,
-                                                    const void *entry)
+#ifdef CONFIG_AFS_FSCACHE
+static uint16_t afs_vlocation_cache_get_key(const void *cookie_netfs_data,
+                                           void *buffer, uint16_t bufmax)
 {
-       const struct afs_cache_vlocation *vldb = entry;
-       struct afs_vlocation *vlocation = target;
+       const struct afs_vlocation *vlocation = cookie_netfs_data;
+       uint16_t klen;
 
-       _enter("{%s},{%s}", vlocation->vldb.name, vldb->name);
+       _enter("{%s},%p,%u", vlocation->vldb.name, buffer, bufmax);
 
-       if (strncmp(vlocation->vldb.name, vldb->name, sizeof(vldb->name)) == 0
-           ) {
-               if (!vlocation->valid ||
-                   vlocation->vldb.rtime == vldb->rtime
-                   ) {
-                       vlocation->vldb = *vldb;
-                       vlocation->valid = 1;
-                       _leave(" = SUCCESS [c->m]");
-                       return CACHEFS_MATCH_SUCCESS;
-               }
-               /* need to update cache if cached info differs */
-               else if (memcmp(&vlocation->vldb, vldb, sizeof(*vldb)) != 0) {
-                       /* delete if VIDs for this name differ */
-                       if (memcmp(&vlocation->vldb.vid,
-                                  &vldb->vid,
-                                  sizeof(vldb->vid)) != 0) {
-                               _leave(" = DELETE");
-                               return CACHEFS_MATCH_SUCCESS_DELETE;
-                       }
+       klen = strnlen(vlocation->vldb.name, sizeof(vlocation->vldb.name));
+       if (klen > bufmax)
+               return 0;
 
-                       _leave(" = UPDATE");
-                       return CACHEFS_MATCH_SUCCESS_UPDATE;
-               }
-               else {
-                       _leave(" = SUCCESS");
-                       return CACHEFS_MATCH_SUCCESS;
-               }
-       }
+       memcpy(buffer, vlocation->vldb.name, klen);
+
+       _leave(" = %u", klen);
+       return klen;
+
+} /* end afs_vlocation_cache_get_key() */
+#endif
+
+/*****************************************************************************/
+/*
+ * provide new auxilliary cache data
+ */
+#ifdef CONFIG_AFS_FSCACHE
+static uint16_t afs_vlocation_cache_get_aux(const void *cookie_netfs_data,
+                                           void *buffer, uint16_t bufmax)
+{
+       const struct afs_vlocation *vlocation = cookie_netfs_data;
+       uint16_t dlen;
+
+       _enter("{%s},%p,%u", vlocation->vldb.name, buffer, bufmax);
+
+       dlen = sizeof(struct afs_cache_vlocation);
+       dlen -= offsetof(struct afs_cache_vlocation, nservers);
+       if (dlen > bufmax)
+               return 0;
+
+       memcpy(buffer, (uint8_t *)&vlocation->vldb.nservers, dlen);
 
-       _leave(" = FAILED");
-       return CACHEFS_MATCH_FAILED;
-} /* end afs_vlocation_cache_match() */
+       _leave(" = %u", dlen);
+       return dlen;
+
+} /* end afs_vlocation_cache_get_aux() */
 #endif
 
 /*****************************************************************************/
 /*
- * update a VLDB record stored in the cache
+ * check that the auxilliary data indicates that the entry is still valid
  */
-#ifdef AFS_CACHING_SUPPORT
-static void afs_vlocation_cache_update(void *source, void *entry)
+#ifdef CONFIG_AFS_FSCACHE
+static fscache_checkaux_t afs_vlocation_cache_check_aux(void *cookie_netfs_data,
+                                                       const void *buffer,
+                                                       uint16_t buflen)
 {
-       struct afs_cache_vlocation *vldb = entry;
-       struct afs_vlocation *vlocation = source;
+       const struct afs_cache_vlocation *cvldb;
+       struct afs_vlocation *vlocation = cookie_netfs_data;
+       uint16_t dlen;
+
+       _enter("{%s},%p,%u", vlocation->vldb.name, buffer, buflen);
+
+       /* check the size of the data is what we're expecting */
+       dlen = sizeof(struct afs_cache_vlocation);
+       dlen -= offsetof(struct afs_cache_vlocation, nservers);
+       if (dlen != buflen)
+               return FSCACHE_CHECKAUX_OBSOLETE;
+
+       cvldb = container_of(buffer, struct afs_cache_vlocation, nservers);
 
-       _enter("");
+       /* if what's on disk is more valid than what's in memory, then use the
+        * VL record from the cache */
+       if (!vlocation->valid || vlocation->vldb.rtime == cvldb->rtime) {
+               memcpy((uint8_t *)&vlocation->vldb.nservers, buffer, dlen);
+               vlocation->valid = 1;
+               _leave(" = SUCCESS [c->m]");
+               return FSCACHE_CHECKAUX_OKAY;
+       }
+
+       /* need to update the cache if the cached info differs */
+       if (memcmp(&vlocation->vldb, buffer, dlen) != 0) {
+               /* delete if the volume IDs for this name differ */
+               if (memcmp(&vlocation->vldb.vid, &cvldb->vid,
+                          sizeof(cvldb->vid)) != 0
+                   ) {
+                       _leave(" = OBSOLETE");
+                       return FSCACHE_CHECKAUX_OBSOLETE;
+               }
+
+               _leave(" = UPDATE");
+               return FSCACHE_CHECKAUX_NEEDS_UPDATE;
+       }
 
-       *vldb = vlocation->vldb;
+       _leave(" = OKAY");
+       return FSCACHE_CHECKAUX_OKAY;
 
-} /* end afs_vlocation_cache_update() */
+} /* end afs_vlocation_cache_check_aux() */
 #endif