Message ID | 20200228161847.28107-1-schatzberg.dan@gmail.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | loop: Fix irq lock ordering bug | expand |
diff --git a/drivers/block/loop.c b/drivers/block/loop.c index eb766db48685..366658e60064 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -768,12 +768,18 @@ static ssize_t loop_attr_backing_file_show(struct loop_device *lo, char *buf) { ssize_t ret; char *p = NULL; + struct file *filp = NULL; spin_lock_irq(&lo->lo_lock); if (lo->lo_backing_file) - p = file_path(lo->lo_backing_file, buf, PAGE_SIZE - 1); + filp = get_file(lo->lo_backing_file); spin_unlock_irq(&lo->lo_lock); + if (filp) { + p = file_path(filp, buf, PAGE_SIZE - 1); + fput(filp); + } + if (IS_ERR_OR_NULL(p)) ret = PTR_ERR(p); else {
"loop: Use worker per cgroup instead of kworker" in patch series "Charge loop device i/o to issuing cgroup", v3. introduced a lock ordering bug. The previously existing lo->lo_lock was always acquired as spin_lock_irq but never actually used in irq context. The above patch started to use this lock in irq context which triggered a lockdep warning on sysfs reading. Fix this by executing file_path outside of the lock. Signed-off-by: Dan Schatzberg <schatzberg.dan@gmail.com> --- drivers/block/loop.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)