lightnvm: pblk: prevent premature sync point resets
authorHans Holmberg <hans.holmberg@cnexlabs.com>
Fri, 5 Jan 2018 13:16:11 +0000 (14:16 +0100)
committerJens Axboe <axboe@kernel.dk>
Fri, 5 Jan 2018 15:50:12 +0000 (08:50 -0700)
Unless we protect flush pointer updates with a lock, we risk
resetting new flush points before we've synced all sectors
up to that point.

This patch protects new flush points with the same spin lock
that is being held when advancing the sync pointer and
resetting completed flush points.

Signed-off-by: Hans Holmberg <hans.holmberg@cnexlabs.com>
Signed-off-by: Javier González <javier@cnexlabs.com>
Signed-off-by: Matias Bjørling <m@bjorling.me>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/lightnvm/pblk-rb.c

index 672ef8c4789279979d5c29be2d3e8d5aa58179f7..ec8fc314646ba5ffcf04855a81935f5185f9f4bf 100644 (file)
@@ -367,17 +367,17 @@ static int pblk_rb_flush_point_set(struct pblk_rb *rb, struct bio *bio,
        flush_point = (pos == 0) ? (rb->nr_entries - 1) : (pos - 1);
        entry = &rb->entries[flush_point];
 
+       pblk_rb_sync_init(rb, NULL);
+
        /* Protect flush points */
        smp_store_release(&rb->flush_point, flush_point);
 
-       if (!bio)
-               return 0;
+       if (bio)
+               bio_list_add(&entry->w_ctx.bios, bio);
 
-       spin_lock_irq(&rb->s_lock);
-       bio_list_add(&entry->w_ctx.bios, bio);
-       spin_unlock_irq(&rb->s_lock);
+       pblk_rb_sync_end(rb, NULL);
 
-       return 1;
+       return bio ? 1 : 0;
 }
 
 static int __pblk_rb_may_write(struct pblk_rb *rb, unsigned int nr_entries,