Home Home > GIT Browse > SLE12-SP5-AZURE
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuis Henriques <lhenriques@suse.com>2019-08-27 11:51:08 +0100
committerLuis Henriques <lhenriques@suse.com>2019-09-05 10:08:48 +0100
commitd42cfc2988e042628fb628174d19e084d93561bd (patch)
treead4dee4286b9dc56ca957feae9ef3606b2044a77
parentb8a1b4b45f0335e96904c21ec715cd54da1f623b (diff)
ceph: fix buffer free while holding i_ceph_lock in fill_inode()
(bsc#1148133).
-rw-r--r--patches.suse/ceph-fix-buffer-free-while-holding-i_ceph_lock-in-fill_inode.patch81
-rw-r--r--series.conf1
2 files changed, 82 insertions, 0 deletions
diff --git a/patches.suse/ceph-fix-buffer-free-while-holding-i_ceph_lock-in-fill_inode.patch b/patches.suse/ceph-fix-buffer-free-while-holding-i_ceph_lock-in-fill_inode.patch
new file mode 100644
index 0000000000..ac35db37f1
--- /dev/null
+++ b/patches.suse/ceph-fix-buffer-free-while-holding-i_ceph_lock-in-fill_inode.patch
@@ -0,0 +1,81 @@
+From: Luis Henriques <lhenriques@suse.com>
+Date: Fri, 19 Jul 2019 15:32:22 +0100
+Subject: ceph: fix buffer free while holding i_ceph_lock in fill_inode()
+Git-commit: af8a85a41734f37b67ba8ce69d56b685bee4ac48
+Patch-mainline: v5.3-rc6
+References: bsc#1148133
+
+Calling ceph_buffer_put() in fill_inode() may result in freeing the
+i_xattrs.blob buffer while holding the i_ceph_lock. This can be fixed by
+postponing the call until later, when the lock is released.
+
+The following backtrace was triggered by fstests generic/070.
+
+ BUG: sleeping function called from invalid context at mm/vmalloc.c:2283
+ in_atomic(): 1, irqs_disabled(): 0, pid: 3852, name: kworker/0:4
+ 6 locks held by kworker/0:4/3852:
+ #0: 000000004270f6bb ((wq_completion)ceph-msgr){+.+.}, at: process_one_work+0x1b8/0x5f0
+ #1: 00000000eb420803 ((work_completion)(&(&con->work)->work)){+.+.}, at: process_one_work+0x1b8/0x5f0
+ #2: 00000000be1c53a4 (&s->s_mutex){+.+.}, at: dispatch+0x288/0x1476
+ #3: 00000000559cb958 (&mdsc->snap_rwsem){++++}, at: dispatch+0x2eb/0x1476
+ #4: 000000000d5ebbae (&req->r_fill_mutex){+.+.}, at: dispatch+0x2fc/0x1476
+ #5: 00000000a83d0514 (&(&ci->i_ceph_lock)->rlock){+.+.}, at: fill_inode.isra.0+0xf8/0xf70
+ CPU: 0 PID: 3852 Comm: kworker/0:4 Not tainted 5.2.0+ #441
+ Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.12.1-0-ga5cab58-prebuilt.qemu.org 04/01/2014
+ Workqueue: ceph-msgr ceph_con_workfn
+ Call Trace:
+ dump_stack+0x67/0x90
+ ___might_sleep.cold+0x9f/0xb1
+ vfree+0x4b/0x60
+ ceph_buffer_release+0x1b/0x60
+ fill_inode.isra.0+0xa9b/0xf70
+ ceph_fill_trace+0x13b/0xc70
+ ? dispatch+0x2eb/0x1476
+ dispatch+0x320/0x1476
+ ? __mutex_unlock_slowpath+0x4d/0x2a0
+ ceph_con_workfn+0xc97/0x2ec0
+ ? process_one_work+0x1b8/0x5f0
+ process_one_work+0x244/0x5f0
+ worker_thread+0x4d/0x3e0
+ kthread+0x105/0x140
+ ? process_one_work+0x5f0/0x5f0
+ ? kthread_park+0x90/0x90
+ ret_from_fork+0x3a/0x50
+
+Signed-off-by: Luis Henriques <lhenriques@suse.com>
+Reviewed-by: Jeff Layton <jlayton@kernel.org>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+---
+ fs/ceph/inode.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+--- a/fs/ceph/inode.c
++++ b/fs/ceph/inode.c
+@@ -744,6 +744,7 @@ static int fill_inode(struct inode *inod
+ int issued = 0, implemented, new_issued;
+ struct timespec mtime, atime, ctime;
+ struct ceph_buffer *xattr_blob = NULL;
++ struct ceph_buffer *old_blob = NULL;
+ struct ceph_string *pool_ns = NULL;
+ struct ceph_cap *new_cap = NULL;
+ int err = 0;
+@@ -874,7 +875,7 @@ static int fill_inode(struct inode *inod
+ if ((ci->i_xattrs.version == 0 || !(issued & CEPH_CAP_XATTR_EXCL)) &&
+ le64_to_cpu(info->xattr_version) > ci->i_xattrs.version) {
+ if (ci->i_xattrs.blob)
+- ceph_buffer_put(ci->i_xattrs.blob);
++ old_blob = ci->i_xattrs.blob;
+ ci->i_xattrs.blob = xattr_blob;
+ if (xattr_blob)
+ memcpy(ci->i_xattrs.blob->vec.iov_base,
+@@ -1019,8 +1020,8 @@ static int fill_inode(struct inode *inod
+ out:
+ if (new_cap)
+ ceph_put_cap(mdsc, new_cap);
+- if (xattr_blob)
+- ceph_buffer_put(xattr_blob);
++ ceph_buffer_put(old_blob);
++ ceph_buffer_put(xattr_blob);
+ ceph_put_string(pool_ns);
+ return err;
+ }
diff --git a/series.conf b/series.conf
index cc2d427a2d..f3345fe653 100644
--- a/series.conf
+++ b/series.conf
@@ -24129,6 +24129,7 @@
patches.suse/libceph-allow-ceph_buffer_put-to-receive-a-null-ceph_buffer.patch
patches.suse/ceph-fix-buffer-free-while-holding-i_ceph_lock-in-_ceph_setxattr.patch
patches.suse/ceph-fix-buffer-free-while-holding-i_ceph_lock-in-_ceph_build_xattrs_blob.patch
+ patches.suse/ceph-fix-buffer-free-while-holding-i_ceph_lock-in-fill_inode.patch
patches.suse/vfs-fix-page-locking-deadlocks-when-deduping-files.patch
patches.suse/fs-xfs-Fix-return-code-of-xfs_break_leased_layouts.patch
patches.suse/Revert-dm-bufio-fix-deadlock-with-loop-device.patch