Re: [PATCH 002 of 6] md: Fix use-after-free bug when dropping an rdev from an md array.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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/