linux/fs/fscache/cookie.c
<<
>>
Prefs
   1/* netfs cookie management
   2 *
   3 * Copyright (C) 2004-2007 Red Hat, Inc. All Rights Reserved.
   4 * Written by David Howells (dhowells@redhat.com)
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the License, or (at your option) any later version.
  10 *
  11 * See Documentation/filesystems/caching/netfs-api.txt for more information on
  12 * the netfs API.
  13 */
  14
  15#define FSCACHE_DEBUG_LEVEL COOKIE
  16#include <linux/module.h>
  17#include <linux/slab.h>
  18#include "internal.h"
  19
  20struct kmem_cache *fscache_cookie_jar;
  21
  22static atomic_t fscache_object_debug_id = ATOMIC_INIT(0);
  23
  24static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie);
  25static int fscache_alloc_object(struct fscache_cache *cache,
  26                                struct fscache_cookie *cookie);
  27static int fscache_attach_object(struct fscache_cookie *cookie,
  28                                 struct fscache_object *object);
  29
  30/*
  31 * initialise an cookie jar slab element prior to any use
  32 */
  33void fscache_cookie_init_once(void *_cookie)
  34{
  35        struct fscache_cookie *cookie = _cookie;
  36
  37        memset(cookie, 0, sizeof(*cookie));
  38        spin_lock_init(&cookie->lock);
  39        spin_lock_init(&cookie->stores_lock);
  40        INIT_HLIST_HEAD(&cookie->backing_objects);
  41}
  42
  43/*
  44 * request a cookie to represent an object (index, datafile, xattr, etc)
  45 * - parent specifies the parent object
  46 *   - the top level index cookie for each netfs is stored in the fscache_netfs
  47 *     struct upon registration
  48 * - def points to the definition
  49 * - the netfs_data will be passed to the functions pointed to in *def
  50 * - all attached caches will be searched to see if they contain this object
  51 * - index objects aren't stored on disk until there's a dependent file that
  52 *   needs storing
  53 * - other objects are stored in a selected cache immediately, and all the
  54 *   indices forming the path to it are instantiated if necessary
  55 * - we never let on to the netfs about errors
  56 *   - we may set a negative cookie pointer, but that's okay
  57 */
  58struct fscache_cookie *__fscache_acquire_cookie(
  59        struct fscache_cookie *parent,
  60        const struct fscache_cookie_def *def,
  61        void *netfs_data)
  62{
  63        struct fscache_cookie *cookie;
  64
  65        BUG_ON(!def);
  66
  67        _enter("{%s},{%s},%p",
  68               parent ? (char *) parent->def->name : "<no-parent>",
  69               def->name, netfs_data);
  70
  71        fscache_stat(&fscache_n_acquires);
  72
  73        /* if there's no parent cookie, then we don't create one here either */
  74        if (!parent) {
  75                fscache_stat(&fscache_n_acquires_null);
  76                _leave(" [no parent]");
  77                return NULL;
  78        }
  79
  80        /* validate the definition */
  81        BUG_ON(!def->get_key);
  82        BUG_ON(!def->name[0]);
  83
  84        BUG_ON(def->type == FSCACHE_COOKIE_TYPE_INDEX &&
  85               parent->def->type != FSCACHE_COOKIE_TYPE_INDEX);
  86
  87        /* allocate and initialise a cookie */
  88        cookie = kmem_cache_alloc(fscache_cookie_jar, GFP_KERNEL);
  89        if (!cookie) {
  90                fscache_stat(&fscache_n_acquires_oom);
  91                _leave(" [ENOMEM]");
  92                return NULL;
  93        }
  94
  95        atomic_set(&cookie->usage, 1);
  96        atomic_set(&cookie->n_children, 0);
  97
  98        atomic_inc(&parent->usage);
  99        atomic_inc(&parent->n_children);
 100
 101        cookie->def             = def;
 102        cookie->parent          = parent;
 103        cookie->netfs_data      = netfs_data;
 104        cookie->flags           = 0;
 105
 106        /* radix tree insertion won't use the preallocation pool unless it's
 107         * told it may not wait */
 108        INIT_RADIX_TREE(&cookie->stores, GFP_NOFS & ~__GFP_WAIT);
 109
 110        switch (cookie->def->type) {
 111        case FSCACHE_COOKIE_TYPE_INDEX:
 112                fscache_stat(&fscache_n_cookie_index);
 113                break;
 114        case FSCACHE_COOKIE_TYPE_DATAFILE:
 115                fscache_stat(&fscache_n_cookie_data);
 116                break;
 117        default:
 118                fscache_stat(&fscache_n_cookie_special);
 119                break;
 120        }
 121
 122        /* if the object is an index then we need do nothing more here - we
 123         * create indices on disk when we need them as an index may exist in
 124         * multiple caches */
 125        if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) {
 126                if (fscache_acquire_non_index_cookie(cookie) < 0) {
 127                        atomic_dec(&parent->n_children);
 128                        __fscache_cookie_put(cookie);
 129                        fscache_stat(&fscache_n_acquires_nobufs);
 130                        _leave(" = NULL");
 131                        return NULL;
 132                }
 133        }
 134
 135        fscache_stat(&fscache_n_acquires_ok);
 136        _leave(" = %p", cookie);
 137        return cookie;
 138}
 139EXPORT_SYMBOL(__fscache_acquire_cookie);
 140
 141/*
 142 * acquire a non-index cookie
 143 * - this must make sure the index chain is instantiated and instantiate the
 144 *   object representation too
 145 */
 146static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie)
 147{
 148        struct fscache_object *object;
 149        struct fscache_cache *cache;
 150        uint64_t i_size;
 151        int ret;
 152
 153        _enter("");
 154
 155        cookie->flags = 1 << FSCACHE_COOKIE_UNAVAILABLE;
 156
 157        /* now we need to see whether the backing objects for this cookie yet
 158         * exist, if not there'll be nothing to search */
 159        down_read(&fscache_addremove_sem);
 160
 161        if (list_empty(&fscache_cache_list)) {
 162                up_read(&fscache_addremove_sem);
 163                _leave(" = 0 [no caches]");
 164                return 0;
 165        }
 166
 167        /* select a cache in which to store the object */
 168        cache = fscache_select_cache_for_object(cookie->parent);
 169        if (!cache) {
 170                up_read(&fscache_addremove_sem);
 171                fscache_stat(&fscache_n_acquires_no_cache);
 172                _leave(" = -ENOMEDIUM [no cache]");
 173                return -ENOMEDIUM;
 174        }
 175
 176        _debug("cache %s", cache->tag->name);
 177
 178        cookie->flags =
 179                (1 << FSCACHE_COOKIE_LOOKING_UP) |
 180                (1 << FSCACHE_COOKIE_CREATING) |
 181                (1 << FSCACHE_COOKIE_NO_DATA_YET);
 182
 183        /* ask the cache to allocate objects for this cookie and its parent
 184         * chain */
 185        ret = fscache_alloc_object(cache, cookie);
 186        if (ret < 0) {
 187                up_read(&fscache_addremove_sem);
 188                _leave(" = %d", ret);
 189                return ret;
 190        }
 191
 192        /* pass on how big the object we're caching is supposed to be */
 193        cookie->def->get_attr(cookie->netfs_data, &i_size);
 194
 195        spin_lock(&cookie->lock);
 196        if (hlist_empty(&cookie->backing_objects)) {
 197                spin_unlock(&cookie->lock);
 198                goto unavailable;
 199        }
 200
 201        object = hlist_entry(cookie->backing_objects.first,
 202                             struct fscache_object, cookie_link);
 203
 204        fscache_set_store_limit(object, i_size);
 205
 206        /* initiate the process of looking up all the objects in the chain
 207         * (done by fscache_initialise_object()) */
 208        fscache_enqueue_object(object);
 209
 210        spin_unlock(&cookie->lock);
 211
 212        /* we may be required to wait for lookup to complete at this point */
 213        if (!fscache_defer_lookup) {
 214                _debug("non-deferred lookup %p", &cookie->flags);
 215                wait_on_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP,
 216                            fscache_wait_bit, TASK_UNINTERRUPTIBLE);
 217                _debug("complete");
 218                if (test_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags))
 219                        goto unavailable;
 220        }
 221
 222        up_read(&fscache_addremove_sem);
 223        _leave(" = 0 [deferred]");
 224        return 0;
 225
 226unavailable:
 227        up_read(&fscache_addremove_sem);
 228        _leave(" = -ENOBUFS");
 229        return -ENOBUFS;
 230}
 231
 232/*
 233 * recursively allocate cache object records for a cookie/cache combination
 234 * - caller must be holding the addremove sem
 235 */
 236static int fscache_alloc_object(struct fscache_cache *cache,
 237                                struct fscache_cookie *cookie)
 238{
 239        struct fscache_object *object;
 240        int ret;
 241
 242        _enter("%p,%p{%s}", cache, cookie, cookie->def->name);
 243
 244        spin_lock(&cookie->lock);
 245        hlist_for_each_entry(object, &cookie->backing_objects,
 246                             cookie_link) {
 247                if (object->cache == cache)
 248                        goto object_already_extant;
 249        }
 250        spin_unlock(&cookie->lock);
 251
 252        /* ask the cache to allocate an object (we may end up with duplicate
 253         * objects at this stage, but we sort that out later) */
 254        fscache_stat(&fscache_n_cop_alloc_object);
 255        object = cache->ops->alloc_object(cache, cookie);
 256        fscache_stat_d(&fscache_n_cop_alloc_object);
 257        if (IS_ERR(object)) {
 258                fscache_stat(&fscache_n_object_no_alloc);
 259                ret = PTR_ERR(object);
 260                goto error;
 261        }
 262
 263        fscache_stat(&fscache_n_object_alloc);
 264
 265        object->debug_id = atomic_inc_return(&fscache_object_debug_id);
 266
 267        _debug("ALLOC OBJ%x: %s {%lx}",
 268               object->debug_id, cookie->def->name, object->events);
 269
 270        ret = fscache_alloc_object(cache, cookie->parent);
 271        if (ret < 0)
 272                goto error_put;
 273
 274        /* only attach if we managed to allocate all we needed, otherwise
 275         * discard the object we just allocated and instead use the one
 276         * attached to the cookie */
 277        if (fscache_attach_object(cookie, object) < 0) {
 278                fscache_stat(&fscache_n_cop_put_object);
 279                cache->ops->put_object(object);
 280                fscache_stat_d(&fscache_n_cop_put_object);
 281        }
 282
 283        _leave(" = 0");
 284        return 0;
 285
 286object_already_extant:
 287        ret = -ENOBUFS;
 288        if (object->state >= FSCACHE_OBJECT_DYING) {
 289                spin_unlock(&cookie->lock);
 290                goto error;
 291        }
 292        spin_unlock(&cookie->lock);
 293        _leave(" = 0 [found]");
 294        return 0;
 295
 296error_put:
 297        fscache_stat(&fscache_n_cop_put_object);
 298        cache->ops->put_object(object);
 299        fscache_stat_d(&fscache_n_cop_put_object);
 300error:
 301        _leave(" = %d", ret);
 302        return ret;
 303}
 304
 305/*
 306 * attach a cache object to a cookie
 307 */
 308static int fscache_attach_object(struct fscache_cookie *cookie,
 309                                 struct fscache_object *object)
 310{
 311        struct fscache_object *p;
 312        struct fscache_cache *cache = object->cache;
 313        int ret;
 314
 315        _enter("{%s},{OBJ%x}", cookie->def->name, object->debug_id);
 316
 317        spin_lock(&cookie->lock);
 318
 319        /* there may be multiple initial creations of this object, but we only
 320         * want one */
 321        ret = -EEXIST;
 322        hlist_for_each_entry(p, &cookie->backing_objects, cookie_link) {
 323                if (p->cache == object->cache) {
 324                        if (p->state >= FSCACHE_OBJECT_DYING)
 325                                ret = -ENOBUFS;
 326                        goto cant_attach_object;
 327                }
 328        }
 329
 330        /* pin the parent object */
 331        spin_lock_nested(&cookie->parent->lock, 1);
 332        hlist_for_each_entry(p, &cookie->parent->backing_objects,
 333                             cookie_link) {
 334                if (p->cache == object->cache) {
 335                        if (p->state >= FSCACHE_OBJECT_DYING) {
 336                                ret = -ENOBUFS;
 337                                spin_unlock(&cookie->parent->lock);
 338                                goto cant_attach_object;
 339                        }
 340                        object->parent = p;
 341                        spin_lock(&p->lock);
 342                        p->n_children++;
 343                        spin_unlock(&p->lock);
 344                        break;
 345                }
 346        }
 347        spin_unlock(&cookie->parent->lock);
 348
 349        /* attach to the cache's object list */
 350        if (list_empty(&object->cache_link)) {
 351                spin_lock(&cache->object_list_lock);
 352                list_add(&object->cache_link, &cache->object_list);
 353                spin_unlock(&cache->object_list_lock);
 354        }
 355
 356        /* attach to the cookie */
 357        object->cookie = cookie;
 358        atomic_inc(&cookie->usage);
 359        hlist_add_head(&object->cookie_link, &cookie->backing_objects);
 360
 361        fscache_objlist_add(object);
 362        ret = 0;
 363
 364cant_attach_object:
 365        spin_unlock(&cookie->lock);
 366        _leave(" = %d", ret);
 367        return ret;
 368}
 369
 370/*
 371 * Invalidate an object.  Callable with spinlocks held.
 372 */
 373void __fscache_invalidate(struct fscache_cookie *cookie)
 374{
 375        struct fscache_object *object;
 376
 377        _enter("{%s}", cookie->def->name);
 378
 379        fscache_stat(&fscache_n_invalidates);
 380
 381        /* Only permit invalidation of data files.  Invalidating an index will
 382         * require the caller to release all its attachments to the tree rooted
 383         * there, and if it's doing that, it may as well just retire the
 384         * cookie.
 385         */
 386        ASSERTCMP(cookie->def->type, ==, FSCACHE_COOKIE_TYPE_DATAFILE);
 387
 388        /* We will be updating the cookie too. */
 389        BUG_ON(!cookie->def->get_aux);
 390
 391        /* If there's an object, we tell the object state machine to handle the
 392         * invalidation on our behalf, otherwise there's nothing to do.
 393         */
 394        if (!hlist_empty(&cookie->backing_objects)) {
 395                spin_lock(&cookie->lock);
 396
 397                if (!hlist_empty(&cookie->backing_objects) &&
 398                    !test_and_set_bit(FSCACHE_COOKIE_INVALIDATING,
 399                                      &cookie->flags)) {
 400                        object = hlist_entry(cookie->backing_objects.first,
 401                                             struct fscache_object,
 402                                             cookie_link);
 403                        if (object->state < FSCACHE_OBJECT_DYING)
 404                                fscache_raise_event(
 405                                        object, FSCACHE_OBJECT_EV_INVALIDATE);
 406                }
 407
 408                spin_unlock(&cookie->lock);
 409        }
 410
 411        _leave("");
 412}
 413EXPORT_SYMBOL(__fscache_invalidate);
 414
 415/*
 416 * Wait for object invalidation to complete.
 417 */
 418void __fscache_wait_on_invalidate(struct fscache_cookie *cookie)
 419{
 420        _enter("%p", cookie);
 421
 422        wait_on_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING,
 423                    fscache_wait_bit_interruptible,
 424                    TASK_UNINTERRUPTIBLE);
 425
 426        _leave("");
 427}
 428EXPORT_SYMBOL(__fscache_wait_on_invalidate);
 429
 430/*
 431 * update the index entries backing a cookie
 432 */
 433void __fscache_update_cookie(struct fscache_cookie *cookie)
 434{
 435        struct fscache_object *object;
 436
 437        fscache_stat(&fscache_n_updates);
 438
 439        if (!cookie) {
 440                fscache_stat(&fscache_n_updates_null);
 441                _leave(" [no cookie]");
 442                return;
 443        }
 444
 445        _enter("{%s}", cookie->def->name);
 446
 447        BUG_ON(!cookie->def->get_aux);
 448
 449        spin_lock(&cookie->lock);
 450
 451        /* update the index entry on disk in each cache backing this cookie */
 452        hlist_for_each_entry(object,
 453                             &cookie->backing_objects, cookie_link) {
 454                fscache_raise_event(object, FSCACHE_OBJECT_EV_UPDATE);
 455        }
 456
 457        spin_unlock(&cookie->lock);
 458        _leave("");
 459}
 460EXPORT_SYMBOL(__fscache_update_cookie);
 461
 462/*
 463 * release a cookie back to the cache
 464 * - the object will be marked as recyclable on disk if retire is true
 465 * - all dependents of this cookie must have already been unregistered
 466 *   (indices/files/pages)
 467 */
 468void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
 469{
 470        struct fscache_cache *cache;
 471        struct fscache_object *object;
 472        unsigned long event;
 473
 474        fscache_stat(&fscache_n_relinquishes);
 475        if (retire)
 476                fscache_stat(&fscache_n_relinquishes_retire);
 477
 478        if (!cookie) {
 479                fscache_stat(&fscache_n_relinquishes_null);
 480                _leave(" [no cookie]");
 481                return;
 482        }
 483
 484        _enter("%p{%s,%p},%d",
 485               cookie, cookie->def->name, cookie->netfs_data, retire);
 486
 487        if (atomic_read(&cookie->n_children) != 0) {
 488                printk(KERN_ERR "FS-Cache: Cookie '%s' still has children\n",
 489                       cookie->def->name);
 490                BUG();
 491        }
 492
 493        /* wait for the cookie to finish being instantiated (or to fail) */
 494        if (test_bit(FSCACHE_COOKIE_CREATING, &cookie->flags)) {
 495                fscache_stat(&fscache_n_relinquishes_waitcrt);
 496                wait_on_bit(&cookie->flags, FSCACHE_COOKIE_CREATING,
 497                            fscache_wait_bit, TASK_UNINTERRUPTIBLE);
 498        }
 499
 500        event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE;
 501
 502try_again:
 503        spin_lock(&cookie->lock);
 504
 505        /* break links with all the active objects */
 506        while (!hlist_empty(&cookie->backing_objects)) {
 507                int n_reads;
 508                object = hlist_entry(cookie->backing_objects.first,
 509                                     struct fscache_object,
 510                                     cookie_link);
 511
 512                _debug("RELEASE OBJ%x", object->debug_id);
 513
 514                set_bit(FSCACHE_COOKIE_WAITING_ON_READS, &cookie->flags);
 515                n_reads = atomic_read(&object->n_reads);
 516                if (n_reads) {
 517                        int n_ops = object->n_ops;
 518                        int n_in_progress = object->n_in_progress;
 519                        spin_unlock(&cookie->lock);
 520                        printk(KERN_ERR "FS-Cache:"
 521                               " Cookie '%s' still has %d outstanding reads (%d,%d)\n",
 522                               cookie->def->name,
 523                               n_reads, n_ops, n_in_progress);
 524                        wait_on_bit(&cookie->flags, FSCACHE_COOKIE_WAITING_ON_READS,
 525                                    fscache_wait_bit, TASK_UNINTERRUPTIBLE);
 526                        printk("Wait finished\n");
 527                        goto try_again;
 528                }
 529
 530                /* detach each cache object from the object cookie */
 531                spin_lock(&object->lock);
 532                hlist_del_init(&object->cookie_link);
 533
 534                cache = object->cache;
 535                object->cookie = NULL;
 536                fscache_raise_event(object, event);
 537                spin_unlock(&object->lock);
 538
 539                if (atomic_dec_and_test(&cookie->usage))
 540                        /* the cookie refcount shouldn't be reduced to 0 yet */
 541                        BUG();
 542        }
 543
 544        /* detach pointers back to the netfs */
 545        cookie->netfs_data      = NULL;
 546        cookie->def             = NULL;
 547
 548        spin_unlock(&cookie->lock);
 549
 550        if (cookie->parent) {
 551                ASSERTCMP(atomic_read(&cookie->parent->usage), >, 0);
 552                ASSERTCMP(atomic_read(&cookie->parent->n_children), >, 0);
 553                atomic_dec(&cookie->parent->n_children);
 554        }
 555
 556        /* finally dispose of the cookie */
 557        ASSERTCMP(atomic_read(&cookie->usage), >, 0);
 558        fscache_cookie_put(cookie);
 559
 560        _leave("");
 561}
 562EXPORT_SYMBOL(__fscache_relinquish_cookie);
 563
 564/*
 565 * destroy a cookie
 566 */
 567void __fscache_cookie_put(struct fscache_cookie *cookie)
 568{
 569        struct fscache_cookie *parent;
 570
 571        _enter("%p", cookie);
 572
 573        for (;;) {
 574                _debug("FREE COOKIE %p", cookie);
 575                parent = cookie->parent;
 576                BUG_ON(!hlist_empty(&cookie->backing_objects));
 577                kmem_cache_free(fscache_cookie_jar, cookie);
 578
 579                if (!parent)
 580                        break;
 581
 582                cookie = parent;
 583                BUG_ON(atomic_read(&cookie->usage) <= 0);
 584                if (!atomic_dec_and_test(&cookie->usage))
 585                        break;
 586        }
 587
 588        _leave("");
 589}
 590