Ignore:
Timestamp:
03/31/12 01:43:19 (15 months ago)
Author:
BrainSlayer
Message:

update kernels

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/linux/universal/linux-3.3/drivers/md/dm-thin.c

    r18778 r18879  
    125125        struct bio_prison *prison; 
    126126        struct cell_key key; 
    127         unsigned count; 
     127        struct bio *holder; 
    128128        struct bio_list bios; 
    129129}; 
     
    221221 * cells will be unlocked even if the calling thread is blocked. 
    222222 * 
    223  * Returns the number of entries in the cell prior to the new addition 
    224  * or < 0 on failure. 
     223 * Returns 1 if the cell was already held, 0 if @inmate is the new holder. 
    225224 */ 
    226225static int bio_detain(struct bio_prison *prison, struct cell_key *key, 
    227226                      struct bio *inmate, struct cell **ref) 
    228227{ 
    229         int r; 
     228        int r = 1; 
    230229        unsigned long flags; 
    231230        uint32_t hash = hash_key(prison, key); 
    232         struct cell *uninitialized_var(cell), *cell2 = NULL; 
     231        struct cell *cell, *cell2; 
    233232 
    234233        BUG_ON(hash > prison->nr_buckets); 
    235234 
    236235        spin_lock_irqsave(&prison->lock, flags); 
     236 
    237237        cell = __search_bucket(prison->cells + hash, key); 
    238  
    239         if (!cell) { 
    240                 /* 
    241                  * Allocate a new cell 
    242                  */ 
    243                 spin_unlock_irqrestore(&prison->lock, flags); 
    244                 cell2 = mempool_alloc(prison->cell_pool, GFP_NOIO); 
    245                 spin_lock_irqsave(&prison->lock, flags); 
    246  
    247                 /* 
    248                  * We've been unlocked, so we have to double check that 
    249                  * nobody else has inserted this cell in the meantime. 
    250                  */ 
    251                 cell = __search_bucket(prison->cells + hash, key); 
    252  
    253                 if (!cell) { 
    254                         cell = cell2; 
    255                         cell2 = NULL; 
    256  
    257                         cell->prison = prison; 
    258                         memcpy(&cell->key, key, sizeof(cell->key)); 
    259                         cell->count = 0; 
    260                         bio_list_init(&cell->bios); 
    261                         hlist_add_head(&cell->list, prison->cells + hash); 
    262                 } 
    263         } 
    264  
    265         r = cell->count++; 
    266         bio_list_add(&cell->bios, inmate); 
     238        if (cell) { 
     239                bio_list_add(&cell->bios, inmate); 
     240                goto out; 
     241        } 
     242 
     243        /* 
     244         * Allocate a new cell 
     245         */ 
    267246        spin_unlock_irqrestore(&prison->lock, flags); 
    268  
    269         if (cell2) 
     247        cell2 = mempool_alloc(prison->cell_pool, GFP_NOIO); 
     248        spin_lock_irqsave(&prison->lock, flags); 
     249 
     250        /* 
     251         * We've been unlocked, so we have to double check that 
     252         * nobody else has inserted this cell in the meantime. 
     253         */ 
     254        cell = __search_bucket(prison->cells + hash, key); 
     255        if (cell) { 
    270256                mempool_free(cell2, prison->cell_pool); 
     257                bio_list_add(&cell->bios, inmate); 
     258                goto out; 
     259        } 
     260 
     261        /* 
     262         * Use new cell. 
     263         */ 
     264        cell = cell2; 
     265 
     266        cell->prison = prison; 
     267        memcpy(&cell->key, key, sizeof(cell->key)); 
     268        cell->holder = inmate; 
     269        bio_list_init(&cell->bios); 
     270        hlist_add_head(&cell->list, prison->cells + hash); 
     271 
     272        r = 0; 
     273 
     274out: 
     275        spin_unlock_irqrestore(&prison->lock, flags); 
    271276 
    272277        *ref = cell; 
     
    284289        hlist_del(&cell->list); 
    285290 
    286         if (inmates) 
    287                 bio_list_merge(inmates, &cell->bios); 
     291        bio_list_add(inmates, cell->holder); 
     292        bio_list_merge(inmates, &cell->bios); 
    288293 
    289294        mempool_free(cell, prison->cell_pool); 
     
    306311 * a sanity check. 
    307312 */ 
     313static void __cell_release_singleton(struct cell *cell, struct bio *bio) 
     314{ 
     315        hlist_del(&cell->list); 
     316        BUG_ON(cell->holder != bio); 
     317        BUG_ON(!bio_list_empty(&cell->bios)); 
     318} 
     319 
    308320static void cell_release_singleton(struct cell *cell, struct bio *bio) 
    309321{ 
     322        unsigned long flags; 
    310323        struct bio_prison *prison = cell->prison; 
    311         struct bio_list bios; 
    312         struct bio *b; 
     324 
     325        spin_lock_irqsave(&prison->lock, flags); 
     326        __cell_release_singleton(cell, bio); 
     327        spin_unlock_irqrestore(&prison->lock, flags); 
     328} 
     329 
     330/* 
     331 * Sometimes we don't want the holder, just the additional bios. 
     332 */ 
     333static void __cell_release_no_holder(struct cell *cell, struct bio_list *inmates) 
     334{ 
     335        struct bio_prison *prison = cell->prison; 
     336 
     337        hlist_del(&cell->list); 
     338        bio_list_merge(inmates, &cell->bios); 
     339 
     340        mempool_free(cell, prison->cell_pool); 
     341} 
     342 
     343static void cell_release_no_holder(struct cell *cell, struct bio_list *inmates) 
     344{ 
    313345        unsigned long flags; 
    314  
    315         bio_list_init(&bios); 
     346        struct bio_prison *prison = cell->prison; 
    316347 
    317348        spin_lock_irqsave(&prison->lock, flags); 
    318         __cell_release(cell, &bios); 
     349        __cell_release_no_holder(cell, inmates); 
    319350        spin_unlock_irqrestore(&prison->lock, flags); 
    320  
    321         b = bio_list_pop(&bios); 
    322         BUG_ON(b != bio); 
    323         BUG_ON(!bio_list_empty(&bios)); 
    324351} 
    325352 
     
    801828 * a write bio that covers the block and has already been processed. 
    802829 */ 
    803 static void cell_defer_except(struct thin_c *tc, struct cell *cell, 
    804                               struct bio *exception) 
     830static void cell_defer_except(struct thin_c *tc, struct cell *cell) 
    805831{ 
    806832        struct bio_list bios; 
    807         struct bio *bio; 
    808833        struct pool *pool = tc->pool; 
    809834        unsigned long flags; 
    810835 
    811836        bio_list_init(&bios); 
    812         cell_release(cell, &bios); 
    813837 
    814838        spin_lock_irqsave(&pool->lock, flags); 
    815         while ((bio = bio_list_pop(&bios))) 
    816                 if (bio != exception) 
    817                         bio_list_add(&pool->deferred_bios, bio); 
     839        cell_release_no_holder(cell, &pool->deferred_bios); 
    818840        spin_unlock_irqrestore(&pool->lock, flags); 
    819841 
     
    855877         */ 
    856878        if (bio) { 
    857                 cell_defer_except(tc, m->cell, bio); 
     879                cell_defer_except(tc, m->cell); 
    858880                bio_endio(bio, 0); 
    859881        } else 
Note: See TracChangeset for help on using the changeset viewer.