libnvdimm, btt: ensure that flags were also unchanged during a map_read
authorVishal Verma <vishal.l.verma@intel.com>
Thu, 31 Aug 2017 01:36:00 +0000 (19:36 -0600)
committerDan Williams <dan.j.williams@intel.com>
Thu, 31 Aug 2017 22:05:10 +0000 (15:05 -0700)
In btt_map_read, we read the map twice to make sure that the map entry
didn't change after we added it to the read tracking table. In
anticipation of expanding the use of the error bit, also make sure that
the error and zero flags are constant across the two map reads.

Signed-off-by: Vishal Verma <vishal.l.verma@intel.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
drivers/nvdimm/btt.c

index bb816bc1a906eb4a916ec2985c302bcabfc723e5..15d1b071746bba9fac0138699753c13a1ecaca8f 100644 (file)
@@ -1032,6 +1032,7 @@ static int btt_read_pg(struct btt *btt, struct bio_integrity_payload *bip,
                 */
                while (1) {
                        u32 new_map;
+                       int new_t, new_e;
 
                        if (t_flag) {
                                zero_fill_data(page, off, cur_len);
@@ -1050,15 +1051,18 @@ static int btt_read_pg(struct btt *btt, struct bio_integrity_payload *bip,
                         */
                        barrier();
 
-                       ret = btt_map_read(arena, premap, &new_map, &t_flag,
-                                               &e_flag, NVDIMM_IO_ATOMIC);
+                       ret = btt_map_read(arena, premap, &new_map, &new_t,
+                                               &new_e, NVDIMM_IO_ATOMIC);
                        if (ret)
                                goto out_rtt;
 
-                       if (postmap == new_map)
+                       if ((postmap == new_map) && (t_flag == new_t) &&
+                                       (e_flag == new_e))
                                break;
 
                        postmap = new_map;
+                       t_flag = new_t;
+                       e_flag = new_e;
                }
 
                ret = btt_data_read(arena, page, off, postmap, cur_len);