All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] rbd: do not allow remove of mounted-on image
@ 2012-11-16 15:43 Alex Elder
  2012-11-16 22:27 ` Josh Durgin
  2012-11-19 23:42 ` [PATCH, v2] " Alex Elder
  0 siblings, 2 replies; 4+ messages in thread
From: Alex Elder @ 2012-11-16 15:43 UTC (permalink / raw)
  To: ceph-devel

There is no check in rbd_remove() to see if anybody holds ope the
image being removed.  That's not cool.

Add a simple open count that goes up and down with opens and closes
(releases) of the device, and don't allow an rbd image to be removed
if the count is non-zero.  Both functions are protected by the
bd_mutex so there's no need for any other concurrency protection.

Signed-off-by: Alex Elder <elder@inktank.com>
---
 drivers/block/rbd.c |    9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
index fba0822..9d9a2f3 100644
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -255,6 +255,7 @@ struct rbd_device {

 	/* sysfs related */
 	struct device		dev;
+	unsigned long		open_count;
 };

 static DEFINE_MUTEX(ctl_mutex);	  /* Serialize open/close/setup/teardown */
@@ -358,6 +359,7 @@ static int rbd_open(struct block_device *bdev,
fmode_t mode)

 	rbd_get_dev(rbd_dev);
 	set_device_ro(bdev, rbd_dev->mapping.read_only);
+	rbd_dev->open_count++;

 	return 0;
 }
@@ -366,6 +368,8 @@ static int rbd_release(struct gendisk *disk, fmode_t
mode)
 {
 	struct rbd_device *rbd_dev = disk->private_data;

+	rbd_assert(rbd_dev->open_count > 0);
+	rbd_dev->open_count--;
 	rbd_put_dev(rbd_dev);

 	return 0;
@@ -3764,6 +3768,11 @@ static ssize_t rbd_remove(struct bus_type *bus,
 		goto done;
 	}

+	if (rbd_dev->open_count) {
+		ret = -EBUSY;
+		goto done;
+	}
+
 	rbd_remove_all_snaps(rbd_dev);
 	rbd_bus_del_dev(rbd_dev);

-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] rbd: do not allow remove of mounted-on image
  2012-11-16 15:43 [PATCH] rbd: do not allow remove of mounted-on image Alex Elder
@ 2012-11-16 22:27 ` Josh Durgin
  2012-11-17  5:22   ` Alex Elder
  2012-11-19 23:42 ` [PATCH, v2] " Alex Elder
  1 sibling, 1 reply; 4+ messages in thread
From: Josh Durgin @ 2012-11-16 22:27 UTC (permalink / raw)
  To: Alex Elder; +Cc: ceph-devel

On 11/16/2012 07:43 AM, Alex Elder wrote:
> There is no check in rbd_remove() to see if anybody holds ope the
> image being removed.  That's not cool.
>
> Add a simple open count that goes up and down with opens and closes
> (releases) of the device, and don't allow an rbd image to be removed
> if the count is non-zero.  Both functions are protected by the
> bd_mutex so there's no need for any other concurrency protection.
>
> Signed-off-by: Alex Elder <elder@inktank.com>
> ---
>   drivers/block/rbd.c |    9 +++++++++
>   1 file changed, 9 insertions(+)
>
> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
> index fba0822..9d9a2f3 100644
> --- a/drivers/block/rbd.c
> +++ b/drivers/block/rbd.c
> @@ -255,6 +255,7 @@ struct rbd_device {
>
>   	/* sysfs related */
>   	struct device		dev;
> +	unsigned long		open_count;
>   };
>
>   static DEFINE_MUTEX(ctl_mutex);	  /* Serialize open/close/setup/teardown */
> @@ -358,6 +359,7 @@ static int rbd_open(struct block_device *bdev,
> fmode_t mode)
>
>   	rbd_get_dev(rbd_dev);
>   	set_device_ro(bdev, rbd_dev->mapping.read_only);
> +	rbd_dev->open_count++;
>
>   	return 0;
>   }
> @@ -366,6 +368,8 @@ static int rbd_release(struct gendisk *disk, fmode_t
> mode)
>   {
>   	struct rbd_device *rbd_dev = disk->private_data;
>
> +	rbd_assert(rbd_dev->open_count > 0);
> +	rbd_dev->open_count--;
>   	rbd_put_dev(rbd_dev);
>
>   	return 0;
> @@ -3764,6 +3768,11 @@ static ssize_t rbd_remove(struct bus_type *bus,
>   		goto done;
>   	}
>
> +	if (rbd_dev->open_count) {
> +		ret = -EBUSY;
> +		goto done;
> +	}
> +

Is this protected by bd_mutex?

>   	rbd_remove_all_snaps(rbd_dev);
>   	rbd_bus_del_dev(rbd_dev);
>


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH] rbd: do not allow remove of mounted-on image
  2012-11-16 22:27 ` Josh Durgin
@ 2012-11-17  5:22   ` Alex Elder
  0 siblings, 0 replies; 4+ messages in thread
From: Alex Elder @ 2012-11-17  5:22 UTC (permalink / raw)
  To: Josh Durgin; +Cc: ceph-devel

On 11/16/2012 04:27 PM, Josh Durgin wrote:
> On 11/16/2012 07:43 AM, Alex Elder wrote:
>> There is no check in rbd_remove() to see if anybody holds ope the
>> image being removed.  That's not cool.
>>
>> Add a simple open count that goes up and down with opens and closes
>> (releases) of the device, and don't allow an rbd image to be removed
>> if the count is non-zero.  Both functions are protected by the
>> bd_mutex so there's no need for any other concurrency protection.
>>
>> Signed-off-by: Alex Elder <elder@inktank.com>
>> ---
>>   drivers/block/rbd.c |    9 +++++++++
>>   1 file changed, 9 insertions(+)
>>
>> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
>> index fba0822..9d9a2f3 100644
>> --- a/drivers/block/rbd.c
>> +++ b/drivers/block/rbd.c
>> @@ -255,6 +255,7 @@ struct rbd_device {
>>
>>       /* sysfs related */
>>       struct device        dev;
>> +    unsigned long        open_count;
>>   };
>>
>>   static DEFINE_MUTEX(ctl_mutex);      /* Serialize
>> open/close/setup/teardown */
>> @@ -358,6 +359,7 @@ static int rbd_open(struct block_device *bdev,
>> fmode_t mode)
>>
>>       rbd_get_dev(rbd_dev);
>>       set_device_ro(bdev, rbd_dev->mapping.read_only);
>> +    rbd_dev->open_count++;
>>
>>       return 0;
>>   }
>> @@ -366,6 +368,8 @@ static int rbd_release(struct gendisk *disk, fmode_t
>> mode)
>>   {
>>       struct rbd_device *rbd_dev = disk->private_data;
>>
>> +    rbd_assert(rbd_dev->open_count > 0);
>> +    rbd_dev->open_count--;
>>       rbd_put_dev(rbd_dev);
>>
>>       return 0;
>> @@ -3764,6 +3768,11 @@ static ssize_t rbd_remove(struct bus_type *bus,
>>           goto done;
>>       }
>>
>> +    if (rbd_dev->open_count) {
>> +        ret = -EBUSY;
>> +        goto done;
>> +    }
>> +
> 
> Is this protected by bd_mutex?

No it's not, and that's a very good point.

I'll have to look at that over the weekend.
Thanks.

					-Alex


>>       rbd_remove_all_snaps(rbd_dev);
>>       rbd_bus_del_dev(rbd_dev);
>>
> 


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH, v2] rbd: do not allow remove of mounted-on image
  2012-11-16 15:43 [PATCH] rbd: do not allow remove of mounted-on image Alex Elder
  2012-11-16 22:27 ` Josh Durgin
@ 2012-11-19 23:42 ` Alex Elder
  1 sibling, 0 replies; 4+ messages in thread
From: Alex Elder @ 2012-11-19 23:42 UTC (permalink / raw)
  To: ceph-devel

There is no check in rbd_remove() to see if anybody holds open the
image being removed.  That's not cool.

Add a simple open count that goes up and down with opens and closes
(releases) of the device, and don't allow an rbd image to be removed
if the count is non-zero.

Protect the updates of the open count value with ctl_mutex to ensure
the underlying rbd device doesn't get removed while concurrently
being opened.

Signed-off-by: Alex Elder <elder@inktank.com>
---
v2: added ctl_mutex locking for rbd_open() and rbd_release()

 drivers/block/rbd.c |   13 +++++++++++++
 1 file changed, 13 insertions(+)

Index: b/drivers/block/rbd.c
===================================================================
--- a/drivers/block/rbd.c
+++ b/drivers/block/rbd.c
@@ -255,6 +255,7 @@ struct rbd_device {

 	/* sysfs related */
 	struct device		dev;
+	unsigned long		open_count;
 };

 static DEFINE_MUTEX(ctl_mutex);	  /* Serialize open/close/setup/teardown */
@@ -356,8 +357,11 @@ static int rbd_open(struct block_device
 	if ((mode & FMODE_WRITE) && rbd_dev->mapping.read_only)
 		return -EROFS;

+	mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
 	rbd_get_dev(rbd_dev);
 	set_device_ro(bdev, rbd_dev->mapping.read_only);
+	rbd_dev->open_count++;
+	mutex_unlock(&ctl_mutex);

 	return 0;
 }
@@ -366,7 +370,11 @@ static int rbd_release(struct gendisk *d
 {
 	struct rbd_device *rbd_dev = disk->private_data;

+	mutex_lock_nested(&ctl_mutex, SINGLE_DEPTH_NESTING);
+	rbd_assert(rbd_dev->open_count > 0);
+	rbd_dev->open_count--;
 	rbd_put_dev(rbd_dev);
+	mutex_unlock(&ctl_mutex);

 	return 0;
 }
@@ -3764,6 +3772,11 @@ static ssize_t rbd_remove(struct bus_typ
 		goto done;
 	}

+	if (rbd_dev->open_count) {
+		ret = -EBUSY;
+		goto done;
+	}
+
 	rbd_remove_all_snaps(rbd_dev);
 	rbd_bus_del_dev(rbd_dev);


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-11-19 23:42 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-11-16 15:43 [PATCH] rbd: do not allow remove of mounted-on image Alex Elder
2012-11-16 22:27 ` Josh Durgin
2012-11-17  5:22   ` Alex Elder
2012-11-19 23:42 ` [PATCH, v2] " Alex Elder

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.