* Re: [dm-devel] WANTED new maintainer for Linux/md (and mdadm)
From: Jes Sorensen @ 2016-01-06 16:53 UTC (permalink / raw)
To: Brassow Jonathan
Cc: device-mapper development, linux-raid, LKML, J. Bruce Fields,
Phil Turmel, Linus Torvalds, Doug Ledford, NeilBrown, Xiao Ni
In-Reply-To: <0AAF8A3C-BE70-4510-A8EA-F64B2F4A0B4D@redhat.com>
Brassow Jonathan <jbrassow@redhat.com> writes:
> Many thanks Neil for all the work you’ve done and the help you gave me
> while working on the DM/MD interactions bits. I’m happy you are
> sticking around for the raid1-cluster and raid5-journal bits and I’m
> interested to see what comes out of those.
>
> I know there are a number of folks around Red Hat who are capable and
> possibly interested to share the load. They should be back from PTO
> soon and we’ll make sure they know about the opportunity.
Thanks Neil!
I mentioned to Neil last year that I could probably be convinced,
bribed, shamed, into maintaining mdadm.
The kernel MD stack I think really needs a team to run it. There is just
too much internal knowledge sitting in Neil's head and I personally am a
little scared of taking on that. Shaohua Li would be a good candidate
for that team IMHO.
Cheers,
Jes
> thanks,
> brassow
>
>> On Dec 21, 2015, at 12:10 AM, NeilBrown <neilb@suse.com> wrote:
>>
>>
>> hi,
>> I became maintainer for md (Linux Software RAID) in late 2001 and on
>> the whole it has been fun and a valuable experience. But I have been
>> losing interest in recent years (https://lwn.net/Articles/511073/) and
>> as was mentioned at the kernel summit, I would like to resign. Some
>> years ago I managed to hand over nfsd to the excellent Bruce Fields,
>> but I do not seem to have the gift that Linus has of attracting
>> maintainers. While there are a number of people who know quite a bit
>> about md and/or have contributed to development, there is no obvious
>> candidate for replacement maintainer - no one who has already been
>> doing significant parts of the maintainer role.
>>
>> So I have decided to fall back on the mechanism by which I ended up
>> being maintainer in the first place. I will create a vacuum and hope
>> someone fills it (yes: I was sucked-in....). So as of 1st February
>> 2016 I will be resigning.
>>
>> At the kernel summit in October Linus talked about the value of
>> maintainership teams (https://lwn.net/Articles/662979/). I think it
>> would be great if a (small) team formed to continue to oversee md
>> rather than just a single individual (or maybe the dm team could extend
>> to include md??). If I had managed to be part of a team rather than
>> "going it alone" for so long, I might feel less tired of the whole
>> thing now.
>>
>> I don't see it as my place to appoint that team or any individuals, or
>> even to nominate any candidates. A very important attribute of a
>> maintainer is that they need to care about the code and the subsystem
>> and I cannot tell other people to care (or even know if they do). It
>> is really up to individuals to volunteer. A few people have been
>> mentioned to me in earlier less-public conversations. Any of them may
>> well be suitable, but I would rather they named themselves if
>> interested.
>>
>> So I'm hoping to get one or more volunteers to be maintainer:
>> - to gather and manage patches and outstanding issues,
>> - to review patches or get them reviewed
>> - to follow up bug reports and get them resolved
>> - to feed patches upstream, maybe directly to Linus,
>> maybe through some other maintainer, depending on what
>> relationships already exist or can be formed,
>> - to guide the longer term direction (saying "no" is important
>> sometimes),
>> - to care,
>> but also to be aware that maintainership takes real effort and time, as
>> does anything that is really worthwhile.
>>
>> This all applies to mdadm as well as md (except you would ultimately
>> *be* upstream for mdadm, not needing to send it anywhere). Even if a
>> clear team doesn't form it would be great if different people
>> maintained mdadm and md.
>>
>> One part of the job that I have put a lot of time in to is following
>> the linux-raid@vger.kernel.org list and providing support. This makes
>> people feel good about md and so more adventurous in using it.
>> Consequently I tend to hear about bugs and usability issues nice and
>> early (well before paying customers hit them in most cases) and that is
>> a big win.
>> In recent times I've been doing less of this and have been absolutely
>> thrilled that the gap has been more than filled by other very competent
>> community members. Not developers particular but a number of md users
>> have been providing excellent support. I'd particularly like to
>> high-light Phil Turmel who is very forthcoming with excellent advice,
>> but he is certainly not the only one who deserves a lot of thanks.
>> So "Thank you" to everyone who answers questions on linux-raid.
>>
>> This would be a good place for any future maintainer to hang out to
>> receive wisdom as well as to provide support.
>>
>> I will still be around. I can certainly help out in some sort of
>> mentor role, and can probably be convinced to review patches and
>> comment on designs. But I really want to head towards spending less
>> time on md (there are so many other interesting things to learn about).
>>
>> So: if anyone is interested - please announce yourself, ask questions
>> and start doing things. I have no clear idea about how a transition
>> will happen. That is really up to you (plural). Take the bull by the
>> horns and start *being* a maintainer(team). I won't get in your way
>> and I'll help where I can.
>>
>> Thanks,
>> NeilBrown
>>
>> P.S. I'm committed to continue to work with the raid5-journal effort
>> From Facebook and the raid1-cluster effort from SUSE and the
>> line-in-the-sand of 1st February won't affect my support for those.
>> --
>> dm-devel mailing list
>> dm-devel@redhat.com
>> https://www.redhat.com/mailman/listinfo/dm-devel
>
> --
> 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
* Re: [dm-devel] [PATCH 01/35] block/fs/drivers: remove rw argument from submit_bio
From: Bart Van Assche @ 2016-01-06 15:59 UTC (permalink / raw)
To: device-mapper development, linux-f2fs-devel, linux-ext4,
konrad.wilk, drbd-dev, philipp.reisner, lars.ellenberg,
linux-raid, linux-fsdevel, linux-bcache, linux-block,
linux-kernel, linux-scsi, linux-mtd, target-devel, linux-btrfs,
osd-dev, xfs, ocfs2-devel
Cc: Mike Christie
In-Reply-To: <1452027218-32303-2-git-send-email-mchristi@redhat.com>
On 01/05/2016 09:53 PM, mchristi@redhat.com wrote:
> From: Mike Christie <mchristi@redhat.com>
>
> This has callers of submit_bio/submit_bio_wait set the bio->bi_rw
> instead of passing it in. This makes that use the same as
> generic_make_request and how we set the other bio fields.
Reviewed-by: Bart Van Assche <bart.vanassche@sandisk.com>
^ permalink raw reply
* Re: raid5 async_xor: sleep in atomic
From: Vinod Koul @ 2016-01-06 9:08 UTC (permalink / raw)
To: Dan Williams
Cc: NeilBrown, Stanislav Samsonov, linux-raid,
dmaengine@vger.kernel.org
In-Reply-To: <CAPcyv4g6ieqx29kPE8ak7Sh2F0ksXEuz-NaYC8tBMW3Ek7ei0Q@mail.gmail.com>
On Mon, Jan 04, 2016 at 09:28:52AM -0800, Dan Williams wrote:
> On Sun, Jan 3, 2016 at 5:33 PM, NeilBrown <neilb@suse.com> wrote:
> > On Mon, Dec 28 2015, Stanislav Samsonov wrote:
> >
> >> On 24 December 2015 at 00:46, Dan Williams <dan.j.williams@intel.com> wrote:
> >>>
> >>> On Wed, Dec 23, 2015 at 2:39 PM, NeilBrown <neilb@suse.com> wrote:
> >>> > On Thu, Dec 24 2015, Dan Williams wrote:
> >>> >>> Changing the GFP_NOIO to GFP_ATOMIC in all the calls to
> >>> >>> dmaengine_get_unmap_data() in crypto/async_tx/ would probably fix the
> >>> >>> issue... or make it crash even worse :-)
> >>> >>>
> >>> >>> Dan: do you have any wisdom here? The xor is using the percpu data in
> >>> >>> raid5, so it cannot be sleep, but GFP_NOIO allows sleep.
> >>> >>> Does the code handle failure to get_unmap_data() safely? It looks like
> >>> >>> it probably does.
> >>> >>
> >>> >> Those GFP_NOIO should move to GFP_NOWAIT. We don't want GFP_ATOMIC
> >>> >> allocations to consume emergency reserves for a performance
> >>> >> optimization. Longer term async_tx needs to be merged into md
> >>> >> directly as we can allocate this unmap data statically per-stripe
> >>> >> rather than per request. This asyntc_tx re-write has been on the todo
> >>> >> list for years, but never seems to make it to the top.
> >>> >
> >>> > So the following maybe?
> >>> > If I could get an acked-by from you Dan, and a Tested-by: from you
> >>> > Slava, I'll submit upstream.
> >>> >
> >>> > Thanks,
> >>> > NeilBrown
> >>> >
> >>> > From: NeilBrown <neilb@suse.com>
> >>> > Date: Thu, 24 Dec 2015 09:35:18 +1100
> >>> > Subject: [PATCH] async_tx: use GFP_NOWAIT rather than GFP_IO
> >>> >
> >>> > These async_XX functions are called from md/raid5 in an atomic
> >>> > section, between get_cpu() and put_cpu(), so they must not sleep.
> >>> > So use GFP_NOWAIT rather than GFP_IO.
> >>> >
> >>> > Dan Williams writes: Longer term async_tx needs to be merged into md
> >>> > directly as we can allocate this unmap data statically per-stripe
> >>> > rather than per request.
> >>> >
> >>> > Reported-by: Stanislav Samsonov <slava@annapurnalabs.com>
> >>> > Signed-off-by: NeilBrown <neilb@suse.com>
> >>>
> >>> Acked-by: Dan Williams <dan.j.williams@intel.com>
> >>
> >> Tested-by: Slava Samsonov <slava@annapurnalabs.com>
> >
> > Thanks.
> >
> > I guess this was problem was introduced by
> > Commit: 7476bd79fc01 ("async_pq: convert to dmaengine_unmap_data")
> > in 3.13.
>
> Yes.
>
> > Do we think it deserves to go to -stable?
>
> I think so, yes.
>
> > (I just realised that this is really Dan's code more than mine,
> > so why am I submitting it ???
>
> True! I was grateful for your offer, but I should have taken over
> coordination...
>
> > But we are here now so it may as well go
> > in through the md tree.)
>
> That or Vinod is maintaining drivers/dma/ these days (added Cc's).
I can queue it up, pls send me the patch with ACKs. Looks like this might be
4.4 material, I am finalizing that in next day or so :)
--
~Vinod
^ permalink raw reply
* Re: [PATCH v2 0/2] Introduce the bulk IV mode for improving the crypto engine efficiency
From: Baolin Wang @ 2016-01-06 6:49 UTC (permalink / raw)
To: Mark Brown
Cc: Milan Broz, Jens Axboe, Alasdair G Kergon, Mike Snitzer, dm-devel,
neilb, dan.j.williams, martin.petersen, sagig, Kent Overstreet,
keith.busch, tj, Arnd Bergmann, linux-block, linux-raid, LKML
In-Reply-To: <20160104201343.GQ16023@sirena.org.uk>
On 5 January 2016 at 04:13, Mark Brown <broonie@kernel.org> wrote:
> On Sat, Jan 02, 2016 at 11:46:08PM +0100, Milan Broz wrote:
>
>> Anyway, I think that you should optimize driver, not add strange hw-dependent
>> crypto modes to dmcrypt. This is not the first crypto accelerator that is just not
>> suited for this kind of use.
>
>> (If it can process batch of chunks of data each with own IV, then it can work
>> with dmcrypt, but I think such optimized code should be inside crypto API,
>> not in dmcrypt.)
>
> The flip side of this is there is an awful lot of hardware out there
> that has basically this pattern and if we can make the difference
> between people being able to encrypt or not encrypt their storage due to
> performance then that seems like a win. Getting hardware changes isn't
Yeah, Now many vendors will supply AES hardware engine to improve the
encryption speed. Like Qualcom or Spreadtrum, they both support the
AES engine, which can handle the IV things in engine interior. So it
can handle bulk data with just one initial IV, which is implemented in
the out of tree req-dm-crypt code. That is why Milan's testing is
failed, cause there is no hardware engine to support this.
> going to be a fast process. From a brief look at the crypto layer it
> does look there may be things we can do there, if only in terms of
> factoring out the common patterns for driving the queue of operations
> into the hardware so it's easy for drivers to do the best thing.
>
> One thing that occurs to me for the IV programming that has been
> proposed for SPI by Martin Sparl (and seen good results on Raspberry PI)
> is to insert transfers programming the crypto engine into the stream of
> DMA operations so we can keep the hardware busy. It won't work with
> every SoC out there but it will work with a lot of them, it's what
> hardware that explicitly supports this will be doing internally. It's
> the sort of thing that would benefit from factoring out, it's a lot of
> hassle to implement per driver.
>
> The main thing the out of tree req-dm-crypt code is doing was using a
> larger block size which does seem like a reasonable thing to allow
> people to tune for performance tradeofffs but I undertand that's a lot
> harder to achieve in a good way than one might hope.
--
Baolin.wang
Best Regards
^ permalink raw reply
* Re: [PATCH 3/4] raid5-cache: handle flush request for journal hotadd
From: NeilBrown @ 2016-01-06 2:07 UTC (permalink / raw)
To: Shaohua Li; +Cc: linux-raid, Kernel-team, songliubraving
In-Reply-To: <20160106014704.GA4056779@devbig084.prn1.facebook.com>
[-- Attachment #1: Type: text/plain, Size: 1653 bytes --]
On Wed, Jan 06 2016, Shaohua Li wrote:
> On Wed, Jan 06, 2016 at 12:12:05PM +1100, NeilBrown wrote:
>> On Wed, Jan 06 2016, Shaohua Li wrote:
>>
>> > When we hotadd journal for array which isn't created with journal, the
>> > array might be running write requests. Such writes aren't protected by
>> > journal yet, so we can't skip disk flush. There is no easy way to know
>> > when all such writes are finished, but the time should be enough after
>> > reclaim runs once.
>>
>> There is an easy way to know when such writes are finished.
>> Call mddev_suspend(mddev). This is used for the more intrusive
>> reconfiguration such as initiating a reshape.
>> I think it would be perfectly appropriate to
>> call mddev_suspend()
>> attach the journal
>> call mddev_resume()
>
> hot add/remove disk is called in raid5d, we can't wait IO there.
> mddev_suspend() will wait IO. So we can't call mddev_suspend()
Fair point. I wonder if it should be though.
Activating a spare is a very different thing to activating a journal.
Activating a spare is just one small step on the way from being degraded
to being optimal.
Activating a spare is a distinct change in how the array behaves, not
unlike adding a bitmap.
So I think that adding a journal should happen a lot like adding a
bitmap.
When you write "journal" to the 'state' file, or call ADD_NEW_DISK with
MD_DISK_JOURNAL set, ->hot_add_disk() should be called directly, a bit
like add_bound_rdev() does when adding a device to a 'linear' array.
Having remove_and_add_spares() add a journal certainly doesn't seem like
a good idea.
Thanks,
NeilBrown
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]
^ permalink raw reply
* Re: [PATCH 2/2] raid5-cache: correctly handle stripe with enough journal space
From: Shaohua Li @ 2016-01-06 1:55 UTC (permalink / raw)
To: NeilBrown; +Cc: linux-raid
In-Reply-To: <871t9vxyjv.fsf@notabene.neil.brown.name>
On Wed, Jan 06, 2016 at 12:54:28PM +1100, NeilBrown wrote:
> On Tue, Jan 05 2016, Shaohua Li wrote:
>
> > If there are spaces in journal, we do nothing. Likely a typo merging
> > recent io_unit mempool patch.
>
> Very likely.
>
> I think the same effect as your patch can be achieved with
>
> diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
> index 55a905e56e8a..6d2b4789a928 100644
> --- a/drivers/md/raid5-cache.c
> +++ b/drivers/md/raid5-cache.c
> @@ -500,7 +500,7 @@ int r5l_write_stripe(struct r5l_log *log, struct stripe_head *sh)
> spin_unlock(&log->no_space_stripes_lock);
>
> r5l_wake_reclaim(log, reserve);
> -
> + } else {
> ret = r5l_log_stripe(log, sh, data_pages, parity_pages);
> if (ret) {
> spin_lock_irq(&log->io_list_lock);
>
> Are you OK with me just merging that into the offending patch?
sure, please go ahead
^ permalink raw reply
* Re: [PATCH 2/2] raid5-cache: correctly handle stripe with enough journal space
From: NeilBrown @ 2016-01-06 1:54 UTC (permalink / raw)
To: Shaohua Li, linux-raid
In-Reply-To: <8bafb456f68b960bebaff8b742021d565554d5d4.1451954517.git.shli@fb.com>
[-- Attachment #1: Type: text/plain, Size: 2327 bytes --]
On Tue, Jan 05 2016, Shaohua Li wrote:
> If there are spaces in journal, we do nothing. Likely a typo merging
> recent io_unit mempool patch.
Very likely.
I think the same effect as your patch can be achieved with
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 55a905e56e8a..6d2b4789a928 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -500,7 +500,7 @@ int r5l_write_stripe(struct r5l_log *log, struct stripe_head *sh)
spin_unlock(&log->no_space_stripes_lock);
r5l_wake_reclaim(log, reserve);
-
+ } else {
ret = r5l_log_stripe(log, sh, data_pages, parity_pages);
if (ret) {
spin_lock_irq(&log->io_list_lock);
Are you OK with me just merging that into the offending patch?
Thanks,
NeilBrown
>
> Signed-off-by: Shaohua Li <shli@fb.com>
> ---
> drivers/md/raid5-cache.c | 14 +++++++-------
> 1 file changed, 7 insertions(+), 7 deletions(-)
>
> diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
> index 55a905e..d242a36 100644
> --- a/drivers/md/raid5-cache.c
> +++ b/drivers/md/raid5-cache.c
> @@ -494,19 +494,19 @@ int r5l_write_stripe(struct r5l_log *log, struct stripe_head *sh)
> mutex_lock(&log->io_mutex);
> /* meta + data */
> reserve = (1 + write_disks) << (PAGE_SHIFT - 9);
> - if (!r5l_has_free_space(log, reserve)) {
> - spin_lock(&log->no_space_stripes_lock);
> - list_add_tail(&sh->log_list, &log->no_space_stripes);
> - spin_unlock(&log->no_space_stripes_lock);
> -
> - r5l_wake_reclaim(log, reserve);
> -
> + if (r5l_has_free_space(log, reserve)) {
> ret = r5l_log_stripe(log, sh, data_pages, parity_pages);
> if (ret) {
> spin_lock_irq(&log->io_list_lock);
> list_add_tail(&sh->log_list, &log->no_mem_stripes);
> spin_unlock_irq(&log->io_list_lock);
> }
> + } else {
> + spin_lock(&log->no_space_stripes_lock);
> + list_add_tail(&sh->log_list, &log->no_space_stripes);
> + spin_unlock(&log->no_space_stripes_lock);
> +
> + r5l_wake_reclaim(log, reserve);
> }
>
> mutex_unlock(&log->io_mutex);
> --
> 2.4.6
>
> --
> 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
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]
^ permalink raw reply related
* Re: [PATCH 1/2] raid5-cache: destroy mempool
From: NeilBrown @ 2016-01-06 1:50 UTC (permalink / raw)
To: Shaohua Li, linux-raid
In-Reply-To: <9ab2f48aab9ddc9aa7ac2b9b6a594a97c2d82f5f.1451954517.git.shli@fb.com>
[-- Attachment #1: Type: text/plain, Size: 750 bytes --]
On Tue, Jan 05 2016, Shaohua Li wrote:
> io_unit mempool isn't destroied with recent changes.
>
> Signed-off-by: Shaohua Li <shli@fb.com>
> ---
> drivers/md/raid5-cache.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
> index d992d62..55a905e 100644
> --- a/drivers/md/raid5-cache.c
> +++ b/drivers/md/raid5-cache.c
> @@ -1257,6 +1257,7 @@ void r5l_exit_log(struct r5l_log *log)
> md_unregister_thread(&log->reclaim_thread);
> mempool_destroy(log->meta_pool);
> bioset_free(log->bs);
> + mempool_destroy(log->io_pool);
> kmem_cache_destroy(log->io_kc);
> kfree(log);
> }
Thanks!
I've merge that into the offending patch rather than adding it as a
separate patch.
NeilBrown
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]
^ permalink raw reply
* Re: [PATCH 3/4] raid5-cache: handle flush request for journal hotadd
From: Shaohua Li @ 2016-01-06 1:47 UTC (permalink / raw)
To: NeilBrown; +Cc: linux-raid, Kernel-team, songliubraving
In-Reply-To: <87d1tfy0ii.fsf@notabene.neil.brown.name>
On Wed, Jan 06, 2016 at 12:12:05PM +1100, NeilBrown wrote:
> On Wed, Jan 06 2016, Shaohua Li wrote:
>
> > When we hotadd journal for array which isn't created with journal, the
> > array might be running write requests. Such writes aren't protected by
> > journal yet, so we can't skip disk flush. There is no easy way to know
> > when all such writes are finished, but the time should be enough after
> > reclaim runs once.
>
> There is an easy way to know when such writes are finished.
> Call mddev_suspend(mddev). This is used for the more intrusive
> reconfiguration such as initiating a reshape.
> I think it would be perfectly appropriate to
> call mddev_suspend()
> attach the journal
> call mddev_resume()
hot add/remove disk is called in raid5d, we can't wait IO there.
mddev_suspend() will wait IO. So we can't call mddev_suspend()
Thanks,
Shaohua
^ permalink raw reply
* Re: [PATCH] IMSM: Add support for VMD
From: NeilBrown @ 2016-01-06 1:23 UTC (permalink / raw)
Cc: linux-raid, pawel.baldysiak, artur.paszkiewicz
In-Reply-To: <20160105160304.17913.4114.stgit@gklab-154-222.intel.com>
[-- Attachment #1: Type: text/plain, Size: 569 bytes --]
On Wed, Jan 06 2016, Pawel Baldysiak wrote:
> The Intel Volume Management Device (VMD) is an integrated
> endpoint on the platform's PCIe root complex that acts
> as a host bridge to a secondary PCIe domain.
>
> This patch adds proper handling of NVMe devices attached to VMD domain.
> Each VMD domain is treated as a separate controller (HBA).
> Spanning between domains is forbidden.
>
> Signed-off-by: Pawel Baldysiak <pawel.baldysiak@intel.com>
I'm not pretending that I follow what is happening here, but I'll take
your word for it.
applied, thanks.
NeilBrown
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]
^ permalink raw reply
* Re: [PATCH 3/4] raid5-cache: handle flush request for journal hotadd
From: NeilBrown @ 2016-01-06 1:12 UTC (permalink / raw)
To: Shaohua Li, linux-raid; +Cc: Kernel-team, songliubraving
In-Reply-To: <7b8a15be93941a393a5a08232659fef9ead4610b.1452028077.git.shli@fb.com>
[-- Attachment #1: Type: text/plain, Size: 654 bytes --]
On Wed, Jan 06 2016, Shaohua Li wrote:
> When we hotadd journal for array which isn't created with journal, the
> array might be running write requests. Such writes aren't protected by
> journal yet, so we can't skip disk flush. There is no easy way to know
> when all such writes are finished, but the time should be enough after
> reclaim runs once.
There is an easy way to know when such writes are finished.
Call mddev_suspend(mddev). This is used for the more intrusive
reconfiguration such as initiating a reshape.
I think it would be perfectly appropriate to
call mddev_suspend()
attach the journal
call mddev_resume()
Thanks,
NeilBrown
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]
^ permalink raw reply
* Re: [PATCH 1/4] raid5-cache: use rcu api to access r5conf->log
From: NeilBrown @ 2016-01-06 1:04 UTC (permalink / raw)
To: Shaohua Li, linux-raid; +Cc: Kernel-team, songliubraving
In-Reply-To: <b2e460b69224288a2b7dfc66f86672551cdb9319.1452028077.git.shli@fb.com>
[-- Attachment #1: Type: text/plain, Size: 470 bytes --]
On Wed, Jan 06 2016, Shaohua Li wrote:
> If we add journal disk to an array which isn't created with journal, IO
> might be running in the array. We must be careful about the log checks
> to make sure log is fully initialized, which is the job of
> rcu_dereference(). Don't need rcu read lock protection here, as
> hotremove only happens when there is no write requests.
Very sensible, especially as conf->log is set using rcu_assign_ptr().
Applied, thanks
NeilBrown
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]
^ permalink raw reply
* Re: [PATCH 2/4] raid5-cache: avoid write failure for journal hotadd
From: NeilBrown @ 2016-01-06 1:03 UTC (permalink / raw)
To: Shaohua Li, linux-raid; +Cc: Kernel-team, songliubraving
In-Reply-To: <1eb31e4a94d3bb5d723164cdcb30a76d1feac7ef.1452028077.git.shli@fb.com>
[-- Attachment #1: Type: text/plain, Size: 3970 bytes --]
On Wed, Jan 06 2016, Shaohua Li wrote:
> r5l_log_disk_error() will make write request fail if there is no log,
> but MD_HAS_JOURNAL is set. When we hotadd journal, MD_HAS_JOURNAL is set
> but the r5l_log isn't fully initialized yet. Adding a new flag to
> indicate the situation and let r5l_log_disk_error() handle the
> situation.
>
> Based on Song Liu's original patch
> Signed-off-by: Shaohua Li <shli@fb.com>
> ---
> drivers/md/md.c | 10 +++++++++-
> drivers/md/md.h | 2 ++
> drivers/md/raid5-cache.c | 16 +++++++++++++---
> 3 files changed, 24 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/md/md.c b/drivers/md/md.c
> index c0c3e6d..9f1d609 100644
> --- a/drivers/md/md.c
> +++ b/drivers/md/md.c
> @@ -6899,8 +6899,16 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
> else if (!(info.state & (1<<MD_DISK_SYNC)))
> /* Need to clear read-only for this */
> break;
> - else
> + else {
> + if ((info.state & (1<<MD_DISK_JOURNAL)) &&
> + !test_bit(MD_HAS_JOURNAL, &mddev->flags))
> + set_bit(MD_JOURNAL_NOT_INITIALIZED,
> + &mddev->flags);
> err = add_new_disk(mddev, &info);
> + if (err)
> + clear_bit(MD_JOURNAL_NOT_INITIALIZED,
> + &mddev->flags);
> + }
> goto unlock;
> }
> break;
> diff --git a/drivers/md/md.h b/drivers/md/md.h
> index e16a17c..d18e0d4 100644
> --- a/drivers/md/md.h
> +++ b/drivers/md/md.h
> @@ -238,6 +238,8 @@ struct mddev {
> #define MD_RELOAD_SB 7 /* Reload the superblock because another node
> * updated it.
> */
> +#define MD_JOURNAL_NOT_INITIALIZED 8 /* hot add a journal, and journal isn't
> + * ready to use yet */
>
> int suspended;
> atomic_t active_io;
> diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
> index 31e0fad..5a0f680 100644
> --- a/drivers/md/raid5-cache.c
> +++ b/drivers/md/raid5-cache.c
> @@ -859,9 +859,17 @@ bool r5l_log_disk_error(struct r5conf *conf)
> rcu_read_lock();
> log = rcu_dereference(conf->log);
>
> - if (!log)
> - ret = test_bit(MD_HAS_JOURNAL, &conf->mddev->flags);
> - else
> + if (!log) {
> + ret = test_bit(MD_HAS_JOURNAL, &conf->mddev->flags) &&
> + !test_bit(MD_JOURNAL_NOT_INITIALIZED, &conf->mddev->flags);
> + smp_mb__after_atomic();
> + /*
> + * r5l_init_log sets ->log first and then clear INITIALIZED, we
> + * check in reverse order to avoid race condition.
> + */
> + log = rcu_dereference(conf->log);
> + }
> + if (log)
> ret = test_bit(Faulty, &log->rdev->flags);
> rcu_read_unlock();
> return ret;
> @@ -1242,6 +1250,8 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev)
> goto error;
>
> rcu_assign_pointer(conf->log, log);
> + smp_mb__before_atomic();
> + clear_bit(MD_JOURNAL_NOT_INITIALIZED, &conf->mddev->flags);
> return 0;
>
> error:
> --
> 2.4.6
I don't feel at all comfortable about this.
Having one flag saying "there is a journal" and another saying
"actually, no there isn't" just isn't very clean.
So I wondered "why is MD_HAS_JOURNAL set so early", and discovered it
being set in super_1_validate() - but in the wrong place.
super_1_validate should only make changes the mddev when
mddev->raid_disks is zero. In that case all the array details are
initialised from the metadata.
Other calls to super_1_validate should validate that the new metadata
matches mddev, and may set some details in 'rdev'.
So:
if (mddev->recovery_cp == MaxSector)
set_bit(MD_JOURNAL_CLEAN, &mddev->flags);
and
if (le32_to_cpu(sb->feature_map) & MD_FEATURE_JOURNAL)
set_bit(MD_HAS_JOURNAL, &mddev->flags);
don't fit the pattern.
These should be moved to the "mddev->raid_disks == 0" section of
super_1_validate.
Then when a journal is hot-added, the MD_HAS_JOURNAL flag should be set
once the journal is actually active.
Thanks,
NeilBrown
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 818 bytes --]
^ permalink raw reply
* Re: [PATCH 35/35] block, drivers, fs: rename REQ_FLUSH to REQ_PREFLUSH
From: kbuild test robot @ 2016-01-05 23:53 UTC (permalink / raw)
Cc: linux-bcache, linux-block, osd-dev, ocfs2-devel, linux-scsi,
konrad.wilk, linux-kernel, xfs, philipp.reisner, linux-f2fs-devel,
linux-raid, Mike Christie, dm-devel, target-devel, linux-mtd,
kbuild-all, linux-fsdevel, lars.ellenberg, linux-ext4,
linux-btrfs, drbd-dev
In-Reply-To: <1452027218-32303-36-git-send-email-mchristi@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 2459 bytes --]
Hi Mike,
[auto build test ERROR on next-20160105]
[cannot apply to dm/for-next v4.4-rc8 v4.4-rc7 v4.4-rc6 v4.4-rc8]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/mchristi-redhat-com/separate-operations-from-flags-in-the-bio-request-structs/20160106-052858
config: um-x86_64_defconfig (attached as .config)
reproduce:
# save the attached .config to linux build tree
make ARCH=um SUBARCH=x86_64
All errors (new ones prefixed by >>):
arch/um/drivers/ubd_kern.c: In function 'ubd_add':
arch/um/drivers/ubd_kern.c:869:43: error: macro "blk_queue_flush" passed 2 arguments, but takes just 1
blk_queue_flush(ubd_dev->queue, REQ_FLUSH);
^
arch/um/drivers/ubd_kern.c:869:2: error: 'blk_queue_flush' undeclared (first use in this function)
blk_queue_flush(ubd_dev->queue, REQ_FLUSH);
^
arch/um/drivers/ubd_kern.c:869:2: note: each undeclared identifier is reported only once for each function it appears in
arch/um/drivers/ubd_kern.c: In function 'do_ubd_request':
>> arch/um/drivers/ubd_kern.c:1293:24: error: 'REQ_FLUSH' undeclared (first use in this function)
if (req->cmd_flags & REQ_FLUSH) {
^
vim +/REQ_FLUSH +1293 arch/um/drivers/ubd_kern.c
a0044bdf Jeff Dike 2007-05-06 1287 dev->start_sg = 0;
a0044bdf Jeff Dike 2007-05-06 1288 dev->end_sg = blk_rq_map_sg(q, req, dev->sg);
a0044bdf Jeff Dike 2007-05-06 1289 }
a0044bdf Jeff Dike 2007-05-06 1290
a0044bdf Jeff Dike 2007-05-06 1291 req = dev->request;
805f11a0 Richard Weinberger 2013-08-18 1292
805f11a0 Richard Weinberger 2013-08-18 @1293 if (req->cmd_flags & REQ_FLUSH) {
805f11a0 Richard Weinberger 2013-08-18 1294 io_req = kmalloc(sizeof(struct io_thread_req),
805f11a0 Richard Weinberger 2013-08-18 1295 GFP_ATOMIC);
805f11a0 Richard Weinberger 2013-08-18 1296 if (io_req == NULL) {
:::::: The code at line 1293 was first introduced by commit
:::::: 805f11a0d515658106bfbfadceff0eb30bd90ad2 um: ubd: Add REQ_FLUSH suppport
:::::: TO: Richard Weinberger <richard@nod.at>
:::::: CC: Richard Weinberger <richard@nod.at>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 7110 bytes --]
[-- Attachment #3: Type: text/plain, Size: 121 bytes --]
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply
* Re: [PATCH 34/35] block: add QUEUE_FLAGs for flush and fua
From: kbuild test robot @ 2016-01-05 23:46 UTC (permalink / raw)
Cc: linux-bcache, linux-block, osd-dev, ocfs2-devel, linux-scsi,
konrad.wilk, linux-kernel, xfs, philipp.reisner, linux-f2fs-devel,
linux-raid, Mike Christie, dm-devel, target-devel, linux-mtd,
kbuild-all, linux-fsdevel, lars.ellenberg, linux-ext4,
linux-btrfs, drbd-dev
In-Reply-To: <1452027218-32303-35-git-send-email-mchristi@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 2365 bytes --]
Hi Mike,
[auto build test ERROR on next-20160105]
[cannot apply to dm/for-next v4.4-rc8 v4.4-rc7 v4.4-rc6 v4.4-rc8]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/mchristi-redhat-com/separate-operations-from-flags-in-the-bio-request-structs/20160106-052858
config: um-x86_64_defconfig (attached as .config)
reproduce:
# save the attached .config to linux build tree
make ARCH=um SUBARCH=x86_64
All errors (new ones prefixed by >>):
arch/um/drivers/ubd_kern.c: In function 'ubd_add':
>> arch/um/drivers/ubd_kern.c:869:43: error: macro "blk_queue_flush" passed 2 arguments, but takes just 1
blk_queue_flush(ubd_dev->queue, REQ_FLUSH);
^
>> arch/um/drivers/ubd_kern.c:869:2: error: 'blk_queue_flush' undeclared (first use in this function)
blk_queue_flush(ubd_dev->queue, REQ_FLUSH);
^
arch/um/drivers/ubd_kern.c:869:2: note: each undeclared identifier is reported only once for each function it appears in
vim +/blk_queue_flush +869 arch/um/drivers/ubd_kern.c
62f96cb0 Jeff Dike 2007-02-10 863 ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock);
62f96cb0 Jeff Dike 2007-02-10 864 if (ubd_dev->queue == NULL) {
62f96cb0 Jeff Dike 2007-02-10 865 *error_out = "Failed to initialize device queue";
80c13749 Jeff Dike 2006-09-29 866 goto out;
62f96cb0 Jeff Dike 2007-02-10 867 }
62f96cb0 Jeff Dike 2007-02-10 868 ubd_dev->queue->queuedata = ubd_dev;
805f11a0 Richard Weinberger 2013-08-18 @869 blk_queue_flush(ubd_dev->queue, REQ_FLUSH);
62f96cb0 Jeff Dike 2007-02-10 870
8a78362c Martin K. Petersen 2010-02-26 871 blk_queue_max_segments(ubd_dev->queue, MAX_SG);
792dd4fc Christoph Hellwig 2009-03-31 872 err = ubd_disk_register(UBD_MAJOR, ubd_dev->size, n, &ubd_gendisk[n]);
:::::: The code at line 869 was first introduced by commit
:::::: 805f11a0d515658106bfbfadceff0eb30bd90ad2 um: ubd: Add REQ_FLUSH suppport
:::::: TO: Richard Weinberger <richard@nod.at>
:::::: CC: Richard Weinberger <richard@nod.at>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 7110 bytes --]
[-- Attachment #3: Type: text/plain, Size: 121 bytes --]
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply
* Re: [PATCH 05/35] fs: have ll_rw_block users pass in op and flags separately
From: kbuild test robot @ 2016-01-05 23:20 UTC (permalink / raw)
Cc: linux-bcache, linux-block, osd-dev, ocfs2-devel, linux-scsi,
konrad.wilk, linux-kernel, xfs, philipp.reisner, linux-f2fs-devel,
linux-raid, Mike Christie, dm-devel, target-devel, linux-mtd,
kbuild-all, linux-fsdevel, lars.ellenberg, linux-ext4,
linux-btrfs, drbd-dev
In-Reply-To: <1452027218-32303-6-git-send-email-mchristi@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 5828 bytes --]
Hi Mike,
[auto build test WARNING on next-20160105]
[cannot apply to dm/for-next v4.4-rc8 v4.4-rc7 v4.4-rc6 v4.4-rc8]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]
url: https://github.com/0day-ci/linux/commits/mchristi-redhat-com/separate-operations-from-flags-in-the-bio-request-structs/20160106-052858
reproduce: make htmldocs
All warnings (new ones prefixed by >>):
>> fs/buffer.c:3091: warning: No description found for parameter 'op_flags'
include/linux/jbd2.h:439: warning: No description found for parameter 'i_transaction'
include/linux/jbd2.h:439: warning: No description found for parameter 'i_next_transaction'
include/linux/jbd2.h:439: warning: No description found for parameter 'i_list'
include/linux/jbd2.h:439: warning: No description found for parameter 'i_vfs_inode'
include/linux/jbd2.h:439: warning: No description found for parameter 'i_flags'
include/linux/jbd2.h:495: warning: No description found for parameter 'h_rsv_handle'
include/linux/jbd2.h:495: warning: No description found for parameter 'h_reserved'
include/linux/jbd2.h:495: warning: No description found for parameter 'h_type'
include/linux/jbd2.h:495: warning: No description found for parameter 'h_line_no'
include/linux/jbd2.h:495: warning: No description found for parameter 'h_start_jiffies'
include/linux/jbd2.h:495: warning: No description found for parameter 'h_requested_credits'
include/linux/jbd2.h:495: warning: No description found for parameter 'h_lockdep_map'
include/linux/jbd2.h:1038: warning: No description found for parameter 'j_chkpt_bhs[JBD2_NR_BATCH]'
include/linux/jbd2.h:1038: warning: No description found for parameter 'j_devname[BDEVNAME_SIZE+24]'
include/linux/jbd2.h:1038: warning: No description found for parameter 'j_average_commit_time'
include/linux/jbd2.h:1038: warning: No description found for parameter 'j_min_batch_time'
include/linux/jbd2.h:1038: warning: No description found for parameter 'j_max_batch_time'
include/linux/jbd2.h:1038: warning: No description found for parameter 'j_commit_callback'
include/linux/jbd2.h:1038: warning: No description found for parameter 'j_failed_commit'
include/linux/jbd2.h:1038: warning: No description found for parameter 'j_chksum_driver'
include/linux/jbd2.h:1038: warning: No description found for parameter 'j_csum_seed'
include/linux/jbd2.h:1038: warning: Excess struct/union/enum/typedef member 'j_history' description in 'journal_s'
include/linux/jbd2.h:1038: warning: Excess struct/union/enum/typedef member 'j_history_max' description in 'journal_s'
include/linux/jbd2.h:1038: warning: Excess struct/union/enum/typedef member 'j_history_cur' description in 'journal_s'
fs/jbd2/transaction.c:429: warning: No description found for parameter 'rsv_blocks'
fs/jbd2/transaction.c:429: warning: No description found for parameter 'gfp_mask'
fs/jbd2/transaction.c:429: warning: No description found for parameter 'type'
fs/jbd2/transaction.c:429: warning: No description found for parameter 'line_no'
fs/jbd2/transaction.c:505: warning: No description found for parameter 'type'
fs/jbd2/transaction.c:505: warning: No description found for parameter 'line_no'
fs/jbd2/transaction.c:635: warning: No description found for parameter 'gfp_mask'
vim +/op_flags +3091 fs/buffer.c
^1da177e Linus Torvalds 2005-04-16 3075 *
^1da177e Linus Torvalds 2005-04-16 3076 * This function drops any buffer that it cannot get a lock on (with the
9cb569d6 Christoph Hellwig 2010-08-11 3077 * BH_Lock state bit), any buffer that appears to be clean when doing a write
9cb569d6 Christoph Hellwig 2010-08-11 3078 * request, and any buffer that appears to be up-to-date when doing read
9cb569d6 Christoph Hellwig 2010-08-11 3079 * request. Further it marks as clean buffers that are processed for
9cb569d6 Christoph Hellwig 2010-08-11 3080 * writing (the buffer cache won't assume that they are actually clean
9cb569d6 Christoph Hellwig 2010-08-11 3081 * until the buffer gets unlocked).
^1da177e Linus Torvalds 2005-04-16 3082 *
^1da177e Linus Torvalds 2005-04-16 3083 * ll_rw_block sets b_end_io to simple completion handler that marks
e227867f Masanari Iida 2014-02-18 3084 * the buffer up-to-date (if appropriate), unlocks the buffer and wakes
^1da177e Linus Torvalds 2005-04-16 3085 * any waiters.
^1da177e Linus Torvalds 2005-04-16 3086 *
^1da177e Linus Torvalds 2005-04-16 3087 * All of the buffers must be for the same device, and must also be a
^1da177e Linus Torvalds 2005-04-16 3088 * multiple of the current approved size for the device.
^1da177e Linus Torvalds 2005-04-16 3089 */
3390b48e Mike Christie 2016-01-05 3090 void ll_rw_block(int op, int op_flags, int nr, struct buffer_head *bhs[])
^1da177e Linus Torvalds 2005-04-16 @3091 {
^1da177e Linus Torvalds 2005-04-16 3092 int i;
^1da177e Linus Torvalds 2005-04-16 3093
^1da177e Linus Torvalds 2005-04-16 3094 for (i = 0; i < nr; i++) {
^1da177e Linus Torvalds 2005-04-16 3095 struct buffer_head *bh = bhs[i];
^1da177e Linus Torvalds 2005-04-16 3096
9cb569d6 Christoph Hellwig 2010-08-11 3097 if (!trylock_buffer(bh))
^1da177e Linus Torvalds 2005-04-16 3098 continue;
3390b48e Mike Christie 2016-01-05 3099 if (op == WRITE) {
:::::: The code at line 3091 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2
:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/octet-stream, Size: 6240 bytes --]
[-- Attachment #3: Type: text/plain, Size: 121 bytes --]
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply
* [PATCH 4/4] raid5-cache: handle batch stripe for journal hotadd
From: Shaohua Li @ 2016-01-05 21:26 UTC (permalink / raw)
To: linux-raid; +Cc: Kernel-team, songliubraving, neilb
In-Reply-To: <cover.1452028077.git.shli@fb.com>
Journal doesn't support batch stripe. If journal is hotadded, there
might be pending requests which are already batched. When journal is
enabled, such requests should be skipped.
Signed-off-by: Shaohua Li <shli@fb.com>
---
drivers/md/raid5-cache.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index fcda2d2..560de57 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -453,7 +453,7 @@ int r5l_write_stripe(struct r5conf *conf, struct stripe_head *sh)
return -EAGAIN;
/* Don't support stripe batch */
if (sh->log_io || !test_bit(R5_Wantwrite, &sh->dev[sh->pd_idx].flags) ||
- test_bit(STRIPE_SYNCING, &sh->state)) {
+ test_bit(STRIPE_SYNCING, &sh->state) || sh->batch_head) {
/* the stripe is written to log, we start writing it to raid */
clear_bit(STRIPE_LOG_TRAPPED, &sh->state);
return -EAGAIN;
--
2.4.6
^ permalink raw reply related
* [PATCH 3/4] raid5-cache: handle flush request for journal hotadd
From: Shaohua Li @ 2016-01-05 21:26 UTC (permalink / raw)
To: linux-raid; +Cc: Kernel-team, songliubraving, neilb
In-Reply-To: <cover.1452028077.git.shli@fb.com>
When we hotadd journal for array which isn't created with journal, the
array might be running write requests. Such writes aren't protected by
journal yet, so we can't skip disk flush. There is no easy way to know
when all such writes are finished, but the time should be enough after
reclaim runs once.
Signed-off-by: Shaohua Li <shli@fb.com>
---
drivers/md/raid5-cache.c | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 5a0f680..fcda2d2 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -97,6 +97,7 @@ struct r5l_log {
bool need_cache_flush;
bool in_teardown;
+ bool force_flush_all_disks;
};
/*
@@ -526,10 +527,27 @@ void r5l_write_stripe_run(struct r5conf *conf)
int r5l_handle_flush_request(struct r5conf *conf, struct bio *bio)
{
- struct r5l_log *log = ACCESS_ONCE(conf->log);
+ struct r5l_log *log;
- if (!log)
+ /* raid5_remove_disk writes_pending check isn't helpful for flush */
+ rcu_read_lock();
+ log = rcu_dereference(conf->log);
+ if (!log) {
+ rcu_read_unlock();
return -ENODEV;
+ }
+
+ /*
+ * If we add journal to array without journal before, the array might
+ * run write requests before journal runs. such requests are not
+ * protected by journal, so we can't skip flush.
+ */
+ if (log->force_flush_all_disks) {
+ rcu_read_unlock();
+ md_flush_request(log->rdev->mddev, bio);
+ return 0;
+ }
+ rcu_read_unlock();
/*
* we flush log disk cache first, then write stripe data to raid disks.
* So if bio is finished, the log disk cache is flushed already. The
@@ -798,6 +816,8 @@ static void r5l_do_reclaim(struct r5l_log *log)
log->last_cp_seq = next_cp_seq;
mutex_unlock(&log->io_mutex);
+ log->force_flush_all_disks = false;
+
r5l_run_no_space_stripes(log);
}
@@ -1246,6 +1266,8 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev)
INIT_LIST_HEAD(&log->no_space_stripes);
spin_lock_init(&log->no_space_stripes_lock);
+ if (test_bit(MD_JOURNAL_NOT_INITIALIZED, &conf->mddev->flags))
+ log->force_flush_all_disks = true;
if (r5l_load_log(log))
goto error;
--
2.4.6
^ permalink raw reply related
* [PATCH 2/4] raid5-cache: avoid write failure for journal hotadd
From: Shaohua Li @ 2016-01-05 21:26 UTC (permalink / raw)
To: linux-raid; +Cc: Kernel-team, songliubraving, neilb
In-Reply-To: <cover.1452028077.git.shli@fb.com>
r5l_log_disk_error() will make write request fail if there is no log,
but MD_HAS_JOURNAL is set. When we hotadd journal, MD_HAS_JOURNAL is set
but the r5l_log isn't fully initialized yet. Adding a new flag to
indicate the situation and let r5l_log_disk_error() handle the
situation.
Based on Song Liu's original patch
Signed-off-by: Shaohua Li <shli@fb.com>
---
drivers/md/md.c | 10 +++++++++-
drivers/md/md.h | 2 ++
drivers/md/raid5-cache.c | 16 +++++++++++++---
3 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index c0c3e6d..9f1d609 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -6899,8 +6899,16 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
else if (!(info.state & (1<<MD_DISK_SYNC)))
/* Need to clear read-only for this */
break;
- else
+ else {
+ if ((info.state & (1<<MD_DISK_JOURNAL)) &&
+ !test_bit(MD_HAS_JOURNAL, &mddev->flags))
+ set_bit(MD_JOURNAL_NOT_INITIALIZED,
+ &mddev->flags);
err = add_new_disk(mddev, &info);
+ if (err)
+ clear_bit(MD_JOURNAL_NOT_INITIALIZED,
+ &mddev->flags);
+ }
goto unlock;
}
break;
diff --git a/drivers/md/md.h b/drivers/md/md.h
index e16a17c..d18e0d4 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -238,6 +238,8 @@ struct mddev {
#define MD_RELOAD_SB 7 /* Reload the superblock because another node
* updated it.
*/
+#define MD_JOURNAL_NOT_INITIALIZED 8 /* hot add a journal, and journal isn't
+ * ready to use yet */
int suspended;
atomic_t active_io;
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 31e0fad..5a0f680 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -859,9 +859,17 @@ bool r5l_log_disk_error(struct r5conf *conf)
rcu_read_lock();
log = rcu_dereference(conf->log);
- if (!log)
- ret = test_bit(MD_HAS_JOURNAL, &conf->mddev->flags);
- else
+ if (!log) {
+ ret = test_bit(MD_HAS_JOURNAL, &conf->mddev->flags) &&
+ !test_bit(MD_JOURNAL_NOT_INITIALIZED, &conf->mddev->flags);
+ smp_mb__after_atomic();
+ /*
+ * r5l_init_log sets ->log first and then clear INITIALIZED, we
+ * check in reverse order to avoid race condition.
+ */
+ log = rcu_dereference(conf->log);
+ }
+ if (log)
ret = test_bit(Faulty, &log->rdev->flags);
rcu_read_unlock();
return ret;
@@ -1242,6 +1250,8 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev)
goto error;
rcu_assign_pointer(conf->log, log);
+ smp_mb__before_atomic();
+ clear_bit(MD_JOURNAL_NOT_INITIALIZED, &conf->mddev->flags);
return 0;
error:
--
2.4.6
^ permalink raw reply related
* [PATCH 1/4] raid5-cache: use rcu api to access r5conf->log
From: Shaohua Li @ 2016-01-05 21:26 UTC (permalink / raw)
To: linux-raid; +Cc: Kernel-team, songliubraving, neilb
In-Reply-To: <cover.1452028077.git.shli@fb.com>
If we add journal disk to an array which isn't created with journal, IO
might be running in the array. We must be careful about the log checks
to make sure log is fully initialized, which is the job of
rcu_dereference(). Don't need rcu read lock protection here, as
hotremove only happens when there is no write requests.
Signed-off-by: Shaohua Li <shli@fb.com>
---
drivers/md/raid5-cache.c | 19 +++++++++++++------
drivers/md/raid5.c | 20 ++++++++++----------
drivers/md/raid5.h | 10 +++++-----
3 files changed, 28 insertions(+), 21 deletions(-)
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index d242a36..31e0fad 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -438,7 +438,7 @@ static void r5l_wake_reclaim(struct r5l_log *log, sector_t space);
* running in raid5d, where reclaim could wait for raid5d too (when it flushes
* data from log to raid disks), so we shouldn't wait for reclaim here
*/
-int r5l_write_stripe(struct r5l_log *log, struct stripe_head *sh)
+int r5l_write_stripe(struct r5conf *conf, struct stripe_head *sh)
{
int write_disks = 0;
int data_pages, parity_pages;
@@ -446,6 +446,7 @@ int r5l_write_stripe(struct r5l_log *log, struct stripe_head *sh)
int reserve;
int i;
int ret = 0;
+ struct r5l_log *log = rcu_dereference(conf->log);
if (!log)
return -EAGAIN;
@@ -513,8 +514,9 @@ int r5l_write_stripe(struct r5l_log *log, struct stripe_head *sh)
return 0;
}
-void r5l_write_stripe_run(struct r5l_log *log)
+void r5l_write_stripe_run(struct r5conf *conf)
{
+ struct r5l_log *log = rcu_dereference(conf->log);
if (!log)
return;
mutex_lock(&log->io_mutex);
@@ -522,8 +524,10 @@ void r5l_write_stripe_run(struct r5l_log *log)
mutex_unlock(&log->io_mutex);
}
-int r5l_handle_flush_request(struct r5l_log *log, struct bio *bio)
+int r5l_handle_flush_request(struct r5conf *conf, struct bio *bio)
{
+ struct r5l_log *log = ACCESS_ONCE(conf->log);
+
if (!log)
return -ENODEV;
/*
@@ -664,9 +668,10 @@ static void r5l_log_flush_endio(struct bio *bio)
* 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)
+void r5l_flush_stripe_to_raid(struct r5conf *conf)
{
bool do_flush;
+ struct r5l_log *log = rcu_dereference(conf->log);
if (!log || !log->need_cache_flush)
return;
@@ -800,7 +805,7 @@ static void r5l_reclaim_thread(struct md_thread *thread)
{
struct mddev *mddev = thread->mddev;
struct r5conf *conf = mddev->private;
- struct r5l_log *log = conf->log;
+ struct r5l_log *log = rcu_dereference(conf->log);
if (!log)
return;
@@ -820,9 +825,11 @@ static void r5l_wake_reclaim(struct r5l_log *log, sector_t space)
md_wakeup_thread(log->reclaim_thread);
}
-void r5l_quiesce(struct r5l_log *log, int state)
+void r5l_quiesce(struct r5conf *conf, int state)
{
struct mddev *mddev;
+ struct r5l_log *log = rcu_dereference(conf->log);
+
if (!log || state == 2)
return;
if (state == 0) {
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index a086014..e74ead1 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -757,7 +757,7 @@ static bool stripe_can_batch(struct stripe_head *sh)
{
struct r5conf *conf = sh->raid_conf;
- if (conf->log)
+ if (ACCESS_ONCE(conf->log))
return false;
return test_bit(STRIPE_BATCH_READY, &sh->state) &&
!test_bit(STRIPE_BITMAP_PENDING, &sh->state) &&
@@ -897,7 +897,7 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
might_sleep();
- if (r5l_write_stripe(conf->log, sh) == 0)
+ if (r5l_write_stripe(conf, sh) == 0)
return;
for (i = disks; i--; ) {
int rw;
@@ -5148,7 +5148,7 @@ static void make_request(struct mddev *mddev, struct bio * bi)
bool do_prepare;
if (unlikely(bi->bi_rw & REQ_FLUSH)) {
- int ret = r5l_handle_flush_request(conf->log, bi);
+ int ret = r5l_handle_flush_request(conf, bi);
if (ret == 0)
return;
@@ -5751,7 +5751,7 @@ static int handle_active_stripes(struct r5conf *conf, int group,
break;
if (i == NR_STRIPE_HASH_LOCKS) {
spin_unlock_irq(&conf->device_lock);
- r5l_flush_stripe_to_raid(conf->log);
+ r5l_flush_stripe_to_raid(conf);
spin_lock_irq(&conf->device_lock);
return batch_size;
}
@@ -5762,7 +5762,7 @@ 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);
+ r5l_flush_stripe_to_raid(conf);
if (release_inactive) {
spin_lock_irq(&conf->device_lock);
return 0;
@@ -5770,7 +5770,7 @@ static int handle_active_stripes(struct r5conf *conf, int group,
for (i = 0; i < batch_size; i++)
handle_stripe(batch[i]);
- r5l_write_stripe_run(conf->log);
+ r5l_write_stripe_run(conf);
cond_resched();
@@ -5904,7 +5904,7 @@ static void raid5d(struct md_thread *thread)
mutex_unlock(&conf->cache_size_mutex);
}
- r5l_flush_stripe_to_raid(conf->log);
+ r5l_flush_stripe_to_raid(conf);
async_tx_issue_pending_all();
blk_finish_plug(&plug);
@@ -7291,7 +7291,7 @@ static int raid5_resize(struct mddev *mddev, sector_t sectors)
sector_t newsize;
struct r5conf *conf = mddev->private;
- if (conf->log)
+ if (ACCESS_ONCE(conf->log))
return -EINVAL;
sectors &= ~((sector_t)conf->chunk_sectors - 1);
newsize = raid5_size(mddev, sectors, mddev->raid_disks);
@@ -7344,7 +7344,7 @@ static int check_reshape(struct mddev *mddev)
{
struct r5conf *conf = mddev->private;
- if (conf->log)
+ if (ACCESS_ONCE(conf->log))
return -EINVAL;
if (mddev->delta_disks == 0 &&
mddev->new_layout == mddev->layout &&
@@ -7622,7 +7622,7 @@ static void raid5_quiesce(struct mddev *mddev, int state)
unlock_all_device_hash_locks_irq(conf);
break;
}
- r5l_quiesce(conf->log, state);
+ r5l_quiesce(conf, state);
}
static void *raid45_takeover_raid0(struct mddev *mddev, int level)
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h
index a415e1c..96969fb 100644
--- a/drivers/md/raid5.h
+++ b/drivers/md/raid5.h
@@ -626,11 +626,11 @@ raid5_get_active_stripe(struct r5conf *conf, sector_t sector,
int previous, int noblock, int noquiesce);
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 int r5l_write_stripe(struct r5conf *conf, struct stripe_head *head_sh);
+extern void r5l_write_stripe_run(struct r5conf *conf);
+extern void r5l_flush_stripe_to_raid(struct r5conf *conf);
extern void r5l_stripe_write_finished(struct stripe_head *sh);
-extern int r5l_handle_flush_request(struct r5l_log *log, struct bio *bio);
-extern void r5l_quiesce(struct r5l_log *log, int state);
+extern int r5l_handle_flush_request(struct r5conf *conf, struct bio *bio);
+extern void r5l_quiesce(struct r5conf *conf, int state);
extern bool r5l_log_disk_error(struct r5conf *conf);
#endif
--
2.4.6
^ permalink raw reply related
* [PATCH 0/4]raid5-cache: fix journal hotadd
From: Shaohua Li @ 2016-01-05 21:26 UTC (permalink / raw)
To: linux-raid; +Cc: Kernel-team, songliubraving, neilb
Hi Neil,
This patch set fix some issues for journal disk hotadd, mainly for raid array
which isn't created with journal support. If there are write IO running in the
array when journal disk is adding, the write IO isn't protected by journal (eg,
expose write hole issue), but this is unavoidable.
Thanks,
Shaohua
Shaohua Li (4):
raid5-cache: use rcu api to access r5conf->log
raid5-cache: avoid write failure for journal hotadd
raid5-cache: handle flush request for journal hotadd
raid5-cache: handle batch stripe for journal hotadd
drivers/md/md.c | 10 +++++++-
drivers/md/md.h | 2 ++
drivers/md/raid5-cache.c | 61 +++++++++++++++++++++++++++++++++++++++---------
drivers/md/raid5.c | 20 ++++++++--------
drivers/md/raid5.h | 10 ++++----
5 files changed, 76 insertions(+), 27 deletions(-)
--
2.4.6
^ permalink raw reply
* [PATCH 35/35] block, drivers, fs: rename REQ_FLUSH to REQ_PREFLUSH
From: mchristi @ 2016-01-05 20:53 UTC (permalink / raw)
To: linux-f2fs-devel, linux-ext4, konrad.wilk, drbd-dev,
philipp.reisner, lars.ellenberg, linux-raid, dm-devel,
linux-fsdevel, linux-bcache, linux-block, linux-kernel,
linux-scsi, linux-mtd, target-devel, linux-btrfs, osd-dev, xfs,
ocfs2-devel
Cc: Mike Christie
In-Reply-To: <1452027218-32303-1-git-send-email-mchristi@redhat.com>
From: Mike Christie <mchristi@redhat.com>
To avoid confusion between REQ_OP_FLUSH, which is handled by
request_fn drivers, and upper layers requesting the block layer
perform a flush sequence along with possibly a WRITE, this patch
renames REQ_FLUSH to REQ_PREFLUSH.
Signed-off-by: Mike Christie <mchristi@redhat.com>
---
Documentation/block/writeback_cache_control.txt | 31 +++++++++++++------------
block/blk-core.c | 12 +++++-----
block/blk-flush.c | 4 ++--
block/blk-mq.c | 4 ++--
drivers/block/drbd/drbd_actlog.c | 2 +-
drivers/block/drbd/drbd_main.c | 2 +-
drivers/block/drbd/drbd_receiver.c | 2 +-
drivers/block/drbd/drbd_req.c | 2 +-
drivers/md/bcache/journal.c | 2 +-
drivers/md/bcache/request.c | 8 +++----
drivers/md/dm-cache-target.c | 9 +++----
drivers/md/dm-crypt.c | 7 +++---
drivers/md/dm-era-target.c | 4 ++--
drivers/md/dm-io.c | 2 +-
drivers/md/dm-log-writes.c | 2 +-
drivers/md/dm-raid1.c | 5 ++--
drivers/md/dm-region-hash.c | 4 ++--
drivers/md/dm-snap.c | 6 ++---
drivers/md/dm-stripe.c | 2 +-
drivers/md/dm-thin.c | 8 +++----
drivers/md/dm.c | 12 +++++-----
drivers/md/linear.c | 2 +-
drivers/md/md.c | 2 +-
drivers/md/multipath.c | 2 +-
drivers/md/raid0.c | 2 +-
drivers/md/raid1.c | 3 ++-
drivers/md/raid10.c | 2 +-
drivers/md/raid5-cache.c | 2 +-
drivers/md/raid5.c | 2 +-
fs/btrfs/check-integrity.c | 8 +++----
fs/jbd2/journal.c | 2 +-
fs/xfs/xfs_buf.c | 2 +-
include/linux/blk_types.h | 8 +++----
include/linux/fs.h | 4 ++--
include/trace/events/f2fs.h | 2 +-
kernel/trace/blktrace.c | 5 ++--
36 files changed, 92 insertions(+), 86 deletions(-)
diff --git a/Documentation/block/writeback_cache_control.txt b/Documentation/block/writeback_cache_control.txt
index ea5550f..9869f18 100644
--- a/Documentation/block/writeback_cache_control.txt
+++ b/Documentation/block/writeback_cache_control.txt
@@ -20,11 +20,11 @@ a forced cache flush, and the Force Unit Access (FUA) flag for requests.
Explicit cache flushes
----------------------
-The REQ_FLUSH flag can be OR ed into the r/w flags of a bio submitted from
+The REQ_PREFLUSH flag can be OR ed into the r/w flags of a bio submitted from
the filesystem and will make sure the volatile cache of the storage device
has been flushed before the actual I/O operation is started. This explicitly
guarantees that previously completed write requests are on non-volatile
-storage before the flagged bio starts. In addition the REQ_FLUSH flag can be
+storage before the flagged bio starts. In addition the REQ_PREFLUSH flag can be
set on an otherwise empty bio structure, which causes only an explicit cache
flush without any dependent I/O. It is recommend to use
the blkdev_issue_flush() helper for a pure cache flush.
@@ -41,21 +41,21 @@ signaled after the data has been committed to non-volatile storage.
Implementation details for filesystems
--------------------------------------
-Filesystems can simply set the REQ_FLUSH and REQ_FUA bits and do not have to
+Filesystems can simply set the REQ_PREFLUSH and REQ_FUA bits and do not have to
worry if the underlying devices need any explicit cache flushing and how
-the Forced Unit Access is implemented. The REQ_FLUSH and REQ_FUA flags
+the Forced Unit Access is implemented. The REQ_PREFLUSH and REQ_FUA flags
may both be set on a single bio.
Implementation details for make_request_fn based block drivers
--------------------------------------------------------------
-These drivers will always see the REQ_FLUSH and REQ_FUA bits as they sit
+These drivers will always see the REQ_PREFLUSH and REQ_FUA bits as they sit
directly below the submit_bio interface. For remapping drivers the REQ_FUA
bits need to be propagated to underlying devices, and a global flush needs
-to be implemented for bios with the REQ_FLUSH bit set. For real device
-drivers that do not have a volatile cache the REQ_FLUSH and REQ_FUA bits
-on non-empty bios can simply be ignored, and REQ_FLUSH requests without
+to be implemented for bios with the REQ_PREFLUSH bit set. For real device
+drivers that do not have a volatile cache the REQ_PREFLUSH and REQ_FUA bits
+on non-empty bios can simply be ignored, and REQ_PREFLUSH requests without
data can be completed successfully without doing any work. Drivers for
devices with volatile caches need to implement the support for these
flags themselves without any help from the block layer.
@@ -65,21 +65,22 @@ Implementation details for request_fn based block drivers
--------------------------------------------------------------
For devices that do not support volatile write caches there is no driver
-support required, the block layer completes empty REQ_FLUSH requests before
-entering the driver and strips off the REQ_FLUSH and REQ_FUA bits from
-requests that have a payload. For devices with volatile write caches the
-driver needs to tell the block layer that it supports flushing caches by
+support required, the block layer completes empty REQ_PREFLUSH requests
+before entering the driver and strips off the REQ_PREFLUSH and REQ_FUA bits
+from requests that have a payload. For devices with volatile write caches
+the driver needs to tell the block layer that it supports flushing caches by
doing:
- blk_queue_flush(sdkp->disk->queue, REQ_FLUSH);
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, sdkp->disk->queue);
and handle empty REQ_OP_FLUSH requests in its prep_fn/request_fn. Note that
-REQ_FLUSH requests with a payload are automatically turned into a sequence
+REQ_PREFLUSH requests with a payload are automatically turned into a sequence
of an empty REQ_OP_FLUSH request followed by the actual write by the block
layer. For devices that also support the FUA bit the block layer needs
to be told to pass through the REQ_FUA bit using:
- blk_queue_flush(sdkp->disk->queue, REQ_FLUSH | REQ_FUA);
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, sdkp->disk->queue);
+ queue_flag_set_unlocked(QUEUE_FLAG_FUA, sdkp->disk->queue);
and the driver must handle write requests that have the REQ_FUA bit set
in prep_fn/request_fn. If the FUA bit is not natively supported the block
diff --git a/block/blk-core.c b/block/blk-core.c
index bb29230..dbc9082 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1029,7 +1029,7 @@ static bool blk_rq_should_init_elevator(struct bio *bio)
* Flush requests do not use the elevator so skip initialization.
* This allows a request to share the flush and elevator data.
*/
- if (bio->bi_rw & (REQ_FLUSH | REQ_FUA))
+ if (bio->bi_rw & (REQ_PREFLUSH | REQ_FUA))
return false;
return true;
@@ -1737,7 +1737,7 @@ static blk_qc_t blk_queue_bio(struct request_queue *q, struct bio *bio)
return BLK_QC_T_NONE;
}
- if (bio->bi_rw & (REQ_FLUSH | REQ_FUA)) {
+ if (bio->bi_rw & (REQ_PREFLUSH | REQ_FUA)) {
spin_lock_irq(q->queue_lock);
where = ELEVATOR_INSERT_FLUSH;
goto get_rq;
@@ -1969,9 +1969,9 @@ generic_make_request_checks(struct bio *bio)
* drivers without flush support don't have to worry
* about them.
*/
- if ((bio->bi_rw & (REQ_FLUSH | REQ_FUA)) &&
+ if ((bio->bi_rw & (REQ_PREFLUSH | REQ_FUA)) &&
!(blk_queue_flush(q) || blk_queue_fua(q))) {
- bio->bi_rw &= ~(REQ_FLUSH | REQ_FUA);
+ bio->bi_rw &= ~(REQ_PREFLUSH | REQ_FUA);
if (!nr_sectors) {
err = 0;
goto end_io;
@@ -2218,7 +2218,7 @@ int blk_insert_cloned_request(struct request_queue *q, struct request *rq)
*/
BUG_ON(blk_queued_rq(rq));
- if (rq->cmd_flags & (REQ_FLUSH|REQ_FUA))
+ if (rq->cmd_flags & (REQ_PREFLUSH | REQ_FUA))
where = ELEVATOR_INSERT_FLUSH;
add_acct_request(q, rq, where);
@@ -3310,7 +3310,7 @@ void blk_flush_plug_list(struct blk_plug *plug, bool from_schedule)
/*
* rq is already accounted, so use raw insert
*/
- if (rq->cmd_flags & (REQ_FLUSH | REQ_FUA))
+ if (rq->cmd_flags & (REQ_PREFLUSH | REQ_FUA))
__elv_add_request(q, rq, ELEVATOR_INSERT_FLUSH);
else
__elv_add_request(q, rq, ELEVATOR_INSERT_SORT_MERGE);
diff --git a/block/blk-flush.c b/block/blk-flush.c
index 633f9b3..9cf387c 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -104,7 +104,7 @@ static unsigned int blk_flush_policy(struct request *rq)
policy |= REQ_FSEQ_DATA;
if (blk_queue_flush(q)) {
- if (rq->cmd_flags & REQ_FLUSH)
+ if (rq->cmd_flags & REQ_PREFLUSH)
policy |= REQ_FSEQ_PREFLUSH;
if (!blk_queue_fua(q) && (rq->cmd_flags & REQ_FUA))
policy |= REQ_FSEQ_POSTFLUSH;
@@ -393,7 +393,7 @@ void blk_insert_flush(struct request *rq)
* @policy now records what operations need to be done. Adjust
* REQ_FLUSH and FUA for the driver.
*/
- rq->cmd_flags &= ~REQ_FLUSH;
+ rq->cmd_flags &= ~REQ_PREFLUSH;
if (!blk_queue_fua(q))
rq->cmd_flags &= ~REQ_FUA;
diff --git a/block/blk-mq.c b/block/blk-mq.c
index 72a028b..bb376a8 100644
--- a/block/blk-mq.c
+++ b/block/blk-mq.c
@@ -1244,7 +1244,7 @@ static int blk_mq_direct_issue_request(struct request *rq, blk_qc_t *cookie)
static blk_qc_t blk_mq_make_request(struct request_queue *q, struct bio *bio)
{
const int is_sync = rw_is_sync(bio->bi_op, bio->bi_rw);
- const int is_flush_fua = bio->bi_rw & (REQ_FLUSH | REQ_FUA);
+ const int is_flush_fua = bio->bi_rw & (REQ_PREFLUSH | REQ_FUA);
struct blk_map_ctx data;
struct request *rq;
unsigned int request_count = 0;
@@ -1341,7 +1341,7 @@ done:
static blk_qc_t blk_sq_make_request(struct request_queue *q, struct bio *bio)
{
const int is_sync = rw_is_sync(bio->bi_op, bio->bi_rw);
- const int is_flush_fua = bio->bi_rw & (REQ_FLUSH | REQ_FUA);
+ const int is_flush_fua = bio->bi_rw & (REQ_PREFLUSH | REQ_FUA);
struct blk_plug *plug;
unsigned int request_count = 0;
struct blk_map_ctx data;
diff --git a/drivers/block/drbd/drbd_actlog.c b/drivers/block/drbd/drbd_actlog.c
index 2fa8534..9f5e00b 100644
--- a/drivers/block/drbd/drbd_actlog.c
+++ b/drivers/block/drbd/drbd_actlog.c
@@ -148,7 +148,7 @@ static int _drbd_md_sync_page_io(struct drbd_device *device,
device->md_io.error = -ENODEV;
if ((op == REQ_OP_WRITE) && !test_bit(MD_NO_FUA, &device->flags))
- op_flags |= REQ_FUA | REQ_FLUSH;
+ op_flags |= REQ_FUA | REQ_PREFLUSH;
op_flags |= REQ_SYNC | REQ_NOIDLE;
bio = bio_alloc_drbd(GFP_NOIO);
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index 7bc78ab..88543d1 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -1608,7 +1608,7 @@ static u32 bio_flags_to_wire(struct drbd_connection *connection, struct bio *bio
if (connection->agreed_pro_version >= 95)
return (bio->bi_rw & REQ_SYNC ? DP_RW_SYNC : 0) |
(bio->bi_rw & REQ_FUA ? DP_FUA : 0) |
- (bio->bi_rw & REQ_FLUSH ? DP_FLUSH : 0) |
+ (bio->bi_rw & REQ_PREFLUSH ? DP_FLUSH : 0) |
(bio->bi_op == REQ_OP_DISCARD ? DP_DISCARD : 0);
else
return bio->bi_rw & REQ_SYNC ? DP_RW_SYNC : 0;
diff --git a/drivers/block/drbd/drbd_receiver.c b/drivers/block/drbd/drbd_receiver.c
index 880de0d..752948f 100644
--- a/drivers/block/drbd/drbd_receiver.c
+++ b/drivers/block/drbd/drbd_receiver.c
@@ -2159,7 +2159,7 @@ static unsigned long wire_flags_to_bio_flags(u32 dpf)
{
return (dpf & DP_RW_SYNC ? REQ_SYNC : 0) |
(dpf & DP_FUA ? REQ_FUA : 0) |
- (dpf & DP_FLUSH ? REQ_FLUSH : 0);
+ (dpf & DP_FLUSH ? REQ_PREFLUSH : 0);
}
static unsigned long wire_flags_to_bio_op(u32 dpf)
diff --git a/drivers/block/drbd/drbd_req.c b/drivers/block/drbd/drbd_req.c
index 2255dcf..eef6e95 100644
--- a/drivers/block/drbd/drbd_req.c
+++ b/drivers/block/drbd/drbd_req.c
@@ -1132,7 +1132,7 @@ static int drbd_process_write_request(struct drbd_request *req)
* replicating, in which case there is no point. */
if (unlikely(req->i.size == 0)) {
/* The only size==0 bios we expect are empty flushes. */
- D_ASSERT(device, req->master_bio->bi_rw & REQ_FLUSH);
+ D_ASSERT(device, req->master_bio->bi_rw & REQ_PREFLUSH);
if (remote)
_req_mod(req, QUEUE_AS_DRBD_BARRIER);
return remote;
diff --git a/drivers/md/bcache/journal.c b/drivers/md/bcache/journal.c
index 68fa0f0..6e0a330 100644
--- a/drivers/md/bcache/journal.c
+++ b/drivers/md/bcache/journal.c
@@ -627,7 +627,7 @@ static void journal_write_unlocked(struct closure *cl)
bio->bi_iter.bi_sector = PTR_OFFSET(k, i);
bio->bi_bdev = ca->bdev;
bio->bi_op = REQ_OP_WRITE;
- bio->bi_rw = REQ_SYNC|REQ_META|REQ_FLUSH|REQ_FUA;
+ bio->bi_rw = REQ_SYNC|REQ_META|REQ_PREFLUSH|REQ_FUA;
bio->bi_iter.bi_size = sectors << 9;
bio->bi_end_io = journal_write_endio;
diff --git a/drivers/md/bcache/request.c b/drivers/md/bcache/request.c
index be8cd63f..3947114 100644
--- a/drivers/md/bcache/request.c
+++ b/drivers/md/bcache/request.c
@@ -205,10 +205,10 @@ static void bch_data_insert_start(struct closure *cl)
return bch_data_invalidate(cl);
/*
- * Journal writes are marked REQ_FLUSH; if the original write was a
+ * Journal writes are marked REQ_PREFLUSH; if the original write was a
* flush, it'll wait on the journal write.
*/
- bio->bi_rw &= ~(REQ_FLUSH|REQ_FUA);
+ bio->bi_rw &= ~(REQ_PREFLUSH|REQ_FUA);
do {
unsigned i;
@@ -668,7 +668,7 @@ static inline struct search *search_alloc(struct bio *bio,
s->iop.write_prio = 0;
s->iop.error = 0;
s->iop.flags = 0;
- s->iop.flush_journal = (bio->bi_rw & (REQ_FLUSH|REQ_FUA)) != 0;
+ s->iop.flush_journal = (bio->bi_rw & (REQ_PREFLUSH|REQ_FUA)) != 0;
s->iop.wq = bcache_wq;
return s;
@@ -920,7 +920,7 @@ static void cached_dev_write(struct cached_dev *dc, struct search *s)
bch_writeback_add(dc);
s->iop.bio = bio;
- if (bio->bi_rw & REQ_FLUSH) {
+ if (bio->bi_rw & REQ_PREFLUSH) {
/* Also need to send a flush to the backing device */
struct bio *flush = bio_alloc_bioset(GFP_NOIO, 0,
dc->disk.bio_split);
diff --git a/drivers/md/dm-cache-target.c b/drivers/md/dm-cache-target.c
index fe222c0..3c9aebe 100644
--- a/drivers/md/dm-cache-target.c
+++ b/drivers/md/dm-cache-target.c
@@ -788,7 +788,7 @@ static void check_if_tick_bio_needed(struct cache *cache, struct bio *bio)
spin_lock_irqsave(&cache->lock, flags);
if (cache->need_tick_bio &&
- !(bio->bi_rw & (REQ_FUA | REQ_FLUSH)) &&
+ !(bio->bi_rw & (REQ_FUA | REQ_PREFLUSH)) &&
bio->bi_op != REQ_OP_DISCARD) {
pb->tick = true;
cache->need_tick_bio = false;
@@ -830,7 +830,7 @@ static dm_oblock_t get_bio_block(struct cache *cache, struct bio *bio)
static int bio_triggers_commit(struct cache *cache, struct bio *bio)
{
- return bio->bi_rw & (REQ_FLUSH | REQ_FUA);
+ return bio->bi_rw & (REQ_PREFLUSH | REQ_FUA);
}
/*
@@ -1063,7 +1063,8 @@ static void dec_io_migrations(struct cache *cache)
static bool discard_or_flush(struct bio *bio)
{
- return bio->bi_op == REQ_OP_DISCARD || bio->bi_rw & (REQ_FLUSH | REQ_FUA);
+ return bio->bi_op == REQ_OP_DISCARD ||
+ bio->bi_rw & (REQ_PREFLUSH | REQ_FUA);
}
static void __cell_defer(struct cache *cache, struct dm_bio_prison_cell *cell)
@@ -1974,7 +1975,7 @@ static void process_deferred_bios(struct cache *cache)
bio = bio_list_pop(&bios);
- if (bio->bi_rw & REQ_FLUSH)
+ if (bio->bi_rw & REQ_PREFLUSH)
process_flush_bio(cache, bio);
else if (bio->bi_op == REQ_OP_DISCARD)
process_discard_bio(cache, &structs, bio);
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index b7cbd39..7e39d3c 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -1909,11 +1909,12 @@ static int crypt_map(struct dm_target *ti, struct bio *bio)
struct crypt_config *cc = ti->private;
/*
- * If bio is REQ_FLUSH or REQ_DISCARD, just bypass crypt queues.
- * - for REQ_FLUSH device-mapper core ensures that no IO is in-flight
+ * If bio is REQ_PREFLUSH or REQ_DISCARD, just bypass crypt queues.
+ * - for REQ_PREFLUSH device-mapper core ensures that no IO is in-flight
* - for REQ_DISCARD caller must use flush if IO ordering matters
*/
- if (unlikely(bio->bi_rw & REQ_FLUSH || bio->bi_op == REQ_OP_DISCARD)) {
+ if (unlikely(bio->bi_rw & REQ_PREFLUSH ||
+ bio->bi_op == REQ_OP_DISCARD)) {
bio->bi_bdev = cc->dev->bdev;
if (bio_sectors(bio))
bio->bi_iter.bi_sector = cc->start +
diff --git a/drivers/md/dm-era-target.c b/drivers/md/dm-era-target.c
index 665bf32..2faf49d8 100644
--- a/drivers/md/dm-era-target.c
+++ b/drivers/md/dm-era-target.c
@@ -1540,9 +1540,9 @@ static int era_map(struct dm_target *ti, struct bio *bio)
remap_to_origin(era, bio);
/*
- * REQ_FLUSH bios carry no data, so we're not interested in them.
+ * REQ_PREFLUSH bios carry no data, so we're not interested in them.
*/
- if (!(bio->bi_rw & REQ_FLUSH) &&
+ if (!(bio->bi_rw & REQ_PREFLUSH) &&
(bio_data_dir(bio) == WRITE) &&
!metadata_current_marked(era->md, block)) {
defer_bio(era, bio);
diff --git a/drivers/md/dm-io.c b/drivers/md/dm-io.c
index 790b185..84aa27c 100644
--- a/drivers/md/dm-io.c
+++ b/drivers/md/dm-io.c
@@ -381,7 +381,7 @@ static void dispatch_io(int op, int op_flags, unsigned int num_regions,
*/
for (i = 0; i < num_regions; i++) {
*dp = old_pages;
- if (where[i].count || (op_flags & REQ_FLUSH))
+ if (where[i].count || (op_flags & REQ_PREFLUSH))
do_region(op, op_flags, i, where + i, dp, io);
}
diff --git a/drivers/md/dm-log-writes.c b/drivers/md/dm-log-writes.c
index 813bb4d..0848a43 100644
--- a/drivers/md/dm-log-writes.c
+++ b/drivers/md/dm-log-writes.c
@@ -555,7 +555,7 @@ static int log_writes_map(struct dm_target *ti, struct bio *bio)
struct bio_vec bv;
size_t alloc_size;
int i = 0;
- bool flush_bio = (bio->bi_rw & REQ_FLUSH);
+ bool flush_bio = (bio->bi_rw & REQ_PREFLUSH);
bool fua_bio = (bio->bi_rw & REQ_FUA);
bool discard_bio = (bio->bi_op == REQ_OP_DISCARD);
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c
index 54cc0c7..9f34923 100644
--- a/drivers/md/dm-raid1.c
+++ b/drivers/md/dm-raid1.c
@@ -704,7 +704,7 @@ static void do_writes(struct mirror_set *ms, struct bio_list *writes)
bio_list_init(&requeue);
while ((bio = bio_list_pop(writes))) {
- if ((bio->bi_rw & REQ_FLUSH) ||
+ if ((bio->bi_rw & REQ_PREFLUSH) ||
(bio->bi_op == REQ_OP_DISCARD)) {
bio_list_add(&sync, bio);
continue;
@@ -1253,7 +1253,8 @@ static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
* We need to dec pending if this was a write.
*/
if (rw == WRITE) {
- if (!(bio->bi_rw & REQ_FLUSH) && bio->bi_op != REQ_OP_DISCARD)
+ if (!(bio->bi_rw & REQ_PREFLUSH) &&
+ bio->bi_op != REQ_OP_DISCARD)
dm_rh_dec(ms->rh, bio_record->write_region);
return error;
}
diff --git a/drivers/md/dm-region-hash.c b/drivers/md/dm-region-hash.c
index ce4af57..d257428 100644
--- a/drivers/md/dm-region-hash.c
+++ b/drivers/md/dm-region-hash.c
@@ -398,7 +398,7 @@ void dm_rh_mark_nosync(struct dm_region_hash *rh, struct bio *bio)
region_t region = dm_rh_bio_to_region(rh, bio);
int recovering = 0;
- if (bio->bi_rw & REQ_FLUSH) {
+ if (bio->bi_rw & REQ_PREFLUSH) {
rh->flush_failure = 1;
return;
}
@@ -526,7 +526,7 @@ void dm_rh_inc_pending(struct dm_region_hash *rh, struct bio_list *bios)
struct bio *bio;
for (bio = bios->head; bio; bio = bio->bi_next) {
- if (bio->bi_rw & REQ_FLUSH || bio->bi_op == REQ_OP_DISCARD)
+ if (bio->bi_rw & REQ_PREFLUSH || bio->bi_op == REQ_OP_DISCARD)
continue;
rh_inc(rh, dm_rh_bio_to_region(rh, bio));
}
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index f68d0ae..6e82975 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -1681,7 +1681,7 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio)
init_tracked_chunk(bio);
- if (bio->bi_rw & REQ_FLUSH) {
+ if (bio->bi_rw & REQ_PREFLUSH) {
bio->bi_bdev = s->cow->bdev;
return DM_MAPIO_REMAPPED;
}
@@ -1800,7 +1800,7 @@ static int snapshot_merge_map(struct dm_target *ti, struct bio *bio)
init_tracked_chunk(bio);
- if (bio->bi_rw & REQ_FLUSH) {
+ if (bio->bi_rw & REQ_PREFLUSH) {
if (!dm_bio_get_target_bio_nr(bio))
bio->bi_bdev = s->origin->bdev;
else
@@ -2286,7 +2286,7 @@ static int origin_map(struct dm_target *ti, struct bio *bio)
bio->bi_bdev = o->dev->bdev;
- if (unlikely(bio->bi_rw & REQ_FLUSH))
+ if (unlikely(bio->bi_rw & REQ_PREFLUSH))
return DM_MAPIO_REMAPPED;
if (bio_rw(bio) != WRITE)
diff --git a/drivers/md/dm-stripe.c b/drivers/md/dm-stripe.c
index 12b1630..e6f330c 100644
--- a/drivers/md/dm-stripe.c
+++ b/drivers/md/dm-stripe.c
@@ -286,7 +286,7 @@ static int stripe_map(struct dm_target *ti, struct bio *bio)
uint32_t stripe;
unsigned target_bio_nr;
- if (bio->bi_rw & REQ_FLUSH) {
+ if (bio->bi_rw & REQ_PREFLUSH) {
target_bio_nr = dm_bio_get_target_bio_nr(bio);
BUG_ON(target_bio_nr >= sc->stripes);
bio->bi_bdev = sc->stripe[target_bio_nr].dev->bdev;
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 1e170e7..5eac816 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -697,7 +697,7 @@ static void remap_to_origin(struct thin_c *tc, struct bio *bio)
static int bio_triggers_commit(struct thin_c *tc, struct bio *bio)
{
- return (bio->bi_rw & (REQ_FLUSH | REQ_FUA)) &&
+ return (bio->bi_rw & (REQ_PREFLUSH | REQ_FUA)) &&
dm_thin_changed_this_transaction(tc->td);
}
@@ -868,7 +868,7 @@ static void __inc_remap_and_issue_cell(void *context,
struct bio *bio;
while ((bio = bio_list_pop(&cell->bios))) {
- if (bio->bi_rw & (REQ_FLUSH | REQ_FUA) ||
+ if (bio->bi_rw & (REQ_PREFLUSH | REQ_FUA) ||
bio->bi_op == REQ_OP_DISCARD)
bio_list_add(&info->defer_bios, bio);
else {
@@ -1647,7 +1647,7 @@ static void __remap_and_issue_shared_cell(void *context,
while ((bio = bio_list_pop(&cell->bios))) {
if ((bio_data_dir(bio) == WRITE) ||
- (bio->bi_rw & (REQ_FLUSH | REQ_FUA) ||
+ (bio->bi_rw & (REQ_PREFLUSH | REQ_FUA) ||
bio->bi_op == REQ_OP_DISCARD))
bio_list_add(&info->defer_bios, bio);
else {
@@ -2560,7 +2560,7 @@ static int thin_bio_map(struct dm_target *ti, struct bio *bio)
return DM_MAPIO_SUBMITTED;
}
- if (bio->bi_rw & (REQ_FLUSH | REQ_FUA) ||
+ if (bio->bi_rw & (REQ_PREFLUSH | REQ_FUA) ||
bio->bi_op == REQ_OP_DISCARD) {
thin_defer_bio_with_throttle(tc, bio);
return DM_MAPIO_SUBMITTED;
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 90135b6..5336148c 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -964,12 +964,12 @@ static void dec_pending(struct dm_io *io, int error)
if (io_error == DM_ENDIO_REQUEUE)
return;
- if ((bio->bi_rw & REQ_FLUSH) && bio->bi_iter.bi_size) {
+ if ((bio->bi_rw & REQ_PREFLUSH) && bio->bi_iter.bi_size) {
/*
* Preflush done for flush with data, reissue
- * without REQ_FLUSH.
+ * without REQ_PREFLUSH.
*/
- bio->bi_rw &= ~REQ_FLUSH;
+ bio->bi_rw &= ~REQ_PREFLUSH;
queue_io(md, bio);
} else {
/* done with normal IO or empty flush */
@@ -1428,7 +1428,7 @@ EXPORT_SYMBOL_GPL(dm_set_target_max_io_len);
/*
* A target may call dm_accept_partial_bio only from the map routine. It is
- * allowed for all bio types except REQ_FLUSH.
+ * allowed for all bio types except REQ_PREFLUSH.
*
* dm_accept_partial_bio informs the dm that the target only wants to process
* additional n_sectors sectors of the bio and the rest of the data should be
@@ -1458,7 +1458,7 @@ void dm_accept_partial_bio(struct bio *bio, unsigned n_sectors)
{
struct dm_target_io *tio = container_of(bio, struct dm_target_io, clone);
unsigned bi_size = bio->bi_iter.bi_size >> SECTOR_SHIFT;
- BUG_ON(bio->bi_rw & REQ_FLUSH);
+ BUG_ON(bio->bi_rw & REQ_PREFLUSH);
BUG_ON(bi_size > *tio->len_ptr);
BUG_ON(n_sectors > bi_size);
*tio->len_ptr -= bi_size - n_sectors;
@@ -1733,7 +1733,7 @@ static void __split_and_process_bio(struct mapped_device *md,
start_io_acct(ci.io);
- if (bio->bi_rw & REQ_FLUSH) {
+ if (bio->bi_rw & REQ_PREFLUSH) {
ci.bio = &ci.md->flush_bio;
ci.sector_count = 0;
error = __send_empty_flush(&ci);
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index aad82c7..657053e 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -221,7 +221,7 @@ static void linear_make_request(struct mddev *mddev, struct bio *bio)
struct bio *split;
sector_t start_sector, end_sector, data_offset;
- if (unlikely(bio->bi_rw & REQ_FLUSH)) {
+ if (unlikely(bio->bi_rw & REQ_PREFLUSH)) {
md_flush_request(mddev, bio);
return;
}
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 7e16813..4f666d1 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -422,7 +422,7 @@ static void md_submit_flush_data(struct work_struct *ws)
/* an empty barrier - all done */
bio_endio(bio);
else {
- bio->bi_rw &= ~REQ_FLUSH;
+ bio->bi_rw &= ~REQ_PREFLUSH;
mddev->pers->make_request(mddev, bio);
}
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index 7331a80..b651af1 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -111,7 +111,7 @@ static void multipath_make_request(struct mddev *mddev, struct bio * bio)
struct multipath_bh * mp_bh;
struct multipath_info *multipath;
- if (unlikely(bio->bi_rw & REQ_FLUSH)) {
+ if (unlikely(bio->bi_rw & REQ_PREFLUSH)) {
md_flush_request(mddev, bio);
return;
}
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index e0d1b8c..f95463d 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -458,7 +458,7 @@ static void raid0_make_request(struct mddev *mddev, struct bio *bio)
struct md_rdev *tmp_dev;
struct bio *split;
- if (unlikely(bio->bi_rw & REQ_FLUSH)) {
+ if (unlikely(bio->bi_rw & REQ_PREFLUSH)) {
md_flush_request(mddev, bio);
return;
}
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 2a42daa..2856b50 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1056,7 +1056,8 @@ static void make_request(struct mddev *mddev, struct bio * bio)
const int op = bio->bi_op;
const int rw = bio_data_dir(bio);
const unsigned long do_sync = (bio->bi_rw & REQ_SYNC);
- const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA));
+ const unsigned long do_flush_fua = (bio->bi_rw &
+ (REQ_PREFLUSH | REQ_FUA));
const unsigned long do_sec = (bio->bi_rw & REQ_SECURE);
struct md_rdev *blocked_rdev;
struct blk_plug_cb *cb;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 1cfc061..6171ff7 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1452,7 +1452,7 @@ static void make_request(struct mddev *mddev, struct bio *bio)
struct bio *split;
- if (unlikely(bio->bi_rw & REQ_FLUSH)) {
+ if (unlikely(bio->bi_rw & REQ_PREFLUSH)) {
md_flush_request(mddev, bio);
return;
}
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index 311b7f2..c9f4ed5 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -536,7 +536,7 @@ int r5l_handle_flush_request(struct r5l_log *log, struct bio *bio)
bio_endio(bio);
return 0;
}
- bio->bi_rw &= ~REQ_FLUSH;
+ bio->bi_rw &= ~REQ_PREFLUSH;
return -EAGAIN;
}
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index aafd49e..2109881 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -5154,7 +5154,7 @@ static void make_request(struct mddev *mddev, struct bio * bi)
DEFINE_WAIT(w);
bool do_prepare;
- if (unlikely(bi->bi_rw & REQ_FLUSH)) {
+ if (unlikely(bi->bi_rw & REQ_PREFLUSH)) {
int ret = r5l_handle_flush_request(conf->log, bi);
if (ret == 0)
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c
index 1623d11..e63ad0f 100644
--- a/fs/btrfs/check-integrity.c
+++ b/fs/btrfs/check-integrity.c
@@ -2237,7 +2237,7 @@ static void btrfsic_bio_end_io(struct bio *bp)
block->dev_bytenr, block->mirror_num);
next_block = block->next_in_same_bio;
block->iodone_w_error = iodone_w_error;
- if (block->submit_bio_bh_rw & REQ_FLUSH) {
+ if (block->submit_bio_bh_rw & REQ_PREFLUSH) {
dev_state->last_flush_gen++;
if ((dev_state->state->print_mask &
BTRFSIC_PRINT_MASK_END_IO_BIO_BH))
@@ -2273,7 +2273,7 @@ static void btrfsic_bh_end_io(struct buffer_head *bh, int uptodate)
block->dev_bytenr, block->mirror_num);
block->iodone_w_error = iodone_w_error;
- if (block->submit_bio_bh_rw & REQ_FLUSH) {
+ if (block->submit_bio_bh_rw & REQ_PREFLUSH) {
dev_state->last_flush_gen++;
if ((dev_state->state->print_mask &
BTRFSIC_PRINT_MASK_END_IO_BIO_BH))
@@ -2926,7 +2926,7 @@ int btrfsic_submit_bh(int op, int op_flags, struct buffer_head *bh)
btrfsic_process_written_block(dev_state, dev_bytenr,
&bh->b_data, 1, NULL,
NULL, bh, op_flags);
- } else if (NULL != dev_state && (op_flags & REQ_FLUSH)) {
+ } else if (NULL != dev_state && (op_flags & REQ_PREFLUSH)) {
if (dev_state->state->print_mask &
BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH)
printk(KERN_INFO
@@ -3024,7 +3024,7 @@ static void __btrfsic_submit_bio(struct bio *bio)
kunmap(bio->bi_io_vec[i].bv_page);
}
kfree(mapped_datav);
- } else if (NULL != dev_state && (bio->bi_rw & REQ_FLUSH)) {
+ } else if (NULL != dev_state && (bio->bi_rw & REQ_PREFLUSH)) {
if (dev_state->state->print_mask &
BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH)
printk(KERN_INFO
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c
index 7104d76..2e4760b 100644
--- a/fs/jbd2/journal.c
+++ b/fs/jbd2/journal.c
@@ -1331,7 +1331,7 @@ static int jbd2_write_superblock(journal_t *journal, int write_flags)
trace_jbd2_write_superblock(journal, write_flags);
if (!(journal->j_flags & JBD2_BARRIER))
- write_flags &= ~(REQ_FUA | REQ_FLUSH);
+ write_flags &= ~(REQ_FUA | REQ_PREFLUSH);
lock_buffer(bh);
if (buffer_write_io_error(bh)) {
/*
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 4cfba72..d355483 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1235,7 +1235,7 @@ _xfs_buf_ioapply(
if (bp->b_flags & XBF_FUA)
op_flags |= REQ_FUA;
if (bp->b_flags & XBF_FLUSH)
- op_flags |= REQ_FLUSH;
+ op_flags |= REQ_PREFLUSH;
/*
* Run the write verifier callback function if it exists. If
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index b4ef8d7..d637d8b 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -158,7 +158,7 @@ enum rq_flag_bits {
__REQ_NOIDLE, /* don't anticipate more IO after this one */
__REQ_INTEGRITY, /* I/O includes block integrity payload */
__REQ_FUA, /* forced unit access */
- __REQ_FLUSH, /* request for cache flush */
+ __REQ_PREFLUSH, /* request for cache flush */
/* bio only flags */
__REQ_RAHEAD, /* read ahead, can fail anytime */
@@ -202,12 +202,12 @@ enum rq_flag_bits {
(REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER)
#define REQ_COMMON_MASK \
(REQ_FAILFAST_MASK | REQ_SYNC | REQ_META | REQ_PRIO | REQ_NOIDLE | \
- REQ_FLUSH | REQ_FUA | REQ_SECURE | REQ_INTEGRITY)
+ REQ_PREFLUSH | REQ_FUA | REQ_SECURE | REQ_INTEGRITY)
#define REQ_CLONE_MASK REQ_COMMON_MASK
/* This mask is used for both bio and request merge checking */
#define REQ_NOMERGE_FLAGS \
- (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA | REQ_FLUSH_SEQ)
+ (REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_PREFLUSH | REQ_FUA | REQ_FLUSH_SEQ)
#define REQ_RAHEAD (1ULL << __REQ_RAHEAD)
#define REQ_THROTTLED (1ULL << __REQ_THROTTLED)
@@ -225,7 +225,7 @@ enum rq_flag_bits {
#define REQ_PREEMPT (1ULL << __REQ_PREEMPT)
#define REQ_ALLOCED (1ULL << __REQ_ALLOCED)
#define REQ_COPY_USER (1ULL << __REQ_COPY_USER)
-#define REQ_FLUSH (1ULL << __REQ_FLUSH)
+#define REQ_PREFLUSH (1ULL << __REQ_PREFLUSH)
#define REQ_FLUSH_SEQ (1ULL << __REQ_FLUSH_SEQ)
#define REQ_IO_STAT (1ULL << __REQ_IO_STAT)
#define REQ_MIXED_MERGE (1ULL << __REQ_MIXED_MERGE)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index d57a5b5..7197027 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -203,9 +203,9 @@ typedef void (dax_iodone_t)(struct buffer_head *bh_map, int uptodate);
#define READ_SYNC REQ_SYNC
#define WRITE_SYNC (REQ_SYNC | REQ_NOIDLE)
#define WRITE_ODIRECT REQ_SYNC
-#define WRITE_FLUSH (REQ_SYNC | REQ_NOIDLE | REQ_FLUSH)
+#define WRITE_FLUSH (REQ_SYNC | REQ_NOIDLE | REQ_PREFLUSH)
#define WRITE_FUA (REQ_SYNC | REQ_NOIDLE | REQ_FUA)
-#define WRITE_FLUSH_FUA (REQ_SYNC | REQ_NOIDLE | REQ_FLUSH | REQ_FUA)
+#define WRITE_FLUSH_FUA (REQ_SYNC | REQ_NOIDLE | REQ_PREFLUSH | REQ_FUA)
/*
* Attribute flags. These should be or-ed together to figure out what
diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h
index ed3fc87..9df1cd8 100644
--- a/include/trace/events/f2fs.h
+++ b/include/trace/events/f2fs.h
@@ -33,7 +33,7 @@ TRACE_DEFINE_ENUM(SSR);
TRACE_DEFINE_ENUM(__REQ_RAHEAD);
TRACE_DEFINE_ENUM(__REQ_SYNC);
TRACE_DEFINE_ENUM(__REQ_NOIDLE);
-TRACE_DEFINE_ENUM(__REQ_FLUSH);
+TRACE_DEFINE_ENUM(__REQ_PREFLUSH);
TRACE_DEFINE_ENUM(__REQ_FUA);
TRACE_DEFINE_ENUM(__REQ_PRIO);
TRACE_DEFINE_ENUM(__REQ_META);
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 3a54c83..c94dec7 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -189,6 +189,7 @@ static const u32 ddir_act[2] = { BLK_TC_ACT(BLK_TC_READ),
BLK_TC_ACT(BLK_TC_WRITE) };
#define BLK_TC_RAHEAD BLK_TC_AHEAD
+#define BLK_TC_PREFLUSH BLK_TC_FLUSH
/* The ilog2() calls fall out because they're constant */
#define MASK_TC_BIT(rw, __name) ((rw & REQ_ ## __name) << \
@@ -219,7 +220,7 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
what |= MASK_TC_BIT(op_flags, SYNC);
what |= MASK_TC_BIT(op_flags, RAHEAD);
what |= MASK_TC_BIT(op_flags, META);
- what |= MASK_TC_BIT(op_flags, FLUSH);
+ what |= MASK_TC_BIT(op_flags, PREFLUSH);
what |= MASK_TC_BIT(op_flags, FUA);
if (op == REQ_OP_DISCARD)
what |= BLK_TC_ACT(BLK_TC_DISCARD);
@@ -1777,7 +1778,7 @@ void blk_fill_rwbs(char *rwbs, int op, u32 rw, int bytes)
{
int i = 0;
- if (rw & REQ_FLUSH ||
+ if (rw & REQ_PREFLUSH ||
op == REQ_OP_FLUSH)
rwbs[i++] = 'F';
--
1.8.3.1
^ permalink raw reply related
* [PATCH 34/35] block: add QUEUE_FLAGs for flush and fua
From: mchristi @ 2016-01-05 20:53 UTC (permalink / raw)
To: linux-f2fs-devel, linux-ext4, konrad.wilk, drbd-dev,
philipp.reisner, lars.ellenberg, linux-raid, dm-devel,
linux-fsdevel, linux-bcache, linux-block, linux-kernel,
linux-scsi, linux-mtd, target-devel, linux-btrfs, osd-dev, xfs,
ocfs2-devel
Cc: Mike Christie
In-Reply-To: <1452027218-32303-1-git-send-email-mchristi@redhat.com>
From: Mike Christie <mchristi@redhat.com>
The last patch added a REQ_OP_FLUSH for request_fn drivers
and the next patch renames REQ_FLUSH to REQ_PREFLUSH which
will be used by file systems and make_request_fn drivers.
This leaves REQ_FLUSH/REQ_FUA defined for drivers to tell
the block layer if flush/fua is supported. The names are
confusing and I bet will will accidentally be used by
people to request flushes. To avoid that, this patch adds
QUEUE_FLAGs for flush and fua which drivers will use to
indicate what they support.
Signed-off-by: Mike Christie <mchristi@redhat.com>
---
block/blk-core.c | 3 +-
block/blk-flush.c | 12 ++++----
block/blk-settings.c | 20 --------------
drivers/block/drbd/drbd_main.c | 3 +-
drivers/block/loop.c | 2 +-
drivers/block/mtip32xx/mtip32xx.c | 3 +-
drivers/block/nbd.c | 6 ++--
drivers/block/osdblk.c | 2 +-
drivers/block/ps3disk.c | 2 +-
drivers/block/skd_main.c | 3 +-
drivers/block/virtio_blk.c | 4 +--
drivers/block/xen-blkback/xenbus.c | 2 +-
drivers/block/xen-blkfront.c | 55 ++++++++++++++++++++++---------------
drivers/ide/ide-disk.c | 6 ++--
drivers/md/bcache/super.c | 4 +--
drivers/md/dm-table.c | 32 +++++++++++++--------
drivers/md/md.c | 3 +-
drivers/md/raid5-cache.c | 3 +-
drivers/mmc/card/block.c | 3 +-
drivers/mtd/mtd_blkdevs.c | 2 +-
drivers/nvme/host/core.c | 6 ++--
drivers/scsi/sd.c | 13 +++++----
drivers/target/target_core_iblock.c | 6 ++--
include/linux/blkdev.h | 6 ++--
24 files changed, 107 insertions(+), 94 deletions(-)
diff --git a/block/blk-core.c b/block/blk-core.c
index ae2afab..bb29230 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1969,7 +1969,8 @@ generic_make_request_checks(struct bio *bio)
* drivers without flush support don't have to worry
* about them.
*/
- if ((bio->bi_rw & (REQ_FLUSH | REQ_FUA)) && !q->flush_flags) {
+ if ((bio->bi_rw & (REQ_FLUSH | REQ_FUA)) &&
+ !(blk_queue_flush(q) || blk_queue_fua(q))) {
bio->bi_rw &= ~(REQ_FLUSH | REQ_FUA);
if (!nr_sectors) {
err = 0;
diff --git a/block/blk-flush.c b/block/blk-flush.c
index 0e5561e..633f9b3 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -95,17 +95,18 @@ enum {
static bool blk_kick_flush(struct request_queue *q,
struct blk_flush_queue *fq);
-static unsigned int blk_flush_policy(unsigned int fflags, struct request *rq)
+static unsigned int blk_flush_policy(struct request *rq)
{
+ struct request_queue *q = rq->q;
unsigned int policy = 0;
if (blk_rq_sectors(rq))
policy |= REQ_FSEQ_DATA;
- if (fflags & REQ_FLUSH) {
+ if (blk_queue_flush(q)) {
if (rq->cmd_flags & REQ_FLUSH)
policy |= REQ_FSEQ_PREFLUSH;
- if (!(fflags & REQ_FUA) && (rq->cmd_flags & REQ_FUA))
+ if (!blk_queue_fua(q) && (rq->cmd_flags & REQ_FUA))
policy |= REQ_FSEQ_POSTFLUSH;
}
return policy;
@@ -385,8 +386,7 @@ static void mq_flush_data_end_io(struct request *rq, int error)
void blk_insert_flush(struct request *rq)
{
struct request_queue *q = rq->q;
- unsigned int fflags = q->flush_flags; /* may change, cache */
- unsigned int policy = blk_flush_policy(fflags, rq);
+ unsigned int policy = blk_flush_policy(rq);
struct blk_flush_queue *fq = blk_get_flush_queue(q, rq->mq_ctx);
/*
@@ -394,7 +394,7 @@ void blk_insert_flush(struct request *rq)
* REQ_FLUSH and FUA for the driver.
*/
rq->cmd_flags &= ~REQ_FLUSH;
- if (!(fflags & REQ_FUA))
+ if (!blk_queue_fua(q))
rq->cmd_flags &= ~REQ_FUA;
/*
diff --git a/block/blk-settings.c b/block/blk-settings.c
index dd49735..3cef016 100644
--- a/block/blk-settings.c
+++ b/block/blk-settings.c
@@ -820,26 +820,6 @@ void blk_queue_update_dma_alignment(struct request_queue *q, int mask)
}
EXPORT_SYMBOL(blk_queue_update_dma_alignment);
-/**
- * blk_queue_flush - configure queue's cache flush capability
- * @q: the request queue for the device
- * @flush: 0, REQ_FLUSH or REQ_FLUSH | REQ_FUA
- *
- * Tell block layer cache flush capability of @q. If it supports
- * flushing, REQ_FLUSH should be set. If it supports bypassing
- * write cache for individual writes, REQ_FUA should be set.
- */
-void blk_queue_flush(struct request_queue *q, unsigned int flush)
-{
- WARN_ON_ONCE(flush & ~(REQ_FLUSH | REQ_FUA));
-
- if (WARN_ON_ONCE(!(flush & REQ_FLUSH) && (flush & REQ_FUA)))
- flush &= ~REQ_FUA;
-
- q->flush_flags = flush & (REQ_FLUSH | REQ_FUA);
-}
-EXPORT_SYMBOL_GPL(blk_queue_flush);
-
void blk_queue_flush_queueable(struct request_queue *q, bool queueable)
{
q->flush_not_queueable = !queueable;
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c
index df2ce0b..7bc78ab 100644
--- a/drivers/block/drbd/drbd_main.c
+++ b/drivers/block/drbd/drbd_main.c
@@ -2761,7 +2761,8 @@ enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsig
q->backing_dev_info.congested_data = device;
blk_queue_make_request(q, drbd_make_request);
- blk_queue_flush(q, REQ_FLUSH | REQ_FUA);
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, q);
+ queue_flag_set_unlocked(QUEUE_FLAG_FUA, q);
/* Setting the max_hw_sectors to an odd value of 8kibyte here
This triggers a max_bio_size message upon first attach or connect */
blk_queue_max_hw_sectors(q, DRBD_MAX_BIO_SIZE_SAFE >> 8);
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index a3d1293..297a91f 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -937,7 +937,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
mapping_set_gfp_mask(mapping, lo->old_gfp_mask & ~(__GFP_IO|__GFP_FS));
if (!(lo_flags & LO_FLAGS_READ_ONLY) && file->f_op->fsync)
- blk_queue_flush(lo->lo_queue, REQ_FLUSH);
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, lo->lo_queue);
loop_update_dio(lo);
set_capacity(lo->lo_disk, size);
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c
index 8751caa..461a3f9 100644
--- a/drivers/block/mtip32xx/mtip32xx.c
+++ b/drivers/block/mtip32xx/mtip32xx.c
@@ -3908,7 +3908,8 @@ skip_create_disk:
* write back cache is not supported in the device. FUA depends on
* write back cache support, hence setting flush support to zero.
*/
- blk_queue_flush(dd->queue, 0);
+ queue_flag_clear_unlocked(QUEUE_FLAG_FLUSH, dd->queue) ;
+ queue_flag_clear_unlocked(QUEUE_FLAG_FUA, dd->queue);
/* Signal trim support */
if (dd->trim_supp == true) {
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index ced3382..c21b421 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -750,9 +750,11 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD,
nbd->disk->queue);
if (nbd->flags & NBD_FLAG_SEND_FLUSH)
- blk_queue_flush(nbd->disk->queue, REQ_FLUSH);
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH,
+ nbd->disk->queue);
else
- blk_queue_flush(nbd->disk->queue, 0);
+ queue_flag_clear_unlocked(QUEUE_FLAG_FLUSH,
+ nbd->disk->queue);
thread = kthread_run(nbd_thread_send, nbd, "%s",
nbd_name(nbd));
diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c
index 3f8a0a0..d03f06a 100644
--- a/drivers/block/osdblk.c
+++ b/drivers/block/osdblk.c
@@ -437,7 +437,7 @@ static int osdblk_init_disk(struct osdblk_device *osdev)
blk_queue_stack_limits(q, osd_request_queue(osdev->osd));
blk_queue_prep_rq(q, blk_queue_start_tag);
- blk_queue_flush(q, REQ_FLUSH);
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, q);
disk->queue = q;
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index 95c524b..5985fdc 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -468,7 +468,7 @@ static int ps3disk_probe(struct ps3_system_bus_device *_dev)
blk_queue_dma_alignment(queue, dev->blk_size-1);
blk_queue_logical_block_size(queue, dev->blk_size);
- blk_queue_flush(queue, REQ_FLUSH);
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, queue);
blk_queue_max_segments(queue, -1);
blk_queue_max_segment_size(queue, dev->bounce_size);
diff --git a/drivers/block/skd_main.c b/drivers/block/skd_main.c
index a15cc2e..68d0e22 100644
--- a/drivers/block/skd_main.c
+++ b/drivers/block/skd_main.c
@@ -4409,7 +4409,8 @@ static int skd_cons_disk(struct skd_device *skdev)
disk->queue = q;
q->queuedata = skdev;
- blk_queue_flush(q, REQ_FLUSH | REQ_FUA);
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, q);
+ queue_flag_set_unlocked(QUEUE_FLAG_FUA, q);
blk_queue_max_segments(q, skdev->sgs_per_request);
blk_queue_max_hw_sectors(q, SKD_N_MAX_SECTORS);
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index c6d3bc2..b8a508b 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -489,9 +489,9 @@ static void virtblk_update_cache_mode(struct virtio_device *vdev)
struct virtio_blk *vblk = vdev->priv;
if (writeback)
- blk_queue_flush(vblk->disk->queue, REQ_FLUSH);
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, vblk->disk->queue);
else
- blk_queue_flush(vblk->disk->queue, 0);
+ queue_flag_clear_unlocked(QUEUE_FLAG_FLUSH, vblk->disk->queue);
revalidate_disk(vblk->disk);
}
diff --git a/drivers/block/xen-blkback/xenbus.c b/drivers/block/xen-blkback/xenbus.c
index f53cff4..4569692 100644
--- a/drivers/block/xen-blkback/xenbus.c
+++ b/drivers/block/xen-blkback/xenbus.c
@@ -413,7 +413,7 @@ static int xen_vbd_create(struct xen_blkif *blkif, blkif_vdev_t handle,
vbd->type |= VDISK_REMOVABLE;
q = bdev_get_queue(bdev);
- if (q && q->flush_flags)
+ if (q && (blk_queue_flush(q) || blk_queue_fua(q)))
vbd->flush_support = true;
if (q && blk_queue_secdiscard(q))
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 1d48f0a..6007c86 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -146,6 +146,7 @@ struct blkfront_info
unsigned int persistent_gnts_c;
unsigned long shadow_free;
unsigned int feature_flush;
+ unsigned int feature_fua;
unsigned int feature_discard:1;
unsigned int feature_secdiscard:1;
unsigned int discard_granularity;
@@ -655,19 +656,15 @@ static int blkif_queue_rw_req(struct request *req)
* implement it the same way. (It's also a FLUSH+FUA,
* since it is guaranteed ordered WRT previous writes.)
*/
- switch (info->feature_flush &
- ((REQ_FLUSH|REQ_FUA))) {
- case REQ_FLUSH|REQ_FUA:
+ if (blk_queue_flush(info->rq) &&
+ blk_queue_fua(info->rq))
ring_req->operation =
BLKIF_OP_WRITE_BARRIER;
- break;
- case REQ_FLUSH:
+ else if (blk_queue_flush(info->rq))
ring_req->operation =
BLKIF_OP_FLUSH_DISKCACHE;
- break;
- default:
+ else
ring_req->operation = 0;
- }
}
ring_req->u.rw.nr_segments = num_grant;
}
@@ -740,9 +737,9 @@ static inline bool blkif_request_flush_invalid(struct request *req,
{
return ((req->cmd_type != REQ_TYPE_FS) ||
((req->op == REQ_OP_FLUSH) &&
- !(info->feature_flush & REQ_FLUSH)) ||
+ !(blk_queue_flush(info->rq))) ||
((req->cmd_flags & REQ_FUA) &&
- !(info->feature_flush & REQ_FUA)));
+ !(blk_queue_fua(info->rq))));
}
static int blkif_queue_rq(struct blk_mq_hw_ctx *hctx,
@@ -838,23 +835,30 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size,
return 0;
}
-static const char *flush_info(unsigned int feature_flush)
+static const char *flush_info(struct blkfront_info *info)
{
- switch (feature_flush & ((REQ_FLUSH | REQ_FUA))) {
- case REQ_FLUSH|REQ_FUA:
+ if (blk_queue_flush(info->rq) && blk_queue_fua(info->rq))
return "barrier: enabled;";
- case REQ_FLUSH:
+ else if (blk_queue_flush(info->rq))
return "flush diskcache: enabled;";
- default:
+ else
return "barrier or flush: disabled;";
- }
}
static void xlvbd_flush(struct blkfront_info *info)
{
- blk_queue_flush(info->rq, info->feature_flush);
+ if (info->feature_flush)
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, info->rq);
+ else
+ queue_flag_clear_unlocked(QUEUE_FLAG_FLUSH, info->rq);
+
+ if (info->feature_fua)
+ queue_flag_set_unlocked(QUEUE_FLAG_FUA, info->rq);
+ else
+ queue_flag_clear_unlocked(QUEUE_FLAG_FUA, info->rq);
+
pr_info("blkfront: %s: %s %s %s %s %s\n",
- info->gd->disk_name, flush_info(info->feature_flush),
+ info->gd->disk_name, flush_info(info),
"persistent grants:", info->feature_persistent ?
"enabled;" : "disabled;", "indirect descriptors:",
info->max_indirect_segments ? "enabled;" : "disabled;");
@@ -1373,6 +1377,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
if (unlikely(error)) {
if (error == -EOPNOTSUPP)
error = 0;
+ info->feature_fua = 0;
info->feature_flush = 0;
xlvbd_flush(info);
}
@@ -1936,6 +1941,7 @@ static int blkfront_gather_backend_features(struct blkfront_info *info)
unsigned int indirect_segments;
info->feature_flush = 0;
+ info->feature_fua = 0;
err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
"feature-barrier", "%d", &barrier,
@@ -1948,8 +1954,11 @@ static int blkfront_gather_backend_features(struct blkfront_info *info)
*
* If there are barriers, then we use flush.
*/
- if (!err && barrier)
- info->feature_flush = REQ_FLUSH | REQ_FUA;
+ if (!err && barrier) {
+ info->feature_flush = 1;
+ info->feature_fua = 1;
+ }
+
/*
* And if there is "feature-flush-cache" use that above
* barriers.
@@ -1958,8 +1967,10 @@ static int blkfront_gather_backend_features(struct blkfront_info *info)
"feature-flush-cache", "%d", &flush,
NULL);
- if (!err && flush)
- info->feature_flush = REQ_FLUSH;
+ if (!err && flush) {
+ info->feature_flush = 1;
+ info->feature_fua = 0;
+ }
err = xenbus_gather(XBT_NIL, info->xbdev->otherend,
"feature-discard", "%d", &discard,
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 6474ed3..4501ca7 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -522,8 +522,8 @@ static int ide_do_setfeature(ide_drive_t *drive, u8 feature, u8 nsect)
static void update_flush(ide_drive_t *drive)
{
u16 *id = drive->id;
- unsigned flush = 0;
+ queue_flag_clear_unlocked(QUEUE_FLAG_FLUSH, drive->queue);
if (drive->dev_flags & IDE_DFLAG_WCACHE) {
unsigned long long capacity;
int barrier;
@@ -546,12 +546,10 @@ static void update_flush(ide_drive_t *drive)
drive->name, barrier ? "" : "not ");
if (barrier) {
- flush = REQ_FLUSH;
blk_queue_prep_rq(drive->queue, idedisk_prep_fn);
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, drive->queue);
}
}
-
- blk_queue_flush(drive->queue, flush);
}
ide_devset_get_flag(wcache, IDE_DFLAG_WCACHE);
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c
index b11f7f4..3d75a0f 100644
--- a/drivers/md/bcache/super.c
+++ b/drivers/md/bcache/super.c
@@ -820,8 +820,8 @@ static int bcache_device_init(struct bcache_device *d, unsigned block_size,
clear_bit(QUEUE_FLAG_ADD_RANDOM, &d->disk->queue->queue_flags);
set_bit(QUEUE_FLAG_DISCARD, &d->disk->queue->queue_flags);
- blk_queue_flush(q, REQ_FLUSH|REQ_FUA);
-
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, q);
+ queue_flag_set_unlocked(QUEUE_FLAG_FUA, q);
return 0;
}
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 061152a..5e940f7 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -1312,13 +1312,21 @@ static void dm_table_verify_integrity(struct dm_table *t)
static int device_flush_capable(struct dm_target *ti, struct dm_dev *dev,
sector_t start, sector_t len, void *data)
{
- unsigned flush = (*(unsigned *)data);
struct request_queue *q = bdev_get_queue(dev->bdev);
- return q && (q->flush_flags & flush);
+ return q && blk_queue_flush(q);
}
-static bool dm_table_supports_flush(struct dm_table *t, unsigned flush)
+static int device_fua_capable(struct dm_target *ti, struct dm_dev *dev,
+ sector_t start, sector_t len, void *data)
+{
+ struct request_queue *q = bdev_get_queue(dev->bdev);
+
+ return q && blk_queue_fua(q);
+}
+
+static bool dm_table_supports_flush(struct dm_table *t,
+ iterate_devices_callout_fn support_test)
{
struct dm_target *ti;
unsigned i = 0;
@@ -1339,7 +1347,7 @@ static bool dm_table_supports_flush(struct dm_table *t, unsigned flush)
return true;
if (ti->type->iterate_devices &&
- ti->type->iterate_devices(ti, device_flush_capable, &flush))
+ ti->type->iterate_devices(ti, support_test, NULL))
return true;
}
@@ -1470,8 +1478,6 @@ static bool dm_table_supports_discards(struct dm_table *t)
void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
struct queue_limits *limits)
{
- unsigned flush = 0;
-
/*
* Copy table's limits to the DM device's request_queue
*/
@@ -1482,12 +1488,14 @@ void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
else
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, q);
- if (dm_table_supports_flush(t, REQ_FLUSH)) {
- flush |= REQ_FLUSH;
- if (dm_table_supports_flush(t, REQ_FUA))
- flush |= REQ_FUA;
- }
- blk_queue_flush(q, flush);
+ if (dm_table_supports_flush(t, device_flush_capable)) {
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, q);
+ if (dm_table_supports_flush(t, device_fua_capable))
+ queue_flag_set_unlocked(QUEUE_FLAG_FUA, q);
+ else
+ queue_flag_clear_unlocked(QUEUE_FLAG_FUA, q);
+ } else
+ queue_flag_clear_unlocked(QUEUE_FLAG_FLUSH, q);
if (!dm_table_discard_zeroes_data(t))
q->limits.discard_zeroes_data = 0;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index ee1ef20..7e16813 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -5040,7 +5040,8 @@ static int md_alloc(dev_t dev, char *name)
disk->fops = &md_fops;
disk->private_data = mddev;
disk->queue = mddev->queue;
- blk_queue_flush(mddev->queue, REQ_FLUSH | REQ_FUA);
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, mddev->queue);
+ queue_flag_set_unlocked(QUEUE_FLAG_FUA, mddev->queue);
/* Allow extended partitions. This makes the
* 'mdp' device redundant, but we can't really
* remove it now.
diff --git a/drivers/md/raid5-cache.c b/drivers/md/raid5-cache.c
index e19c2f0..311b7f2 100644
--- a/drivers/md/raid5-cache.c
+++ b/drivers/md/raid5-cache.c
@@ -1189,6 +1189,7 @@ ioerr:
int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev)
{
+ struct request_queue *q = rdev->bdev->bd_disk->queue;
struct r5l_log *log;
if (PAGE_SIZE != 4096)
@@ -1198,7 +1199,7 @@ int r5l_init_log(struct r5conf *conf, struct md_rdev *rdev)
return -ENOMEM;
log->rdev = rdev;
- log->need_cache_flush = (rdev->bdev->bd_disk->queue->flush_flags != 0);
+ log->need_cache_flush = (blk_queue_flush(q) || blk_queue_fua(q));
log->uuid_checksum = crc32c_le(~0, rdev->mddev->uuid,
sizeof(rdev->mddev->uuid));
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 7caf236..c1fad5f 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -2277,7 +2277,8 @@ static struct mmc_blk_data *mmc_blk_alloc_req(struct mmc_card *card,
((card->ext_csd.rel_param & EXT_CSD_WR_REL_PARAM_EN) ||
card->ext_csd.rel_sectors)) {
md->flags |= MMC_BLK_REL_WR;
- blk_queue_flush(md->queue.queue, REQ_FLUSH | REQ_FUA);
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, md->queue.queue);
+ queue_flag_set_unlocked(QUEUE_FLAG_FUA, md->queue.queue);
}
if (mmc_card_mmc(card) &&
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index 67da1cd..4462627 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -409,7 +409,7 @@ int add_mtd_blktrans_dev(struct mtd_blktrans_dev *new)
goto error3;
if (tr->flush)
- blk_queue_flush(new->rq, REQ_FLUSH);
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, new->rq);
new->rq->queuedata = new;
blk_queue_logical_block_size(new->rq, tr->blksize);
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 1375a83..9f253bc 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1078,8 +1078,10 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, unsigned nsid)
}
if (ctrl->stripe_size)
blk_queue_chunk_sectors(ns->queue, ctrl->stripe_size >> 9);
- if (ctrl->vwc & NVME_CTRL_VWC_PRESENT)
- blk_queue_flush(ns->queue, REQ_FLUSH | REQ_FUA);
+ if (ctrl->vwc & NVME_CTRL_VWC_PRESENT) {
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, ns->queue);
+ queue_flag_set_unlocked(QUEUE_FLAG_FUA, ns->queue);
+ }
blk_queue_virt_boundary(ns->queue, ctrl->page_size - 1);
disk->major = nvme_major;
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index abaaa7e..91142f1 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -137,15 +137,18 @@ static const char *sd_cache_types[] = {
static void sd_set_flush_flag(struct scsi_disk *sdkp)
{
- unsigned flush = 0;
+ struct request_queue *q = sdkp->disk->queue;
if (sdkp->WCE) {
- flush |= REQ_FLUSH;
+ queue_flag_set_unlocked(QUEUE_FLAG_FLUSH, q);
if (sdkp->DPOFUA)
- flush |= REQ_FUA;
+ queue_flag_set_unlocked(QUEUE_FLAG_FUA, q);
+ else
+ queue_flag_clear_unlocked(QUEUE_FLAG_FUA, q);
+ } else {
+ queue_flag_clear_unlocked(QUEUE_FLAG_FUA, q);
+ queue_flag_clear_unlocked(QUEUE_FLAG_FLUSH, q);
}
-
- blk_queue_flush(sdkp->disk->queue, flush);
}
static ssize_t
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index b83195b..78bf469 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -671,11 +671,11 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
* Force writethrough using WRITE_FUA if a volatile write cache
* is not enabled, or if initiator set the Force Unit Access bit.
*/
- if (q->flush_flags & REQ_FUA) {
+ if (blk_queue_fua(q)) {
if (cmd->se_cmd_flags & SCF_FUA) {
op = REQ_OP_WRITE;
op_flags = WRITE_FUA;
- } else if (!(q->flush_flags & REQ_FLUSH)) {
+ } else if (!blk_queue_flush(q)) {
op = REQ_OP_WRITE;
op_flags = WRITE_FUA;
} else {
@@ -842,7 +842,7 @@ static bool iblock_get_write_cache(struct se_device *dev)
struct block_device *bd = ib_dev->ibd_bd;
struct request_queue *q = bdev_get_queue(bd);
- return q->flush_flags & REQ_FLUSH;
+ return blk_queue_flush(q);
}
static const struct target_backend_ops iblock_ops = {
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index ec0d0d0..09724ed 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -434,7 +434,6 @@ struct request_queue {
/*
* for flush operations
*/
- unsigned int flush_flags;
unsigned int flush_not_queueable:1;
struct blk_flush_queue *fq;
@@ -492,6 +491,8 @@ struct request_queue {
#define QUEUE_FLAG_INIT_DONE 20 /* queue is initialized */
#define QUEUE_FLAG_NO_SG_MERGE 21 /* don't attempt to merge SG segments*/
#define QUEUE_FLAG_POLL 22 /* IO polling enabled if set */
+#define QUEUE_FLAG_FLUSH 23 /* supports FLUSH/PREFLUSH */
+#define QUEUE_FLAG_FUA 24 /* supports FUA */
#define QUEUE_FLAG_DEFAULT ((1 << QUEUE_FLAG_IO_STAT) | \
(1 << QUEUE_FLAG_STACKABLE) | \
@@ -580,6 +581,8 @@ static inline void queue_flag_clear(unsigned int flag, struct request_queue *q)
#define blk_queue_discard(q) test_bit(QUEUE_FLAG_DISCARD, &(q)->queue_flags)
#define blk_queue_secdiscard(q) (blk_queue_discard(q) && \
test_bit(QUEUE_FLAG_SECDISCARD, &(q)->queue_flags))
+#define blk_queue_flush(q) test_bit(QUEUE_FLAG_FLUSH, &(q)->queue_flags)
+#define blk_queue_fua(q) test_bit(QUEUE_FLAG_FUA, &(q)->queue_flags)
#define blk_noretry_request(rq) \
((rq)->cmd_flags & (REQ_FAILFAST_DEV|REQ_FAILFAST_TRANSPORT| \
@@ -1007,7 +1010,6 @@ extern void blk_queue_update_dma_alignment(struct request_queue *, int);
extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *);
extern void blk_queue_rq_timed_out(struct request_queue *, rq_timed_out_fn *);
extern void blk_queue_rq_timeout(struct request_queue *, unsigned int);
-extern void blk_queue_flush(struct request_queue *q, unsigned int flush);
extern void blk_queue_flush_queueable(struct request_queue *q, bool queueable);
extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
--
1.8.3.1
^ permalink raw reply related
* [PATCH 33/35] block, drivers: add REQ_OP_FLUSH operation
From: mchristi @ 2016-01-05 20:53 UTC (permalink / raw)
To: linux-f2fs-devel, linux-ext4, konrad.wilk, drbd-dev,
philipp.reisner, lars.ellenberg, linux-raid, dm-devel,
linux-fsdevel, linux-bcache, linux-block, linux-kernel,
linux-scsi, linux-mtd, target-devel, linux-btrfs, osd-dev, xfs,
ocfs2-devel
Cc: Mike Christie
In-Reply-To: <1452027218-32303-1-git-send-email-mchristi@redhat.com>
From: Mike Christie <mchristi@redhat.com>
This adds a REQ_OP_FLUSH operation that is sent to request_fn
based drivers by the block layer's flush code, instead of
sending requests with the request->cmd_flags REQ_FLUSH bit set.
For the following 3 flush related patches, I have not tested
every driver. I have only tested scsi with xfs and btrfs.
Signed-off-by: Mike Christie <mchristi@redhat.com>
---
Documentation/block/writeback_cache_control.txt | 6 +++---
block/blk-flush.c | 6 +++---
drivers/block/loop.c | 4 ++--
drivers/block/nbd.c | 2 +-
drivers/block/osdblk.c | 2 +-
drivers/block/ps3disk.c | 4 ++--
drivers/block/skd_main.c | 2 +-
drivers/block/virtio_blk.c | 2 +-
drivers/block/xen-blkfront.c | 8 ++++----
drivers/ide/ide-disk.c | 2 +-
drivers/md/dm.c | 4 ++--
drivers/mmc/card/block.c | 5 ++---
drivers/mmc/card/queue.h | 2 +-
drivers/mtd/mtd_blkdevs.c | 2 +-
drivers/nvme/host/pci.c | 2 +-
drivers/scsi/sd.c | 7 +++----
include/linux/blk_types.h | 1 +
include/linux/blkdev.h | 3 +++
kernel/trace/blktrace.c | 5 ++++-
19 files changed, 37 insertions(+), 32 deletions(-)
diff --git a/Documentation/block/writeback_cache_control.txt b/Documentation/block/writeback_cache_control.txt
index 83407d3..ea5550f 100644
--- a/Documentation/block/writeback_cache_control.txt
+++ b/Documentation/block/writeback_cache_control.txt
@@ -73,9 +73,9 @@ doing:
blk_queue_flush(sdkp->disk->queue, REQ_FLUSH);
-and handle empty REQ_FLUSH requests in its prep_fn/request_fn. Note that
+and handle empty REQ_OP_FLUSH requests in its prep_fn/request_fn. Note that
REQ_FLUSH requests with a payload are automatically turned into a sequence
-of an empty REQ_FLUSH request followed by the actual write by the block
+of an empty REQ_OP_FLUSH request followed by the actual write by the block
layer. For devices that also support the FUA bit the block layer needs
to be told to pass through the REQ_FUA bit using:
@@ -83,4 +83,4 @@ to be told to pass through the REQ_FUA bit using:
and the driver must handle write requests that have the REQ_FUA bit set
in prep_fn/request_fn. If the FUA bit is not natively supported the block
-layer turns it into an empty REQ_FLUSH request after the actual write.
+layer turns it into an empty REQ_OP_FLUSH request after the actual write.
diff --git a/block/blk-flush.c b/block/blk-flush.c
index b4eb0e8..0e5561e 100644
--- a/block/blk-flush.c
+++ b/block/blk-flush.c
@@ -29,7 +29,7 @@
* The actual execution of flush is double buffered. Whenever a request
* needs to execute PRE or POSTFLUSH, it queues at
* fq->flush_queue[fq->flush_pending_idx]. Once certain criteria are met, a
- * flush is issued and the pending_idx is toggled. When the flush
+ * REQ_OP_FLUSH is issued and the pending_idx is toggled. When the flush
* completes, all the requests which were pending are proceeded to the next
* step. This allows arbitrary merging of different types of FLUSH/FUA
* requests.
@@ -329,8 +329,8 @@ static bool blk_kick_flush(struct request_queue *q, struct blk_flush_queue *fq)
}
flush_rq->cmd_type = REQ_TYPE_FS;
- flush_rq->cmd_flags = WRITE_FLUSH | REQ_FLUSH_SEQ;
- flush_rq->op = REQ_OP_WRITE;
+ flush_rq->cmd_flags = REQ_SYNC | REQ_NOIDLE | REQ_FLUSH_SEQ;
+ flush_rq->op = REQ_OP_FLUSH;
flush_rq->rq_disk = first_rq->rq_disk;
flush_rq->end_io = flush_end_io;
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 1afc03c..a3d1293 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -536,7 +536,7 @@ static int do_req_filebacked(struct loop_device *lo, struct request *rq)
pos = ((loff_t) blk_rq_pos(rq) << 9) + lo->lo_offset;
if (op_is_write(rq->op)) {
- if (rq->cmd_flags & REQ_FLUSH)
+ if (rq->op == REQ_OP_FLUSH)
ret = lo_req_flush(lo, rq);
else if (rq->op == REQ_OP_DISCARD)
ret = lo_discard(lo, rq, pos);
@@ -1653,7 +1653,7 @@ static int loop_queue_rq(struct blk_mq_hw_ctx *hctx,
if (lo->lo_state != Lo_bound)
return -EIO;
- if (lo->use_dio && (!(cmd->rq->cmd_flags & REQ_FLUSH) ||
+ if (lo->use_dio && (cmd->rq->op != REQ_OP_FLUSH ||
cmd->rq->op == REQ_OP_DISCARD))
cmd->use_aio = true;
else
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index 8e8f7e3..ced3382 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -244,7 +244,7 @@ static int nbd_send_req(struct nbd_device *nbd, struct request *req)
type = NBD_CMD_DISC;
else if (req->op == REQ_OP_DISCARD)
type = NBD_CMD_TRIM;
- else if (req->cmd_flags & REQ_FLUSH)
+ else if (req->op == REQ_OP_FLUSH)
type = NBD_CMD_FLUSH;
else if (rq_data_dir(req) == WRITE)
type = NBD_CMD_WRITE;
diff --git a/drivers/block/osdblk.c b/drivers/block/osdblk.c
index 1b709a4..3f8a0a0 100644
--- a/drivers/block/osdblk.c
+++ b/drivers/block/osdblk.c
@@ -321,7 +321,7 @@ static void osdblk_rq_fn(struct request_queue *q)
* driver-specific, etc.
*/
- do_flush = rq->cmd_flags & REQ_FLUSH;
+ do_flush = (rq->op == REQ_OP_FLUSH);
do_write = (rq_data_dir(rq) == WRITE);
if (!do_flush) { /* osd_flush does not use a bio */
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index c120d70..95c524b 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -196,7 +196,7 @@ static void ps3disk_do_request(struct ps3_storage_device *dev,
dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
while ((req = blk_fetch_request(q))) {
- if (req->cmd_flags & REQ_FLUSH) {
+ if (req->op == REQ_OP_FLUSH) {
if (ps3disk_submit_flush_request(dev, req))
break;
} else if (req->cmd_type == REQ_TYPE_FS) {
@@ -256,7 +256,7 @@ static irqreturn_t ps3disk_interrupt(int irq, void *data)
return IRQ_HANDLED;
}
- if (req->cmd_flags & REQ_FLUSH) {
+ if (req->op == REQ_OP_FLUSH) {
read = 0;
op = "flush";
} else {
diff --git a/drivers/block/skd_main.c b/drivers/block/skd_main.c
index f89a0c8..a15cc2e 100644
--- a/drivers/block/skd_main.c
+++ b/drivers/block/skd_main.c
@@ -624,7 +624,7 @@ static void skd_request_fn(struct request_queue *q)
count = blk_rq_sectors(req);
data_dir = rq_data_dir(req);
- if (req->cmd_flags & REQ_FLUSH)
+ if (req->op == REQ_OP_FLUSH)
flush++;
if (req->cmd_flags & REQ_FUA)
diff --git a/drivers/block/virtio_blk.c b/drivers/block/virtio_blk.c
index 6ca3549..c6d3bc2 100644
--- a/drivers/block/virtio_blk.c
+++ b/drivers/block/virtio_blk.c
@@ -172,7 +172,7 @@ static int virtio_queue_rq(struct blk_mq_hw_ctx *hctx,
BUG_ON(req->nr_phys_segments + 2 > vblk->sg_elems);
vbr->req = req;
- if (req->cmd_flags & REQ_FLUSH) {
+ if (req->op == REQ_OP_FLUSH) {
vbr->out_hdr.type = cpu_to_virtio32(vblk->vdev, VIRTIO_BLK_T_FLUSH);
vbr->out_hdr.sector = 0;
vbr->out_hdr.ioprio = cpu_to_virtio32(vblk->vdev, req_get_ioprio(vbr->req));
diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index d4aa473..1d48f0a 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -635,7 +635,7 @@ static int blkif_queue_rw_req(struct request *req)
* The indirect operation can only be a BLKIF_OP_READ or
* BLKIF_OP_WRITE
*/
- BUG_ON(req->cmd_flags & (REQ_FLUSH | REQ_FUA));
+ BUG_ON(req->op == REQ_OP_FLUSH || req->cmd_flags & REQ_FUA);
ring_req->operation = BLKIF_OP_INDIRECT;
ring_req->u.indirect.indirect_op = rq_data_dir(req) ?
BLKIF_OP_WRITE : BLKIF_OP_READ;
@@ -647,7 +647,7 @@ static int blkif_queue_rw_req(struct request *req)
ring_req->u.rw.handle = info->handle;
ring_req->operation = rq_data_dir(req) ?
BLKIF_OP_WRITE : BLKIF_OP_READ;
- if (req->cmd_flags & (REQ_FLUSH | REQ_FUA)) {
+ if (req->op == REQ_OP_FLUSH || req->cmd_flags & REQ_FUA) {
/*
* Ideally we can do an unordered flush-to-disk.
* In case the backend onlysupports barriers, use that.
@@ -739,7 +739,7 @@ static inline bool blkif_request_flush_invalid(struct request *req,
struct blkfront_info *info)
{
return ((req->cmd_type != REQ_TYPE_FS) ||
- ((req->cmd_flags & REQ_FLUSH) &&
+ ((req->op == REQ_OP_FLUSH) &&
!(info->feature_flush & REQ_FLUSH)) ||
((req->cmd_flags & REQ_FUA) &&
!(info->feature_flush & REQ_FUA)));
@@ -1692,7 +1692,7 @@ static int blkif_recover(struct blkfront_info *info)
/*
* Get the bios in the request so we can re-queue them.
*/
- if (copy[i].request->cmd_flags & REQ_FLUSH ||
+ if (copy[i].request->op == REQ_OP_FLUSH ||
copy[i].request->op == REQ_OP_DISCARD ||
copy[i].request->cmd_flags & (REQ_FUA | REQ_SECURE)) {
/*
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 37a8a90..6474ed3 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -431,7 +431,7 @@ static int idedisk_prep_fn(struct request_queue *q, struct request *rq)
ide_drive_t *drive = q->queuedata;
struct ide_cmd *cmd;
- if (!(rq->cmd_flags & REQ_FLUSH))
+ if (rq->op != REQ_OP_FLUSH)
return BLKPREP_OK;
if (rq->special) {
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 7c6e386..90135b6 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -2097,7 +2097,7 @@ static void dm_request_fn(struct request_queue *q)
/* always use block 0 to find the target for flushes for now */
pos = 0;
- if (!(rq->cmd_flags & REQ_FLUSH))
+ if (rq->op != REQ_OP_FLUSH)
pos = blk_rq_pos(rq);
ti = dm_table_find_target(map, pos);
@@ -2657,7 +2657,7 @@ static int dm_mq_queue_rq(struct blk_mq_hw_ctx *hctx,
/* always use block 0 to find the target for flushes for now */
pos = 0;
- if (!(rq->cmd_flags & REQ_FLUSH))
+ if (rq->op != REQ_OP_FLUSH)
pos = blk_rq_pos(rq);
ti = dm_table_find_target(map, pos);
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index cc9b1ff..7caf236 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1691,7 +1691,7 @@ static u8 mmc_blk_prep_packed_list(struct mmc_queue *mq, struct request *req)
!IS_ALIGNED(blk_rq_sectors(next), 8))
break;
- if (next->op == REQ_OP_DISCARD || next->cmd_flags & REQ_FLUSH)
+ if (next->op == REQ_OP_DISCARD || next->op == REQ_OP_FLUSH)
break;
if (rq_data_dir(cur) != rq_data_dir(next))
@@ -2116,7 +2116,6 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
struct mmc_card *card = md->queue.card;
struct mmc_host *host = card->host;
unsigned long flags;
- unsigned int cmd_flags = req ? req->cmd_flags : 0;
if (req && !mq->mqrq_prev->req)
/* claim host only for the first request */
@@ -2140,7 +2139,7 @@ static int mmc_blk_issue_rq(struct mmc_queue *mq, struct request *req)
ret = mmc_blk_issue_secdiscard_rq(mq, req);
else
ret = mmc_blk_issue_discard_rq(mq, req);
- } else if (cmd_flags & REQ_FLUSH) {
+ } else if (req && req->op == REQ_OP_FLUSH) {
/* complete ongoing async transfer before issuing flush */
if (card->host->areq)
mmc_blk_issue_rw_rq(mq, NULL);
diff --git a/drivers/mmc/card/queue.h b/drivers/mmc/card/queue.h
index f166e5b..6c67e4e 100644
--- a/drivers/mmc/card/queue.h
+++ b/drivers/mmc/card/queue.h
@@ -3,7 +3,7 @@
static inline bool mmc_req_is_special(struct request *req)
{
- return req && (req->cmd_flags & REQ_FLUSH || req->op == REQ_OP_DISCARD);
+ return req && (req->op == REQ_OP_FLUSH || req->op == REQ_OP_DISCARD);
}
struct request;
diff --git a/drivers/mtd/mtd_blkdevs.c b/drivers/mtd/mtd_blkdevs.c
index b2e0bce..67da1cd 100644
--- a/drivers/mtd/mtd_blkdevs.c
+++ b/drivers/mtd/mtd_blkdevs.c
@@ -87,7 +87,7 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
if (req->cmd_type != REQ_TYPE_FS)
return -EIO;
- if (req->cmd_flags & REQ_FLUSH)
+ if (req->op == REQ_OP_FLUSH)
return tr->flush(dev);
if (blk_rq_pos(req) + blk_rq_cur_sectors(req) >
diff --git a/drivers/nvme/host/pci.c b/drivers/nvme/host/pci.c
index c51205a..334a5a1 100644
--- a/drivers/nvme/host/pci.c
+++ b/drivers/nvme/host/pci.c
@@ -668,7 +668,7 @@ static int nvme_queue_rq(struct blk_mq_hw_ctx *hctx,
} else {
if (req->cmd_type == REQ_TYPE_DRV_PRIV)
memcpy(&cmnd, req->cmd, sizeof(cmnd));
- else if (req->cmd_flags & REQ_FLUSH)
+ else if (req->op == REQ_OP_FLUSH)
nvme_setup_flush(ns, &cmnd);
else
nvme_setup_rw(ns, req, &cmnd);
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 2737527..abaaa7e 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1143,12 +1143,11 @@ static int sd_init_command(struct scsi_cmnd *cmd)
return sd_setup_discard_cmnd(cmd);
case REQ_OP_WRITE_SAME:
return sd_setup_write_same_cmnd(cmd);
+ case REQ_OP_FLUSH:
+ return sd_setup_flush_cmnd(cmd);
case REQ_OP_READ:
case REQ_OP_WRITE:
- if (rq->cmd_flags & REQ_FLUSH)
- return sd_setup_flush_cmnd(cmd);
- else
- return sd_setup_read_write_cmnd(cmd);
+ return sd_setup_read_write_cmnd(cmd);
default:
BUG();
}
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index 5d19b393..b4ef8d7 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -239,6 +239,7 @@ enum req_op {
REQ_OP_WRITE,
REQ_OP_DISCARD, /* request to discard sectors */
REQ_OP_WRITE_SAME, /* write same block many times */
+ REQ_OP_FLUSH, /* request for cache flush */
};
typedef unsigned int blk_qc_t;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 83d6f033..ec0d0d0 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -651,6 +651,9 @@ static inline bool rq_mergeable(struct request *rq)
if (rq->cmd_type != REQ_TYPE_FS)
return false;
+ if (rq->op == REQ_OP_FLUSH)
+ return false;
+
if (rq->cmd_flags & REQ_NOMERGE_FLAGS)
return false;
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 4a9ac83..3a54c83 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -223,6 +223,8 @@ static void __blk_add_trace(struct blk_trace *bt, sector_t sector, int bytes,
what |= MASK_TC_BIT(op_flags, FUA);
if (op == REQ_OP_DISCARD)
what |= BLK_TC_ACT(BLK_TC_DISCARD);
+ if (op == REQ_OP_FLUSH)
+ what |= BLK_TC_ACT(BLK_TC_FLUSH);
pid = tsk->pid;
if (act_log_check(bt, what, sector, pid))
@@ -1775,7 +1777,8 @@ void blk_fill_rwbs(char *rwbs, int op, u32 rw, int bytes)
{
int i = 0;
- if (rw & REQ_FLUSH)
+ if (rw & REQ_FLUSH ||
+ op == REQ_OP_FLUSH)
rwbs[i++] = 'F';
if (op == REQ_OP_WRITE)
--
1.8.3.1
^ permalink raw reply related
* [PATCH 32/35] block: shrink bi_rw and bi_op
From: mchristi @ 2016-01-05 20:53 UTC (permalink / raw)
To: linux-f2fs-devel, linux-ext4, konrad.wilk, drbd-dev,
philipp.reisner, lars.ellenberg, linux-raid, dm-devel,
linux-fsdevel, linux-bcache, linux-block, linux-kernel,
linux-scsi, linux-mtd, target-devel, linux-btrfs, osd-dev, xfs,
ocfs2-devel
Cc: Mike Christie
In-Reply-To: <1452027218-32303-1-git-send-email-mchristi@redhat.com>
From: Mike Christie <mchristi@redhat.com>
There is no need for bi_op/op and bi_rw to be so large
now, so this patch shrinks them.
Signed-off-by: Mike Christie <mchristi@redhat.com>
---
block/blk-core.c | 2 +-
drivers/md/dm-flakey.c | 2 +-
drivers/md/raid5.c | 13 +++++++------
fs/btrfs/check-integrity.c | 4 ++--
fs/btrfs/inode.c | 2 +-
include/linux/bio.h | 13 ++-----------
include/linux/blk_types.h | 11 +++--------
include/linux/blkdev.h | 2 +-
8 files changed, 18 insertions(+), 31 deletions(-)
diff --git a/block/blk-core.c b/block/blk-core.c
index 0f6cb5c..ae2afab 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1854,7 +1854,7 @@ static void handle_bad_sector(struct bio *bio)
char b[BDEVNAME_SIZE];
printk(KERN_INFO "attempt to access beyond end of device\n");
- printk(KERN_INFO "%s: rw=%d,%ld, want=%Lu, limit=%Lu\n",
+ printk(KERN_INFO "%s: rw=%d,%u, want=%Lu, limit=%Lu\n",
bdevname(bio->bi_bdev, b),
bio->bi_op, bio->bi_rw,
(unsigned long long)bio_end_sector(bio),
diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c
index 09e2afc..b831226 100644
--- a/drivers/md/dm-flakey.c
+++ b/drivers/md/dm-flakey.c
@@ -266,7 +266,7 @@ static void corrupt_bio_data(struct bio *bio, struct flakey_c *fc)
data[fc->corrupt_bio_byte - 1] = fc->corrupt_bio_value;
DMDEBUG("Corrupting data bio=%p by writing %u to byte %u "
- "(rw=%c bi_rw=%lu bi_sector=%llu cur_bytes=%u)\n",
+ "(rw=%c bi_rw=%u bi_sector=%llu cur_bytes=%u)\n",
bio, fc->corrupt_bio_value, fc->corrupt_bio_byte,
(bio_data_dir(bio) == WRITE) ? 'w' : 'r', bio->bi_rw,
(unsigned long long)bio->bi_iter.bi_sector, bio_bytes);
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index fa4fe95..aafd49e 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -1015,9 +1015,9 @@ again:
: raid5_end_read_request;
bi->bi_private = sh;
- pr_debug("%s: for %llu schedule op %ld on disc %d\n",
+ pr_debug("%s: for %llu schedule op %d,%u on disc %d\n",
__func__, (unsigned long long)sh->sector,
- bi->bi_rw, i);
+ bi->bi_op, bi->bi_rw, i);
atomic_inc(&sh->count);
if (sh != head_sh)
atomic_inc(&head_sh->count);
@@ -1067,10 +1067,10 @@ again:
rbi->bi_end_io = raid5_end_write_request;
rbi->bi_private = sh;
- pr_debug("%s: for %llu schedule op %ld on "
+ pr_debug("%s: for %llu schedule op %d,%u on "
"replacement disc %d\n",
__func__, (unsigned long long)sh->sector,
- rbi->bi_rw, i);
+ rbi->bi_op, rbi->bi_rw, i);
atomic_inc(&sh->count);
if (sh != head_sh)
atomic_inc(&head_sh->count);
@@ -1102,8 +1102,9 @@ again:
if (!rdev && !rrdev) {
if (op_is_write(op))
set_bit(STRIPE_DEGRADED, &sh->state);
- pr_debug("skip op %ld on disc %d for sector %llu\n",
- bi->bi_rw, i, (unsigned long long)sh->sector);
+ pr_debug("skip op %d,%u on disc %d for sector %llu\n",
+ bi->bi_op, bi->bi_rw, i,
+ (unsigned long long)sh->sector);
clear_bit(R5_LOCKED, &sh->dev[i].flags);
set_bit(STRIPE_HANDLE, &sh->state);
}
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c
index e409d1f..1623d11 100644
--- a/fs/btrfs/check-integrity.c
+++ b/fs/btrfs/check-integrity.c
@@ -2985,7 +2985,7 @@ static void __btrfsic_submit_bio(struct bio *bio)
if (dev_state->state->print_mask &
BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH)
printk(KERN_INFO
- "submit_bio(rw=%d,0x%lx, bi_vcnt=%u,"
+ "submit_bio(rw=%d,0x%x, bi_vcnt=%u,"
" bi_sector=%llu (bytenr %llu), bi_bdev=%p)\n",
bio->bi_op, bio->bi_rw, bio->bi_vcnt,
(unsigned long long)bio->bi_iter.bi_sector,
@@ -3028,7 +3028,7 @@ static void __btrfsic_submit_bio(struct bio *bio)
if (dev_state->state->print_mask &
BTRFSIC_PRINT_MASK_SUBMIT_BIO_BH)
printk(KERN_INFO
- "submit_bio(rw=%d,0x%lx FLUSH, bdev=%p)\n",
+ "submit_bio(rw=%d,0x%x FLUSH, bdev=%p)\n",
bio->bi_op, bio->bi_rw, bio->bi_bdev);
if (!dev_state->dummy_block_for_bio_bh_flush.is_iodone) {
if ((dev_state->state->print_mask &
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index a96984f..b9c3799 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -8061,7 +8061,7 @@ static void btrfs_end_dio_bio(struct bio *bio)
if (err)
btrfs_warn(BTRFS_I(dip->inode)->root->fs_info,
- "direct IO failed ino %llu rw %d,%lu sector %#Lx len %u err no %d",
+ "direct IO failed ino %llu rw %d,0x%x sector %#Lx len %u err no %d",
btrfs_ino(dip->inode), bio->bi_op, bio->bi_rw,
(unsigned long long)bio->bi_iter.bi_sector,
bio->bi_iter.bi_size, err);
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 1e4b3b5..c91afc1 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -44,18 +44,9 @@
#define BIO_MAX_SIZE (BIO_MAX_PAGES << PAGE_CACHE_SHIFT)
#define BIO_MAX_SECTORS (BIO_MAX_SIZE >> 9)
-/*
- * upper 16 bits of bi_rw define the io priority of this bio
- */
-#define BIO_PRIO_SHIFT (8 * sizeof(unsigned long) - IOPRIO_BITS)
-#define bio_prio(bio) ((bio)->bi_rw >> BIO_PRIO_SHIFT)
+#define bio_prio(bio) (bio)->bi_ioprio
#define bio_prio_valid(bio) ioprio_valid(bio_prio(bio))
-
-#define bio_set_prio(bio, prio) do { \
- WARN_ON(prio >= (1 << IOPRIO_BITS)); \
- (bio)->bi_rw &= ((1UL << BIO_PRIO_SHIFT) - 1); \
- (bio)->bi_rw |= ((unsigned long) (prio) << BIO_PRIO_SHIFT); \
-} while (0)
+#define bio_set_prio(bio, prio) ((bio)->bi_ioprio = prio)
/*
* various member access, note that bio_data should of course not be used
diff --git a/include/linux/blk_types.h b/include/linux/blk_types.h
index bb30c2b..5d19b393 100644
--- a/include/linux/blk_types.h
+++ b/include/linux/blk_types.h
@@ -48,14 +48,9 @@ struct bio {
struct block_device *bi_bdev;
unsigned int bi_flags; /* status, command, etc */
int bi_error;
- unsigned long bi_rw; /* bottom bits rq_flags_bits
- * top bits priority
- */
- /*
- * this will be a u8 in the next patches and bi_rw can be shrunk to
- * a u32. For compat in these transistional patches op is a int here.
- */
- int bi_op; /* REQ_OP */
+ unsigned int bi_rw; /* rq_flag_bits */
+ unsigned short bi_ioprio;
+ u8 bi_op; /* REQ_OP */
struct bvec_iter bi_iter;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index bc024c7..83d6f033 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -96,7 +96,7 @@ struct request {
struct request_queue *q;
struct blk_mq_ctx *mq_ctx;
- int op;
+ u8 op;
u64 cmd_flags;
unsigned cmd_type;
unsigned long atomic_flags;
--
1.8.3.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