]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/md/dm-table.c
Merge branch 'omap-pool'
[linux-2.6-omap-h63xx.git] / drivers / md / dm-table.c
index 2fd66c30f7f8b02fd699f7b3c5cab52bd6f4d89d..e8361b191b9b223baef941bfc14212dc052d127f 100644 (file)
@@ -399,28 +399,30 @@ static int check_device_area(struct dm_dev_internal *dd, sector_t start,
 }
 
 /*
- * This upgrades the mode on an already open dm_dev.  Being
+ * This upgrades the mode on an already open dm_dev, being
  * careful to leave things as they were if we fail to reopen the
- * device.
+ * device and not to touch the existing bdev field in case
+ * it is accessed concurrently inside dm_table_any_congested().
  */
 static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode,
                        struct mapped_device *md)
 {
        int r;
-       struct dm_dev_internal dd_copy;
-       dev_t dev = dd->dm_dev.bdev->bd_dev;
+       struct dm_dev_internal dd_new, dd_old;
 
-       dd_copy = *dd;
+       dd_new = dd_old = *dd;
+
+       dd_new.dm_dev.mode |= new_mode;
+       dd_new.dm_dev.bdev = NULL;
+
+       r = open_dev(&dd_new, dd->dm_dev.bdev->bd_dev, md);
+       if (r)
+               return r;
 
        dd->dm_dev.mode |= new_mode;
-       dd->dm_dev.bdev = NULL;
-       r = open_dev(dd, dev, md);
-       if (!r)
-               close_dev(&dd_copy, md);
-       else
-               *dd = dd_copy;
+       close_dev(&dd_old, md);
 
-       return r;
+       return 0;
 }
 
 /*