Changeset 18879 for src/linux/universal/linux-3.3/drivers/md/dm-thin.c
- Timestamp:
- 03/31/12 01:43:19 (15 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/linux/universal/linux-3.3/drivers/md/dm-thin.c
r18778 r18879 125 125 struct bio_prison *prison; 126 126 struct cell_key key; 127 unsigned count;127 struct bio *holder; 128 128 struct bio_list bios; 129 129 }; … … 221 221 * cells will be unlocked even if the calling thread is blocked. 222 222 * 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. 225 224 */ 226 225 static int bio_detain(struct bio_prison *prison, struct cell_key *key, 227 226 struct bio *inmate, struct cell **ref) 228 227 { 229 int r ;228 int r = 1; 230 229 unsigned long flags; 231 230 uint32_t hash = hash_key(prison, key); 232 struct cell * uninitialized_var(cell), *cell2 = NULL;231 struct cell *cell, *cell2; 233 232 234 233 BUG_ON(hash > prison->nr_buckets); 235 234 236 235 spin_lock_irqsave(&prison->lock, flags); 236 237 237 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 */ 267 246 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) { 270 256 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 274 out: 275 spin_unlock_irqrestore(&prison->lock, flags); 271 276 272 277 *ref = cell; … … 284 289 hlist_del(&cell->list); 285 290 286 if (inmates)287 bio_list_merge(inmates, &cell->bios);291 bio_list_add(inmates, cell->holder); 292 bio_list_merge(inmates, &cell->bios); 288 293 289 294 mempool_free(cell, prison->cell_pool); … … 306 311 * a sanity check. 307 312 */ 313 static 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 308 320 static void cell_release_singleton(struct cell *cell, struct bio *bio) 309 321 { 322 unsigned long flags; 310 323 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 */ 333 static 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 343 static void cell_release_no_holder(struct cell *cell, struct bio_list *inmates) 344 { 313 345 unsigned long flags; 314 315 bio_list_init(&bios); 346 struct bio_prison *prison = cell->prison; 316 347 317 348 spin_lock_irqsave(&prison->lock, flags); 318 __cell_release (cell, &bios);349 __cell_release_no_holder(cell, inmates); 319 350 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));324 351 } 325 352 … … 801 828 * a write bio that covers the block and has already been processed. 802 829 */ 803 static void cell_defer_except(struct thin_c *tc, struct cell *cell, 804 struct bio *exception) 830 static void cell_defer_except(struct thin_c *tc, struct cell *cell) 805 831 { 806 832 struct bio_list bios; 807 struct bio *bio;808 833 struct pool *pool = tc->pool; 809 834 unsigned long flags; 810 835 811 836 bio_list_init(&bios); 812 cell_release(cell, &bios);813 837 814 838 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); 818 840 spin_unlock_irqrestore(&pool->lock, flags); 819 841 … … 855 877 */ 856 878 if (bio) { 857 cell_defer_except(tc, m->cell , bio);879 cell_defer_except(tc, m->cell); 858 880 bio_endio(bio, 0); 859 881 } else
Note: See TracChangeset
for help on using the changeset viewer.
