aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/bitmap.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@cse.unsw.edu.au>2005-09-09 19:23:50 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-09-09 19:39:11 -0400
commit3178b0dbdf67322f6506582e494bdf553cc85c32 (patch)
treea1169a85a0b3a54f1368dcdd86f656cfe4edd89e /drivers/md/bitmap.c
parent585f0dd5a955c420ff3af5193aa07d6f789bf81a (diff)
[PATCH] md: do not set mddev->bitmap until bitmap is fully initialised
When hot-adding a bitmap, bitmap_daemon_work could get called while the bitmap is being created, so don't set mddev->bitmap until the bitmap is ready. This requires freeing the bitmap inside bitmap_create if creation failed part-way through. Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md/bitmap.c')
-rw-r--r--drivers/md/bitmap.c33
1 files changed, 24 insertions, 9 deletions
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c
index f0f510c13410..c971d38f3a05 100644
--- a/drivers/md/bitmap.c
+++ b/drivers/md/bitmap.c
@@ -1503,17 +1503,14 @@ void bitmap_flush(mddev_t *mddev)
1503/* 1503/*
1504 * free memory that was allocated 1504 * free memory that was allocated
1505 */ 1505 */
1506void bitmap_destroy(mddev_t *mddev) 1506static void bitmap_free(struct bitmap *bitmap)
1507{ 1507{
1508 unsigned long k, pages; 1508 unsigned long k, pages;
1509 struct bitmap_page *bp; 1509 struct bitmap_page *bp;
1510 struct bitmap *bitmap = mddev->bitmap;
1511 1510
1512 if (!bitmap) /* there was no bitmap */ 1511 if (!bitmap) /* there was no bitmap */
1513 return; 1512 return;
1514 1513
1515 mddev->bitmap = NULL; /* disconnect from the md device */
1516
1517 /* release the bitmap file and kill the daemon */ 1514 /* release the bitmap file and kill the daemon */
1518 bitmap_file_put(bitmap); 1515 bitmap_file_put(bitmap);
1519 1516
@@ -1531,6 +1528,17 @@ void bitmap_destroy(mddev_t *mddev)
1531 kfree(bp); 1528 kfree(bp);
1532 kfree(bitmap); 1529 kfree(bitmap);
1533} 1530}
1531void bitmap_destroy(mddev_t *mddev)
1532{
1533 struct bitmap *bitmap = mddev->bitmap;
1534
1535 if (!bitmap) /* there was no bitmap */
1536 return;
1537
1538 mddev->bitmap = NULL; /* disconnect from the md device */
1539
1540 bitmap_free(bitmap);
1541}
1534 1542
1535/* 1543/*
1536 * initialize the bitmap structure 1544 * initialize the bitmap structure
@@ -1561,15 +1569,15 @@ int bitmap_create(mddev_t *mddev)
1561 1569
1562 spin_lock_init(&bitmap->lock); 1570 spin_lock_init(&bitmap->lock);
1563 bitmap->mddev = mddev; 1571 bitmap->mddev = mddev;
1564 mddev->bitmap = bitmap;
1565 1572
1566 spin_lock_init(&bitmap->write_lock); 1573 spin_lock_init(&bitmap->write_lock);
1567 INIT_LIST_HEAD(&bitmap->complete_pages); 1574 INIT_LIST_HEAD(&bitmap->complete_pages);
1568 init_waitqueue_head(&bitmap->write_wait); 1575 init_waitqueue_head(&bitmap->write_wait);
1569 bitmap->write_pool = mempool_create(WRITE_POOL_SIZE, write_pool_alloc, 1576 bitmap->write_pool = mempool_create(WRITE_POOL_SIZE, write_pool_alloc,
1570 write_pool_free, NULL); 1577 write_pool_free, NULL);
1578 err = -ENOMEM;
1571 if (!bitmap->write_pool) 1579 if (!bitmap->write_pool)
1572 return -ENOMEM; 1580 goto error;
1573 1581
1574 bitmap->file = file; 1582 bitmap->file = file;
1575 bitmap->offset = mddev->bitmap_offset; 1583 bitmap->offset = mddev->bitmap_offset;
@@ -1577,7 +1585,7 @@ int bitmap_create(mddev_t *mddev)
1577 /* read superblock from bitmap file (this sets bitmap->chunksize) */ 1585 /* read superblock from bitmap file (this sets bitmap->chunksize) */
1578 err = bitmap_read_sb(bitmap); 1586 err = bitmap_read_sb(bitmap);
1579 if (err) 1587 if (err)
1580 return err; 1588 goto error;
1581 1589
1582 bitmap->chunkshift = find_first_bit(&bitmap->chunksize, 1590 bitmap->chunkshift = find_first_bit(&bitmap->chunksize,
1583 sizeof(bitmap->chunksize)); 1591 sizeof(bitmap->chunksize));
@@ -1601,8 +1609,9 @@ int bitmap_create(mddev_t *mddev)
1601#else 1609#else
1602 bitmap->bp = kmalloc(pages * sizeof(*bitmap->bp), GFP_KERNEL); 1610 bitmap->bp = kmalloc(pages * sizeof(*bitmap->bp), GFP_KERNEL);
1603#endif 1611#endif
1612 err = -ENOMEM;
1604 if (!bitmap->bp) 1613 if (!bitmap->bp)
1605 return -ENOMEM; 1614 goto error;
1606 memset(bitmap->bp, 0, pages * sizeof(*bitmap->bp)); 1615 memset(bitmap->bp, 0, pages * sizeof(*bitmap->bp));
1607 1616
1608 bitmap->flags |= BITMAP_ACTIVE; 1617 bitmap->flags |= BITMAP_ACTIVE;
@@ -1617,16 +1626,22 @@ int bitmap_create(mddev_t *mddev)
1617 err = bitmap_init_from_disk(bitmap, start); 1626 err = bitmap_init_from_disk(bitmap, start);
1618 1627
1619 if (err) 1628 if (err)
1620 return err; 1629 goto error;
1621 1630
1622 printk(KERN_INFO "created bitmap (%lu pages) for device %s\n", 1631 printk(KERN_INFO "created bitmap (%lu pages) for device %s\n",
1623 pages, bmname(bitmap)); 1632 pages, bmname(bitmap));
1624 1633
1634 mddev->bitmap = bitmap;
1635
1625 /* kick off the bitmap daemons */ 1636 /* kick off the bitmap daemons */
1626 err = bitmap_start_daemons(bitmap); 1637 err = bitmap_start_daemons(bitmap);
1627 if (err) 1638 if (err)
1628 return err; 1639 return err;
1629 return bitmap_update_sb(bitmap); 1640 return bitmap_update_sb(bitmap);
1641
1642 error:
1643 bitmap_free(bitmap);
1644 return err;
1630} 1645}
1631 1646
1632/* the bitmap API -- for raid personalities */ 1647/* the bitmap API -- for raid personalities */