LCOV - code coverage report
Current view: top level - fs - mbcache.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 3 162 1.9 %
Date: 2014-02-18 Functions: 1 17 5.9 %
Branches: 2 92 2.2 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * linux/fs/mbcache.c
       3                 :            :  * (C) 2001-2002 Andreas Gruenbacher, <a.gruenbacher@computer.org>
       4                 :            :  */
       5                 :            : 
       6                 :            : /*
       7                 :            :  * Filesystem Meta Information Block Cache (mbcache)
       8                 :            :  *
       9                 :            :  * The mbcache caches blocks of block devices that need to be located
      10                 :            :  * by their device/block number, as well as by other criteria (such
      11                 :            :  * as the block's contents).
      12                 :            :  *
      13                 :            :  * There can only be one cache entry in a cache per device and block number.
      14                 :            :  * Additional indexes need not be unique in this sense. The number of
      15                 :            :  * additional indexes (=other criteria) can be hardwired at compile time
      16                 :            :  * or specified at cache create time.
      17                 :            :  *
      18                 :            :  * Each cache entry is of fixed size. An entry may be `valid' or `invalid'
      19                 :            :  * in the cache. A valid entry is in the main hash tables of the cache,
      20                 :            :  * and may also be in the lru list. An invalid entry is not in any hashes
      21                 :            :  * or lists.
      22                 :            :  *
      23                 :            :  * A valid cache entry is only in the lru list if no handles refer to it.
      24                 :            :  * Invalid cache entries will be freed when the last handle to the cache
      25                 :            :  * entry is released. Entries that cannot be freed immediately are put
      26                 :            :  * back on the lru list.
      27                 :            :  */
      28                 :            : 
      29                 :            : #include <linux/kernel.h>
      30                 :            : #include <linux/module.h>
      31                 :            : 
      32                 :            : #include <linux/hash.h>
      33                 :            : #include <linux/fs.h>
      34                 :            : #include <linux/mm.h>
      35                 :            : #include <linux/slab.h>
      36                 :            : #include <linux/sched.h>
      37                 :            : #include <linux/init.h>
      38                 :            : #include <linux/mbcache.h>
      39                 :            : 
      40                 :            : 
      41                 :            : #ifdef MB_CACHE_DEBUG
      42                 :            : # define mb_debug(f...) do { \
      43                 :            :                 printk(KERN_DEBUG f); \
      44                 :            :                 printk("\n"); \
      45                 :            :         } while (0)
      46                 :            : #define mb_assert(c) do { if (!(c)) \
      47                 :            :                 printk(KERN_ERR "assertion " #c " failed\n"); \
      48                 :            :         } while(0)
      49                 :            : #else
      50                 :            : # define mb_debug(f...) do { } while(0)
      51                 :            : # define mb_assert(c) do { } while(0)
      52                 :            : #endif
      53                 :            : #define mb_error(f...) do { \
      54                 :            :                 printk(KERN_ERR f); \
      55                 :            :                 printk("\n"); \
      56                 :            :         } while(0)
      57                 :            : 
      58                 :            : #define MB_CACHE_WRITER ((unsigned short)~0U >> 1)
      59                 :            : 
      60                 :            : static DECLARE_WAIT_QUEUE_HEAD(mb_cache_queue);
      61                 :            :                 
      62                 :            : MODULE_AUTHOR("Andreas Gruenbacher <a.gruenbacher@computer.org>");
      63                 :            : MODULE_DESCRIPTION("Meta block cache (for extended attributes)");
      64                 :            : MODULE_LICENSE("GPL");
      65                 :            : 
      66                 :            : EXPORT_SYMBOL(mb_cache_create);
      67                 :            : EXPORT_SYMBOL(mb_cache_shrink);
      68                 :            : EXPORT_SYMBOL(mb_cache_destroy);
      69                 :            : EXPORT_SYMBOL(mb_cache_entry_alloc);
      70                 :            : EXPORT_SYMBOL(mb_cache_entry_insert);
      71                 :            : EXPORT_SYMBOL(mb_cache_entry_release);
      72                 :            : EXPORT_SYMBOL(mb_cache_entry_free);
      73                 :            : EXPORT_SYMBOL(mb_cache_entry_get);
      74                 :            : #if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
      75                 :            : EXPORT_SYMBOL(mb_cache_entry_find_first);
      76                 :            : EXPORT_SYMBOL(mb_cache_entry_find_next);
      77                 :            : #endif
      78                 :            : 
      79                 :            : /*
      80                 :            :  * Global data: list of all mbcache's, lru list, and a spinlock for
      81                 :            :  * accessing cache data structures on SMP machines. The lru list is
      82                 :            :  * global across all mbcaches.
      83                 :            :  */
      84                 :            : 
      85                 :            : static LIST_HEAD(mb_cache_list);
      86                 :            : static LIST_HEAD(mb_cache_lru_list);
      87                 :            : static DEFINE_SPINLOCK(mb_cache_spinlock);
      88                 :            : 
      89                 :            : static inline int
      90                 :            : __mb_cache_entry_is_hashed(struct mb_cache_entry *ce)
      91                 :            : {
      92                 :          0 :         return !list_empty(&ce->e_block_list);
      93                 :            : }
      94                 :            : 
      95                 :            : 
      96                 :            : static void
      97                 :            : __mb_cache_entry_unhash(struct mb_cache_entry *ce)
      98                 :            : {
      99 [ #  # ][ #  # ]:          0 :         if (__mb_cache_entry_is_hashed(ce)) {
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     100                 :            :                 list_del_init(&ce->e_block_list);
     101                 :            :                 list_del(&ce->e_index.o_list);
     102                 :            :         }
     103                 :            : }
     104                 :            : 
     105                 :            : 
     106                 :            : static void
     107                 :          0 : __mb_cache_entry_forget(struct mb_cache_entry *ce, gfp_t gfp_mask)
     108                 :            : {
     109                 :          0 :         struct mb_cache *cache = ce->e_cache;
     110                 :            : 
     111                 :            :         mb_assert(!(ce->e_used || ce->e_queued));
     112                 :          0 :         kmem_cache_free(cache->c_entry_cache, ce);
     113                 :          0 :         atomic_dec(&cache->c_entry_count);
     114                 :          0 : }
     115                 :            : 
     116                 :            : 
     117                 :            : static void
     118                 :          0 : __mb_cache_entry_release_unlock(struct mb_cache_entry *ce)
     119                 :            :         __releases(mb_cache_spinlock)
     120                 :            : {
     121                 :            :         /* Wake up all processes queuing for this cache entry. */
     122         [ #  # ]:          0 :         if (ce->e_queued)
     123                 :          0 :                 wake_up_all(&mb_cache_queue);
     124         [ #  # ]:          0 :         if (ce->e_used >= MB_CACHE_WRITER)
     125                 :          0 :                 ce->e_used -= MB_CACHE_WRITER;
     126                 :          0 :         ce->e_used--;
     127         [ #  # ]:          0 :         if (!(ce->e_used || ce->e_queued)) {
     128         [ #  # ]:          0 :                 if (!__mb_cache_entry_is_hashed(ce))
     129                 :            :                         goto forget;
     130                 :            :                 mb_assert(list_empty(&ce->e_lru_list));
     131                 :          0 :                 list_add_tail(&ce->e_lru_list, &mb_cache_lru_list);
     132                 :            :         }
     133                 :            :         spin_unlock(&mb_cache_spinlock);
     134                 :          0 :         return;
     135                 :            : forget:
     136                 :            :         spin_unlock(&mb_cache_spinlock);
     137                 :          0 :         __mb_cache_entry_forget(ce, GFP_KERNEL);
     138                 :            : }
     139                 :            : 
     140                 :            : 
     141                 :            : /*
     142                 :            :  * mb_cache_shrink_scan()  memory pressure callback
     143                 :            :  *
     144                 :            :  * This function is called by the kernel memory management when memory
     145                 :            :  * gets low.
     146                 :            :  *
     147                 :            :  * @shrink: (ignored)
     148                 :            :  * @sc: shrink_control passed from reclaim
     149                 :            :  *
     150                 :            :  * Returns the number of objects freed.
     151                 :            :  */
     152                 :            : static unsigned long
     153                 :          0 : mb_cache_shrink_scan(struct shrinker *shrink, struct shrink_control *sc)
     154                 :            : {
     155                 :          0 :         LIST_HEAD(free_list);
     156                 :            :         struct mb_cache_entry *entry, *tmp;
     157                 :          0 :         int nr_to_scan = sc->nr_to_scan;
     158                 :            :         gfp_t gfp_mask = sc->gfp_mask;
     159                 :            :         unsigned long freed = 0;
     160                 :            : 
     161                 :            :         mb_debug("trying to free %d entries", nr_to_scan);
     162                 :            :         spin_lock(&mb_cache_spinlock);
     163 [ #  # ][ #  # ]:          0 :         while (nr_to_scan-- && !list_empty(&mb_cache_lru_list)) {
     164                 :            :                 struct mb_cache_entry *ce =
     165                 :            :                         list_entry(mb_cache_lru_list.next,
     166                 :            :                                    struct mb_cache_entry, e_lru_list);
     167                 :          0 :                 list_move_tail(&ce->e_lru_list, &free_list);
     168                 :            :                 __mb_cache_entry_unhash(ce);
     169                 :          0 :                 freed++;
     170                 :            :         }
     171                 :            :         spin_unlock(&mb_cache_spinlock);
     172         [ #  # ]:          0 :         list_for_each_entry_safe(entry, tmp, &free_list, e_lru_list) {
     173                 :          0 :                 __mb_cache_entry_forget(entry, gfp_mask);
     174                 :            :         }
     175                 :          0 :         return freed;
     176                 :            : }
     177                 :            : 
     178                 :            : static unsigned long
     179                 :          0 : mb_cache_shrink_count(struct shrinker *shrink, struct shrink_control *sc)
     180                 :            : {
     181                 :            :         struct mb_cache *cache;
     182                 :            :         unsigned long count = 0;
     183                 :            : 
     184                 :            :         spin_lock(&mb_cache_spinlock);
     185         [ +  + ]:    2960435 :         list_for_each_entry(cache, &mb_cache_list, c_cache_list) {
     186                 :            :                 mb_debug("cache %s (%d)", cache->c_name,
     187                 :            :                           atomic_read(&cache->c_entry_count));
     188                 :    1480242 :                 count += atomic_read(&cache->c_entry_count);
     189                 :            :         }
     190                 :            :         spin_unlock(&mb_cache_spinlock);
     191                 :            : 
     192                 :     740121 :         return vfs_pressure_ratio(count);
     193                 :            : }
     194                 :            : 
     195                 :            : static struct shrinker mb_cache_shrinker = {
     196                 :            :         .count_objects = mb_cache_shrink_count,
     197                 :            :         .scan_objects = mb_cache_shrink_scan,
     198                 :            :         .seeks = DEFAULT_SEEKS,
     199                 :            : };
     200                 :            : 
     201                 :            : /*
     202                 :            :  * mb_cache_create()  create a new cache
     203                 :            :  *
     204                 :            :  * All entries in one cache are equal size. Cache entries may be from
     205                 :            :  * multiple devices. If this is the first mbcache created, registers
     206                 :            :  * the cache with kernel memory management. Returns NULL if no more
     207                 :            :  * memory was available.
     208                 :            :  *
     209                 :            :  * @name: name of the cache (informal)
     210                 :            :  * @bucket_bits: log2(number of hash buckets)
     211                 :            :  */
     212                 :            : struct mb_cache *
     213                 :          0 : mb_cache_create(const char *name, int bucket_bits)
     214                 :            : {
     215                 :          0 :         int n, bucket_count = 1 << bucket_bits;
     216                 :            :         struct mb_cache *cache = NULL;
     217                 :            : 
     218                 :            :         cache = kmalloc(sizeof(struct mb_cache), GFP_KERNEL);
     219         [ #  # ]:          0 :         if (!cache)
     220                 :            :                 return NULL;
     221                 :          0 :         cache->c_name = name;
     222                 :          0 :         atomic_set(&cache->c_entry_count, 0);
     223                 :          0 :         cache->c_bucket_bits = bucket_bits;
     224                 :          0 :         cache->c_block_hash = kmalloc(bucket_count * sizeof(struct list_head),
     225                 :            :                                       GFP_KERNEL);
     226         [ #  # ]:          0 :         if (!cache->c_block_hash)
     227                 :            :                 goto fail;
     228         [ #  # ]:          0 :         for (n=0; n<bucket_count; n++)
     229                 :          0 :                 INIT_LIST_HEAD(&cache->c_block_hash[n]);
     230                 :          0 :         cache->c_index_hash = kmalloc(bucket_count * sizeof(struct list_head),
     231                 :            :                                       GFP_KERNEL);
     232         [ #  # ]:          0 :         if (!cache->c_index_hash)
     233                 :            :                 goto fail;
     234         [ #  # ]:          0 :         for (n=0; n<bucket_count; n++)
     235                 :          0 :                 INIT_LIST_HEAD(&cache->c_index_hash[n]);
     236                 :          0 :         cache->c_entry_cache = kmem_cache_create(name,
     237                 :            :                 sizeof(struct mb_cache_entry), 0,
     238                 :            :                 SLAB_RECLAIM_ACCOUNT|SLAB_MEM_SPREAD, NULL);
     239         [ #  # ]:          0 :         if (!cache->c_entry_cache)
     240                 :            :                 goto fail2;
     241                 :            : 
     242                 :            :         /*
     243                 :            :          * Set an upper limit on the number of cache entries so that the hash
     244                 :            :          * chains won't grow too long.
     245                 :            :          */
     246                 :          0 :         cache->c_max_entries = bucket_count << 4;
     247                 :            : 
     248                 :            :         spin_lock(&mb_cache_spinlock);
     249                 :          0 :         list_add(&cache->c_cache_list, &mb_cache_list);
     250                 :            :         spin_unlock(&mb_cache_spinlock);
     251                 :          0 :         return cache;
     252                 :            : 
     253                 :            : fail2:
     254                 :          0 :         kfree(cache->c_index_hash);
     255                 :            : 
     256                 :            : fail:
     257                 :          0 :         kfree(cache->c_block_hash);
     258                 :          0 :         kfree(cache);
     259                 :          0 :         return NULL;
     260                 :            : }
     261                 :            : 
     262                 :            : 
     263                 :            : /*
     264                 :            :  * mb_cache_shrink()
     265                 :            :  *
     266                 :            :  * Removes all cache entries of a device from the cache. All cache entries
     267                 :            :  * currently in use cannot be freed, and thus remain in the cache. All others
     268                 :            :  * are freed.
     269                 :            :  *
     270                 :            :  * @bdev: which device's cache entries to shrink
     271                 :            :  */
     272                 :            : void
     273                 :          0 : mb_cache_shrink(struct block_device *bdev)
     274                 :            : {
     275                 :          0 :         LIST_HEAD(free_list);
     276                 :            :         struct list_head *l, *ltmp;
     277                 :            : 
     278                 :            :         spin_lock(&mb_cache_spinlock);
     279         [ #  # ]:          0 :         list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
     280                 :            :                 struct mb_cache_entry *ce =
     281                 :            :                         list_entry(l, struct mb_cache_entry, e_lru_list);
     282         [ #  # ]:          0 :                 if (ce->e_bdev == bdev) {
     283                 :          0 :                         list_move_tail(&ce->e_lru_list, &free_list);
     284                 :            :                         __mb_cache_entry_unhash(ce);
     285                 :            :                 }
     286                 :            :         }
     287                 :            :         spin_unlock(&mb_cache_spinlock);
     288         [ #  # ]:          0 :         list_for_each_safe(l, ltmp, &free_list) {
     289                 :          0 :                 __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
     290                 :            :                                                    e_lru_list), GFP_KERNEL);
     291                 :            :         }
     292                 :          0 : }
     293                 :            : 
     294                 :            : 
     295                 :            : /*
     296                 :            :  * mb_cache_destroy()
     297                 :            :  *
     298                 :            :  * Shrinks the cache to its minimum possible size (hopefully 0 entries),
     299                 :            :  * and then destroys it. If this was the last mbcache, un-registers the
     300                 :            :  * mbcache from kernel memory management.
     301                 :            :  */
     302                 :            : void
     303                 :          0 : mb_cache_destroy(struct mb_cache *cache)
     304                 :            : {
     305                 :          0 :         LIST_HEAD(free_list);
     306                 :            :         struct list_head *l, *ltmp;
     307                 :            : 
     308                 :            :         spin_lock(&mb_cache_spinlock);
     309         [ #  # ]:          0 :         list_for_each_safe(l, ltmp, &mb_cache_lru_list) {
     310                 :            :                 struct mb_cache_entry *ce =
     311                 :            :                         list_entry(l, struct mb_cache_entry, e_lru_list);
     312         [ #  # ]:          0 :                 if (ce->e_cache == cache) {
     313                 :          0 :                         list_move_tail(&ce->e_lru_list, &free_list);
     314                 :            :                         __mb_cache_entry_unhash(ce);
     315                 :            :                 }
     316                 :            :         }
     317                 :            :         list_del(&cache->c_cache_list);
     318                 :            :         spin_unlock(&mb_cache_spinlock);
     319                 :            : 
     320         [ #  # ]:          0 :         list_for_each_safe(l, ltmp, &free_list) {
     321                 :          0 :                 __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry,
     322                 :            :                                                    e_lru_list), GFP_KERNEL);
     323                 :            :         }
     324                 :            : 
     325         [ #  # ]:          0 :         if (atomic_read(&cache->c_entry_count) > 0) {
     326                 :          0 :                 mb_error("cache %s: %d orphaned entries",
     327                 :            :                           cache->c_name,
     328                 :            :                           atomic_read(&cache->c_entry_count));
     329                 :            :         }
     330                 :            : 
     331                 :          0 :         kmem_cache_destroy(cache->c_entry_cache);
     332                 :            : 
     333                 :          0 :         kfree(cache->c_index_hash);
     334                 :          0 :         kfree(cache->c_block_hash);
     335                 :          0 :         kfree(cache);
     336                 :          0 : }
     337                 :            : 
     338                 :            : /*
     339                 :            :  * mb_cache_entry_alloc()
     340                 :            :  *
     341                 :            :  * Allocates a new cache entry. The new entry will not be valid initially,
     342                 :            :  * and thus cannot be looked up yet. It should be filled with data, and
     343                 :            :  * then inserted into the cache using mb_cache_entry_insert(). Returns NULL
     344                 :            :  * if no more memory was available.
     345                 :            :  */
     346                 :            : struct mb_cache_entry *
     347                 :          0 : mb_cache_entry_alloc(struct mb_cache *cache, gfp_t gfp_flags)
     348                 :            : {
     349                 :            :         struct mb_cache_entry *ce = NULL;
     350                 :            : 
     351         [ #  # ]:          0 :         if (atomic_read(&cache->c_entry_count) >= cache->c_max_entries) {
     352                 :            :                 spin_lock(&mb_cache_spinlock);
     353         [ #  # ]:          0 :                 if (!list_empty(&mb_cache_lru_list)) {
     354                 :            :                         ce = list_entry(mb_cache_lru_list.next,
     355                 :            :                                         struct mb_cache_entry, e_lru_list);
     356                 :          0 :                         list_del_init(&ce->e_lru_list);
     357                 :            :                         __mb_cache_entry_unhash(ce);
     358                 :            :                 }
     359                 :            :                 spin_unlock(&mb_cache_spinlock);
     360                 :            :         }
     361         [ #  # ]:          0 :         if (!ce) {
     362                 :          0 :                 ce = kmem_cache_alloc(cache->c_entry_cache, gfp_flags);
     363         [ #  # ]:          0 :                 if (!ce)
     364                 :            :                         return NULL;
     365                 :          0 :                 atomic_inc(&cache->c_entry_count);
     366                 :          0 :                 INIT_LIST_HEAD(&ce->e_lru_list);
     367                 :          0 :                 INIT_LIST_HEAD(&ce->e_block_list);
     368                 :          0 :                 ce->e_cache = cache;
     369                 :          0 :                 ce->e_queued = 0;
     370                 :            :         }
     371                 :          0 :         ce->e_used = 1 + MB_CACHE_WRITER;
     372                 :          0 :         return ce;
     373                 :            : }
     374                 :            : 
     375                 :            : 
     376                 :            : /*
     377                 :            :  * mb_cache_entry_insert()
     378                 :            :  *
     379                 :            :  * Inserts an entry that was allocated using mb_cache_entry_alloc() into
     380                 :            :  * the cache. After this, the cache entry can be looked up, but is not yet
     381                 :            :  * in the lru list as the caller still holds a handle to it. Returns 0 on
     382                 :            :  * success, or -EBUSY if a cache entry for that device + inode exists
     383                 :            :  * already (this may happen after a failed lookup, but when another process
     384                 :            :  * has inserted the same cache entry in the meantime).
     385                 :            :  *
     386                 :            :  * @bdev: device the cache entry belongs to
     387                 :            :  * @block: block number
     388                 :            :  * @key: lookup key
     389                 :            :  */
     390                 :            : int
     391                 :          0 : mb_cache_entry_insert(struct mb_cache_entry *ce, struct block_device *bdev,
     392                 :            :                       sector_t block, unsigned int key)
     393                 :            : {
     394                 :          0 :         struct mb_cache *cache = ce->e_cache;
     395                 :            :         unsigned int bucket;
     396                 :            :         struct list_head *l;
     397                 :            :         int error = -EBUSY;
     398                 :            : 
     399                 :          0 :         bucket = hash_long((unsigned long)bdev + (block & 0xffffffff), 
     400                 :            :                            cache->c_bucket_bits);
     401                 :            :         spin_lock(&mb_cache_spinlock);
     402         [ #  # ]:          0 :         list_for_each_prev(l, &cache->c_block_hash[bucket]) {
     403                 :            :                 struct mb_cache_entry *ce =
     404                 :            :                         list_entry(l, struct mb_cache_entry, e_block_list);
     405 [ #  # ][ #  # ]:          0 :                 if (ce->e_bdev == bdev && ce->e_block == block)
     406                 :            :                         goto out;
     407                 :            :         }
     408                 :            :         __mb_cache_entry_unhash(ce);
     409                 :          0 :         ce->e_bdev = bdev;
     410                 :          0 :         ce->e_block = block;
     411                 :          0 :         list_add(&ce->e_block_list, &cache->c_block_hash[bucket]);
     412                 :          0 :         ce->e_index.o_key = key;
     413                 :          0 :         bucket = hash_long(key, cache->c_bucket_bits);
     414                 :          0 :         list_add(&ce->e_index.o_list, &cache->c_index_hash[bucket]);
     415                 :            :         error = 0;
     416                 :            : out:
     417                 :            :         spin_unlock(&mb_cache_spinlock);
     418                 :          0 :         return error;
     419                 :            : }
     420                 :            : 
     421                 :            : 
     422                 :            : /*
     423                 :            :  * mb_cache_entry_release()
     424                 :            :  *
     425                 :            :  * Release a handle to a cache entry. When the last handle to a cache entry
     426                 :            :  * is released it is either freed (if it is invalid) or otherwise inserted
     427                 :            :  * in to the lru list.
     428                 :            :  */
     429                 :            : void
     430                 :          0 : mb_cache_entry_release(struct mb_cache_entry *ce)
     431                 :            : {
     432                 :            :         spin_lock(&mb_cache_spinlock);
     433                 :          0 :         __mb_cache_entry_release_unlock(ce);
     434                 :          0 : }
     435                 :            : 
     436                 :            : 
     437                 :            : /*
     438                 :            :  * mb_cache_entry_free()
     439                 :            :  *
     440                 :            :  * This is equivalent to the sequence mb_cache_entry_takeout() --
     441                 :            :  * mb_cache_entry_release().
     442                 :            :  */
     443                 :            : void
     444                 :          0 : mb_cache_entry_free(struct mb_cache_entry *ce)
     445                 :            : {
     446                 :            :         spin_lock(&mb_cache_spinlock);
     447                 :            :         mb_assert(list_empty(&ce->e_lru_list));
     448                 :            :         __mb_cache_entry_unhash(ce);
     449                 :          0 :         __mb_cache_entry_release_unlock(ce);
     450                 :          0 : }
     451                 :            : 
     452                 :            : 
     453                 :            : /*
     454                 :            :  * mb_cache_entry_get()
     455                 :            :  *
     456                 :            :  * Get a cache entry  by device / block number. (There can only be one entry
     457                 :            :  * in the cache per device and block.) Returns NULL if no such cache entry
     458                 :            :  * exists. The returned cache entry is locked for exclusive access ("single
     459                 :            :  * writer").
     460                 :            :  */
     461                 :            : struct mb_cache_entry *
     462                 :          0 : mb_cache_entry_get(struct mb_cache *cache, struct block_device *bdev,
     463                 :            :                    sector_t block)
     464                 :            : {
     465                 :            :         unsigned int bucket;
     466                 :            :         struct list_head *l;
     467                 :            :         struct mb_cache_entry *ce;
     468                 :            : 
     469                 :          0 :         bucket = hash_long((unsigned long)bdev + (block & 0xffffffff),
     470                 :            :                            cache->c_bucket_bits);
     471                 :            :         spin_lock(&mb_cache_spinlock);
     472         [ #  # ]:          0 :         list_for_each(l, &cache->c_block_hash[bucket]) {
     473                 :          0 :                 ce = list_entry(l, struct mb_cache_entry, e_block_list);
     474 [ #  # ][ #  # ]:          0 :                 if (ce->e_bdev == bdev && ce->e_block == block) {
     475                 :          0 :                         DEFINE_WAIT(wait);
     476                 :            : 
     477         [ #  # ]:          0 :                         if (!list_empty(&ce->e_lru_list))
     478                 :            :                                 list_del_init(&ce->e_lru_list);
     479                 :            : 
     480         [ #  # ]:          0 :                         while (ce->e_used > 0) {
     481                 :          0 :                                 ce->e_queued++;
     482                 :          0 :                                 prepare_to_wait(&mb_cache_queue, &wait,
     483                 :            :                                                 TASK_UNINTERRUPTIBLE);
     484                 :            :                                 spin_unlock(&mb_cache_spinlock);
     485                 :          0 :                                 schedule();
     486                 :            :                                 spin_lock(&mb_cache_spinlock);
     487                 :          0 :                                 ce->e_queued--;
     488                 :            :                         }
     489                 :          0 :                         finish_wait(&mb_cache_queue, &wait);
     490                 :          0 :                         ce->e_used += 1 + MB_CACHE_WRITER;
     491                 :            : 
     492         [ #  # ]:          0 :                         if (!__mb_cache_entry_is_hashed(ce)) {
     493                 :          0 :                                 __mb_cache_entry_release_unlock(ce);
     494                 :          0 :                                 return NULL;
     495                 :            :                         }
     496                 :          0 :                         goto cleanup;
     497                 :            :                 }
     498                 :            :         }
     499                 :            :         ce = NULL;
     500                 :            : 
     501                 :            : cleanup:
     502                 :            :         spin_unlock(&mb_cache_spinlock);
     503                 :          0 :         return ce;
     504                 :            : }
     505                 :            : 
     506                 :            : #if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0)
     507                 :            : 
     508                 :            : static struct mb_cache_entry *
     509                 :          0 : __mb_cache_entry_find(struct list_head *l, struct list_head *head,
     510                 :            :                       struct block_device *bdev, unsigned int key)
     511                 :            : {
     512         [ #  # ]:          0 :         while (l != head) {
     513                 :          0 :                 struct mb_cache_entry *ce =
     514                 :            :                         list_entry(l, struct mb_cache_entry, e_index.o_list);
     515 [ #  # ][ #  # ]:          0 :                 if (ce->e_bdev == bdev && ce->e_index.o_key == key) {
     516                 :          0 :                         DEFINE_WAIT(wait);
     517                 :            : 
     518         [ #  # ]:          0 :                         if (!list_empty(&ce->e_lru_list))
     519                 :            :                                 list_del_init(&ce->e_lru_list);
     520                 :            : 
     521                 :            :                         /* Incrementing before holding the lock gives readers
     522                 :            :                            priority over writers. */
     523                 :          0 :                         ce->e_used++;
     524         [ #  # ]:          0 :                         while (ce->e_used >= MB_CACHE_WRITER) {
     525                 :          0 :                                 ce->e_queued++;
     526                 :          0 :                                 prepare_to_wait(&mb_cache_queue, &wait,
     527                 :            :                                                 TASK_UNINTERRUPTIBLE);
     528                 :            :                                 spin_unlock(&mb_cache_spinlock);
     529                 :          0 :                                 schedule();
     530                 :            :                                 spin_lock(&mb_cache_spinlock);
     531                 :          0 :                                 ce->e_queued--;
     532                 :            :                         }
     533                 :          0 :                         finish_wait(&mb_cache_queue, &wait);
     534                 :            : 
     535         [ #  # ]:          0 :                         if (!__mb_cache_entry_is_hashed(ce)) {
     536                 :          0 :                                 __mb_cache_entry_release_unlock(ce);
     537                 :            :                                 spin_lock(&mb_cache_spinlock);
     538                 :          0 :                                 return ERR_PTR(-EAGAIN);
     539                 :            :                         }
     540                 :            :                         return ce;
     541                 :            :                 }
     542                 :          0 :                 l = l->next;
     543                 :            :         }
     544                 :            :         return NULL;
     545                 :            : }
     546                 :            : 
     547                 :            : 
     548                 :            : /*
     549                 :            :  * mb_cache_entry_find_first()
     550                 :            :  *
     551                 :            :  * Find the first cache entry on a given device with a certain key in
     552                 :            :  * an additional index. Additional matches can be found with
     553                 :            :  * mb_cache_entry_find_next(). Returns NULL if no match was found. The
     554                 :            :  * returned cache entry is locked for shared access ("multiple readers").
     555                 :            :  *
     556                 :            :  * @cache: the cache to search
     557                 :            :  * @bdev: the device the cache entry should belong to
     558                 :            :  * @key: the key in the index
     559                 :            :  */
     560                 :            : struct mb_cache_entry *
     561                 :          0 : mb_cache_entry_find_first(struct mb_cache *cache, struct block_device *bdev,
     562                 :            :                           unsigned int key)
     563                 :            : {
     564                 :          0 :         unsigned int bucket = hash_long(key, cache->c_bucket_bits);
     565                 :            :         struct list_head *l;
     566                 :            :         struct mb_cache_entry *ce;
     567                 :            : 
     568                 :            :         spin_lock(&mb_cache_spinlock);
     569                 :          0 :         l = cache->c_index_hash[bucket].next;
     570                 :          0 :         ce = __mb_cache_entry_find(l, &cache->c_index_hash[bucket], bdev, key);
     571                 :            :         spin_unlock(&mb_cache_spinlock);
     572                 :          0 :         return ce;
     573                 :            : }
     574                 :            : 
     575                 :            : 
     576                 :            : /*
     577                 :            :  * mb_cache_entry_find_next()
     578                 :            :  *
     579                 :            :  * Find the next cache entry on a given device with a certain key in an
     580                 :            :  * additional index. Returns NULL if no match could be found. The previous
     581                 :            :  * entry is atomatically released, so that mb_cache_entry_find_next() can
     582                 :            :  * be called like this:
     583                 :            :  *
     584                 :            :  * entry = mb_cache_entry_find_first();
     585                 :            :  * while (entry) {
     586                 :            :  *      ...
     587                 :            :  *      entry = mb_cache_entry_find_next(entry, ...);
     588                 :            :  * }
     589                 :            :  *
     590                 :            :  * @prev: The previous match
     591                 :            :  * @bdev: the device the cache entry should belong to
     592                 :            :  * @key: the key in the index
     593                 :            :  */
     594                 :            : struct mb_cache_entry *
     595                 :          0 : mb_cache_entry_find_next(struct mb_cache_entry *prev,
     596                 :            :                          struct block_device *bdev, unsigned int key)
     597                 :            : {
     598                 :          0 :         struct mb_cache *cache = prev->e_cache;
     599                 :          0 :         unsigned int bucket = hash_long(key, cache->c_bucket_bits);
     600                 :            :         struct list_head *l;
     601                 :            :         struct mb_cache_entry *ce;
     602                 :            : 
     603                 :            :         spin_lock(&mb_cache_spinlock);
     604                 :          0 :         l = prev->e_index.o_list.next;
     605                 :          0 :         ce = __mb_cache_entry_find(l, &cache->c_index_hash[bucket], bdev, key);
     606                 :          0 :         __mb_cache_entry_release_unlock(prev);
     607                 :          0 :         return ce;
     608                 :            : }
     609                 :            : 
     610                 :            : #endif  /* !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) */
     611                 :            : 
     612                 :          0 : static int __init init_mbcache(void)
     613                 :            : {
     614                 :          0 :         register_shrinker(&mb_cache_shrinker);
     615                 :          0 :         return 0;
     616                 :            : }
     617                 :            : 
     618                 :          0 : static void __exit exit_mbcache(void)
     619                 :            : {
     620                 :          0 :         unregister_shrinker(&mb_cache_shrinker);
     621                 :          0 : }
     622                 :            : 
     623                 :            : module_init(init_mbcache)
     624                 :            : module_exit(exit_mbcache)
     625                 :            : 

Generated by: LCOV version 1.9