dm-table.c (ab4c1424882be9cd70b89abf2b484add355712fa) | dm-table.c (d58168763f74d1edbc296d7038c60efe6493fdd4) |
---|---|
1/* 2 * Copyright (C) 2001 Sistina Software (UK) Limited. | 1/* 2 * Copyright (C) 2001 Sistina Software (UK) Limited. |
3 * Copyright (C) 2004 Red Hat, Inc. All rights reserved. | 3 * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved. |
4 * 5 * This file is released under the GPL. 6 */ 7 8#include "dm.h" 9 10#include <linux/module.h> 11#include <linux/vmalloc.h> 12#include <linux/blkdev.h> 13#include <linux/namei.h> 14#include <linux/ctype.h> 15#include <linux/slab.h> 16#include <linux/interrupt.h> 17#include <linux/mutex.h> | 4 * 5 * This file is released under the GPL. 6 */ 7 8#include "dm.h" 9 10#include <linux/module.h> 11#include <linux/vmalloc.h> 12#include <linux/blkdev.h> 13#include <linux/namei.h> 14#include <linux/ctype.h> 15#include <linux/slab.h> 16#include <linux/interrupt.h> 17#include <linux/mutex.h> |
18#include <linux/delay.h> |
|
18#include <asm/atomic.h> 19 20#define DM_MSG_PREFIX "table" 21 22#define MAX_DEPTH 16 23#define NODE_SIZE L1_CACHE_BYTES 24#define KEYS_PER_NODE (NODE_SIZE / sizeof(sector_t)) 25#define CHILDREN_PER_NODE (KEYS_PER_NODE + 1) 26 | 19#include <asm/atomic.h> 20 21#define DM_MSG_PREFIX "table" 22 23#define MAX_DEPTH 16 24#define NODE_SIZE L1_CACHE_BYTES 25#define KEYS_PER_NODE (NODE_SIZE / sizeof(sector_t)) 26#define CHILDREN_PER_NODE (KEYS_PER_NODE + 1) 27 |
28/* 29 * The table has always exactly one reference from either mapped_device->map 30 * or hash_cell->new_map. This reference is not counted in table->holders. 31 * A pair of dm_create_table/dm_destroy_table functions is used for table 32 * creation/destruction. 33 * 34 * Temporary references from the other code increase table->holders. A pair 35 * of dm_table_get/dm_table_put functions is used to manipulate it. 36 * 37 * When the table is about to be destroyed, we wait for table->holders to 38 * drop to zero. 39 */ 40 |
|
27struct dm_table { 28 struct mapped_device *md; 29 atomic_t holders; 30 31 /* btree table */ 32 unsigned int depth; 33 unsigned int counts[MAX_DEPTH]; /* in nodes */ 34 sector_t *index[MAX_DEPTH]; --- 188 unchanged lines hidden (view full) --- 223 unsigned num_targets, struct mapped_device *md) 224{ 225 struct dm_table *t = kzalloc(sizeof(*t), GFP_KERNEL); 226 227 if (!t) 228 return -ENOMEM; 229 230 INIT_LIST_HEAD(&t->devices); | 41struct dm_table { 42 struct mapped_device *md; 43 atomic_t holders; 44 45 /* btree table */ 46 unsigned int depth; 47 unsigned int counts[MAX_DEPTH]; /* in nodes */ 48 sector_t *index[MAX_DEPTH]; --- 188 unchanged lines hidden (view full) --- 237 unsigned num_targets, struct mapped_device *md) 238{ 239 struct dm_table *t = kzalloc(sizeof(*t), GFP_KERNEL); 240 241 if (!t) 242 return -ENOMEM; 243 244 INIT_LIST_HEAD(&t->devices); |
231 atomic_set(&t->holders, 1); | 245 atomic_set(&t->holders, 0); |
232 t->barriers_supported = 1; 233 234 if (!num_targets) 235 num_targets = KEYS_PER_NODE; 236 237 num_targets = dm_round_up(num_targets, KEYS_PER_NODE); 238 239 if (alloc_targets(t, num_targets)) { --- 14 unchanged lines hidden (view full) --- 254 255 list_for_each_safe(tmp, next, devices) { 256 struct dm_dev_internal *dd = 257 list_entry(tmp, struct dm_dev_internal, list); 258 kfree(dd); 259 } 260} 261 | 246 t->barriers_supported = 1; 247 248 if (!num_targets) 249 num_targets = KEYS_PER_NODE; 250 251 num_targets = dm_round_up(num_targets, KEYS_PER_NODE); 252 253 if (alloc_targets(t, num_targets)) { --- 14 unchanged lines hidden (view full) --- 268 269 list_for_each_safe(tmp, next, devices) { 270 struct dm_dev_internal *dd = 271 list_entry(tmp, struct dm_dev_internal, list); 272 kfree(dd); 273 } 274} 275 |
262static void table_destroy(struct dm_table *t) | 276void dm_table_destroy(struct dm_table *t) |
263{ 264 unsigned int i; 265 | 277{ 278 unsigned int i; 279 |
280 while (atomic_read(&t->holders)) 281 msleep(1); 282 smp_mb(); 283 |
|
266 /* free the indexes (see dm_table_complete) */ 267 if (t->depth >= 2) 268 vfree(t->index[t->depth - 2]); 269 270 /* free the targets */ 271 for (i = 0; i < t->num_targets; i++) { 272 struct dm_target *tgt = t->targets + i; 273 --- 21 unchanged lines hidden (view full) --- 295 atomic_inc(&t->holders); 296} 297 298void dm_table_put(struct dm_table *t) 299{ 300 if (!t) 301 return; 302 | 284 /* free the indexes (see dm_table_complete) */ 285 if (t->depth >= 2) 286 vfree(t->index[t->depth - 2]); 287 288 /* free the targets */ 289 for (i = 0; i < t->num_targets; i++) { 290 struct dm_target *tgt = t->targets + i; 291 --- 21 unchanged lines hidden (view full) --- 313 atomic_inc(&t->holders); 314} 315 316void dm_table_put(struct dm_table *t) 317{ 318 if (!t) 319 return; 320 |
303 if (atomic_dec_and_test(&t->holders)) 304 table_destroy(t); | 321 smp_mb__before_atomic_dec(); 322 atomic_dec(&t->holders); |
305} 306 307/* 308 * Checks to see if we need to extend highs or targets. 309 */ 310static inline int check_space(struct dm_table *t) 311{ 312 if (t->num_targets >= t->num_allocated) --- 705 unchanged lines hidden --- | 323} 324 325/* 326 * Checks to see if we need to extend highs or targets. 327 */ 328static inline int check_space(struct dm_table *t) 329{ 330 if (t->num_targets >= t->num_allocated) --- 705 unchanged lines hidden --- |