usb: dwc3: gadget: change detemination method of connect status
[firefly-linux-kernel-4.4.55.git] / drivers / md / dm.c
index 6e15f3565892fce8315cef992e0b2721e8c20088..3384a3eef917bc3a98f4a1598e5629f705c309e2 100644 (file)
@@ -591,7 +591,7 @@ retry:
 
 out:
        dm_put_live_table(md, *srcu_idx);
-       if (r == -ENOTCONN) {
+       if (r == -ENOTCONN && !fatal_signal_pending(current)) {
                msleep(10);
                goto retry;
        }
@@ -603,9 +603,10 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode,
 {
        struct mapped_device *md = bdev->bd_disk->private_data;
        struct dm_target *tgt;
+       struct block_device *tgt_bdev = NULL;
        int srcu_idx, r;
 
-       r = dm_get_live_table_for_ioctl(md, &tgt, &bdev, &mode, &srcu_idx);
+       r = dm_get_live_table_for_ioctl(md, &tgt, &tgt_bdev, &mode, &srcu_idx);
        if (r < 0)
                return r;
 
@@ -620,7 +621,7 @@ static int dm_blk_ioctl(struct block_device *bdev, fmode_t mode,
                        goto out;
        }
 
-       r =  __blkdev_driver_ioctl(bdev, mode, cmd, arg);
+       r =  __blkdev_driver_ioctl(tgt_bdev, mode, cmd, arg);
 out:
        dm_put_live_table(md, srcu_idx);
        return r;
@@ -1108,12 +1109,8 @@ static void rq_completed(struct mapped_device *md, int rw, bool run_queue)
         * back into ->request_fn() could deadlock attempting to grab the
         * queue lock again.
         */
-       if (run_queue) {
-               if (md->queue->mq_ops)
-                       blk_mq_run_hw_queues(md->queue, true);
-               else
-                       blk_run_queue_async(md->queue);
-       }
+       if (!md->queue->mq_ops && run_queue)
+               blk_run_queue_async(md->queue);
 
        /*
         * dm_put() must be at the end of this function. See the comment above
@@ -1190,6 +1187,8 @@ static void dm_unprep_request(struct request *rq)
 
        if (clone)
                free_rq_clone(clone);
+       else if (!tio->md->queue->mq_ops)
+               free_rq_tio(tio);
 }
 
 /*
@@ -1211,9 +1210,9 @@ static void dm_requeue_original_request(struct mapped_device *md,
 {
        int rw = rq_data_dir(rq);
 
+       rq_end_stats(md, rq);
        dm_unprep_request(rq);
 
-       rq_end_stats(md, rq);
        if (!rq->q->mq_ops)
                old_requeue_request(rq);
        else {
@@ -1333,7 +1332,10 @@ static void dm_complete_request(struct request *rq, int error)
        struct dm_rq_target_io *tio = tio_from_request(rq);
 
        tio->error = error;
-       blk_complete_request(rq);
+       if (!rq->q->mq_ops)
+               blk_complete_request(rq);
+       else
+               blk_mq_complete_request(rq, error);
 }
 
 /*
@@ -2258,8 +2260,6 @@ static void cleanup_mapped_device(struct mapped_device *md)
        if (md->bs)
                bioset_free(md->bs);
 
-       cleanup_srcu_struct(&md->io_barrier);
-
        if (md->disk) {
                spin_lock(&_minor_lock);
                md->disk->private_data = NULL;
@@ -2271,6 +2271,8 @@ static void cleanup_mapped_device(struct mapped_device *md)
        if (md->queue)
                blk_cleanup_queue(md->queue);
 
+       cleanup_srcu_struct(&md->io_barrier);
+
        if (md->bdev) {
                bdput(md->bdev);
                md->bdev = NULL;
@@ -2867,6 +2869,7 @@ EXPORT_SYMBOL_GPL(dm_device_name);
 
 static void __dm_destroy(struct mapped_device *md, bool wait)
 {
+       struct request_queue *q = dm_get_md_queue(md);
        struct dm_table *map;
        int srcu_idx;
 
@@ -2877,6 +2880,10 @@ static void __dm_destroy(struct mapped_device *md, bool wait)
        set_bit(DMF_FREEING, &md->flags);
        spin_unlock(&_minor_lock);
 
+       spin_lock_irq(q->queue_lock);
+       queue_flag_set(QUEUE_FLAG_DYING, q);
+       spin_unlock_irq(q->queue_lock);
+
        if (dm_request_based(md) && md->kworker_task)
                flush_kthread_worker(&md->kworker);
 
@@ -3076,7 +3083,8 @@ static void unlock_fs(struct mapped_device *md)
  * Caller must hold md->suspend_lock
  */
 static int __dm_suspend(struct mapped_device *md, struct dm_table *map,
-                       unsigned suspend_flags, int interruptible)
+                       unsigned suspend_flags, int interruptible,
+                       int dmf_suspended_flag)
 {
        bool do_lockfs = suspend_flags & DM_SUSPEND_LOCKFS_FLAG;
        bool noflush = suspend_flags & DM_SUSPEND_NOFLUSH_FLAG;
@@ -3143,6 +3151,8 @@ static int __dm_suspend(struct mapped_device *md, struct dm_table *map,
         * to finish.
         */
        r = dm_wait_for_completion(md, interruptible);
+       if (!r)
+               set_bit(dmf_suspended_flag, &md->flags);
 
        if (noflush)
                clear_bit(DMF_NOFLUSH_SUSPENDING, &md->flags);
@@ -3204,12 +3214,10 @@ retry:
 
        map = rcu_dereference_protected(md->map, lockdep_is_held(&md->suspend_lock));
 
-       r = __dm_suspend(md, map, suspend_flags, TASK_INTERRUPTIBLE);
+       r = __dm_suspend(md, map, suspend_flags, TASK_INTERRUPTIBLE, DMF_SUSPENDED);
        if (r)
                goto out_unlock;
 
-       set_bit(DMF_SUSPENDED, &md->flags);
-
        dm_table_postsuspend_targets(map);
 
 out_unlock:
@@ -3242,10 +3250,11 @@ static int __dm_resume(struct mapped_device *md, struct dm_table *map)
 
 int dm_resume(struct mapped_device *md)
 {
-       int r = -EINVAL;
+       int r;
        struct dm_table *map = NULL;
 
 retry:
+       r = -EINVAL;
        mutex_lock_nested(&md->suspend_lock, SINGLE_DEPTH_NESTING);
 
        if (!dm_suspended_md(md))
@@ -3269,8 +3278,6 @@ retry:
                goto out;
 
        clear_bit(DMF_SUSPENDED, &md->flags);
-
-       r = 0;
 out:
        mutex_unlock(&md->suspend_lock);
 
@@ -3303,9 +3310,8 @@ static void __dm_internal_suspend(struct mapped_device *md, unsigned suspend_fla
         * would require changing .presuspend to return an error -- avoid this
         * until there is a need for more elaborate variants of internal suspend.
         */
-       (void) __dm_suspend(md, map, suspend_flags, TASK_UNINTERRUPTIBLE);
-
-       set_bit(DMF_SUSPENDED_INTERNALLY, &md->flags);
+       (void) __dm_suspend(md, map, suspend_flags, TASK_UNINTERRUPTIBLE,
+                           DMF_SUSPENDED_INTERNALLY);
 
        dm_table_postsuspend_targets(map);
 }