afs: Fix uninitialised spinlock afs_volume::cb_break_lock
authorDavid Howells <dhowells@redhat.com>
Thu, 20 Jun 2019 15:49:35 +0000 (16:49 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 21 Jul 2019 07:03:06 +0000 (09:03 +0200)
[ Upstream commit 90fa9b64523a645a97edc0bdcf2d74759957eeee ]

Fix the cb_break_lock spinlock in afs_volume struct by initialising it when
the volume record is allocated.

Also rename the lock to cb_v_break_lock to distinguish it from the lock of
the same name in the afs_server struct.

Without this, the following trace may be observed when a volume-break
callback is received:

  INFO: trying to register non-static key.
  the code is fine but needs lockdep annotation.
  turning off the locking correctness validator.
  CPU: 2 PID: 50 Comm: kworker/2:1 Not tainted 5.2.0-rc1-fscache+ #3045
  Hardware name: ASUS All Series/H97-PLUS, BIOS 2306 10/09/2014
  Workqueue: afs SRXAFSCB_CallBack
  Call Trace:
   dump_stack+0x67/0x8e
   register_lock_class+0x23b/0x421
   ? check_usage_forwards+0x13c/0x13c
   __lock_acquire+0x89/0xf73
   lock_acquire+0x13b/0x166
   ? afs_break_callbacks+0x1b2/0x3dd
   _raw_write_lock+0x2c/0x36
   ? afs_break_callbacks+0x1b2/0x3dd
   afs_break_callbacks+0x1b2/0x3dd
   ? trace_event_raw_event_afs_server+0x61/0xac
   SRXAFSCB_CallBack+0x11f/0x16c
   process_one_work+0x2c5/0x4ee
   ? worker_thread+0x234/0x2ac
   worker_thread+0x1d8/0x2ac
   ? cancel_delayed_work_sync+0xf/0xf
   kthread+0x11f/0x127
   ? kthread_park+0x76/0x76
   ret_from_fork+0x24/0x30

Fixes: 68251f0a6818 ("afs: Fix whole-volume callback handling")
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
fs/afs/callback.c
fs/afs/internal.h
fs/afs/volume.c

index 5f261fb..4ad7012 100644 (file)
@@ -276,9 +276,9 @@ static void afs_break_one_callback(struct afs_server *server,
                        struct afs_super_info *as = AFS_FS_S(cbi->sb);
                        struct afs_volume *volume = as->volume;
 
-                       write_lock(&volume->cb_break_lock);
+                       write_lock(&volume->cb_v_break_lock);
                        volume->cb_v_break++;
-                       write_unlock(&volume->cb_break_lock);
+                       write_unlock(&volume->cb_v_break_lock);
                } else {
                        data.volume = NULL;
                        data.fid = *fid;
index 34c02fd..aea1961 100644 (file)
@@ -477,7 +477,7 @@ struct afs_volume {
        unsigned int            servers_seq;    /* Incremented each time ->servers changes */
 
        unsigned                cb_v_break;     /* Break-everything counter. */
-       rwlock_t                cb_break_lock;
+       rwlock_t                cb_v_break_lock;
 
        afs_voltype_t           type;           /* type of volume */
        short                   error;
index 3037bd0..5ec186e 100644 (file)
@@ -47,6 +47,7 @@ static struct afs_volume *afs_alloc_volume(struct afs_mount_params *params,
        atomic_set(&volume->usage, 1);
        INIT_LIST_HEAD(&volume->proc_link);
        rwlock_init(&volume->servers_lock);
+       rwlock_init(&volume->cb_v_break_lock);
        memcpy(volume->name, vldb->name, vldb->name_len + 1);
 
        slist = afs_alloc_server_list(params->cell, params->key, vldb, type_mask);