]> git.proxmox.com Git - zfsonlinux.git/blob - zfs-patches/0005-zv_suspend_lock-in-zvol_open-zvol_release.patch
bump version to 0.7.11-pve1~bpo1
[zfsonlinux.git] / zfs-patches / 0005-zv_suspend_lock-in-zvol_open-zvol_release.patch
1 From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
2 From: Boris Protopopov <bprotopopov@users.noreply.github.com>
3 Date: Wed, 9 Aug 2017 14:10:47 -0400
4 Subject: [PATCH] zv_suspend_lock in zvol_open()/zvol_release()
5
6 Acquire zv_suspend_lock on first open and last close only.
7
8 Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
9 Signed-off-by: Boris Protopopov <boris.protopopov@actifio.com>
10 Closes #6342
11
12 Signed-off-by: Stoiko Ivanov <s.ivanov@proxmox.com>
13 ---
14 module/zfs/zvol.c | 64 +++++++++++++++++++++++++++++++++++--------------------
15 1 file changed, 41 insertions(+), 23 deletions(-)
16
17 diff --git a/module/zfs/zvol.c b/module/zfs/zvol.c
18 index 3e7059b3..ffa5fac7 100644
19 --- a/module/zfs/zvol.c
20 +++ b/module/zfs/zvol.c
21 @@ -1347,9 +1347,9 @@ zvol_open(struct block_device *bdev, fmode_t flag)
22 {
23 zvol_state_t *zv;
24 int error = 0;
25 - boolean_t drop_suspend = B_FALSE;
26 + boolean_t drop_suspend = B_TRUE;
27
28 - ASSERT(!mutex_owned(&zvol_state_lock));
29 + ASSERT(!MUTEX_HELD(&zvol_state_lock));
30
31 mutex_enter(&zvol_state_lock);
32 /*
33 @@ -1364,23 +1364,31 @@ zvol_open(struct block_device *bdev, fmode_t flag)
34 return (SET_ERROR(-ENXIO));
35 }
36
37 - /* take zv_suspend_lock before zv_state_lock */
38 - rw_enter(&zv->zv_suspend_lock, RW_READER);
39 -
40 mutex_enter(&zv->zv_state_lock);
41 -
42 /*
43 * make sure zvol is not suspended during first open
44 - * (hold zv_suspend_lock), otherwise, drop the lock
45 + * (hold zv_suspend_lock) and respect proper lock acquisition
46 + * ordering - zv_suspend_lock before zv_state_lock
47 */
48 if (zv->zv_open_count == 0) {
49 - drop_suspend = B_TRUE;
50 + if (!rw_tryenter(&zv->zv_suspend_lock, RW_READER)) {
51 + mutex_exit(&zv->zv_state_lock);
52 + rw_enter(&zv->zv_suspend_lock, RW_READER);
53 + mutex_enter(&zv->zv_state_lock);
54 + /* check to see if zv_suspend_lock is needed */
55 + if (zv->zv_open_count != 0) {
56 + rw_exit(&zv->zv_suspend_lock);
57 + drop_suspend = B_FALSE;
58 + }
59 + }
60 } else {
61 - rw_exit(&zv->zv_suspend_lock);
62 + drop_suspend = B_FALSE;
63 }
64 -
65 mutex_exit(&zvol_state_lock);
66
67 + ASSERT(MUTEX_HELD(&zv->zv_state_lock));
68 + ASSERT(zv->zv_open_count != 0 || RW_READ_HELD(&zv->zv_suspend_lock));
69 +
70 if (zv->zv_open_count == 0) {
71 error = zvol_first_open(zv);
72 if (error)
73 @@ -1417,28 +1425,38 @@ static int
74 zvol_release(struct gendisk *disk, fmode_t mode)
75 {
76 zvol_state_t *zv;
77 - boolean_t drop_suspend = B_FALSE;
78 + boolean_t drop_suspend = B_TRUE;
79
80 - ASSERT(!mutex_owned(&zvol_state_lock));
81 + ASSERT(!MUTEX_HELD(&zvol_state_lock));
82
83 mutex_enter(&zvol_state_lock);
84 zv = disk->private_data;
85 - ASSERT(zv && zv->zv_open_count > 0);
86 -
87 - /* take zv_suspend_lock before zv_state_lock */
88 - rw_enter(&zv->zv_suspend_lock, RW_READER);
89
90 mutex_enter(&zv->zv_state_lock);
91 - mutex_exit(&zvol_state_lock);
92 -
93 + ASSERT(zv->zv_open_count > 0);
94 /*
95 * make sure zvol is not suspended during last close
96 - * (hold zv_suspend_lock), otherwise, drop the lock
97 + * (hold zv_suspend_lock) and respect proper lock acquisition
98 + * ordering - zv_suspend_lock before zv_state_lock
99 */
100 - if (zv->zv_open_count == 1)
101 - drop_suspend = B_TRUE;
102 - else
103 - rw_exit(&zv->zv_suspend_lock);
104 + if (zv->zv_open_count == 1) {
105 + if (!rw_tryenter(&zv->zv_suspend_lock, RW_READER)) {
106 + mutex_exit(&zv->zv_state_lock);
107 + rw_enter(&zv->zv_suspend_lock, RW_READER);
108 + mutex_enter(&zv->zv_state_lock);
109 + /* check to see if zv_suspend_lock is needed */
110 + if (zv->zv_open_count != 1) {
111 + rw_exit(&zv->zv_suspend_lock);
112 + drop_suspend = B_FALSE;
113 + }
114 + }
115 + } else {
116 + drop_suspend = B_FALSE;
117 + }
118 + mutex_exit(&zvol_state_lock);
119 +
120 + ASSERT(MUTEX_HELD(&zv->zv_state_lock));
121 + ASSERT(zv->zv_open_count != 1 || RW_READ_HELD(&zv->zv_suspend_lock));
122
123 zv->zv_open_count--;
124 if (zv->zv_open_count == 0)