CHROMIUM: Fix mismatched mutex_unlock in swapon()

This change fixes the lockdep splat (when CONFIG_LOCKDEP=y and
CONFIG_DEBUG_MUTEXES=y) that happens when "swapon file" is ran:

 ------------[ cut here ]------------
 WARNING: CPU: 1 PID: 676 at kernel/locking/lockdep.c:3382 lock_release+0x2a1/0x630()
 DEBUG_LOCKS_WARN_ON(depth <= 0)
 CPU: 1 PID: 676 Comm: swapon Not tainted 4.4.70-xfstests-09717-g45af45ae8cb0 #1
 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011
  0000000000000000 ffff88007ac2bce8 ffffffff814b384c ffff88007ac2bd30
  ffffffff819b4eb0 ffff88007ac2bd20 ffffffff81077571 ffff88007b24e760
  ffffffff81187ad3 ffff88007ac2be28 ffffffff81d2a5d8 ffff88007b7b87c0
 Call Trace:
  [<ffffffff814b384c>] dump_stack+0x85/0xc9
  [<ffffffff81077571>] warn_slowpath_common+0x81/0xc0
  [<ffffffff81187ad3>] ? SyS_swapon+0xc73/0xf30
  [<ffffffff8107762c>] warn_slowpath_fmt+0x4c/0x50
  [<ffffffff810415b5>] ? kvm_clock_read+0x25/0x30
  [<ffffffff810c9bf1>] lock_release+0x2a1/0x630
  [<ffffffff810a9fe1>] ? sched_clock_cpu+0x91/0xb0
  [<ffffffff81187164>] ? SyS_swapon+0x304/0xf30
  [<ffffffff816f8073>] __mutex_unlock_slowpath+0x43/0x3c0
  [<ffffffff816f8402>] mutex_unlock+0x12/0x20
  [<ffffffff81187ad3>] SyS_swapon+0xc73/0xf30
  [<ffffffff816ff207>] ? int_ret_from_sys_call+0x52/0x9f
  [<ffffffff81001017>] ? trace_hardirqs_on_thunk+0x17/0x19
  [<ffffffff816ff072>] entry_SYSCALL_64_fastpath+0x12/0x76
 ---[ end trace 04cc26a572ac8e68 ]---

In upstream kernel, claim_swapfile() does and unconditional
mutex_lock(&inode->i_mutex) when inode is a regular file. This mutex is
then unlocked in swapon() function's return path. On ChromiumOS though,
since the mutex_lock() is compiled out or disabled by sysctl, the
corresponding mutex_unlock() generates the splat.
The presence of sysctl_disk_based_swap makes it tricky because the
sysctl value may change (in theory) between claim_swapfile() and
the swapon() exit path.
To fix this, instead of compiling out the upstream code, we add a check
for the sysctl value (which is 0 by default) at the beginning of the
swapon() function  and do a proper mutex lock/unlock in all cases.

BUG=b:62107328
TEST=Following steps reproduced the issue:
  $ dd if=/dev/zero of=/swapfile count=1000 bs=4096
  $ mkswap -U <uuid> /swapfile
  $ swapon /swapfile
After the patch, there is no warning.

Change-Id: I81aac1c07bfbad142b699b05a4136251e78b2f71
Reviewed-on: https://chromium-review.googlesource.com/535083
Commit-Ready: Aditya Kali <adityakali@google.com>
Tested-by: Aditya Kali <adityakali@google.com>
Reviewed-by: Guenter Roeck <groeck@chromium.org>
1 file changed