Skip to content

Commit 95c46c3

Browse files
committed
gfs2: Add proper lockspace locking
jira KERNEL-325 Rebuild_History Non-Buildable kernel-4.18.0-553.89.1.el8_10 commit-author Andreas Gruenbacher <agruenba@redhat.com> commit 6ab2655 Empty-Commit: Cherry-Pick Conflicts during history rebuild. Will be included in final tarball splat. Ref for failed cherry-pick at: ciq/ciq_backports/kernel-4.18.0-553.89.1.el8_10/6ab26555.failed GFS2 has been calling functions like dlm_lock() even after the lockspace that these functions operate on has been released with dlm_release_lockspace(). It has always assumed that those functions would return -EINVAL in that case, but that was never guaranteed, and it certainly is no longer the case since commit 4db41bf ("dlm: remove ls_local_handle from struct dlm_ls"). To fix that, add proper lockspace locking. Fixes: 3e11e53 ("GFS2: ignore unlock failures after withdraw") Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Reviewed-by: Andrew Price <anprice@redhat.com> (cherry picked from commit 6ab2655) Signed-off-by: Jonathan Maple <jmaple@ciq.com> # Conflicts: # fs/gfs2/file.c # fs/gfs2/lock_dlm.c
1 parent d0b9331 commit 95c46c3

File tree

1 file changed

+155
-0
lines changed

1 file changed

+155
-0
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
gfs2: Add proper lockspace locking
2+
3+
jira KERNEL-325
4+
Rebuild_History Non-Buildable kernel-4.18.0-553.89.1.el8_10
5+
commit-author Andreas Gruenbacher <agruenba@redhat.com>
6+
commit 6ab26555c9ffef96c56ca16356e55ac5ab61ec93
7+
Empty-Commit: Cherry-Pick Conflicts during history rebuild.
8+
Will be included in final tarball splat. Ref for failed cherry-pick at:
9+
ciq/ciq_backports/kernel-4.18.0-553.89.1.el8_10/6ab26555.failed
10+
11+
GFS2 has been calling functions like dlm_lock() even after the lockspace
12+
that these functions operate on has been released with
13+
dlm_release_lockspace(). It has always assumed that those functions
14+
would return -EINVAL in that case, but that was never guaranteed, and it
15+
certainly is no longer the case since commit 4db41bf4f04f ("dlm: remove
16+
ls_local_handle from struct dlm_ls").
17+
18+
To fix that, add proper lockspace locking.
19+
20+
Fixes: 3e11e5304150 ("GFS2: ignore unlock failures after withdraw")
21+
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
22+
Reviewed-by: Andrew Price <anprice@redhat.com>
23+
(cherry picked from commit 6ab26555c9ffef96c56ca16356e55ac5ab61ec93)
24+
Signed-off-by: Jonathan Maple <jmaple@ciq.com>
25+
26+
# Conflicts:
27+
# fs/gfs2/file.c
28+
# fs/gfs2/lock_dlm.c
29+
diff --cc fs/gfs2/file.c
30+
index dd07e0f60888,bc67fa058c84..000000000000
31+
--- a/fs/gfs2/file.c
32+
+++ b/fs/gfs2/file.c
33+
@@@ -1414,28 -1442,44 +1414,46 @@@ static int gfs2_lock(struct file *file
34+
struct gfs2_inode *ip = GFS2_I(file->f_mapping->host);
35+
struct gfs2_sbd *sdp = GFS2_SB(file->f_mapping->host);
36+
struct lm_lockstruct *ls = &sdp->sd_lockstruct;
37+
+ int ret;
38+
39+
- if (!(fl->c.flc_flags & FL_POSIX))
40+
+ if (!(fl->fl_flags & FL_POSIX))
41+
+ return -ENOLCK;
42+
+ if (__mandatory_lock(&ip->i_inode) && fl->fl_type != F_UNLCK)
43+
return -ENOLCK;
44+
- if (gfs2_withdrawing_or_withdrawn(sdp)) {
45+
- if (lock_is_unlock(fl))
46+
+
47+
+ if (cmd == F_CANCELLK) {
48+
+ /* Hack: */
49+
+ cmd = F_SETLK;
50+
+ fl->fl_type = F_UNLCK;
51+
+ }
52+
+ if (unlikely(gfs2_withdrawn(sdp))) {
53+
+ if (fl->fl_type == F_UNLCK)
54+
locks_lock_file_wait(file, fl);
55+
return -EIO;
56+
}
57+
++<<<<<<< HEAD
58+
+ if (IS_GETLK(cmd))
59+
+ return dlm_posix_get(ls->ls_dlm, ip->i_no_addr, file, fl);
60+
+ else if (fl->fl_type == F_UNLCK)
61+
+ return dlm_posix_unlock(ls->ls_dlm, ip->i_no_addr, file, fl);
62+
+ else
63+
+ return dlm_posix_lock(ls->ls_dlm, ip->i_no_addr, file, cmd, fl);
64+
++=======
65+
+ down_read(&ls->ls_sem);
66+
+ ret = -ENODEV;
67+
+ if (likely(ls->ls_dlm != NULL)) {
68+
+ if (cmd == F_CANCELLK)
69+
+ ret = dlm_posix_cancel(ls->ls_dlm, ip->i_no_addr, file, fl);
70+
+ else if (IS_GETLK(cmd))
71+
+ ret = dlm_posix_get(ls->ls_dlm, ip->i_no_addr, file, fl);
72+
+ else if (lock_is_unlock(fl))
73+
+ ret = dlm_posix_unlock(ls->ls_dlm, ip->i_no_addr, file, fl);
74+
+ else
75+
+ ret = dlm_posix_lock(ls->ls_dlm, ip->i_no_addr, file, cmd, fl);
76+
+ }
77+
+ up_read(&ls->ls_sem);
78+
+ return ret;
79+
-}
80+
-
81+
-static void __flock_holder_uninit(struct file *file, struct gfs2_holder *fl_gh)
82+
-{
83+
- struct gfs2_glock *gl = gfs2_glock_hold(fl_gh->gh_gl);
84+
-
85+
- /*
86+
- * Make sure gfs2_glock_put() won't sleep under the file->f_lock
87+
- * spinlock.
88+
- */
89+
-
90+
- spin_lock(&file->f_lock);
91+
- gfs2_holder_uninit(fl_gh);
92+
- spin_unlock(&file->f_lock);
93+
- gfs2_glock_put(gl);
94+
++>>>>>>> 6ab26555c9ff (gfs2: Add proper lockspace locking)
95+
}
96+
97+
static int do_flock(struct file *file, int cmd, struct file_lock *fl)
98+
diff --cc fs/gfs2/lock_dlm.c
99+
index 0579fdbc9c63,3c7db20ce564..000000000000
100+
--- a/fs/gfs2/lock_dlm.c
101+
+++ b/fs/gfs2/lock_dlm.c
102+
@@@ -334,9 -363,17 +339,19 @@@ static void gdlm_put_lock(struct gfs2_g
103+
return;
104+
}
105+
106+
- if (gl->gl_lksb.sb_lvbptr)
107+
- flags |= DLM_LKF_VALBLK;
108+
-
109+
again:
110+
++<<<<<<< HEAD
111+
+ error = dlm_unlock(ls->ls_dlm, gl->gl_lksb.sb_lkid, DLM_LKF_VALBLK,
112+
+ NULL, gl);
113+
++=======
114+
+ down_read(&ls->ls_sem);
115+
+ error = -ENODEV;
116+
+ if (likely(ls->ls_dlm != NULL)) {
117+
+ error = dlm_unlock(ls->ls_dlm, gl->gl_lksb.sb_lkid, flags,
118+
+ NULL, gl);
119+
+ }
120+
+ up_read(&ls->ls_sem);
121+
++>>>>>>> 6ab26555c9ff (gfs2: Add proper lockspace locking)
122+
if (error == -EBUSY) {
123+
msleep(20);
124+
goto again;
125+
* Unmerged path fs/gfs2/file.c
126+
diff --git a/fs/gfs2/glock.c b/fs/gfs2/glock.c
127+
index de182757764b..8581006a1023 100644
128+
--- a/fs/gfs2/glock.c
129+
+++ b/fs/gfs2/glock.c
130+
@@ -827,9 +827,8 @@ __acquires(&gl->gl_lockref.lock)
131+
}
132+
clear_bit(GLF_PENDING_REPLY, &gl->gl_flags);
133+
134+
- if (ret == -EINVAL && gl->gl_target == LM_ST_UNLOCKED &&
135+
- target == LM_ST_UNLOCKED &&
136+
- test_bit(DFL_UNMOUNT, &ls->ls_recover_flags)) {
137+
+ if (ret == -ENODEV && gl->gl_target == LM_ST_UNLOCKED &&
138+
+ target == LM_ST_UNLOCKED) {
139+
/*
140+
* The lockspace has been released and the lock has
141+
* been unlocked implicitly.
142+
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
143+
index 6eca783f0691..36018c48b8f2 100644
144+
--- a/fs/gfs2/incore.h
145+
+++ b/fs/gfs2/incore.h
146+
@@ -665,6 +665,8 @@ struct lm_lockstruct {
147+
struct completion ls_sync_wait; /* {control,mounted}_{lock,unlock} */
148+
char *ls_lvb_bits;
149+
150+
+ struct rw_semaphore ls_sem;
151+
+
152+
spinlock_t ls_recover_spin; /* protects following fields */
153+
unsigned long ls_recover_flags; /* DFL_ */
154+
uint32_t ls_recover_mount; /* gen in first recover_done cb */
155+
* Unmerged path fs/gfs2/lock_dlm.c

0 commit comments

Comments
 (0)