Skip to content

Commit 77a2dc8

Browse files
committed
gfs2: Fix unlinked inode cleanup
jira LE-3201 Rebuild_History Non-Buildable kernel-rt-4.18.0-553.27.1.rt7.368.el8_10 commit-author Andreas Gruenbacher <agruenba@redhat.com> commit 7c6f714 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-rt-4.18.0-553.27.1.rt7.368.el8_10/7c6f714d.failed Before commit f0e56ed ("gfs2: Split the two kinds of glock "delete" work"), function delete_work_func() was used to trigger the eviction of in-memory inodes from remote as well as deleting unlinked inodes at a later point. These two kinds of work were then split into two kinds of work, and the two places in the code were deferred deletion of inodes is required accidentally ended up queuing the wrong kind of work. This caused unlinked inodes to be left behind, which could in the worst case fill up filesystems and require a filesystem check to recover. Fix that by queuing the right kind of work in try_rgrp_unlink() and gfs2_drop_inode(). Fixes: f0e56ed ("gfs2: Split the two kinds of glock "delete" work") Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> (cherry picked from commit 7c6f714) Signed-off-by: Jonathan Maple <jmaple@ciq.com> # Conflicts: # fs/gfs2/glock.c # fs/gfs2/glock.h # fs/gfs2/super.c
1 parent 3b99996 commit 77a2dc8

File tree

1 file changed

+139
-0
lines changed

1 file changed

+139
-0
lines changed
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
gfs2: Fix unlinked inode cleanup
2+
3+
jira LE-3201
4+
Rebuild_History Non-Buildable kernel-rt-4.18.0-553.27.1.rt7.368.el8_10
5+
commit-author Andreas Gruenbacher <agruenba@redhat.com>
6+
commit 7c6f714d88475ceae5342264858a641eafa19632
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-rt-4.18.0-553.27.1.rt7.368.el8_10/7c6f714d.failed
10+
11+
Before commit f0e56edc2ec7 ("gfs2: Split the two kinds of glock "delete"
12+
work"), function delete_work_func() was used to trigger the eviction of
13+
in-memory inodes from remote as well as deleting unlinked inodes at a
14+
later point. These two kinds of work were then split into two kinds of
15+
work, and the two places in the code were deferred deletion of inodes is
16+
required accidentally ended up queuing the wrong kind of work. This
17+
caused unlinked inodes to be left behind, which could in the worst case
18+
fill up filesystems and require a filesystem check to recover.
19+
20+
Fix that by queuing the right kind of work in try_rgrp_unlink() and
21+
gfs2_drop_inode().
22+
23+
Fixes: f0e56edc2ec7 ("gfs2: Split the two kinds of glock "delete" work")
24+
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
25+
(cherry picked from commit 7c6f714d88475ceae5342264858a641eafa19632)
26+
Signed-off-by: Jonathan Maple <jmaple@ciq.com>
27+
28+
# Conflicts:
29+
# fs/gfs2/glock.c
30+
# fs/gfs2/glock.h
31+
# fs/gfs2/super.c
32+
diff --cc fs/gfs2/glock.c
33+
index 0881a898d05f,9273ec5345ed..000000000000
34+
--- a/fs/gfs2/glock.c
35+
+++ b/fs/gfs2/glock.c
36+
@@@ -977,9 -1012,10 +977,13 @@@ bool gfs2_queue_try_to_evict(struct gfs
37+
&gl->gl_delete, 0);
38+
}
39+
40+
++<<<<<<< HEAD
41+
+static bool gfs2_queue_verify_delete(struct gfs2_glock *gl)
42+
++=======
43+
+ bool gfs2_queue_verify_delete(struct gfs2_glock *gl, bool later)
44+
++>>>>>>> 7c6f714d8847 (gfs2: Fix unlinked inode cleanup)
45+
{
46+
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
47+
- unsigned long delay;
48+
49+
if (test_and_set_bit(GLF_VERIFY_DELETE, &gl->gl_flags))
50+
return false;
51+
diff --cc fs/gfs2/glock.h
52+
index c0ed1817ac0b,63e101d448e9..000000000000
53+
--- a/fs/gfs2/glock.h
54+
+++ b/fs/gfs2/glock.h
55+
@@@ -252,28 -242,28 +252,42 @@@ static inline int gfs2_glock_nq_init(st
56+
return error;
57+
}
58+
59+
++<<<<<<< HEAD
60+
+extern void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state);
61+
+extern void gfs2_glock_complete(struct gfs2_glock *gl, int ret);
62+
+extern bool gfs2_queue_try_to_evict(struct gfs2_glock *gl);
63+
+extern void gfs2_cancel_delete_work(struct gfs2_glock *gl);
64+
+extern void gfs2_flush_delete_work(struct gfs2_sbd *sdp);
65+
+extern void gfs2_gl_hash_clear(struct gfs2_sbd *sdp);
66+
+extern void gfs2_gl_dq_holders(struct gfs2_sbd *sdp);
67+
+extern void gfs2_glock_thaw(struct gfs2_sbd *sdp);
68+
+extern void gfs2_glock_add_to_lru(struct gfs2_glock *gl);
69+
+extern void gfs2_glock_free(struct gfs2_glock *gl);
70+
+extern void gfs2_glock_free_later(struct gfs2_glock *gl);
71+
++=======
72+
+ void gfs2_glock_cb(struct gfs2_glock *gl, unsigned int state);
73+
+ void gfs2_glock_complete(struct gfs2_glock *gl, int ret);
74+
+ bool gfs2_queue_try_to_evict(struct gfs2_glock *gl);
75+
+ bool gfs2_queue_verify_delete(struct gfs2_glock *gl, bool later);
76+
+ void gfs2_cancel_delete_work(struct gfs2_glock *gl);
77+
+ void gfs2_flush_delete_work(struct gfs2_sbd *sdp);
78+
+ void gfs2_gl_hash_clear(struct gfs2_sbd *sdp);
79+
+ void gfs2_gl_dq_holders(struct gfs2_sbd *sdp);
80+
+ void gfs2_glock_thaw(struct gfs2_sbd *sdp);
81+
+ void gfs2_glock_free(struct gfs2_glock *gl);
82+
+ void gfs2_glock_free_later(struct gfs2_glock *gl);
83+
++>>>>>>> 7c6f714d8847 (gfs2: Fix unlinked inode cleanup)
84+
85+
-int __init gfs2_glock_init(void);
86+
-void gfs2_glock_exit(void);
87+
+extern int __init gfs2_glock_init(void);
88+
+extern void gfs2_glock_exit(void);
89+
90+
-void gfs2_create_debugfs_file(struct gfs2_sbd *sdp);
91+
-void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp);
92+
-void gfs2_register_debugfs(void);
93+
-void gfs2_unregister_debugfs(void);
94+
+extern void gfs2_create_debugfs_file(struct gfs2_sbd *sdp);
95+
+extern void gfs2_delete_debugfs_file(struct gfs2_sbd *sdp);
96+
+extern void gfs2_register_debugfs(void);
97+
+extern void gfs2_unregister_debugfs(void);
98+
99+
-void glock_set_object(struct gfs2_glock *gl, void *object);
100+
-void glock_clear_object(struct gfs2_glock *gl, void *object);
101+
+extern void glock_set_object(struct gfs2_glock *gl, void *object);
102+
+extern void glock_clear_object(struct gfs2_glock *gl, void *object);
103+
104+
extern const struct lm_lockops gfs2_dlm_ops;
105+
106+
diff --cc fs/gfs2/super.c
107+
index 544721b9078a,e22c1edc32b3..000000000000
108+
--- a/fs/gfs2/super.c
109+
+++ b/fs/gfs2/super.c
110+
@@@ -1066,8 -1045,8 +1066,13 @@@ static int gfs2_drop_inode(struct inod
111+
struct gfs2_glock *gl = ip->i_iopen_gh.gh_gl;
112+
113+
gfs2_glock_hold(gl);
114+
++<<<<<<< HEAD
115+
+ if (!gfs2_queue_try_to_evict(gl))
116+
+ gfs2_glock_queue_put(gl);
117+
++=======
118+
+ if (!gfs2_queue_verify_delete(gl, true))
119+
+ gfs2_glock_put_async(gl);
120+
++>>>>>>> 7c6f714d8847 (gfs2: Fix unlinked inode cleanup)
121+
return 0;
122+
}
123+
124+
* Unmerged path fs/gfs2/glock.c
125+
* Unmerged path fs/gfs2/glock.h
126+
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
127+
index 89d829045308..4f0923da8abc 100644
128+
--- a/fs/gfs2/rgrp.c
129+
+++ b/fs/gfs2/rgrp.c
130+
@@ -1882,7 +1882,7 @@ static void try_rgrp_unlink(struct gfs2_rgrpd *rgd, u64 *last_unlinked, u64 skip
131+
*/
132+
ip = gl->gl_object;
133+
134+
- if (ip || !gfs2_queue_try_to_evict(gl))
135+
+ if (ip || !gfs2_queue_verify_delete(gl, false))
136+
gfs2_glock_put(gl);
137+
else
138+
found++;
139+
* Unmerged path fs/gfs2/super.c

0 commit comments

Comments
 (0)