if (!cqr->lpm)
                        cqr->lpm = dasd_path_get_opm(device);
        }
+       /*
+        * remember the amount of formatted tracks to prevent double format on
+        * ESE devices
+        */
+       if (cqr->block)
+               cqr->trkcount = atomic_read(&cqr->block->trkcount);
+
        if (cqr->cpmode == 1) {
                rc = ccw_device_tm_start(device->cdev, cqr->cpaddr,
                                         (long) cqr, cqr->lpm);
 
 }
 
 static bool test_and_set_format_track(struct dasd_format_entry *to_format,
-                                     struct dasd_block *block)
+                                     struct dasd_ccw_req *cqr)
 {
+       struct dasd_block *block = cqr->block;
        struct dasd_format_entry *format;
        unsigned long flags;
        bool rc = false;
 
        spin_lock_irqsave(&block->format_lock, flags);
+       if (cqr->trkcount != atomic_read(&block->trkcount)) {
+               /*
+                * The number of formatted tracks has changed after request
+                * start and we can not tell if the current track was involved.
+                * To avoid data corruption treat it as if the current track is
+                * involved
+                */
+               rc = true;
+               goto out;
+       }
        list_for_each_entry(format, &block->format_list, list) {
                if (format->track == to_format->track) {
                        rc = true;
        unsigned long flags;
 
        spin_lock_irqsave(&block->format_lock, flags);
+       atomic_inc(&block->trkcount);
        list_del_init(&format->list);
        spin_unlock_irqrestore(&block->format_lock, flags);
 }
        }
        format->track = curr_trk;
        /* test if track is already in formatting by another thread */
-       if (test_and_set_format_track(format, block))
+       if (test_and_set_format_track(format, cqr)) {
+               /* this is no real error so do not count down retries */
+               cqr->retries++;
                return ERR_PTR(-EEXIST);
+       }
 
        fdata.start_unit = curr_trk;
        fdata.stop_unit = curr_trk;
 
        void (*callback)(struct dasd_ccw_req *, void *data);
        void *callback_data;
        unsigned int proc_bytes;        /* bytes for partial completion */
+       unsigned int trkcount;          /* count formatted tracks */
 };
 
 /*
 
        struct list_head format_list;
        spinlock_t format_lock;
+       atomic_t trkcount;
 };
 
 struct dasd_attention_data {