* [PATCH 7/8] md: skip resync for raid array with journal
From: Shaohua Li @ 2015-09-02 20:49 UTC (permalink / raw)
To: linux-raid; +Cc: Kernel-team, songliubraving, hch, dan.j.williams, neilb
In-Reply-To: <cover.1441221530.git.shli@fb.com>
If a raid array has journal, the journal can guarantee the consistency,
we can skip resync after a unclean shutdown. The exception is raid
creation or user initiated resync, which we still do a raid resync.
Signed-off-by: Shaohua Li <shli@fb.com>
---
drivers/md/md.c | 4 ++++
drivers/md/md.h | 1 +
2 files changed, 5 insertions(+)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index b3f9eed..95824fb 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1669,6 +1669,8 @@ static int super_1_validate(struct mddev *mddev, struct md_rdev *rdev)
}
set_bit(Journal, &rdev->flags);
rdev->journal_tail = le64_to_cpu(sb->journal_tail);
+ if (mddev->recovery_cp == MaxSector)
+ set_bit(MD_JOURNAL_CLEAN, &mddev->flags);
break;
default:
rdev->saved_raid_disk = role;
@@ -1711,6 +1713,8 @@ static void super_1_sync(struct mddev *mddev, struct md_rdev *rdev)
sb->events = cpu_to_le64(mddev->events);
if (mddev->in_sync)
sb->resync_offset = cpu_to_le64(mddev->recovery_cp);
+ else if (test_bit(MD_JOURNAL_CLEAN, &mddev->flags))
+ sb->resync_offset = cpu_to_le64(MaxSector);
else
sb->resync_offset = cpu_to_le64(0);
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 226f4ba..0288a0b 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -236,6 +236,7 @@ struct mddev {
#define MD_STILL_CLOSED 4 /* If set, then array has not been opened since
* md_ioctl checked on it.
*/
+#define MD_JOURNAL_CLEAN 5 /* A raid with journal is already clean */
int suspended;
atomic_t active_io;
--
1.8.1
^ permalink raw reply related
* [PATCH 8/8] raid5-cache: add trim support for log
From: Shaohua Li @ 2015-09-02 20:49 UTC (permalink / raw)
To: linux-raid; +Cc: Kernel-team, songliubraving, hch, dan.j.williams, neilb
In-Reply-To: <cover.1441221530.git.shli@fb.com>
Since superblock is updated infrequently, we do a simple trim of log
disk (a synchronous trim)
Signed-off-by: Shaohua Li <shli@fb.com>
---
drivers/md/raid5-cache.c | 30 +++++++++++++++++++++++++++++-
1 file changed, 29 insertions(+), 1 deletion(-)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 27fb513..410b85b 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -639,6 +639,34 @@ static void r5l_kick_io_unit(struct r5l_log *log)
}
static void r5l_write_super(struct r5l_log *log, sector_t cp);
+static void r5l_write_super_and_discard_space(struct r5l_log *log,
+ sector_t end)
+{
+ struct block_device *bdev = log->rdev->bdev;
+
+ r5l_write_super(log, end);
+
+ if (!blk_queue_discard(bdev_get_queue(bdev)))
+ return;
+
+ /* discard destroy old data in log, so force a super update */
+ md_update_sb(log->rdev->mddev, 1);
+
+ if (log->last_checkpoint < end) {
+ blkdev_issue_discard(bdev,
+ log->last_checkpoint + log->rdev->data_offset,
+ end - log->last_checkpoint, GFP_NOIO, 0);
+ } else {
+ blkdev_issue_discard(bdev,
+ log->last_checkpoint + log->rdev->data_offset,
+ log->device_size - log->last_checkpoint,
+ GFP_NOIO, 0);
+ blkdev_issue_discard(bdev, log->rdev->data_offset, end,
+ GFP_NOIO, 0);
+ }
+}
+
+
static void r5l_do_reclaim(struct r5l_log *log)
{
struct r5l_io_unit *io, *last;
@@ -694,7 +722,7 @@ static void r5l_do_reclaim(struct r5l_log *log)
* here, because the log area might be reused soon and we don't want to
* confuse recovery
* */
- r5l_write_super(log, last->log_start);
+ r5l_write_super_and_discard_space(log, last->log_start);
mutex_lock(&log->io_mutex);
log->last_checkpoint = last->log_start;
--
1.8.1
^ permalink raw reply related
* Re: Expanding RAID0
From: Alexander Afonyashin @ 2015-09-03 10:53 UTC (permalink / raw)
To: linux-raid
In-Reply-To: <CAETWcftSGsOnm6FX49cPs3S5TTGbAOFt0-s3Fq850q8qJfDtGA@mail.gmail.com>
Hi,
Small correction:
- mdadm -G -l 0 -n 3 /dev/md3
Regards,
Alexander
On Wed, Sep 2, 2015 at 11:57 AM, Alexander Afonyashin
<a.afonyashin@madnet-team.ru> wrote:
> Hi,
>
> I added 3rd drive to 2-disk raid0 (with some issues like mdadm hung
> and all disks became spares) but now it looks like:
>
> md3 : active raid4 sda4[0] sdc4[3] sdb4[1]
> 1304305152 blocks super 1.2 level 4, 512k chunk, algorithm 5 [4/3] [UUU_]
>
> (/dev/sdc4 was added). I wonder what should be better to convert raid4
> back to raid0 again:
> - mdadm -G -l 0 -n 0 /dev/md3
> or
> - echo 0 > /sys/block/md3/md/level
>
> Which command doesn't start 'sync' process again? (I suspect that
> first one does)
>
> Regards,
> Alexander Afonyashin
^ permalink raw reply
* Raid 10 array problems
From: o1bigtenor @ 2015-09-03 22:33 UTC (permalink / raw)
To: linux-raid
Greetings
Had updated a system to Debian 8 which also had a Raid 10 array that
has been in use for about 3 1/2 years. (Setup raid under Debian 6 then
ran it mostly under Debian 7 mounting the array each time after
booting using the command
#mount /dev/dm-o /home/myspace/RAID
and didn't have any major problems with it (besides a failed drive
which was replaced and things went OK).)
Really enjoyed Debian 8's feature where after a boot (done seldom as I
was running the machine 24/7) where in the file manager clicking on
the icon for the 1.8TB drive a dialog box would popup requesting the
root password and upon correct completion the array was accessible.
Found with Debian 8 that I had the option of using a sleep state (shut
down to ram) and liked the idea of reducing power consumption (my box
with 3 gpus and 6 hdds does like to pull power) for over night.
On Aug 28th evening I noticed that I didn't have my raid array accessible.
Went to bed (have learned not to change things when I am very tired as
I can bork things up too fast.
Next morning tried a reboot to see if things would clear themselves -
- they didn't.
After some running in circles I found this in a log:
Aug 30 19:51:40 debiantestingbase kernel: [100718.675021] FAT-fs
(md0): utf8 is not a recommended IO charset for FAT filesystems,
filesystem will be case sensitive!
Aug 30 21:35:33 debiantestingbase kernel: [106954.860493] EXT4-fs
(md0): VFS: Can't find ext4 filesystem
Aug 30 21:37:05 debiantestingbase kernel: [107046.607187] EXT4-fs
(md0): VFS: Can't find ext4 filesystem
Aug 30 22:20:33 debiantestingbase kernel: [109656.411356] PM: Syncing
filesystems ... done.
Aug 28 10:39:56 debiantestingbase udisksd[1777]: Cleaning up mount
point /media/darald/49552036-b46f-4956-ade9-3541a3dd7f0a (device 253:0
no longer exist)
from syslog.3
That UUID was the 'name' of the array previously
Aug 28 10:39:28 debiantestingbase kernel: [ 3.025162] scsi 3:0:0:0:
Direct-Access ATA ST31000524AS JC4B PQ: 0 ANSI: 5
Aug 28 10:39:28 debiantestingbase kernel: [ 3.025768] sd 3:0:0:0:
[sdb] 1953525168 512-byte logical blocks: (1.00 TB/931 GiB)
Aug 28 10:39:28 debiantestingbase kernel: [ 3.026296] sd 3:0:0:0:
[sdb] Write Protect is off
Aug 28 10:39:28 debiantestingbase kernel: [ 3.026304] sd 3:0:0:0:
[sdb] Mode Sense: 00 3a 00 00
Aug 28 10:39:28 debiantestingbase kernel: [ 3.026484] sd 3:0:0:0:
[sdb] Write cache: enabled, read cache: enabled, doesn't support DPO
or FUA
Aug 28 10:39:28 debiantestingbase kernel: [ 3.028273] sdb: sdb1
Aug 28 10:39:28 debiantestingbase kernel: [ 3.028698] sd 3:0:0:0:
[sdb] Attached SCSI disk
Aug 28 10:39:28 debiantestingbase kernel: [ 3.086532] Switched to
clocksource tsc
Aug 28 10:39:28 debiantestingbase kernel: [ 3.168919] md: bind<sdb1>
Aug 28 10:39:28 debiantestingbase kernel: [ 3.342285] ata5: SATA
link up 3.0 Gbps (SStatus 123 SControl 300)
Aug 28 10:39:28 debiantestingbase kernel: [ 3.343153] ata5.00:
ATA-9: ST1000DM003-1ER162, CC45, max UDMA/133
Aug 28 10:39:28 debiantestingbase kernel: [ 3.343158] ata5.00:
1953525168 sectors, multi 16: LBA48 NCQ (depth 31/32), AA
Aug 28 10:39:28 debiantestingbase kernel: [ 3.344067] ata5.00:
configured for UDMA/133
Aug 28 10:39:28 debiantestingbase kernel: [ 3.344255] scsi 4:0:0:0:
Direct-Access ATA ST1000DM003-1ER1 CC45 PQ: 0 ANSI: 5
Aug 28 10:39:28 debiantestingbase kernel: [ 3.344627] sd 4:0:0:0:
[sdc] 1953525168 512-byte logical blocks: (1.00 TB/931 GiB)
Aug 28 10:39:28 debiantestingbase kernel: [ 3.344631] sd 4:0:0:0:
[sdc] 4096-byte physical blocks
Aug 28 10:39:28 debiantestingbase kernel: [ 3.344823] sd 4:0:0:0:
[sdc] Write Protect is off
Aug 28 10:39:28 debiantestingbase kernel: [ 3.344831] sd 4:0:0:0:
[sdc] Mode Sense: 00 3a 00 00
Aug 28 10:39:28 debiantestingbase kernel: [ 3.344946] sd 4:0:0:0:
[sdc] Write cache: enabled, read cache: enabled, doesn't support DPO
or FUA
Aug 28 10:39:28 debiantestingbase kernel: [ 3.411364] sdc: sdc1
Aug 28 10:39:28 debiantestingbase kernel: [ 3.412317] sd 4:0:0:0:
[sdc] Attached SCSI disk
Aug 28 10:39:28 debiantestingbase kernel: [ 3.501080] md: bind<sdc1>
Aug 28 10:39:28 debiantestingbase kernel: [ 3.662509] ata6: SATA
link up 3.0 Gbps (SStatus 123 SControl 300)
Aug 28 10:39:28 debiantestingbase kernel: [ 3.674767] ata6.00:
ATA-8: Corsair Force 3 SSD, 1.3.3, max UDMA/133
Aug 28 10:39:28 debiantestingbase kernel: [ 3.674772] ata6.00:
468862128 sectors, multi 16: LBA48 NCQ (depth 31/32), AA
Aug 28 10:39:28 debiantestingbase kernel: [ 3.684647] ata6.00:
configured for UDMA/133
Aug 28 10:39:28 debiantestingbase kernel: [ 3.684933] scsi 5:0:0:0:
Direct-Access ATA Corsair Force 3 3 PQ: 0 ANSI: 5
Aug 28 10:39:28 debiantestingbase kernel: [ 3.685504] sd 5:0:0:0:
[sdd] 468862128 512-byte logical blocks: (240 GB/223 GiB)
Aug 28 10:39:28 debiantestingbase kernel: [ 3.685975] sd 5:0:0:0:
[sdd] Write Protect is off
Aug 28 10:39:28 debiantestingbase kernel: [ 3.685983] sd 5:0:0:0:
[sdd] Mode Sense: 00 3a 00 00
Aug 28 10:39:28 debiantestingbase kernel: [ 3.686186] sd 5:0:0:0:
[sdd] Write cache: enabled, read cache: enabled, doesn't support DPO
or FUA
Aug 28 10:39:28 debiantestingbase kernel: [ 3.688051] sdd: sdd1
sdd4 < sdd5 sdd6 sdd7 sdd8 sdd9 sdd10 >
Aug 28 10:39:28 debiantestingbase kernel: [ 3.689305] sd 5:0:0:0:
[sdd] Attached SCSI disk
Aug 28 10:39:28 debiantestingbase kernel: [ 4.002712] ata8: SATA
link down (SStatus 0 SControl 300)
Aug 28 10:39:28 debiantestingbase kernel: [ 4.003107] scsi 8:0:0:0:
Direct-Access ATA ST31000524AS JC4B PQ: 0 ANSI: 5
Aug 28 10:39:28 debiantestingbase kernel: [ 4.003597] sd 8:0:0:0:
[sde] 1953525168 512-byte logical blocks: (1.00 TB/931 GiB)
Aug 28 10:39:28 debiantestingbase kernel: [ 4.003843] scsi 9:0:0:0:
Direct-Access ATA ST31000524AS JC4B PQ: 0 ANSI: 5
Aug 28 10:39:28 debiantestingbase kernel: [ 4.003975] sd 8:0:0:0:
[sde] Write Protect is off
Aug 28 10:39:28 debiantestingbase kernel: [ 4.003980] sd 8:0:0:0:
[sde] Mode Sense: 00 3a 00 00
Aug 28 10:39:28 debiantestingbase kernel: [ 4.004090] sd 8:0:0:0:
[sde] Write cache: enabled, read cache: enabled, doesn't support DPO
or FUA
Aug 28 10:39:28 debiantestingbase kernel: [ 4.004478] sd 9:0:0:0:
[sdf] 1953525168 512-byte logical blocks: (1.00 TB/931 GiB)
Aug 28 10:39:28 debiantestingbase kernel: [ 4.004645] sd 9:0:0:0:
[sdf] Write Protect is off
Aug 28 10:39:28 debiantestingbase kernel: [ 4.004650] sd 9:0:0:0:
[sdf] Mode Sense: 00 3a 00 00
Aug 28 10:39:28 debiantestingbase kernel: [ 4.004737] sd 9:0:0:0:
[sdf] Write cache: enabled, read cache: enabled, doesn't support DPO
or FUA
Aug 28 10:39:28 debiantestingbase kernel: [ 4.004778] scsi
15:0:0:0: Processor Marvell 91xx Config 1.01 PQ: 0 ANSI:
5
Aug 28 10:39:28 debiantestingbase kernel: [ 4.006375] sdf: sdf1
Aug 28 10:39:28 debiantestingbase kernel: [ 4.006967] sd 9:0:0:0:
[sdf] Attached SCSI disk
Aug 28 10:39:28 debiantestingbase kernel: [ 4.008855] sde: sde1
Aug 28 10:39:28 debiantestingbase kernel: [ 4.009704] sd 8:0:0:0:
[sde] Attached SCSI disk
Aug 28 10:39:28 debiantestingbase kernel: [ 4.018710] ata16.00:
exception Emask 0x1 SAct 0x0 SErr 0x0 action 0x0
Aug 28 10:39:28 debiantestingbase kernel: [ 4.018753] ata16.00:
irq_stat 0x40000001
Aug 28 10:39:28 debiantestingbase kernel: [ 4.018783] ata16.00: cmd
a0/01:00:00:00:01/00:00:00:00:00/a0 tag 1 dma 16640 in
Aug 28 10:39:28 debiantestingbase kernel: [ 4.018783]
Inquiry 12 01 00 00 ff 00res 50/00:00:af:6d:70/00:00:74:00:00/e0 Emask
0x1 (device error)
Aug 28 10:39:28 debiantestingbase kernel: [ 4.018868] ata16.00:
status: { DRDY }
Aug 28 10:39:28 debiantestingbase kernel: [ 4.125325] random:
nonblocking pool is initialized
Aug 28 10:39:28 debiantestingbase kernel: [ 4.125530] md: bind<sde1>
Aug 28 10:39:28 debiantestingbase kernel: [ 4.142140] md: bind<sdf1>
Aug 28 10:39:28 debiantestingbase kernel: [ 4.144984] md: raid10
personality registered for level 10
Aug 28 10:39:28 debiantestingbase kernel: [ 4.145397]
md/raid10:md0: active with 4 out of 4 devices
Aug 28 10:39:28 debiantestingbase kernel: [ 4.145440] md0: detected
capacity change from 0 to 2000403038208
Aug 28 10:39:28 debiantestingbase kernel: [ 4.208978] md0:
Aug 28 10:39:28 debiantestingbase kernel: [ 4.479305]
device-mapper: uevent: version 1.0.3
Aug 28 10:39:28 debiantestingbase kernel: [ 4.479536]
device-mapper: ioctl: 4.30.0-ioctl (2014-12-22) initialised:
dm-devel@redhat.com
some further information
>> Disk /dev/md0: 1.8 TiB, 2000403038208 bytes, 3907037184 sectors
>> Units: sectors of 1 * 512 = 512 bytes
>> Sector size (logical/physical): 512 bytes / 4096 bytes
>> I/O size (minimum/optimal): 524288 bytes / 1048576 bytes
>> Disklabel type: gpt
>> Disk identifier: 1EB47793-0CDF-4E16-AE84-33EC825AC448
>
>
>
> parted -l
Model: ATA ST31000524AS (scsi)
Disk /dev/sdf: 1000GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 1000GB 1000GB primary raid
Model: Linux Software RAID Array (md)
Disk /dev/md0: 2000GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
# parted -l
Model: ATA ST1000DM003-1ER1 (scsi)
Disk /dev/sda: 1000GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 269MB 268MB fat32 boot, esp
2 269MB 538MB 268MB /boot msftdata
3 538MB 26.8GB 26.2GB ext4 / msftdata
4 26.8GB 93.9GB 67.1GB linux-swap(v1) swap
5 93.9GB 494GB 400GB ext4
Model: ATA ST31000524AS (scsi)
Disk /dev/sdb: 1000GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 1000GB 1000GB primary raid
Model: ATA ST1000DM003-1ER1 (scsi)
Disk /dev/sdc: 1000GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 1049kB 1000GB 1000GB Linux filesystem
Model: ATA Corsair Force 3 (scsi)
Disk /dev/sdd: 240GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 256MB 255MB primary ext2 boot
4 257MB 123GB 123GB extended
5 258MB 21.2GB 21.0GB logical ext4
6 21.2GB 42.2GB 21.0GB logical ext4
7 42.2GB 73.7GB 31.5GB logical ext4
8 73.7GB 77.9GB 4194MB logical ext4
9 77.9GB 98.8GB 21.0GB logical ext4
10 98.8GB 123GB 24.5GB logical linux-swap(v1)
Model: ATA ST31000524AS (scsi)
Disk /dev/sde: 1000GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 1000GB 1000GB primary raid
Model: ATA ST31000524AS (scsi)
Disk /dev/sdf: 1000GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size File system Name Flags
The array was formed from sdb1, sdc1, sde1 and sdf1.
The array had been setup as an ext4 device.
I halted the array using:
mdadm --stop /dev/md0
I then setup a copy from the original drives (sdc1 and sdf1) to a
drive pulled from a project that I have just started on.
dd if=/dev/sdc1 bs=1M | gzip > /mnt/newbackupdisk/sdc1.img.gz
dd if=/dev/sdf1 bs=1M | gzip > /mnt/newbackupdisk/sdf1.img.gz
When I checked using md5sum the copy of sdf1 and the original do NOT match.
Please?
How can I get a copy of the information off of the raid 10 array?
Is there a way to verify this copy?
How to I re-setup the raid 10 array?
Should I be replacing sde (drive with a momentary failure)?
(Hopefully not too many questions nor too much initial information!!)
Any advice will be greatly appreciated!!
TIA
Dee
^ permalink raw reply
* [PATCH] skip match_mddev_units check for special roles
From: Song Liu @ 2015-09-04 6:00 UTC (permalink / raw)
To: linux-raid; +Cc: shli, neilb, hch, dan.j.williams, hch, Kernel-team, Song Liu
match_mddev_units is used to check whether 2 RAID arrays share
same disk(s). Arrays that share disk(s) will not do resync at the
same time for better performance (fewer HDD seek). However, this
check should not apply to Spare, Faulty, and Journal disks, as
they do not paticipate in resync.
In this patch, match_mddev_units skips check for disks with flag
"Faulty" or "Journal" or raid_disk < 0.
Signed-off-by: Song Liu <songliubraving@fb.com>
Signed-off-by: Shaohua Li <shli@fb.com>
---
drivers/md/md.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 95824fb..b96d135 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1957,13 +1957,23 @@ static int match_mddev_units(struct mddev *mddev1, struct mddev *mddev2)
struct md_rdev *rdev, *rdev2;
rcu_read_lock();
- rdev_for_each_rcu(rdev, mddev1)
- rdev_for_each_rcu(rdev2, mddev2)
+ rdev_for_each_rcu(rdev, mddev1) {
+ if (test_bit(Faulty, &rdev->flags) ||
+ test_bit(Journal, &rdev->flags) ||
+ rdev->raid_disk == -1)
+ continue;
+ rdev_for_each_rcu(rdev2, mddev2) {
+ if (test_bit(Faulty, &rdev2->flags) ||
+ test_bit(Journal, &rdev2->flags) ||
+ rdev2->raid_disk == -1)
+ continue;
if (rdev->bdev->bd_contains ==
rdev2->bdev->bd_contains) {
rcu_read_unlock();
return 1;
}
+ }
+ }
rcu_read_unlock();
return 0;
}
--
1.8.1
^ permalink raw reply related
* [PATCH] enable bypass raid5 journal for full stripe writes
From: Song Liu @ 2015-09-04 6:01 UTC (permalink / raw)
To: linux-raid; +Cc: shli, neilb, hch, dan.j.williams, hch, Kernel-team, Song Liu
Summary:
To save life time of journal device, we can config the device to
bypass journal writes for full stripe write. This is configured by:
echo "yes" > /sys/block/mdX/md/r5l_bypass_full_stripe
and
echo "no" > /sys/block/mdX/md/r5l_bypass_full_stripe
For file system integrity, full stripe with REQ_FUA will still
write to journal first.
This patch applies on top of Shaohua's most recent patches:
http://marc.info/?l=linux-raid&m=144122700510667
Signed-off-by: Song Liu <songliubraving@fb.com>
Reviewed-by: Shaohua Li <shli@fb.com>
---
drivers/md/raid5-cache.c | 20 +++++++++++++++++
drivers/md/raid5.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++
drivers/md/raid5.h | 2 ++
3 files changed, 78 insertions(+)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 410b85b..0c3ddc5 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -82,6 +82,8 @@ struct r5l_log {
struct list_head no_space_stripes; /* pending stripes, log has no space */
spinlock_t no_space_stripes_lock;
+
+ int bypass_full_stripe;
};
/*
@@ -438,6 +440,7 @@ int r5l_write_stripe(struct r5l_log *log, struct stripe_head *sh)
int meta_size;
int reserve;
int i;
+ int fua = 0;
if (!log)
return -EAGAIN;
@@ -453,6 +456,8 @@ int r5l_write_stripe(struct r5l_log *log, struct stripe_head *sh)
void *addr;
if (!test_bit(R5_Wantwrite, &sh->dev[i].flags))
continue;
+ if (test_bit(R5_WantFUA, &sh->dev[i].flags))
+ fua = 1;
write_disks++;
/* checksum is already calculated in last run */
if (test_bit(STRIPE_LOG_TRAPPED, &sh->state))
@@ -462,6 +467,10 @@ int r5l_write_stripe(struct r5l_log *log, struct stripe_head *sh)
addr, PAGE_SIZE);
kunmap_atomic(addr);
}
+
+ if (log->bypass_full_stripe && (write_disks == sh->disks) && (!fua))
+ return -EAGAIN; /* bypass journal device */
+
parity_pages = 1 + !!(sh->qd_idx >= 0);
data_pages = write_disks - parity_pages;
@@ -520,6 +529,16 @@ int r5l_handle_flush_request(struct r5l_log *log, struct bio *bio)
return -EAGAIN;
}
+int r5l_get_bypass_full_stripe(struct r5l_log *log)
+{
+ return log->bypass_full_stripe;
+}
+
+void r5l_set_bypass_full_stripe(struct r5l_log *log, int val)
+{
+ log->bypass_full_stripe = val;
+}
+
/* This will run after log space is reclaimed */
static void r5l_run_no_space_stripes(struct r5l_log *log)
{
@@ -1105,6 +1124,7 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev)
if (!log->io_kc)
goto io_kc;
+ log->bypass_full_stripe = 0;
log->reclaim_thread = md_register_thread(r5l_reclaim_thread,
log->rdev->mddev, "reclaim");
if (!log->reclaim_thread)
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 394cdf8..5781987 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -6223,6 +6223,61 @@ raid5_group_thread_cnt = __ATTR(group_thread_cnt, S_IRUGO | S_IWUSR,
raid5_show_group_thread_cnt,
raid5_store_group_thread_cnt);
+static ssize_t
+r5l_show_bypass_full_stripe(struct mddev *mddev, char *page)
+{
+ struct r5conf *conf;
+ int ret = 0;
+
+ spin_lock(&mddev->lock);
+ conf = mddev->private;
+ if (conf) {
+ if (conf->log)
+ ret = sprintf(page, "%s\n",
+ r5l_get_bypass_full_stripe(conf->log) ? "yes" : "no");
+ else
+ ret = sprintf(page, "n/a\n");
+ }
+ spin_unlock(&mddev->lock);
+ return ret;
+}
+
+static ssize_t
+r5l_store_bypass_full_stripe(struct mddev *mddev, const char *page, size_t len)
+{
+ struct r5conf *conf;
+ int err = 0;
+ int val;
+
+ if (strncmp(page, "yes", 3) == 0 &&
+ (page[3] == '\n' || page[3] == '\0'))
+ val = 1;
+ else if (strncmp(page, "no", 2) == 0 &&
+ (page[2] == '\n' || page[2] == '\0'))
+ val = 0;
+ else
+ return -EINVAL;
+
+ mddev_suspend(mddev);
+ spin_lock(&mddev->lock);
+ conf = mddev->private;
+ if (conf) {
+ if (conf->log) {
+ r5l_set_bypass_full_stripe(conf->log, val);
+ } else
+ err = -EINVAL;
+ } else
+ err = -ENODEV;
+ spin_unlock(&mddev->lock);
+ mddev_resume(mddev);
+ return err ?: len;
+}
+
+static struct md_sysfs_entry
+r5l_bypass_full_stripe = __ATTR(r5l_bypass_full_stripe, S_IRUGO | S_IWUSR,
+ r5l_show_bypass_full_stripe,
+ r5l_store_bypass_full_stripe);
+
static struct attribute *raid5_attrs[] = {
&raid5_stripecache_size.attr,
&raid5_stripecache_active.attr,
@@ -6230,6 +6285,7 @@ static struct attribute *raid5_attrs[] = {
&raid5_group_thread_cnt.attr,
&raid5_skip_copy.attr,
&raid5_rmw_level.attr,
+ &r5l_bypass_full_stripe.attr,
NULL,
};
static struct attribute_group raid5_attrs_group = {
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index e6b9a40..c1f6935 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h
@@ -630,4 +630,6 @@ extern void r5l_write_stripe_run(struct r5l_log *log);
extern void r5l_flush_stripe_to_raid(struct r5l_log *log);
extern void r5l_stripe_write_finished(struct stripe_head *sh);
extern int r5l_handle_flush_request(struct r5l_log *log, struct bio *bio);
+extern int r5l_get_bypass_full_stripe(struct r5l_log *log);
+extern void r5l_set_bypass_full_stripe(struct r5l_log *log, int val);
#endif
--
1.8.1
^ permalink raw reply related
* Re: Raid 10 array problems
From: Alexander Afonyashin @ 2015-09-04 6:03 UTC (permalink / raw)
To: o1bigtenor; +Cc: linux-raid
In-Reply-To: <CAPpdf592+kr9HPpqNaqRhTujZGcFUEcXLOKQzm=qcM10Vh-cEA@mail.gmail.com>
Hi,
Please paste the output of mdadm -E /dev/sdb1 (and other 3 partitions:
/dev/sdc1, /dev/sde1, /dev/sdf1)
Regards,
Alexander
On Fri, Sep 4, 2015 at 1:33 AM, o1bigtenor <o1bigtenor@gmail.com> wrote:
> Greetings
>
> Had updated a system to Debian 8 which also had a Raid 10 array that
> has been in use for about 3 1/2 years. (Setup raid under Debian 6 then
> ran it mostly under Debian 7 mounting the array each time after
> booting using the command
>
> #mount /dev/dm-o /home/myspace/RAID
>
> and didn't have any major problems with it (besides a failed drive
> which was replaced and things went OK).)
>
> Really enjoyed Debian 8's feature where after a boot (done seldom as I
> was running the machine 24/7) where in the file manager clicking on
> the icon for the 1.8TB drive a dialog box would popup requesting the
> root password and upon correct completion the array was accessible.
>
> Found with Debian 8 that I had the option of using a sleep state (shut
> down to ram) and liked the idea of reducing power consumption (my box
> with 3 gpus and 6 hdds does like to pull power) for over night.
>
> On Aug 28th evening I noticed that I didn't have my raid array accessible.
>
> Went to bed (have learned not to change things when I am very tired as
> I can bork things up too fast.
>
> Next morning tried a reboot to see if things would clear themselves -
> - they didn't.
>
> After some running in circles I found this in a log:
>
> Aug 30 19:51:40 debiantestingbase kernel: [100718.675021] FAT-fs
> (md0): utf8 is not a recommended IO charset for FAT filesystems,
> filesystem will be case sensitive!
> Aug 30 21:35:33 debiantestingbase kernel: [106954.860493] EXT4-fs
> (md0): VFS: Can't find ext4 filesystem
> Aug 30 21:37:05 debiantestingbase kernel: [107046.607187] EXT4-fs
> (md0): VFS: Can't find ext4 filesystem
> Aug 30 22:20:33 debiantestingbase kernel: [109656.411356] PM: Syncing
> filesystems ... done.
>
>
>
> Aug 28 10:39:56 debiantestingbase udisksd[1777]: Cleaning up mount
> point /media/darald/49552036-b46f-4956-ade9-3541a3dd7f0a (device 253:0
> no longer exist)
>
> from syslog.3
> That UUID was the 'name' of the array previously
>
>
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.025162] scsi 3:0:0:0:
> Direct-Access ATA ST31000524AS JC4B PQ: 0 ANSI: 5
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.025768] sd 3:0:0:0:
> [sdb] 1953525168 512-byte logical blocks: (1.00 TB/931 GiB)
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.026296] sd 3:0:0:0:
> [sdb] Write Protect is off
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.026304] sd 3:0:0:0:
> [sdb] Mode Sense: 00 3a 00 00
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.026484] sd 3:0:0:0:
> [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO
> or FUA
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.028273] sdb: sdb1
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.028698] sd 3:0:0:0:
> [sdb] Attached SCSI disk
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.086532] Switched to
> clocksource tsc
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.168919] md: bind<sdb1>
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.342285] ata5: SATA
> link up 3.0 Gbps (SStatus 123 SControl 300)
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.343153] ata5.00:
> ATA-9: ST1000DM003-1ER162, CC45, max UDMA/133
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.343158] ata5.00:
> 1953525168 sectors, multi 16: LBA48 NCQ (depth 31/32), AA
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.344067] ata5.00:
> configured for UDMA/133
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.344255] scsi 4:0:0:0:
> Direct-Access ATA ST1000DM003-1ER1 CC45 PQ: 0 ANSI: 5
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.344627] sd 4:0:0:0:
> [sdc] 1953525168 512-byte logical blocks: (1.00 TB/931 GiB)
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.344631] sd 4:0:0:0:
> [sdc] 4096-byte physical blocks
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.344823] sd 4:0:0:0:
> [sdc] Write Protect is off
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.344831] sd 4:0:0:0:
> [sdc] Mode Sense: 00 3a 00 00
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.344946] sd 4:0:0:0:
> [sdc] Write cache: enabled, read cache: enabled, doesn't support DPO
> or FUA
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.411364] sdc: sdc1
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.412317] sd 4:0:0:0:
> [sdc] Attached SCSI disk
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.501080] md: bind<sdc1>
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.662509] ata6: SATA
> link up 3.0 Gbps (SStatus 123 SControl 300)
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.674767] ata6.00:
> ATA-8: Corsair Force 3 SSD, 1.3.3, max UDMA/133
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.674772] ata6.00:
> 468862128 sectors, multi 16: LBA48 NCQ (depth 31/32), AA
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.684647] ata6.00:
> configured for UDMA/133
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.684933] scsi 5:0:0:0:
> Direct-Access ATA Corsair Force 3 3 PQ: 0 ANSI: 5
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.685504] sd 5:0:0:0:
> [sdd] 468862128 512-byte logical blocks: (240 GB/223 GiB)
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.685975] sd 5:0:0:0:
> [sdd] Write Protect is off
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.685983] sd 5:0:0:0:
> [sdd] Mode Sense: 00 3a 00 00
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.686186] sd 5:0:0:0:
> [sdd] Write cache: enabled, read cache: enabled, doesn't support DPO
> or FUA
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.688051] sdd: sdd1
> sdd4 < sdd5 sdd6 sdd7 sdd8 sdd9 sdd10 >
> Aug 28 10:39:28 debiantestingbase kernel: [ 3.689305] sd 5:0:0:0:
> [sdd] Attached SCSI disk
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.002712] ata8: SATA
> link down (SStatus 0 SControl 300)
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.003107] scsi 8:0:0:0:
> Direct-Access ATA ST31000524AS JC4B PQ: 0 ANSI: 5
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.003597] sd 8:0:0:0:
> [sde] 1953525168 512-byte logical blocks: (1.00 TB/931 GiB)
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.003843] scsi 9:0:0:0:
> Direct-Access ATA ST31000524AS JC4B PQ: 0 ANSI: 5
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.003975] sd 8:0:0:0:
> [sde] Write Protect is off
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.003980] sd 8:0:0:0:
> [sde] Mode Sense: 00 3a 00 00
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.004090] sd 8:0:0:0:
> [sde] Write cache: enabled, read cache: enabled, doesn't support DPO
> or FUA
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.004478] sd 9:0:0:0:
> [sdf] 1953525168 512-byte logical blocks: (1.00 TB/931 GiB)
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.004645] sd 9:0:0:0:
> [sdf] Write Protect is off
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.004650] sd 9:0:0:0:
> [sdf] Mode Sense: 00 3a 00 00
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.004737] sd 9:0:0:0:
> [sdf] Write cache: enabled, read cache: enabled, doesn't support DPO
> or FUA
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.004778] scsi
> 15:0:0:0: Processor Marvell 91xx Config 1.01 PQ: 0 ANSI:
> 5
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.006375] sdf: sdf1
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.006967] sd 9:0:0:0:
> [sdf] Attached SCSI disk
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.008855] sde: sde1
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.009704] sd 8:0:0:0:
> [sde] Attached SCSI disk
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.018710] ata16.00:
> exception Emask 0x1 SAct 0x0 SErr 0x0 action 0x0
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.018753] ata16.00:
> irq_stat 0x40000001
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.018783] ata16.00: cmd
> a0/01:00:00:00:01/00:00:00:00:00/a0 tag 1 dma 16640 in
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.018783]
> Inquiry 12 01 00 00 ff 00res 50/00:00:af:6d:70/00:00:74:00:00/e0 Emask
> 0x1 (device error)
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.018868] ata16.00:
> status: { DRDY }
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.125325] random:
> nonblocking pool is initialized
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.125530] md: bind<sde1>
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.142140] md: bind<sdf1>
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.144984] md: raid10
> personality registered for level 10
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.145397]
> md/raid10:md0: active with 4 out of 4 devices
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.145440] md0: detected
> capacity change from 0 to 2000403038208
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.208978] md0:
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.479305]
> device-mapper: uevent: version 1.0.3
> Aug 28 10:39:28 debiantestingbase kernel: [ 4.479536]
> device-mapper: ioctl: 4.30.0-ioctl (2014-12-22) initialised:
> dm-devel@redhat.com
>
>
>
> some further information
>
>>> Disk /dev/md0: 1.8 TiB, 2000403038208 bytes, 3907037184 sectors
>>> Units: sectors of 1 * 512 = 512 bytes
>>> Sector size (logical/physical): 512 bytes / 4096 bytes
>>> I/O size (minimum/optimal): 524288 bytes / 1048576 bytes
>>> Disklabel type: gpt
>>> Disk identifier: 1EB47793-0CDF-4E16-AE84-33EC825AC448
>>
>>
>>
>> parted -l
>
>
> Model: ATA ST31000524AS (scsi)
> Disk /dev/sdf: 1000GB
> Sector size (logical/physical): 512B/512B
> Partition Table: msdos
> Disk Flags:
>
> Number Start End Size Type File system Flags
> 1 1049kB 1000GB 1000GB primary raid
>
>
> Model: Linux Software RAID Array (md)
> Disk /dev/md0: 2000GB
> Sector size (logical/physical): 512B/4096B
> Partition Table: gpt
> Disk Flags:
>
> Number Start End Size File system Name Flags
>
>
> # parted -l
> Model: ATA ST1000DM003-1ER1 (scsi)
> Disk /dev/sda: 1000GB
> Sector size (logical/physical): 512B/4096B
> Partition Table: gpt
> Disk Flags:
>
> Number Start End Size File system Name Flags
> 1 1049kB 269MB 268MB fat32 boot, esp
> 2 269MB 538MB 268MB /boot msftdata
> 3 538MB 26.8GB 26.2GB ext4 / msftdata
> 4 26.8GB 93.9GB 67.1GB linux-swap(v1) swap
> 5 93.9GB 494GB 400GB ext4
>
>
> Model: ATA ST31000524AS (scsi)
> Disk /dev/sdb: 1000GB
> Sector size (logical/physical): 512B/512B
> Partition Table: msdos
> Disk Flags:
>
> Number Start End Size Type File system Flags
> 1 1049kB 1000GB 1000GB primary raid
>
>
> Model: ATA ST1000DM003-1ER1 (scsi)
> Disk /dev/sdc: 1000GB
> Sector size (logical/physical): 512B/4096B
> Partition Table: gpt
> Disk Flags:
>
> Number Start End Size File system Name Flags
> 1 1049kB 1000GB 1000GB Linux filesystem
>
>
> Model: ATA Corsair Force 3 (scsi)
> Disk /dev/sdd: 240GB
> Sector size (logical/physical): 512B/512B
> Partition Table: msdos
> Disk Flags:
>
> Number Start End Size Type File system Flags
> 1 1049kB 256MB 255MB primary ext2 boot
> 4 257MB 123GB 123GB extended
> 5 258MB 21.2GB 21.0GB logical ext4
> 6 21.2GB 42.2GB 21.0GB logical ext4
> 7 42.2GB 73.7GB 31.5GB logical ext4
> 8 73.7GB 77.9GB 4194MB logical ext4
> 9 77.9GB 98.8GB 21.0GB logical ext4
> 10 98.8GB 123GB 24.5GB logical linux-swap(v1)
>
>
> Model: ATA ST31000524AS (scsi)
> Disk /dev/sde: 1000GB
> Sector size (logical/physical): 512B/512B
> Partition Table: msdos
> Disk Flags:
>
> Number Start End Size Type File system Flags
> 1 1049kB 1000GB 1000GB primary raid
>
>
> Model: ATA ST31000524AS (scsi)
> Disk /dev/sdf: 1000GB
> Sector size (logical/physical): 512B/512B
> Partition Table: msdos
> Disk Flags:
>
> Number Start End Size File system Name Flags
>
>
> The array was formed from sdb1, sdc1, sde1 and sdf1.
>
> The array had been setup as an ext4 device.
>
> I halted the array using:
>
> mdadm --stop /dev/md0
>
> I then setup a copy from the original drives (sdc1 and sdf1) to a
> drive pulled from a project that I have just started on.
>
>
> dd if=/dev/sdc1 bs=1M | gzip > /mnt/newbackupdisk/sdc1.img.gz
> dd if=/dev/sdf1 bs=1M | gzip > /mnt/newbackupdisk/sdf1.img.gz
>
>
> When I checked using md5sum the copy of sdf1 and the original do NOT match.
>
>
> Please?
>
> How can I get a copy of the information off of the raid 10 array?
> Is there a way to verify this copy?
> How to I re-setup the raid 10 array?
> Should I be replacing sde (drive with a momentary failure)?
>
> (Hopefully not too many questions nor too much initial information!!)
>
> Any advice will be greatly appreciated!!
>
> TIA
>
> Dee
> --
> To unsubscribe from this list: send the line "unsubscribe linux-raid" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH] imsm: don't call abort_reshape() in imsm_manage_reshape()
From: Artur Paszkiewicz @ 2015-09-04 9:33 UTC (permalink / raw)
To: neilb; +Cc: linux-raid, Artur Paszkiewicz, Konrad Dabrowski
Calling abort_reshape() in imsm_manage_reshape() is unnecessary in case
of an error because it is handled by reshape_array(). Calling it when
reshape completes successfully is also unnecessary and leads to a race
condition:
- reshape ends
- mdadm calls abort_reshape() -> sets sync_action to idle
- MD_RECOVERY_INTR is set and md_reap_sync_thread() does not finish the
reshape
Signed-off-by: Artur Paszkiewicz <artur.paszkiewicz@intel.com>
Signed-off-by: Konrad Dabrowski <konrad.dabrowski@intel.com>
---
super-intel.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/super-intel.c b/super-intel.c
index 95a72b6..e609e0c 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -10601,7 +10601,6 @@ static int imsm_manage_reshape(
ret_val = 1;
abort:
free(buf);
- abort_reshape(sra);
return ret_val;
}
--
2.1.4
^ permalink raw reply related
* [PATCH] dm: ioctl: prevent double freeing
From: Sudip Mukherjee @ 2015-09-04 11:22 UTC (permalink / raw)
To: Alasdair Kergon, Mike Snitzer, dm-devel, Neil Brown
Cc: linux-kernel, linux-raid, Sudip Mukherjee
DM_PARAMS_KMALLOC and DM_PARAMS_VMALLOC should never be set together in
param_flags. We are setting these flags while allocating so we know that
there is almost no chance of having these two set together but still we
can have some additional safety.
Signed-off-by: Sudip Mukherjee <sudip@vectorindia.org>
---
drivers/md/dm-ioctl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
index 80a4395..aaad74e 100644
--- a/drivers/md/dm-ioctl.c
+++ b/drivers/md/dm-ioctl.c
@@ -1680,7 +1680,7 @@ static void free_params(struct dm_ioctl *param, size_t param_size, int param_fla
if (param_flags & DM_PARAMS_KMALLOC)
kfree(param);
- if (param_flags & DM_PARAMS_VMALLOC)
+ else if (param_flags & DM_PARAMS_VMALLOC)
vfree(param);
}
--
1.9.1
^ permalink raw reply related
* [PATCH] raid5-cache: check stripe finish out of order
From: Shaohua Li @ 2015-09-04 21:14 UTC (permalink / raw)
To: linux-raid; +Cc: Kernel-team, songliubraving, hch, dan.j.williams, neilb
stripes could finish out of order. Hence r5l_move_io_unit_list() of
__r5l_stripe_write_finished might not move any entry and leave
stripe_end_ios list empty.
This applies on top of http://marc.info/?l=linux-raid&m=144122700510667
Signed-off-by: Shaohua Li <shli@fb.com>
---
drivers/md/raid5-cache.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 410b85b..2dea05f 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -545,8 +545,13 @@ static void __r5l_stripe_write_finished(struct r5l_io_unit *io)
spin_lock_irqsave(&log->io_list_lock, flags);
__r5l_set_io_unit_state(io, IO_UNIT_STRIPE_END);
+ /* might move 0 entry */
r5l_move_io_unit_list(&log->flushed_ios, &log->stripe_end_ios,
IO_UNIT_STRIPE_END);
+ if (list_empty(&log->stripe_end_ios)) {
+ spin_unlock_irqrestore(&log->io_list_lock, flags);
+ return;
+ }
last = list_last_entry(&log->stripe_end_ios,
struct r5l_io_unit, log_sibling);
--
1.8.1
^ permalink raw reply related
* [PATCH] raid5-cache: don't delay stripe captured in log
From: Shaohua Li @ 2015-09-04 21:14 UTC (permalink / raw)
To: linux-raid; +Cc: Kernel-team, songliubraving, hch, dan.j.williams, neilb
There is a case a stripe gets delayed forever.
1. a stripe finishes construction
2. a new bio hits the stripe
3. handle_stripe runs for the stripe. The stripe gets DELAYED bit set
since construction can't run for new bio (the stripe is locked since
step 1)
Without log, handle_stripe will call ops_run_io. After IO finishes, the
stripe gets unlocked and the stripe will restart and run construction
for the new bio. With log, ops_run_io need to run two times. If the
DELAYED bit set, the stripe can't enter into the handle_list, so the
second ops_run_io doesn't run, which leaves the stripe stalled.
Signed-off-by: Shaohua Li <shli@fb.com>
---
drivers/md/raid5-cache.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 2dea05f..785749b1 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -474,6 +474,11 @@ int r5l_write_stripe(struct r5l_log *log, struct stripe_head *sh)
return -EINVAL;
set_bit(STRIPE_LOG_TRAPPED, &sh->state);
+ /*
+ * The stripe must enter state machine again to finish the write, so
+ * don't delay.
+ * */
+ clear_bit(STRIPE_DELAYED, &sh->state);
atomic_inc(&sh->count);
mutex_lock(&log->io_mutex);
--
1.8.1
^ permalink raw reply related
* [GIT PULL REQUEST] md updates for 4.3
From: Neil Brown @ 2015-09-05 9:37 UTC (permalink / raw)
To: Linus Torvalds
Cc: linux-raid, linux-kernel, Goldwyn Rodrigues, Guoqing Jiang,
Lidong Zhong, Sasha Levin, Ard Biesheuvel, Markus Stockhausen,
Yi Zhang, Benjamin Randazzo
[-- Attachment #1: Type: text/plain, Size: 3991 bytes --]
Please pull these updates. I've already merged with the 'block' tree
to resolve a few simple conflicts.
Thanks,
NeilBrown
The following changes since commit 1081230b748de8f03f37f80c53dfa89feda9b8de:
Merge branch 'for-4.3/core' of git://git.kernel.dk/linux-block (2015-09-02 13:10:25 -0700)
are available in the git repository at:
git://neil.brown.name/md tags/md/4.3
for you to fetch changes up to e89c6fdf9e0eb1b5a03574d4ca73e83eae8deb91:
Merge linux-block/for-4.3/core into md/for-linux (2015-09-05 11:08:32 +0200)
----------------------------------------------------------------
md updates for 4.3
- An assortment of little fixes, several for minor races only likely
to be hit during testing
- further cluster-md-raid1 development, not ready for real use yet.
- new RAID6 syndrome code for ARM NEON
- fix a race where a write can return before failure of one device
is properly recorded in metadata, so an immediate crash might result
in that write being lost.
----------------------------------------------------------------
Ard Biesheuvel (1):
md/raid6: delta syndrome for ARM NEON
Benjamin Randazzo (1):
md: simplify get_bitmap_file now that "file" is zeroed.
Guoqing Jiang (11):
md-cluster: use %pU to print UUIDs
md-cluster: split recover_slot for future code reuse
md-cluster: transfer the resync ownership to another node
md-cluster: fix deadlock issue on message lock
md-cluster: init completion within lockres_init
md-cluster: add the error check if failed to get dlm lock
md-cluster: init suspend_list and suspend_lock early in join
md-cluster: remove the unused sb_lock
md-cluster: add missed lockres_free
md-cluster: only call complete(&cinfo->completion) when node join cluster
md-cluster: Read the disk bitmap sb and check if it needs recovery
NeilBrown (20):
md/raid0: update queue parameter in a safer location.
md: Keep /proc/mdstat reporting recovery until fully DONE.
md: close some races between setting and checking sync_action.
md/raid5: consider updating reshape_position at start of reshape.
md/raid10: fix a few typos in comments
md/raid5: always set conf->prev_chunk_sectors and ->prev_algo
md/raid5: switch to use conf->chunk_sectors in place of mddev->chunk_sectors where possible
md/raid5: strengthen check on reshape_position at run.
md/raid5: remove incorrect "min_t()" when calculating writepos.
md: set MD_RECOVERY_RECOVER when starting a degraded array.
md: be careful when testing resync_max against curr_resync_completed.
md: sync sync_completed has correct value as recovery finishes.
md/raid5: handle possible race as reshape completes.
md: extend spinlock protection in register_md_cluster_operations
md-cluster: remove inappropriate try_module_get from join()
md/raid1: ensure device failure recorded before write request returns.
md/raid10: ensure device failure recorded before write request returns.
md/raid5: use bio_list for the list of bios to return.
md/raid5: ensure device failure recorded before write request returns.
Merge linux-block/for-4.3/core into md/for-linux
Sasha Levin (1):
md: setup safemode_timer before it's being used
Documentation/md-cluster.txt | 4 +-
drivers/md/md-cluster.c | 159 ++++++++++++++++++++++++++++---------------
drivers/md/md.c | 110 +++++++++++++++++++-----------
drivers/md/raid0.c | 75 ++++++++++----------
drivers/md/raid1.c | 30 +++++++-
drivers/md/raid1.h | 5 ++
drivers/md/raid10.c | 33 ++++++++-
drivers/md/raid10.h | 6 ++
drivers/md/raid5.c | 140 ++++++++++++++++++++++---------------
drivers/md/raid5.h | 5 +-
lib/raid6/neon.c | 13 +++-
lib/raid6/neon.uc | 46 +++++++++++++
12 files changed, 433 insertions(+), 193 deletions(-)
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]
^ permalink raw reply
* Re: [GIT PULL REQUEST] md updates for 4.3
From: Linus Torvalds @ 2015-09-06 1:03 UTC (permalink / raw)
To: Neil Brown
Cc: linux-raid@vger.kernel.org, Linux Kernel Mailing List,
Goldwyn Rodrigues, Guoqing Jiang, Lidong Zhong, Sasha Levin,
Ard Biesheuvel, Markus Stockhausen, Yi Zhang, Benjamin Randazzo
In-Reply-To: <87si6t6wc9.fsf@notabene.neil.brown.name>
On Sat, Sep 5, 2015 at 2:37 AM, Neil Brown <neil@brown.name> wrote:
>
> Please pull these updates. I've already merged with the 'block' tree
> to resolve a few simple conflicts.
So for the future, I actually prefer to see and handle the conflicts myself.
I really just prefer knowing what's going on, and merge conflicts are
an indication of cross-maintainer issues which are *exactly* the kinds
of things I want to be aware of.
However, in this case I was "ok, I've already done several other merge
resolutions with the wbole damn bio_endio error handling changes", so
I felt I was aware enough about how that ended up being a
cross-subsystem conflict, and just took your pre-merged version.
If you feel that the conflicts are particularly subtle, or just
generally worry about the merge, or just because you want to do some
merge-testing, what some people end up doing is to send me their
unmerged branch, and then send me a separate ".. and here's the merge
I did". I'll then do the merge myself anyway, but then after doing the
merge I'll switch to a temporary testing branch and re-do the merge
with the pre-merged state just to verify. Generally the end result is
identical, but when it isn't, that's actually usually interesting
(sometimes it's just a ordering difference, but sometimes it's a merge
error - and so far I think most merge errors have come from
sub-maintainers, for the simple reason that they generally aren't as
used to merging as I am - so even if they know the code better, I
sometimes catch merge gotcha's better).
Thanks,
Linus
^ permalink raw reply
* Change "mv $targetdir/log $logdir/$log" to "cp $targetdir/log $logdir/$log"
From: Yi Zhang @ 2015-09-07 3:28 UTC (permalink / raw)
To: neil; +Cc: linux-raid
In-Reply-To: <2004794274.22089532.1441594962520.JavaMail.zimbra@redhat.com>
Hi Neil
When I execute mdadm test with --save-logs set, found below error, could you help check it?
Error log:
tests/10ddf-fail-readd... FAILED - see /var/tmp/log-10ddf-fail-readd for details
cp: cannot stat ‘/var/tmp/log’: No such file or directory
Code:
if ( set -ex ; . $_script ) &> $targetdir/log
then
echo "succeeded"
_fail=0
else
log=log
cat $targetdir/stderr >> $targetdir/log
echo "=======================dmesg=================" >> $targetdir/log
dmesg | tail -n 200 >> $targetdir/log
if [ $exitonerror == 0 ]; then
log=log-`basename $_script`
mv $targetdir/log $logdir/$log // This step will move $targetdir/log to $logdir/$log,
fi
echo "FAILED - see $logdir/$log for details"
_fail=1
fi
if [ "$savelogs" == "1" ]; then
cp $targetdir/log $logdir/$_basename.log // If I set $savelogs here, the $targetdir/log doesn't exist now
fi
So could we change the mv to cp?
diff --git a/test b/test
index d0a6cb8..118fa96 100755
--- a/test
+++ b/test
@@ -318,7 +318,7 @@ do_test() {
dmesg | tail -n 200 >> $targetdir/log
if [ $exitonerror == 0 ]; then
log=log-`basename $_script`
- mv $targetdir/log $logdir/$log
+ cp $targetdir/log $logdir/$log
fi
echo "FAILED - see $logdir/$log for details"
_fail=1
Best Regards,
Yi Zhang
--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* raid5-cache I/O path improvements
From: Christoph Hellwig @ 2015-09-07 5:20 UTC (permalink / raw)
To: Shaohua Li, neilb; +Cc: linux-raid, Kernel-team, dan.j.williams
Hi Shaohua, hi Neil,
this series contains a few updates to the raid5-cache feature.
The first patch just ports it to the post-4.2 block layer. As part of that
I noticed that it currently doesn't handle I/O errors - fixes for that will
follow.
The second and third patch simplify the I/O unit state machine and reduce
latency and memory usage for the I/O units. The remainder are just a couple
of cleanups in this area that I stumbled upon.
^ permalink raw reply
* [PATCH 01/10] raid5-cache: port to 4.3-rc
From: Christoph Hellwig @ 2015-09-07 5:20 UTC (permalink / raw)
To: Shaohua Li, neilb; +Cc: linux-raid, Kernel-team, dan.j.williams
In-Reply-To: <1441603250-5119-1-git-send-email-hch@lst.de>
Port for changes in the block layer: bio endio callers don't get passed
a separate error, and bio_get_nr_vecs is gone.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/md/raid5-cache.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 785749b1..c345479 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -222,7 +222,8 @@ static void __r5l_set_io_unit_state(struct r5l_io_unit *io,
io->state = state;
}
-static inline void r5l_log_endio(struct bio *bio, int error)
+/* XXX: totally ignores I/O errors */
+static void r5l_log_endio(struct bio *bio)
{
struct r5l_io_unit *io = bio->bi_private;
struct r5l_log *log = io->log;
@@ -288,8 +289,7 @@ static struct r5l_io_unit *r5l_new_meta(struct r5l_log *log)
io->meta_offset = sizeof(struct r5l_meta_block);
io->seq = log->seq;
- bio = bio_kmalloc(GFP_NOIO | __GFP_NOFAIL,
- bio_get_nr_vecs(log->rdev->bdev));
+ bio = bio_kmalloc(GFP_NOIO | __GFP_NOFAIL, BIO_MAX_PAGES);
io->current_bio = bio;
bio->bi_rw = WRITE;
bio->bi_bdev = log->rdev->bdev;
@@ -358,8 +358,7 @@ static void r5l_append_payload_page(struct r5l_log *log, struct page *page)
alloc_bio:
if (!io->current_bio) {
struct bio *bio;
- bio = bio_kmalloc(GFP_NOIO | __GFP_NOFAIL,
- bio_get_nr_vecs(log->rdev->bdev));
+ bio = bio_kmalloc(GFP_NOIO | __GFP_NOFAIL, BIO_MAX_PAGES);
bio->bi_rw = WRITE;
bio->bi_bdev = log->rdev->bdev;
bio->bi_iter.bi_sector = log->log_start;
@@ -518,7 +517,7 @@ int r5l_handle_flush_request(struct r5l_log *log, struct bio *bio)
* don't need to flush again
* */
if (bio->bi_iter.bi_size == 0) {
- bio_endio(bio, 0);
+ bio_endio(bio);
return 0;
}
bio->bi_rw &= ~REQ_FLUSH;
@@ -581,7 +580,7 @@ void r5l_stripe_write_finished(struct stripe_head *sh)
__r5l_stripe_write_finished(io);
}
-static void r5l_log_flush_endio(struct bio *bio, int error)
+static void r5l_log_flush_endio(struct bio *bio)
{
struct r5l_log *log = container_of(bio, struct r5l_log,
flush_bio);
--
1.9.1
^ permalink raw reply related
* [PATCH 02/10] raid5-cache: free I/O units earlier
From: Christoph Hellwig @ 2015-09-07 5:20 UTC (permalink / raw)
To: Shaohua Li, neilb; +Cc: linux-raid, Kernel-team, dan.j.williams
In-Reply-To: <1441603250-5119-1-git-send-email-hch@lst.de>
There is no good reason to keep the I/O unit structures around after the
stripe has been written back to the RAID array. The only information
we need is the log sequence number, and the checkpoint offset of the
highest successfull writeback. Store those in the log structure, and
free the IO units from __r5l_stripe_write_finished.
Besides simplifying the code this also avoid having to keep the allocation
for the I/O unit around for a potentially long time as superblock updates
that checkpoint the log do not happen very often.
This also fixes the previously incorrect calculation of 'free' in
r5l_do_reclaim as a side effect: previous if took the last unit which
isn't checkpointed into account.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/md/raid5-cache.c | 145 ++++++++++++++++++-----------------------------
1 file changed, 55 insertions(+), 90 deletions(-)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index c345479..803bcc6 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -51,6 +51,9 @@ struct r5l_log {
sector_t log_start; /* log head. where new data appends */
u64 seq; /* log head sequence */
+ sector_t next_checkpoint;
+ u64 next_cp_seq;
+
struct mutex io_mutex;
struct r5l_io_unit *current_io; /* current io_unit accepting new data */
@@ -65,10 +68,6 @@ struct r5l_log {
* cache flush */
struct list_head flushed_ios; /* io_units which settle down in log disk */
struct bio flush_bio;
- struct list_head stripe_end_ios; /* io_units which have been
- * completely written to the RAID *
- * but have not yet been considered *
- * for updating super */
struct kmem_cache *io_kc;
@@ -185,35 +184,6 @@ static void r5l_move_io_unit_list(struct list_head *from, struct list_head *to,
}
}
-/*
- * We don't want too many io_units reside in stripe_end_ios list, which will
- * waste a lot of memory. So we try to remove some. But we must keep at least 2
- * io_units. The superblock must point to a valid meta, if it's the last meta,
- * recovery can scan less
- * */
-static void r5l_compress_stripe_end_list(struct r5l_log *log)
-{
- struct r5l_io_unit *first, *last, *io;
-
- first = list_first_entry(&log->stripe_end_ios,
- struct r5l_io_unit, log_sibling);
- last = list_last_entry(&log->stripe_end_ios,
- struct r5l_io_unit, log_sibling);
- if (first == last)
- return;
- list_del(&first->log_sibling);
- list_del(&last->log_sibling);
- while (!list_empty(&log->stripe_end_ios)) {
- io = list_first_entry(&log->stripe_end_ios,
- struct r5l_io_unit, log_sibling);
- list_del(&io->log_sibling);
- first->log_end = io->log_end;
- r5l_free_io_unit(log, io);
- }
- list_add_tail(&first->log_sibling, &log->stripe_end_ios);
- list_add_tail(&last->log_sibling, &log->stripe_end_ios);
-}
-
static void __r5l_set_io_unit_state(struct r5l_io_unit *io,
enum r5l_io_unit_state state)
{
@@ -540,31 +510,53 @@ static void r5l_run_no_space_stripes(struct r5l_log *log)
spin_unlock(&log->no_space_stripes_lock);
}
+static sector_t r5l_reclaimable_space(struct r5l_log *log)
+{
+ return r5l_ring_distance(log, log->last_checkpoint,
+ log->next_checkpoint);
+}
+
+static bool r5l_complete_flushed_ios(struct r5l_log *log)
+{
+ struct r5l_io_unit *io, *next;
+ bool found = false;
+
+ assert_spin_locked(&log->io_list_lock);
+
+ list_for_each_entry_safe(io, next, &log->flushed_ios, log_sibling) {
+ /* don't change list order */
+ if (io->state < IO_UNIT_STRIPE_END)
+ break;
+
+ log->next_checkpoint = io->log_start;
+ log->next_cp_seq = io->seq;
+
+ list_del(&io->log_sibling);
+ r5l_free_io_unit(log, io);
+
+ found = true;
+ }
+
+
+ return found;
+}
+
static void __r5l_stripe_write_finished(struct r5l_io_unit *io)
{
struct r5l_log *log = io->log;
- struct r5l_io_unit *last;
- sector_t reclaimable_space;
unsigned long flags;
spin_lock_irqsave(&log->io_list_lock, flags);
__r5l_set_io_unit_state(io, IO_UNIT_STRIPE_END);
- /* might move 0 entry */
- r5l_move_io_unit_list(&log->flushed_ios, &log->stripe_end_ios,
- IO_UNIT_STRIPE_END);
- if (list_empty(&log->stripe_end_ios)) {
+
+ if (!r5l_complete_flushed_ios(log)) {
spin_unlock_irqrestore(&log->io_list_lock, flags);
return;
}
- last = list_last_entry(&log->stripe_end_ios,
- struct r5l_io_unit, log_sibling);
- reclaimable_space = r5l_ring_distance(log, log->last_checkpoint,
- last->log_end);
- if (reclaimable_space >= log->max_free_space)
+ if (r5l_reclaimable_space(log) > log->max_free_space)
r5l_wake_reclaim(log, 0);
- r5l_compress_stripe_end_list(log);
spin_unlock_irqrestore(&log->io_list_lock, flags);
wake_up(&log->iounit_wait);
}
@@ -640,13 +632,6 @@ void r5l_flush_stripe_to_raid(struct r5l_log *log)
submit_bio(WRITE_FLUSH, &log->flush_bio);
}
-static void r5l_kick_io_unit(struct r5l_log *log)
-{
- md_wakeup_thread(log->rdev->mddev->thread);
- wait_event_lock_irq(log->iounit_wait, !list_empty(&log->stripe_end_ios),
- log->io_list_lock);
-}
-
static void r5l_write_super(struct r5l_log *log, sector_t cp);
static void r5l_write_super_and_discard_space(struct r5l_log *log,
sector_t end)
@@ -678,10 +663,10 @@ static void r5l_write_super_and_discard_space(struct r5l_log *log,
static void r5l_do_reclaim(struct r5l_log *log)
{
- struct r5l_io_unit *io, *last;
- LIST_HEAD(list);
- sector_t free = 0;
sector_t reclaim_target = xchg(&log->reclaim_target, 0);
+ sector_t reclaimable;
+ sector_t next_checkpoint;
+ u64 next_cp_seq;
spin_lock_irq(&log->io_list_lock);
/*
@@ -690,60 +675,41 @@ static void r5l_do_reclaim(struct r5l_log *log)
* shouldn't reuse space of an unreclaimable io_unit
* */
while (1) {
- struct list_head *target_list = NULL;
-
- while (!list_empty(&log->stripe_end_ios)) {
- io = list_first_entry(&log->stripe_end_ios,
- struct r5l_io_unit, log_sibling);
- list_move_tail(&io->log_sibling, &list);
- free += r5l_ring_distance(log, io->log_start,
- io->log_end);
- }
-
- if (free >= reclaim_target ||
+ reclaimable = r5l_reclaimable_space(log);
+ if (reclaimable >= reclaim_target ||
(list_empty(&log->running_ios) &&
list_empty(&log->io_end_ios) &&
list_empty(&log->flushing_ios) &&
list_empty(&log->flushed_ios)))
break;
- /* Below waiting mostly happens when we shutdown the raid */
- if (!list_empty(&log->flushed_ios))
- target_list = &log->flushed_ios;
- else if (!list_empty(&log->flushing_ios))
- target_list = &log->flushing_ios;
- else if (!list_empty(&log->io_end_ios))
- target_list = &log->io_end_ios;
- else if (!list_empty(&log->running_ios))
- target_list = &log->running_ios;
-
- r5l_kick_io_unit(log);
+ md_wakeup_thread(log->rdev->mddev->thread);
+ wait_event_lock_irq(log->iounit_wait,
+ r5l_reclaimable_space(log) > reclaimable,
+ log->io_list_lock);
}
+
+ next_checkpoint = log->next_checkpoint;
+ next_cp_seq = log->next_cp_seq;
spin_unlock_irq(&log->io_list_lock);
- if (list_empty(&list))
+ BUG_ON(reclaimable < 0);
+ if (reclaimable == 0)
return;
- /* super always point to last valid meta */
- last = list_last_entry(&list, struct r5l_io_unit, log_sibling);
/*
* write_super will flush cache of each raid disk. We must write super
* here, because the log area might be reused soon and we don't want to
* confuse recovery
* */
- r5l_write_super_and_discard_space(log, last->log_start);
+ r5l_write_super_and_discard_space(log, next_checkpoint);
mutex_lock(&log->io_mutex);
- log->last_checkpoint = last->log_start;
- log->last_cp_seq = last->seq;
+ log->last_checkpoint = next_checkpoint;
+ log->last_cp_seq = next_cp_seq;
mutex_unlock(&log->io_mutex);
- r5l_run_no_space_stripes(log);
- while (!list_empty(&list)) {
- io = list_first_entry(&list, struct r5l_io_unit, log_sibling);
- list_del(&io->log_sibling);
- r5l_free_io_unit(log, io);
- }
+ r5l_run_no_space_stripes(log);
}
static void r5l_reclaim_thread(struct md_thread *thread)
@@ -1105,7 +1071,6 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev)
spin_lock_init(&log->io_list_lock);
INIT_LIST_HEAD(&log->running_ios);
INIT_LIST_HEAD(&log->io_end_ios);
- INIT_LIST_HEAD(&log->stripe_end_ios);
INIT_LIST_HEAD(&log->flushing_ios);
INIT_LIST_HEAD(&log->flushed_ios);
bio_init(&log->flush_bio);
--
1.9.1
^ permalink raw reply related
* [PATCH 03/10] raid5-cache: use FUA writes for the log
From: Christoph Hellwig @ 2015-09-07 5:20 UTC (permalink / raw)
To: Shaohua Li, neilb; +Cc: linux-raid, Kernel-team, dan.j.williams
In-Reply-To: <1441603250-5119-1-git-send-email-hch@lst.de>
If we submit writes with the FUA bit for the log they are guaranteed to
be on stable storage once the endio callback is called. This allows
to simplify the IO unit state machine, and decrease latencies a lot
when the device supports FUA. If the device doesnt' support FUA the
block layer has an efficient state machine to emulate it.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/md/raid5-cache.c | 133 +++++++++++++----------------------------------
drivers/md/raid5.c | 9 +---
drivers/md/raid5.h | 1 -
3 files changed, 37 insertions(+), 106 deletions(-)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 803bcc6..1e54249 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -61,13 +61,8 @@ struct r5l_log {
struct list_head running_ios; /* io_units which are still running,
* and have not yet been completely
* written to the log */
- struct list_head io_end_ios; /* io_units which have been completely
- * written to the log but not yet written
- * to the RAID */
- struct list_head flushing_ios; /* io_units which are waiting for log
- * cache flush */
- struct list_head flushed_ios; /* io_units which settle down in log disk */
- struct bio flush_bio;
+ struct list_head finished_ios; /* io_units already written to the
+ * log disk */
struct kmem_cache *io_kc;
@@ -169,21 +164,6 @@ static void r5l_free_io_unit(struct r5l_log *log, struct r5l_io_unit *io)
kmem_cache_free(log->io_kc, io);
}
-static void r5l_move_io_unit_list(struct list_head *from, struct list_head *to,
- enum r5l_io_unit_state state)
-{
- struct r5l_io_unit *io;
-
- while (!list_empty(from)) {
- io = list_first_entry(from, struct r5l_io_unit, log_sibling);
- /* don't change list order */
- if (io->state >= state)
- list_move_tail(&io->log_sibling, to);
- else
- break;
- }
-}
-
static void __r5l_set_io_unit_state(struct r5l_io_unit *io,
enum r5l_io_unit_state state)
{
@@ -192,6 +172,33 @@ static void __r5l_set_io_unit_state(struct r5l_io_unit *io,
io->state = state;
}
+static void r5l_io_run_stripes(struct r5l_io_unit *io)
+{
+ struct stripe_head *sh, *next;
+
+ list_for_each_entry_safe(sh, next, &io->stripe_list, log_list) {
+ list_del_init(&sh->log_list);
+ set_bit(STRIPE_HANDLE, &sh->state);
+ raid5_release_stripe(sh);
+ }
+}
+
+static void r5l_log_run_stripes(struct r5l_log *log)
+{
+ struct r5l_io_unit *io, *next;
+
+ assert_spin_locked(&log->io_list_lock);
+
+ list_for_each_entry_safe(io, next, &log->running_ios, log_sibling) {
+ /* don't change list order */
+ if (io->state < IO_UNIT_IO_END)
+ break;
+
+ list_move_tail(&io->log_sibling, &log->finished_ios);
+ r5l_io_run_stripes(io);
+ }
+}
+
/* XXX: totally ignores I/O errors */
static void r5l_log_endio(struct bio *bio)
{
@@ -206,11 +213,8 @@ static void r5l_log_endio(struct bio *bio)
spin_lock_irqsave(&log->io_list_lock, flags);
__r5l_set_io_unit_state(io, IO_UNIT_IO_END);
- r5l_move_io_unit_list(&log->running_ios, &log->io_end_ios,
- IO_UNIT_IO_END);
+ r5l_log_run_stripes(log);
spin_unlock_irqrestore(&log->io_list_lock, flags);
-
- md_wakeup_thread(log->rdev->mddev->thread);
}
static void r5l_submit_current_io(struct r5l_log *log)
@@ -237,7 +241,7 @@ static void r5l_submit_current_io(struct r5l_log *log)
while ((bio = bio_list_pop(&io->bios))) {
/* all IO must start from rdev->data_offset */
bio->bi_iter.bi_sector += log->rdev->data_offset;
- submit_bio(WRITE, bio);
+ submit_bio(WRITE | REQ_FUA, bio);
}
}
@@ -516,14 +520,14 @@ static sector_t r5l_reclaimable_space(struct r5l_log *log)
log->next_checkpoint);
}
-static bool r5l_complete_flushed_ios(struct r5l_log *log)
+static bool r5l_complete_finished_ios(struct r5l_log *log)
{
struct r5l_io_unit *io, *next;
bool found = false;
assert_spin_locked(&log->io_list_lock);
- list_for_each_entry_safe(io, next, &log->flushed_ios, log_sibling) {
+ list_for_each_entry_safe(io, next, &log->finished_ios, log_sibling) {
/* don't change list order */
if (io->state < IO_UNIT_STRIPE_END)
break;
@@ -549,7 +553,7 @@ static void __r5l_stripe_write_finished(struct r5l_io_unit *io)
spin_lock_irqsave(&log->io_list_lock, flags);
__r5l_set_io_unit_state(io, IO_UNIT_STRIPE_END);
- if (!r5l_complete_flushed_ios(log)) {
+ if (!r5l_complete_finished_ios(log)) {
spin_unlock_irqrestore(&log->io_list_lock, flags);
return;
}
@@ -572,66 +576,6 @@ void r5l_stripe_write_finished(struct stripe_head *sh)
__r5l_stripe_write_finished(io);
}
-static void r5l_log_flush_endio(struct bio *bio)
-{
- struct r5l_log *log = container_of(bio, struct r5l_log,
- flush_bio);
- unsigned long flags;
- struct r5l_io_unit *io;
- struct stripe_head *sh;
-
- spin_lock_irqsave(&log->io_list_lock, flags);
- list_for_each_entry(io, &log->flushing_ios, log_sibling) {
- while (!list_empty(&io->stripe_list)) {
- sh = list_first_entry(&io->stripe_list,
- struct stripe_head, log_list);
- list_del_init(&sh->log_list);
- set_bit(STRIPE_HANDLE, &sh->state);
- raid5_release_stripe(sh);
- }
- }
- list_splice_tail_init(&log->flushing_ios, &log->flushed_ios);
- spin_unlock_irqrestore(&log->io_list_lock, flags);
-}
-
-/*
- * Starting dispatch IO to raid.
- * io_unit(meta) consists of a log. There is one situation we want to avoid. A
- * broken meta in the middle of a log causes recovery can't find meta at the
- * head of log. If operations require meta at the head persistent in log, we
- * must make sure meta before it persistent in log too. A case is:
- *
- * stripe data/parity is in log, we start write stripe to raid disks. stripe
- * data/parity must be persistent in log before we do the write to raid disks.
- *
- * The solution is we restrictly maintain io_unit list order. In this case, we
- * only write stripes of an io_unit to raid disks till the io_unit is the first
- * one whose data/parity is in log.
- * */
-void r5l_flush_stripe_to_raid(struct r5l_log *log)
-{
- bool do_flush;
- if (!log)
- return;
-
- spin_lock_irq(&log->io_list_lock);
- /* flush bio is running */
- if (!list_empty(&log->flushing_ios)) {
- spin_unlock_irq(&log->io_list_lock);
- return;
- }
- list_splice_tail_init(&log->io_end_ios, &log->flushing_ios);
- do_flush = !list_empty(&log->flushing_ios);
- spin_unlock_irq(&log->io_list_lock);
-
- if (!do_flush)
- return;
- bio_reset(&log->flush_bio);
- log->flush_bio.bi_bdev = log->rdev->bdev;
- log->flush_bio.bi_end_io = r5l_log_flush_endio;
- submit_bio(WRITE_FLUSH, &log->flush_bio);
-}
-
static void r5l_write_super(struct r5l_log *log, sector_t cp);
static void r5l_write_super_and_discard_space(struct r5l_log *log,
sector_t end)
@@ -678,9 +622,7 @@ static void r5l_do_reclaim(struct r5l_log *log)
reclaimable = r5l_reclaimable_space(log);
if (reclaimable >= reclaim_target ||
(list_empty(&log->running_ios) &&
- list_empty(&log->io_end_ios) &&
- list_empty(&log->flushing_ios) &&
- list_empty(&log->flushed_ios)))
+ list_empty(&log->finished_ios)))
break;
md_wakeup_thread(log->rdev->mddev->thread);
@@ -1070,10 +1012,7 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev)
spin_lock_init(&log->io_list_lock);
INIT_LIST_HEAD(&log->running_ios);
- INIT_LIST_HEAD(&log->io_end_ios);
- INIT_LIST_HEAD(&log->flushing_ios);
- INIT_LIST_HEAD(&log->flushed_ios);
- bio_init(&log->flush_bio);
+ INIT_LIST_HEAD(&log->finished_ios);
log->io_kc = KMEM_CACHE(r5l_io_unit, 0);
if (!log->io_kc)
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index d86a39e..99e2d13 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -5732,12 +5732,8 @@ static int handle_active_stripes(struct r5conf *conf, int group,
for (i = 0; i < NR_STRIPE_HASH_LOCKS; i++)
if (!list_empty(temp_inactive_list + i))
break;
- if (i == NR_STRIPE_HASH_LOCKS) {
- spin_unlock_irq(&conf->device_lock);
- r5l_flush_stripe_to_raid(conf->log);
- spin_lock_irq(&conf->device_lock);
+ if (i == NR_STRIPE_HASH_LOCKS)
return batch_size;
- }
release_inactive = true;
}
spin_unlock_irq(&conf->device_lock);
@@ -5745,7 +5741,6 @@ static int handle_active_stripes(struct r5conf *conf, int group,
release_inactive_stripe_list(conf, temp_inactive_list,
NR_STRIPE_HASH_LOCKS);
- r5l_flush_stripe_to_raid(conf->log);
if (release_inactive) {
spin_lock_irq(&conf->device_lock);
return 0;
@@ -5875,8 +5870,6 @@ static void raid5d(struct md_thread *thread)
mutex_unlock(&conf->cache_size_mutex);
}
- r5l_flush_stripe_to_raid(conf->log);
-
async_tx_issue_pending_all();
blk_finish_plug(&plug);
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index b85ee02..720f0b3 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h
@@ -624,7 +624,6 @@ extern int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev);
extern void r5l_exit_log(struct r5l_log *log);
extern int r5l_write_stripe(struct r5l_log *log, struct stripe_head *head_sh);
extern void r5l_write_stripe_run(struct r5l_log *log);
-extern void r5l_flush_stripe_to_raid(struct r5l_log *log);
extern void r5l_stripe_write_finished(struct stripe_head *sh);
extern int r5l_handle_flush_request(struct r5l_log *log, struct bio *bio);
#endif
--
1.9.1
^ permalink raw reply related
* [PATCH 04/10] raid5-cache: clean up r5l_get_meta
From: Christoph Hellwig @ 2015-09-07 5:20 UTC (permalink / raw)
To: Shaohua Li, neilb; +Cc: linux-raid, Kernel-team, dan.j.williams
In-Reply-To: <1441603250-5119-1-git-send-email-hch@lst.de>
Remove the only partially used local 'io' variable to simplify the code
flow.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/md/raid5-cache.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 1e54249..10ccda3 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -291,16 +291,12 @@ static struct r5l_io_unit *r5l_new_meta(struct r5l_log *log)
static int r5l_get_meta(struct r5l_log *log, unsigned int payload_size)
{
- struct r5l_io_unit *io;
-
- io = log->current_io;
- if (io && io->meta_offset + payload_size > PAGE_SIZE)
+ if (log->current_io &&
+ log->current_io->meta_offset + payload_size > PAGE_SIZE)
r5l_submit_current_io(log);
- io = log->current_io;
- if (io)
- return 0;
- log->current_io = r5l_new_meta(log);
+ if (!log->current_io)
+ log->current_io = r5l_new_meta(log);
return 0;
}
--
1.9.1
^ permalink raw reply related
* [PATCH 05/10] raid5-cache: refactor bio allocation
From: Christoph Hellwig @ 2015-09-07 5:20 UTC (permalink / raw)
To: Shaohua Li, neilb; +Cc: linux-raid, Kernel-team, dan.j.williams
In-Reply-To: <1441603250-5119-1-git-send-email-hch@lst.de>
Split out a helper to allocate a bio for log writes.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/md/raid5-cache.c | 44 ++++++++++++++++++++------------------------
1 file changed, 20 insertions(+), 24 deletions(-)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 10ccda3..d0ad798 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -245,11 +245,25 @@ static void r5l_submit_current_io(struct r5l_log *log)
}
}
+static struct bio *r5l_bio_alloc(struct r5l_log *log, struct r5l_io_unit *io)
+{
+ struct bio *bio = bio_kmalloc(GFP_NOIO | __GFP_NOFAIL, BIO_MAX_PAGES);
+
+ bio->bi_rw = WRITE;
+ bio->bi_bdev = log->rdev->bdev;
+ bio->bi_iter.bi_sector = log->log_start;
+ bio->bi_end_io = r5l_log_endio;
+ bio->bi_private = io;
+
+ bio_list_add(&io->bios, bio);
+ atomic_inc(&io->pending_io);
+ return bio;
+}
+
static struct r5l_io_unit *r5l_new_meta(struct r5l_log *log)
{
struct r5l_io_unit *io;
struct r5l_meta_block *block;
- struct bio *bio;
io = r5l_alloc_io_unit(log);
@@ -263,17 +277,8 @@ static struct r5l_io_unit *r5l_new_meta(struct r5l_log *log)
io->meta_offset = sizeof(struct r5l_meta_block);
io->seq = log->seq;
- bio = bio_kmalloc(GFP_NOIO | __GFP_NOFAIL, BIO_MAX_PAGES);
- io->current_bio = bio;
- bio->bi_rw = WRITE;
- bio->bi_bdev = log->rdev->bdev;
- bio->bi_iter.bi_sector = log->log_start;
- bio_add_page(bio, io->meta_page, PAGE_SIZE, 0);
- bio->bi_end_io = r5l_log_endio;
- bio->bi_private = io;
-
- bio_list_add(&io->bios, bio);
- atomic_inc(&io->pending_io);
+ io->current_bio = r5l_bio_alloc(log, io);
+ bio_add_page(io->current_bio, io->meta_page, PAGE_SIZE, 0);
log->seq++;
log->log_start = r5l_ring_add(log, log->log_start, BLOCK_SECTORS);
@@ -326,18 +331,9 @@ static void r5l_append_payload_page(struct r5l_log *log, struct page *page)
struct r5l_io_unit *io = log->current_io;
alloc_bio:
- if (!io->current_bio) {
- struct bio *bio;
- bio = bio_kmalloc(GFP_NOIO | __GFP_NOFAIL, BIO_MAX_PAGES);
- bio->bi_rw = WRITE;
- bio->bi_bdev = log->rdev->bdev;
- bio->bi_iter.bi_sector = log->log_start;
- bio->bi_end_io = r5l_log_endio;
- bio->bi_private = io;
- bio_list_add(&io->bios, bio);
- atomic_inc(&io->pending_io);
- io->current_bio = bio;
- }
+ if (!io->current_bio)
+ io->current_bio = r5l_bio_alloc(log, io);
+
if (!bio_add_page(io->current_bio, page, PAGE_SIZE, 0)) {
io->current_bio = NULL;
goto alloc_bio;
--
1.9.1
^ permalink raw reply related
* [PATCH 06/10] raid5-cache: take rdev->data_offset into account early on
From: Christoph Hellwig @ 2015-09-07 5:20 UTC (permalink / raw)
To: Shaohua Li, neilb; +Cc: linux-raid, Kernel-team, dan.j.williams
In-Reply-To: <1441603250-5119-1-git-send-email-hch@lst.de>
Set up bi_sector properly when we allocate an bio instead of updating it
at submission time.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/md/raid5-cache.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index d0ad798..df79d49 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -238,11 +238,8 @@ static void r5l_submit_current_io(struct r5l_log *log)
__r5l_set_io_unit_state(io, IO_UNIT_IO_START);
spin_unlock_irqrestore(&log->io_list_lock, flags);
- while ((bio = bio_list_pop(&io->bios))) {
- /* all IO must start from rdev->data_offset */
- bio->bi_iter.bi_sector += log->rdev->data_offset;
+ while ((bio = bio_list_pop(&io->bios)))
submit_bio(WRITE | REQ_FUA, bio);
- }
}
static struct bio *r5l_bio_alloc(struct r5l_log *log, struct r5l_io_unit *io)
@@ -251,7 +248,7 @@ static struct bio *r5l_bio_alloc(struct r5l_log *log, struct r5l_io_unit *io)
bio->bi_rw = WRITE;
bio->bi_bdev = log->rdev->bdev;
- bio->bi_iter.bi_sector = log->log_start;
+ bio->bi_iter.bi_sector = log->rdev->data_offset + log->log_start;
bio->bi_end_io = r5l_log_endio;
bio->bi_private = io;
--
1.9.1
^ permalink raw reply related
* [PATCH 07/10] raid5-cache: inline r5l_alloc_io_unit into r5l_new_meta
From: Christoph Hellwig @ 2015-09-07 5:20 UTC (permalink / raw)
To: Shaohua Li, neilb; +Cc: linux-raid, Kernel-team, dan.j.williams
In-Reply-To: <1441603250-5119-1-git-send-email-hch@lst.de>
This is the only user, and keeping all code initializing the io_unit
structure together improves readbility.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/md/raid5-cache.c | 26 ++++++++------------------
1 file changed, 8 insertions(+), 18 deletions(-)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index df79d49..2ccc1b0 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -141,23 +141,6 @@ static bool r5l_has_free_space(struct r5l_log *log, sector_t size)
return log->device_size > used_size + size;
}
-static struct r5l_io_unit *r5l_alloc_io_unit(struct r5l_log *log)
-{
- struct r5l_io_unit *io;
- /* We can't handle memory allocate failure so far */
- gfp_t gfp = GFP_NOIO | __GFP_NOFAIL;
-
- io = kmem_cache_zalloc(log->io_kc, gfp);
- io->log = log;
- io->meta_page = alloc_page(gfp | __GFP_ZERO);
-
- bio_list_init(&io->bios);
- INIT_LIST_HEAD(&io->log_sibling);
- INIT_LIST_HEAD(&io->stripe_list);
- io->state = IO_UNIT_RUNNING;
- return io;
-}
-
static void r5l_free_io_unit(struct r5l_log *log, struct r5l_io_unit *io)
{
__free_page(io->meta_page);
@@ -262,8 +245,15 @@ static struct r5l_io_unit *r5l_new_meta(struct r5l_log *log)
struct r5l_io_unit *io;
struct r5l_meta_block *block;
- io = r5l_alloc_io_unit(log);
+ /* We can't handle memory allocate failure so far */
+ io = kmem_cache_zalloc(log->io_kc, GFP_NOIO | __GFP_NOFAIL);
+ io->log = log;
+ bio_list_init(&io->bios);
+ INIT_LIST_HEAD(&io->log_sibling);
+ INIT_LIST_HEAD(&io->stripe_list);
+ io->state = IO_UNIT_RUNNING;
+ io->meta_page = alloc_page(GFP_NOIO | __GFP_NOFAIL | __GFP_ZERO);
block = page_address(io->meta_page);
block->magic = cpu_to_le32(R5LOG_MAGIC);
block->version = R5LOG_VERSION;
--
1.9.1
^ permalink raw reply related
* [PATCH 08/10] raid5-cache: new helper: r5_reserve_log_entry
From: Christoph Hellwig @ 2015-09-07 5:20 UTC (permalink / raw)
To: Shaohua Li, neilb; +Cc: linux-raid, Kernel-team, dan.j.williams
In-Reply-To: <1441603250-5119-1-git-send-email-hch@lst.de>
Factor out code to reserve log space.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/md/raid5-cache.c | 30 +++++++++++++++++++-----------
1 file changed, 19 insertions(+), 11 deletions(-)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 2ccc1b0..ae8caa8 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -240,6 +240,23 @@ static struct bio *r5l_bio_alloc(struct r5l_log *log, struct r5l_io_unit *io)
return bio;
}
+static void r5_reserve_log_entry(struct r5l_log *log, struct r5l_io_unit *io)
+{
+ log->log_start = r5l_ring_add(log, log->log_start, BLOCK_SECTORS);
+
+ /*
+ * If we filled up the log device start from the beginning again,
+ * which will require a new bio.
+ *
+ * Note: for this to work properly the log size needs to me a multiple
+ * of BLOCK_SECTORS.
+ */
+ if (log->log_start == 0)
+ io->current_bio = NULL;
+
+ io->log_end = log->log_start;
+}
+
static struct r5l_io_unit *r5l_new_meta(struct r5l_log *log)
{
struct r5l_io_unit *io;
@@ -268,11 +285,7 @@ static struct r5l_io_unit *r5l_new_meta(struct r5l_log *log)
bio_add_page(io->current_bio, io->meta_page, PAGE_SIZE, 0);
log->seq++;
- log->log_start = r5l_ring_add(log, log->log_start, BLOCK_SECTORS);
- io->log_end = log->log_start;
- /* current bio hit disk end */
- if (log->log_start == 0)
- io->current_bio = NULL;
+ r5_reserve_log_entry(log, io);
spin_lock_irq(&log->io_list_lock);
list_add_tail(&io->log_sibling, &log->running_ios);
@@ -325,13 +338,8 @@ alloc_bio:
io->current_bio = NULL;
goto alloc_bio;
}
- log->log_start = r5l_ring_add(log, log->log_start,
- BLOCK_SECTORS);
- /* current bio hit disk end */
- if (log->log_start == 0)
- io->current_bio = NULL;
- io->log_end = log->log_start;
+ r5_reserve_log_entry(log, io);
}
static void r5l_log_stripe(struct r5l_log *log, struct stripe_head *sh,
--
1.9.1
^ permalink raw reply related
* [PATCH 09/10] raid5-cache: small log->seq cleanup
From: Christoph Hellwig @ 2015-09-07 5:20 UTC (permalink / raw)
To: Shaohua Li, neilb; +Cc: linux-raid, Kernel-team, dan.j.williams
In-Reply-To: <1441603250-5119-1-git-send-email-hch@lst.de>
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/md/raid5-cache.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index ae8caa8..af274e9 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -279,12 +279,11 @@ static struct r5l_io_unit *r5l_new_meta(struct r5l_log *log)
io->log_start = log->log_start;
io->meta_offset = sizeof(struct r5l_meta_block);
- io->seq = log->seq;
+ io->seq = log->seq++;
io->current_bio = r5l_bio_alloc(log, io);
bio_add_page(io->current_bio, io->meta_page, PAGE_SIZE, 0);
- log->seq++;
r5_reserve_log_entry(log, io);
spin_lock_irq(&log->io_list_lock);
--
1.9.1
^ permalink raw reply related
* [PATCH 10/10] raid5-cache: use bio chaining
From: Christoph Hellwig @ 2015-09-07 5:20 UTC (permalink / raw)
To: Shaohua Li, neilb; +Cc: linux-raid, Kernel-team, dan.j.williams
In-Reply-To: <1441603250-5119-1-git-send-email-hch@lst.de>
Simplify the bio completion handler by using bio chaining and submitting
bios as soon as they are full.
Signed-off-by: Christoph Hellwig <hch@lst.de>
---
drivers/md/raid5-cache.c | 38 ++++++++++++++++----------------------
1 file changed, 16 insertions(+), 22 deletions(-)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index af274e9..50ec1aa 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -91,8 +91,6 @@ struct r5l_io_unit {
struct page *meta_page; /* store meta block */
int meta_offset; /* current offset in meta_page */
- struct bio_list bios;
- atomic_t pending_io; /* pending bios not written to log yet */
struct bio *current_bio; /* current_bio accepting new data */
atomic_t pending_stripe; /* how many stripes not flushed to raid */
@@ -103,6 +101,7 @@ struct r5l_io_unit {
struct list_head stripe_list; /* stripes added to the io_unit */
int state;
+ bool need_split_bio;
};
/* r5l_io_unit state */
@@ -191,9 +190,6 @@ static void r5l_log_endio(struct bio *bio)
bio_put(bio);
- if (!atomic_dec_and_test(&io->pending_io))
- return;
-
spin_lock_irqsave(&log->io_list_lock, flags);
__r5l_set_io_unit_state(io, IO_UNIT_IO_END);
r5l_log_run_stripes(log);
@@ -204,7 +200,6 @@ static void r5l_submit_current_io(struct r5l_log *log)
{
struct r5l_io_unit *io = log->current_io;
struct r5l_meta_block *block;
- struct bio *bio;
unsigned long flags;
u32 crc;
@@ -221,22 +216,17 @@ static void r5l_submit_current_io(struct r5l_log *log)
__r5l_set_io_unit_state(io, IO_UNIT_IO_START);
spin_unlock_irqrestore(&log->io_list_lock, flags);
- while ((bio = bio_list_pop(&io->bios)))
- submit_bio(WRITE | REQ_FUA, bio);
+ submit_bio(WRITE | REQ_FUA, io->current_bio);
}
-static struct bio *r5l_bio_alloc(struct r5l_log *log, struct r5l_io_unit *io)
+static struct bio *r5l_bio_alloc(struct r5l_log *log)
{
struct bio *bio = bio_kmalloc(GFP_NOIO | __GFP_NOFAIL, BIO_MAX_PAGES);
bio->bi_rw = WRITE;
bio->bi_bdev = log->rdev->bdev;
bio->bi_iter.bi_sector = log->rdev->data_offset + log->log_start;
- bio->bi_end_io = r5l_log_endio;
- bio->bi_private = io;
- bio_list_add(&io->bios, bio);
- atomic_inc(&io->pending_io);
return bio;
}
@@ -252,7 +242,7 @@ static void r5_reserve_log_entry(struct r5l_log *log, struct r5l_io_unit *io)
* of BLOCK_SECTORS.
*/
if (log->log_start == 0)
- io->current_bio = NULL;
+ io->need_split_bio = true;
io->log_end = log->log_start;
}
@@ -265,7 +255,6 @@ static struct r5l_io_unit *r5l_new_meta(struct r5l_log *log)
/* We can't handle memory allocate failure so far */
io = kmem_cache_zalloc(log->io_kc, GFP_NOIO | __GFP_NOFAIL);
io->log = log;
- bio_list_init(&io->bios);
INIT_LIST_HEAD(&io->log_sibling);
INIT_LIST_HEAD(&io->stripe_list);
io->state = IO_UNIT_RUNNING;
@@ -281,7 +270,9 @@ static struct r5l_io_unit *r5l_new_meta(struct r5l_log *log)
io->meta_offset = sizeof(struct r5l_meta_block);
io->seq = log->seq++;
- io->current_bio = r5l_bio_alloc(log, io);
+ io->current_bio = r5l_bio_alloc(log);
+ io->current_bio->bi_end_io = r5l_log_endio;
+ io->current_bio->bi_private = io;
bio_add_page(io->current_bio, io->meta_page, PAGE_SIZE, 0);
r5_reserve_log_entry(log, io);
@@ -329,15 +320,18 @@ static void r5l_append_payload_page(struct r5l_log *log, struct page *page)
{
struct r5l_io_unit *io = log->current_io;
-alloc_bio:
- if (!io->current_bio)
- io->current_bio = r5l_bio_alloc(log, io);
+ if (io->need_split_bio) {
+ struct bio *prev = io->current_bio;
- if (!bio_add_page(io->current_bio, page, PAGE_SIZE, 0)) {
- io->current_bio = NULL;
- goto alloc_bio;
+ io->current_bio = r5l_bio_alloc(log);
+ bio_chain(io->current_bio, prev);
+
+ submit_bio(WRITE, prev);
}
+ if (!bio_add_page(io->current_bio, page, PAGE_SIZE, 0))
+ BUG();
+
r5_reserve_log_entry(log, io);
}
--
1.9.1
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox