Re: [PATCH 002 of 6] md: Fix use-after-free bug when dropping an rdev from an md array.

2008-01-14 Thread Al Viro
On Mon, Jan 14, 2008 at 12:59:39PM +, Al Viro wrote:

> I really don't like the entire scheme, to be honest.  BTW, what happens
> if you try to add the same device to the same array after having it kicked
> out?  If that comes before your delayed kobject_del(), the things will
> get nasty since sysfs will (rightfully) refuse to add another entry with
> the same name and parent while the old one is still there and for all
> sysfs knows is going to stay there...

More fun questions: what are the locking requirements for ->resize()?
You are calling it with no exclusion whatsoever...  What about
bind_rdev_to_array()?  At the very least, you want to protect
mddev->disks, and AFAICS new_dev_store() has no exclusion at all.
And I suspect that you have other things in there in need of protection
(finding free desc_nr, for one); can all of those be handled by simple
spinlocks?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 002 of 6] md: Fix use-after-free bug when dropping an rdev from an md array.

2008-01-14 Thread Al Viro
On Mon, Jan 14, 2008 at 05:28:44PM +1100, Neil Brown wrote:
> On Monday January 14, [EMAIL PROTECTED] wrote:
> > 
> > Thanks.  I'll see what I can some up with.
> 
> How about this, against current -mm
> 
> On both the read and write path for an rdev attribute, we
> call mddev_lock, first checking that mddev is not NULL.
> Once we get the lock, we check again.
> If rdev->mddev is not NULL, we know it will stay that way as it only
> gets cleared under the same lock.
> 
> While in the rdev show/store routines, we know that the mddev cannot
> get freed, do to the kobject relationships.
> 
> rdev_size_store is awkward because it has to drop the lock.  So we
> take a copy of rdev->mddev before the drop, and we are safe...
> 
> Comments?

*cringe*

I really don't like the entire scheme, to be honest.  BTW, what happens
if you try to add the same device to the same array after having it kicked
out?  If that comes before your delayed kobject_del(), the things will
get nasty since sysfs will (rightfully) refuse to add another entry with
the same name and parent while the old one is still there and for all
sysfs knows is going to stay there...
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 002 of 6] md: Fix use-after-free bug when dropping an rdev from an md array.

2008-01-14 Thread Al Viro
On Mon, Jan 14, 2008 at 05:28:44PM +1100, Neil Brown wrote:
 On Monday January 14, [EMAIL PROTECTED] wrote:
  
  Thanks.  I'll see what I can some up with.
 
 How about this, against current -mm
 
 On both the read and write path for an rdev attribute, we
 call mddev_lock, first checking that mddev is not NULL.
 Once we get the lock, we check again.
 If rdev-mddev is not NULL, we know it will stay that way as it only
 gets cleared under the same lock.
 
 While in the rdev show/store routines, we know that the mddev cannot
 get freed, do to the kobject relationships.
 
 rdev_size_store is awkward because it has to drop the lock.  So we
 take a copy of rdev-mddev before the drop, and we are safe...
 
 Comments?

*cringe*

I really don't like the entire scheme, to be honest.  BTW, what happens
if you try to add the same device to the same array after having it kicked
out?  If that comes before your delayed kobject_del(), the things will
get nasty since sysfs will (rightfully) refuse to add another entry with
the same name and parent while the old one is still there and for all
sysfs knows is going to stay there...
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 002 of 6] md: Fix use-after-free bug when dropping an rdev from an md array.

2008-01-14 Thread Al Viro
On Mon, Jan 14, 2008 at 12:59:39PM +, Al Viro wrote:

 I really don't like the entire scheme, to be honest.  BTW, what happens
 if you try to add the same device to the same array after having it kicked
 out?  If that comes before your delayed kobject_del(), the things will
 get nasty since sysfs will (rightfully) refuse to add another entry with
 the same name and parent while the old one is still there and for all
 sysfs knows is going to stay there...

More fun questions: what are the locking requirements for -resize()?
You are calling it with no exclusion whatsoever...  What about
bind_rdev_to_array()?  At the very least, you want to protect
mddev-disks, and AFAICS new_dev_store() has no exclusion at all.
And I suspect that you have other things in there in need of protection
(finding free desc_nr, for one); can all of those be handled by simple
spinlocks?
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 002 of 6] md: Fix use-after-free bug when dropping an rdev from an md array.

2008-01-13 Thread Neil Brown
On Monday January 14, [EMAIL PROTECTED] wrote:
> 
> Thanks.  I'll see what I can some up with.

How about this, against current -mm

On both the read and write path for an rdev attribute, we
call mddev_lock, first checking that mddev is not NULL.
Once we get the lock, we check again.
If rdev->mddev is not NULL, we know it will stay that way as it only
gets cleared under the same lock.

While in the rdev show/store routines, we know that the mddev cannot
get freed, do to the kobject relationships.

rdev_size_store is awkward because it has to drop the lock.  So we
take a copy of rdev->mddev before the drop, and we are safe...

Comments?

NeilBrown

Signed-off-by: Neil Brown <[EMAIL PROTECTED]>

### Diffstat output
 ./drivers/md/md.c |   35 ++-
 1 file changed, 26 insertions(+), 9 deletions(-)

diff .prev/drivers/md/md.c ./drivers/md/md.c
--- .prev/drivers/md/md.c   2008-01-14 12:26:15.0 +1100
+++ ./drivers/md/md.c   2008-01-14 17:05:53.0 +1100
@@ -1998,9 +1998,11 @@ rdev_size_store(mdk_rdev_t *rdev, const 
char *e;
unsigned long long size = simple_strtoull(buf, , 10);
unsigned long long oldsize = rdev->size;
+   mddev_t *my_mddev = rdev->mddev;
+
if (e==buf || (*e && *e != '\n'))
return -EINVAL;
-   if (rdev->mddev->pers)
+   if (my_mddev->pers)
return -EBUSY;
rdev->size = size;
if (size > oldsize && rdev->mddev->external) {
@@ -2013,7 +2015,7 @@ rdev_size_store(mdk_rdev_t *rdev, const 
int overlap = 0;
struct list_head *tmp, *tmp2;
 
-   mddev_unlock(rdev->mddev);
+   mddev_unlock(my_mddev);
for_each_mddev(mddev, tmp) {
mdk_rdev_t *rdev2;
 
@@ -2033,7 +2035,7 @@ rdev_size_store(mdk_rdev_t *rdev, const 
break;
}
}
-   mddev_lock(rdev->mddev);
+   mddev_lock(my_mddev);
if (overlap) {
/* Someone else could have slipped in a size
 * change here, but doing so is just silly.
@@ -2045,8 +2047,8 @@ rdev_size_store(mdk_rdev_t *rdev, const 
return -EBUSY;
}
}
-   if (size < rdev->mddev->size || rdev->mddev->size == 0)
-   rdev->mddev->size = size;
+   if (size < my_mddev->size || my_mddev->size == 0)
+   my_mddev->size = size;
return len;
 }
 
@@ -2067,10 +2069,21 @@ rdev_attr_show(struct kobject *kobj, str
 {
struct rdev_sysfs_entry *entry = container_of(attr, struct 
rdev_sysfs_entry, attr);
mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
+   mddev_t *mddev = rdev->mddev;
+   ssize_t rv;
 
if (!entry->show)
return -EIO;
-   return entry->show(rdev, page);
+
+   rv = mddev ? mddev_lock(mddev) : -EBUSY;
+   if (!rv) {
+   if (rdev->mddev == NULL)
+   rv = -EBUSY;
+   else
+   rv = entry->show(rdev, page);
+   mddev_unlock(mddev);
+   }
+   return rv;
 }
 
 static ssize_t
@@ -2079,15 +2092,19 @@ rdev_attr_store(struct kobject *kobj, st
 {
struct rdev_sysfs_entry *entry = container_of(attr, struct 
rdev_sysfs_entry, attr);
mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
-   int rv;
+   ssize_t rv;
+   mddev_t *mddev = rdev->mddev;
 
if (!entry->store)
return -EIO;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
-   rv = mddev_lock(rdev->mddev);
+   rv = mddev ? mddev_lock(mddev): -EBUSY;
if (!rv) {
-   rv = entry->store(rdev, page, length);
+   if (rdev->mddev == NULL)
+   rv = -EBUSY;
+   else
+   rv = entry->store(rdev, page, length);
mddev_unlock(rdev->mddev);
}
return rv;
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 002 of 6] md: Fix use-after-free bug when dropping an rdev from an md array.

2008-01-13 Thread Neil Brown
On Monday January 14, [EMAIL PROTECTED] wrote:
> On Mon, Jan 14, 2008 at 02:21:45PM +1100, Neil Brown wrote:
> 
> > Maybe it isn't there any more
> > 
> > Once upon a time, when I 
> >echo remove > /sys/block/mdX/md/dev-YYY/state
> 
> Egads.  And just what will protect you from parallel callers
> of state_store()?  buffer->mutex does *not* do that - it only
> gives you exclusion on given struct file.  Run the command
> above from several shells and you've got independent open
> from each redirect => different struct file *and* different
> buffer for each => no exclusion whatsoever.

well in -mm, rdev_attr_store gets a lock on
rdev->mddev->reconfig_mutex. 
It doesn't test is rdev->mddev is NULL though, so if the write happens
after unbind_rdev_from_array, we lose.
A test for NULL would be easy enough.  And I think that the mddev
won't actually disappear until the rdevs are all gone (you subsequent
comment about kobject_del ordering seems to confirm that) so a simple test
for NULL should be sufficient.

> 
> And _that_ is present right in the mainline tree - it's unrelated
> to -mm kobject changes.
> 
> BTW, yes, you do have a deadlock there - kobject_del() will try to evict
> children, which will include waiting for currently running ->store()
> to finish, which will include the caller since .../state *is* a child of
> that sucker.
> 
> The real problem is the lack of any kind of exclusion considerations in
> md.c itself, AFAICS.  Fun with ordering is secondary (BTW, yes, it is
> a problem - will sysfs ->store() to attribute between export_rdev() and
> kobject_del() work correctly?)

Probably not.  The possibility that rdev->mddev could be NULL would
break a lot of these.  Maybe I should delay setting rdev->mddev to
NULL until after the kobject_del.  Then audit them all.

Thanks.  I'll see what I can some up with.

NeilBrown
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 002 of 6] md: Fix use-after-free bug when dropping an rdev from an md array.

2008-01-13 Thread Al Viro
On Mon, Jan 14, 2008 at 02:21:45PM +1100, Neil Brown wrote:

> Maybe it isn't there any more
> 
> Once upon a time, when I 
>echo remove > /sys/block/mdX/md/dev-YYY/state

Egads.  And just what will protect you from parallel callers
of state_store()?  buffer->mutex does *not* do that - it only
gives you exclusion on given struct file.  Run the command
above from several shells and you've got independent open
from each redirect => different struct file *and* different
buffer for each => no exclusion whatsoever.

And _that_ is present right in the mainline tree - it's unrelated
to -mm kobject changes.

BTW, yes, you do have a deadlock there - kobject_del() will try to evict
children, which will include waiting for currently running ->store()
to finish, which will include the caller since .../state *is* a child of
that sucker.

The real problem is the lack of any kind of exclusion considerations in
md.c itself, AFAICS.  Fun with ordering is secondary (BTW, yes, it is
a problem - will sysfs ->store() to attribute between export_rdev() and
kobject_del() work correctly?)

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 002 of 6] md: Fix use-after-free bug when dropping an rdev from an md array.

2008-01-13 Thread Neil Brown
On Monday January 14, [EMAIL PROTECTED] wrote:
> On Mon, Jan 14, 2008 at 12:45:31PM +1100, NeilBrown wrote:
> > 
> > Due to possible deadlock issues we need to use a schedule work to
> > kobject_del an 'rdev' object from a different thread.
> > 
> > A recent change means that kobject_add no longer gets a refernce, and
> > kobject_del doesn't put a reference.  Consequently, we need to
> > explicitly hold a reference to ensure that the last reference isn't
> > dropped before the scheduled work get a chance to call kobject_del.
> > 
> > Also, rename delayed_delete to md_delayed_delete to that it is more
> > obvious in a stack trace which code is to blame.
> 
> I don't know...  You still get kobject_del() and export_rdev()
> in unpredictable order; sure, it won't be freed under you, but...

I cannot see that that would matter.
kobject_del deletes the object from the kobj tree and free sysfs.
export_rdev disconnects the objects from md structures and releases
the connection with the device.  They are quite independent.

> 
> What is that deadlock problem, anyway?  I don't see anything that
> would look like an obvious candidate in the stuff you are delaying...

Maybe it isn't there any more

Once upon a time, when I 
   echo remove > /sys/block/mdX/md/dev-YYY/state

sysfs_write_file would hold buffer->sem while calling my store
handler.
When my store handler tried to delete the relevant kobject, it would
eventually call orphan_all_buffers which would try to take buf->sem
and deadlock.

orphan_all_buffers doesn't exist any more, so maybe the deadlock is
gone too.
However the comment at the top of sysfs_schedule_callback in
sysfs/file.c says:

 *
 * sysfs attribute methods must not unregister themselves or their parent
 * kobject (which would amount to the same thing).  Attempts to do so will
 * deadlock, since unregistration is mutually exclusive with driver
 * callbacks.
 *

so I'm included to leave the code as it is  ofcourse the comment
could be well out of date.

NeilBrown
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 002 of 6] md: Fix use-after-free bug when dropping an rdev from an md array.

2008-01-13 Thread Al Viro
On Mon, Jan 14, 2008 at 12:45:31PM +1100, NeilBrown wrote:
> 
> Due to possible deadlock issues we need to use a schedule work to
> kobject_del an 'rdev' object from a different thread.
> 
> A recent change means that kobject_add no longer gets a refernce, and
> kobject_del doesn't put a reference.  Consequently, we need to
> explicitly hold a reference to ensure that the last reference isn't
> dropped before the scheduled work get a chance to call kobject_del.
> 
> Also, rename delayed_delete to md_delayed_delete to that it is more
> obvious in a stack trace which code is to blame.

I don't know...  You still get kobject_del() and export_rdev()
in unpredictable order; sure, it won't be freed under you, but...

What is that deadlock problem, anyway?  I don't see anything that
would look like an obvious candidate in the stuff you are delaying...
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 002 of 6] md: Fix use-after-free bug when dropping an rdev from an md array.

2008-01-13 Thread Al Viro
On Mon, Jan 14, 2008 at 12:45:31PM +1100, NeilBrown wrote:
 
 Due to possible deadlock issues we need to use a schedule work to
 kobject_del an 'rdev' object from a different thread.
 
 A recent change means that kobject_add no longer gets a refernce, and
 kobject_del doesn't put a reference.  Consequently, we need to
 explicitly hold a reference to ensure that the last reference isn't
 dropped before the scheduled work get a chance to call kobject_del.
 
 Also, rename delayed_delete to md_delayed_delete to that it is more
 obvious in a stack trace which code is to blame.

I don't know...  You still get kobject_del() and export_rdev()
in unpredictable order; sure, it won't be freed under you, but...

What is that deadlock problem, anyway?  I don't see anything that
would look like an obvious candidate in the stuff you are delaying...
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 002 of 6] md: Fix use-after-free bug when dropping an rdev from an md array.

2008-01-13 Thread Neil Brown
On Monday January 14, [EMAIL PROTECTED] wrote:
 On Mon, Jan 14, 2008 at 12:45:31PM +1100, NeilBrown wrote:
  
  Due to possible deadlock issues we need to use a schedule work to
  kobject_del an 'rdev' object from a different thread.
  
  A recent change means that kobject_add no longer gets a refernce, and
  kobject_del doesn't put a reference.  Consequently, we need to
  explicitly hold a reference to ensure that the last reference isn't
  dropped before the scheduled work get a chance to call kobject_del.
  
  Also, rename delayed_delete to md_delayed_delete to that it is more
  obvious in a stack trace which code is to blame.
 
 I don't know...  You still get kobject_del() and export_rdev()
 in unpredictable order; sure, it won't be freed under you, but...

I cannot see that that would matter.
kobject_del deletes the object from the kobj tree and free sysfs.
export_rdev disconnects the objects from md structures and releases
the connection with the device.  They are quite independent.

 
 What is that deadlock problem, anyway?  I don't see anything that
 would look like an obvious candidate in the stuff you are delaying...

Maybe it isn't there any more

Once upon a time, when I 
   echo remove  /sys/block/mdX/md/dev-YYY/state

sysfs_write_file would hold buffer-sem while calling my store
handler.
When my store handler tried to delete the relevant kobject, it would
eventually call orphan_all_buffers which would try to take buf-sem
and deadlock.

orphan_all_buffers doesn't exist any more, so maybe the deadlock is
gone too.
However the comment at the top of sysfs_schedule_callback in
sysfs/file.c says:

 *
 * sysfs attribute methods must not unregister themselves or their parent
 * kobject (which would amount to the same thing).  Attempts to do so will
 * deadlock, since unregistration is mutually exclusive with driver
 * callbacks.
 *

so I'm included to leave the code as it is  ofcourse the comment
could be well out of date.

NeilBrown
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 002 of 6] md: Fix use-after-free bug when dropping an rdev from an md array.

2008-01-13 Thread Al Viro
On Mon, Jan 14, 2008 at 02:21:45PM +1100, Neil Brown wrote:

 Maybe it isn't there any more
 
 Once upon a time, when I 
echo remove  /sys/block/mdX/md/dev-YYY/state

Egads.  And just what will protect you from parallel callers
of state_store()?  buffer-mutex does *not* do that - it only
gives you exclusion on given struct file.  Run the command
above from several shells and you've got independent open
from each redirect = different struct file *and* different
buffer for each = no exclusion whatsoever.

And _that_ is present right in the mainline tree - it's unrelated
to -mm kobject changes.

BTW, yes, you do have a deadlock there - kobject_del() will try to evict
children, which will include waiting for currently running -store()
to finish, which will include the caller since .../state *is* a child of
that sucker.

The real problem is the lack of any kind of exclusion considerations in
md.c itself, AFAICS.  Fun with ordering is secondary (BTW, yes, it is
a problem - will sysfs -store() to attribute between export_rdev() and
kobject_del() work correctly?)

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 002 of 6] md: Fix use-after-free bug when dropping an rdev from an md array.

2008-01-13 Thread Neil Brown
On Monday January 14, [EMAIL PROTECTED] wrote:
 On Mon, Jan 14, 2008 at 02:21:45PM +1100, Neil Brown wrote:
 
  Maybe it isn't there any more
  
  Once upon a time, when I 
 echo remove  /sys/block/mdX/md/dev-YYY/state
 
 Egads.  And just what will protect you from parallel callers
 of state_store()?  buffer-mutex does *not* do that - it only
 gives you exclusion on given struct file.  Run the command
 above from several shells and you've got independent open
 from each redirect = different struct file *and* different
 buffer for each = no exclusion whatsoever.

well in -mm, rdev_attr_store gets a lock on
rdev-mddev-reconfig_mutex. 
It doesn't test is rdev-mddev is NULL though, so if the write happens
after unbind_rdev_from_array, we lose.
A test for NULL would be easy enough.  And I think that the mddev
won't actually disappear until the rdevs are all gone (you subsequent
comment about kobject_del ordering seems to confirm that) so a simple test
for NULL should be sufficient.

 
 And _that_ is present right in the mainline tree - it's unrelated
 to -mm kobject changes.
 
 BTW, yes, you do have a deadlock there - kobject_del() will try to evict
 children, which will include waiting for currently running -store()
 to finish, which will include the caller since .../state *is* a child of
 that sucker.
 
 The real problem is the lack of any kind of exclusion considerations in
 md.c itself, AFAICS.  Fun with ordering is secondary (BTW, yes, it is
 a problem - will sysfs -store() to attribute between export_rdev() and
 kobject_del() work correctly?)

Probably not.  The possibility that rdev-mddev could be NULL would
break a lot of these.  Maybe I should delay setting rdev-mddev to
NULL until after the kobject_del.  Then audit them all.

Thanks.  I'll see what I can some up with.

NeilBrown
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 002 of 6] md: Fix use-after-free bug when dropping an rdev from an md array.

2008-01-13 Thread Neil Brown
On Monday January 14, [EMAIL PROTECTED] wrote:
 
 Thanks.  I'll see what I can some up with.

How about this, against current -mm

On both the read and write path for an rdev attribute, we
call mddev_lock, first checking that mddev is not NULL.
Once we get the lock, we check again.
If rdev-mddev is not NULL, we know it will stay that way as it only
gets cleared under the same lock.

While in the rdev show/store routines, we know that the mddev cannot
get freed, do to the kobject relationships.

rdev_size_store is awkward because it has to drop the lock.  So we
take a copy of rdev-mddev before the drop, and we are safe...

Comments?

NeilBrown

Signed-off-by: Neil Brown [EMAIL PROTECTED]

### Diffstat output
 ./drivers/md/md.c |   35 ++-
 1 file changed, 26 insertions(+), 9 deletions(-)

diff .prev/drivers/md/md.c ./drivers/md/md.c
--- .prev/drivers/md/md.c   2008-01-14 12:26:15.0 +1100
+++ ./drivers/md/md.c   2008-01-14 17:05:53.0 +1100
@@ -1998,9 +1998,11 @@ rdev_size_store(mdk_rdev_t *rdev, const 
char *e;
unsigned long long size = simple_strtoull(buf, e, 10);
unsigned long long oldsize = rdev-size;
+   mddev_t *my_mddev = rdev-mddev;
+
if (e==buf || (*e  *e != '\n'))
return -EINVAL;
-   if (rdev-mddev-pers)
+   if (my_mddev-pers)
return -EBUSY;
rdev-size = size;
if (size  oldsize  rdev-mddev-external) {
@@ -2013,7 +2015,7 @@ rdev_size_store(mdk_rdev_t *rdev, const 
int overlap = 0;
struct list_head *tmp, *tmp2;
 
-   mddev_unlock(rdev-mddev);
+   mddev_unlock(my_mddev);
for_each_mddev(mddev, tmp) {
mdk_rdev_t *rdev2;
 
@@ -2033,7 +2035,7 @@ rdev_size_store(mdk_rdev_t *rdev, const 
break;
}
}
-   mddev_lock(rdev-mddev);
+   mddev_lock(my_mddev);
if (overlap) {
/* Someone else could have slipped in a size
 * change here, but doing so is just silly.
@@ -2045,8 +2047,8 @@ rdev_size_store(mdk_rdev_t *rdev, const 
return -EBUSY;
}
}
-   if (size  rdev-mddev-size || rdev-mddev-size == 0)
-   rdev-mddev-size = size;
+   if (size  my_mddev-size || my_mddev-size == 0)
+   my_mddev-size = size;
return len;
 }
 
@@ -2067,10 +2069,21 @@ rdev_attr_show(struct kobject *kobj, str
 {
struct rdev_sysfs_entry *entry = container_of(attr, struct 
rdev_sysfs_entry, attr);
mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
+   mddev_t *mddev = rdev-mddev;
+   ssize_t rv;
 
if (!entry-show)
return -EIO;
-   return entry-show(rdev, page);
+
+   rv = mddev ? mddev_lock(mddev) : -EBUSY;
+   if (!rv) {
+   if (rdev-mddev == NULL)
+   rv = -EBUSY;
+   else
+   rv = entry-show(rdev, page);
+   mddev_unlock(mddev);
+   }
+   return rv;
 }
 
 static ssize_t
@@ -2079,15 +2092,19 @@ rdev_attr_store(struct kobject *kobj, st
 {
struct rdev_sysfs_entry *entry = container_of(attr, struct 
rdev_sysfs_entry, attr);
mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
-   int rv;
+   ssize_t rv;
+   mddev_t *mddev = rdev-mddev;
 
if (!entry-store)
return -EIO;
if (!capable(CAP_SYS_ADMIN))
return -EACCES;
-   rv = mddev_lock(rdev-mddev);
+   rv = mddev ? mddev_lock(mddev): -EBUSY;
if (!rv) {
-   rv = entry-store(rdev, page, length);
+   if (rdev-mddev == NULL)
+   rv = -EBUSY;
+   else
+   rv = entry-store(rdev, page, length);
mddev_unlock(rdev-mddev);
}
return rv;
--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/