Use queue_limits_commit_update to apply a consistent freeze vs limits
lock order in queue_attr_store.  Also remove taking the sysfs lock
as it doesn't protect anything here.

Signed-off-by: Christoph Hellwig <[email protected]>
---
 block/blk-sysfs.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index 8d69315e986d..3bac27fcd635 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -687,22 +687,24 @@ queue_attr_store(struct kobject *kobj, struct attribute 
*attr,
        if (entry->load_module)
                entry->load_module(disk, page, length);
 
-       mutex_lock(&q->sysfs_lock);
-       blk_mq_freeze_queue(q);
        if (entry->store_limit) {
                struct queue_limits lim = queue_limits_start_update(q);
 
                res = entry->store_limit(disk, page, length, &lim);
                if (res < 0) {
                        queue_limits_cancel_update(q);
-               } else {
-                       res = queue_limits_commit_update(q, &lim);
-                       if (!res)
-                               res = length;
+                       return res;
                }
-       } else {
-               res = entry->store(disk, page, length);
+
+               res = queue_limits_commit_update_frozen(q, &lim);
+               if (res)
+                       return res;
+               return length;
        }
+
+       mutex_lock(&q->sysfs_lock);
+       blk_mq_freeze_queue(q);
+       res = entry->store(disk, page, length);
        blk_mq_unfreeze_queue(q);
        mutex_unlock(&q->sysfs_lock);
        return res;
-- 
2.45.2


Reply via email to