projects
/
linux-flexiantxendom0-3.2.10.git
/ blobdiff
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
- Updated to 3.4-rc1.
[linux-flexiantxendom0-3.2.10.git]
/
drivers
/
md
/
dm-table.c
diff --git
a/drivers/md/dm-table.c
b/drivers/md/dm-table.c
index
2e227fb
..
8ba897f
100644
(file)
--- a/
drivers/md/dm-table.c
+++ b/
drivers/md/dm-table.c
@@
-438,14
+438,18
@@
static int upgrade_mode(struct dm_dev_internal *dd, fmode_t new_mode,
dd_new = dd_old = *dd;
dd_new = dd_old = *dd;
- dd_new.dm_dev.mode |= new_mode;
+ 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);
dd_new.dm_dev.bdev = NULL;
r = open_dev(&dd_new, dd->dm_dev.bdev->bd_dev, md);
- if (r)
+ if (r == -EROFS) {
+ dd_new.dm_dev.mode &= ~FMODE_WRITE;
+ r = open_dev(&dd_new, dd->dm_dev.bdev->bd_dev, md);
+ }
+ if (!r)
return r;
return r;
- dd->dm_dev.mode |= new_mode;
+ dd->dm_dev.mode = new_mode;
close_dev(&dd_old, md);
return 0;
close_dev(&dd_old, md);
return 0;
@@
-491,17
+495,25
@@
int dm_get_device(struct dm_target *ti, const char *path, fmode_t mode,
dd->dm_dev.mode = mode;
dd->dm_dev.bdev = NULL;
dd->dm_dev.mode = mode;
dd->dm_dev.bdev = NULL;
- if ((r = open_dev(dd, dev, t->md))) {
+ r = open_dev(dd, dev, t->md);
+ if (r == -EROFS) {
+ dd->dm_dev.mode &= ~FMODE_WRITE;
+ r = open_dev(dd, dev, t->md);
+ }
+ if (r) {
kfree(dd);
return r;
}
kfree(dd);
return r;
}
+ if (dd->dm_dev.mode != mode)
+ t->mode = dd->dm_dev.mode;
+
format_dev_t(dd->dm_dev.name, dev);
atomic_set(&dd->count, 0);
list_add(&dd->list, &t->devices);
format_dev_t(dd->dm_dev.name, dev);
atomic_set(&dd->count, 0);
list_add(&dd->list, &t->devices);
- } else if (dd->dm_dev.mode != (mode | dd->dm_dev.mode)) {
+ } else if (dd->dm_dev.mode != mode) {
r = upgrade_mode(dd, mode, t->md);
if (r)
return r;
r = upgrade_mode(dd, mode, t->md);
if (r)
return r;
@@
-554,9
+566,12
@@
EXPORT_SYMBOL_GPL(dm_set_device_limits);
*/
void dm_put_device(struct dm_target *ti, struct dm_dev *d)
{
*/
void dm_put_device(struct dm_target *ti, struct dm_dev *d)
{
- struct dm_dev_internal *dd = container_of(d, struct dm_dev_internal,
- dm_dev);
+ struct dm_dev_internal *dd;
+
+ if (!d)
+ return;
+ dd = container_of(d, struct dm_dev_internal, dm_dev);
if (atomic_dec_and_test(&dd->count)) {
close_dev(dd, ti->table->md);
list_del(&dd->list);
if (atomic_dec_and_test(&dd->count)) {
close_dev(dd, ti->table->md);
list_del(&dd->list);