diff mbox series

block: for jobs, do not clear user_paused until after the resume

Message ID c449263bbcaffbd3db25d833fb57867fda8e3199.1534348766.git.jcody@redhat.com
State New
Headers show
Series block: for jobs, do not clear user_paused until after the resume | expand

Commit Message

Jeff Cody Aug. 15, 2018, 3:59 p.m. UTC
The function job_cancel_async() will always cause an assert for blockjob
user resume.  We set job->user_paused to false, and then call
job->driver->user_resume().  In the case of blockjobs, this is the
block_job_user_resume() function.

In that function, we assert that job.user_paused is set to true.
Unfortunately, right before calling this function, it has explicitly
been set to false.

The fix is pretty simple: set job->user_paused to false only after the
job user_resume() function has been called.

Signed-off-by: Jeff Cody <jcody@redhat.com>
---
 job.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Comments

John Snow Aug. 15, 2018, 9:23 p.m. UTC | #1
On 08/15/2018 11:59 AM, Jeff Cody wrote:
> The function job_cancel_async() will always cause an assert for blockjob
> user resume.  We set job->user_paused to false, and then call
> job->driver->user_resume().  In the case of blockjobs, this is the
> block_job_user_resume() function.
> 
> In that function, we assert that job.user_paused is set to true.
> Unfortunately, right before calling this function, it has explicitly
> been set to false.
> 
> The fix is pretty simple: set job->user_paused to false only after the
> job user_resume() function has been called.
> 
> Signed-off-by: Jeff Cody <jcody@redhat.com>
> ---
>  job.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/job.c b/job.c
> index fa671b431a..e36ebaafd8 100644
> --- a/job.c
> +++ b/job.c
> @@ -732,10 +732,10 @@ static void job_cancel_async(Job *job, bool force)
>  {
>      if (job->user_paused) {
>          /* Do not call job_enter here, the caller will handle it.  */
> -        job->user_paused = false;
>          if (job->driver->user_resume) {
>              job->driver->user_resume(job);
>          }
> +        job->user_paused = false;
>          assert(job->pause_count > 0);
>          job->pause_count--;
>      }
> 

Looks right to me; are you going to make good on your threat of a v2
with a unit test?

Reviewed-by: John Snow <jsnow@redhat.com>
Eric Blake Aug. 15, 2018, 9:25 p.m. UTC | #2
On 08/15/2018 10:59 AM, Jeff Cody wrote:
> The function job_cancel_async() will always cause an assert for blockjob
> user resume.  We set job->user_paused to false, and then call
> job->driver->user_resume().  In the case of blockjobs, this is the
> block_job_user_resume() function.
> 
> In that function, we assert that job.user_paused is set to true.
> Unfortunately, right before calling this function, it has explicitly
> been set to false.
> 
> The fix is pretty simple: set job->user_paused to false only after the
> job user_resume() function has been called.
> 
> Signed-off-by: Jeff Cody <jcody@redhat.com>
> ---
>   job.c | 2 +-
>   1 file changed, 1 insertion(+), 1 deletion(-)
> 

Does this need to CC qemu-stable?

Reviewed-by: Eric Blake <eblake@redhat.com>
Jeff Cody Aug. 15, 2018, 9:30 p.m. UTC | #3
On Wed, Aug 15, 2018 at 04:25:16PM -0500, Eric Blake wrote:
> On 08/15/2018 10:59 AM, Jeff Cody wrote:
> >The function job_cancel_async() will always cause an assert for blockjob
> >user resume.  We set job->user_paused to false, and then call
> >job->driver->user_resume().  In the case of blockjobs, this is the
> >block_job_user_resume() function.
> >
> >In that function, we assert that job.user_paused is set to true.
> >Unfortunately, right before calling this function, it has explicitly
> >been set to false.
> >
> >The fix is pretty simple: set job->user_paused to false only after the
> >job user_resume() function has been called.
> >
> >Signed-off-by: Jeff Cody <jcody@redhat.com>
> >---
> >  job.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> >
> 
> Does this need to CC qemu-stable?
> 

Good point, yes.  I'm going to do a v2 with an iotest, and I'll CC
qemu-stable on that one.

> Reviewed-by: Eric Blake <eblake@redhat.com>
> 

Thanks


-Jeff
Jeff Cody Aug. 15, 2018, 9:31 p.m. UTC | #4
On Wed, Aug 15, 2018 at 05:23:43PM -0400, John Snow wrote:
> 
> 
> On 08/15/2018 11:59 AM, Jeff Cody wrote:
> > The function job_cancel_async() will always cause an assert for blockjob
> > user resume.  We set job->user_paused to false, and then call
> > job->driver->user_resume().  In the case of blockjobs, this is the
> > block_job_user_resume() function.
> > 
> > In that function, we assert that job.user_paused is set to true.
> > Unfortunately, right before calling this function, it has explicitly
> > been set to false.
> > 
> > The fix is pretty simple: set job->user_paused to false only after the
> > job user_resume() function has been called.
> > 
> > Signed-off-by: Jeff Cody <jcody@redhat.com>
> > ---
> >  job.c | 2 +-
> >  1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/job.c b/job.c
> > index fa671b431a..e36ebaafd8 100644
> > --- a/job.c
> > +++ b/job.c
> > @@ -732,10 +732,10 @@ static void job_cancel_async(Job *job, bool force)
> >  {
> >      if (job->user_paused) {
> >          /* Do not call job_enter here, the caller will handle it.  */
> > -        job->user_paused = false;
> >          if (job->driver->user_resume) {
> >              job->driver->user_resume(job);
> >          }
> > +        job->user_paused = false;
> >          assert(job->pause_count > 0);
> >          job->pause_count--;
> >      }
> > 
> 
> Looks right to me; are you going to make good on your threat of a v2
> with a unit test?
>

Yep!

> Reviewed-by: John Snow <jsnow@redhat.com>

Thanks

-Jeff
diff mbox series

Patch

diff --git a/job.c b/job.c
index fa671b431a..e36ebaafd8 100644
--- a/job.c
+++ b/job.c
@@ -732,10 +732,10 @@  static void job_cancel_async(Job *job, bool force)
 {
     if (job->user_paused) {
         /* Do not call job_enter here, the caller will handle it.  */
-        job->user_paused = false;
         if (job->driver->user_resume) {
             job->driver->user_resume(job);
         }
+        job->user_paused = false;
         assert(job->pause_count > 0);
         job->pause_count--;
     }