Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 2596
b: refs/heads/master
c: 7bfa19f
h: refs/heads/master
v: v3
  • Loading branch information
NeilBrown authored and Linus Torvalds committed Jun 22, 2005
1 parent b30770c commit e15af74
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 38 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a654b9d8f851f4ca02649d5825cbe6c608adb10c
refs/heads/master: 7bfa19f2748000d646dbdf8f48258cfe1d257b52
85 changes: 48 additions & 37 deletions trunk/drivers/md/md.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,40 @@ static void free_disk_sb(mdk_rdev_t * rdev)
}


static int super_written(struct bio *bio, unsigned int bytes_done, int error)
{
mdk_rdev_t *rdev = bio->bi_private;
if (bio->bi_size)
return 1;

if (error || !test_bit(BIO_UPTODATE, &bio->bi_flags))
md_error(rdev->mddev, rdev);

if (atomic_dec_and_test(&rdev->mddev->pending_writes))
wake_up(&rdev->mddev->sb_wait);
return 0;
}

void md_super_write(mddev_t *mddev, mdk_rdev_t *rdev,
sector_t sector, int size, struct page *page)
{
/* write first size bytes of page to sector of rdev
* Increment mddev->pending_writes before returning
* and decrement it on completion, waking up sb_wait
* if zero is reached.
* If an error occurred, call md_error
*/
struct bio *bio = bio_alloc(GFP_NOIO, 1);

bio->bi_bdev = rdev->bdev;
bio->bi_sector = sector;
bio_add_page(bio, page, size, 0);
bio->bi_private = rdev;
bio->bi_end_io = super_written;
atomic_inc(&mddev->pending_writes);
submit_bio((1<<BIO_RW)|(1<<BIO_RW_SYNC), bio);
}

static int bi_complete(struct bio *bio, unsigned int bytes_done, int error)
{
if (bio->bi_size)
Expand Down Expand Up @@ -1268,30 +1302,6 @@ void md_print_devices(void)
}


static int write_disk_sb(mdk_rdev_t * rdev)
{
char b[BDEVNAME_SIZE];
if (!rdev->sb_loaded) {
MD_BUG();
return 1;
}
if (rdev->faulty) {
MD_BUG();
return 1;
}

dprintk(KERN_INFO "(write) %s's sb offset: %llu\n",
bdevname(rdev->bdev,b),
(unsigned long long)rdev->sb_offset);

if (sync_page_io(rdev->bdev, rdev->sb_offset<<1, MD_SB_BYTES, rdev->sb_page, WRITE))
return 0;

printk("md: write_disk_sb failed for device %s\n",
bdevname(rdev->bdev,b));
return 1;
}

static void sync_sbs(mddev_t * mddev)
{
mdk_rdev_t *rdev;
Expand All @@ -1306,7 +1316,7 @@ static void sync_sbs(mddev_t * mddev)

static void md_update_sb(mddev_t * mddev)
{
int err, count = 100;
int err;
struct list_head *tmp;
mdk_rdev_t *rdev;
int sync_req;
Expand All @@ -1326,6 +1336,7 @@ static void md_update_sb(mddev_t * mddev)
MD_BUG();
mddev->events --;
}
mddev->sb_dirty = 2;
sync_sbs(mddev);

/*
Expand Down Expand Up @@ -1353,24 +1364,24 @@ static void md_update_sb(mddev_t * mddev)

dprintk("%s ", bdevname(rdev->bdev,b));
if (!rdev->faulty) {
err += write_disk_sb(rdev);
md_super_write(mddev,rdev,
rdev->sb_offset<<1, MD_SB_BYTES,
rdev->sb_page);
dprintk(KERN_INFO "(write) %s's sb offset: %llu\n",
bdevname(rdev->bdev,b),
(unsigned long long)rdev->sb_offset);

} else
dprintk(")\n");
if (!err && mddev->level == LEVEL_MULTIPATH)
if (mddev->level == LEVEL_MULTIPATH)
/* only need to write one superblock... */
break;
}
if (err) {
if (--count) {
printk(KERN_ERR "md: errors occurred during superblock"
" update, repeating\n");
goto repeat;
}
printk(KERN_ERR \
"md: excessive errors occurred during superblock update, exiting\n");
}
wait_event(mddev->sb_wait, atomic_read(&mddev->pending_writes)==0);
/* if there was a failure, sb_dirty was set to 1, and we re-write super */

spin_lock(&mddev->write_lock);
if (mddev->in_sync != sync_req) {
if (mddev->in_sync != sync_req|| mddev->sb_dirty == 1) {
/* have to write it out again */
spin_unlock(&mddev->write_lock);
goto repeat;
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/raid/md_k.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,7 @@ struct mddev_s

spinlock_t write_lock;
wait_queue_head_t sb_wait; /* for waiting on superblock updates */
atomic_t pending_writes; /* number of active superblock writes */

unsigned int safemode; /* if set, update "clean" superblock
* when no writes pending.
Expand Down

0 comments on commit e15af74

Please sign in to comment.