Skip to content

Commit e4199dc

Browse files
committed
gfs2: init system threads before freeze lock
jira LE-1907 Rebuild_History Non-Buildable kernel-4.18.0-477.27.1.el8_8 commit-author Bob Peterson <rpeterso@redhat.com> commit a28dc12 Patch 96b1454 ("gfs2: move freeze glock outside the make_fs_rw and _ro functions") changed the gfs2 mount sequence so that it holds the freeze lock before calling gfs2_make_fs_rw. Before this patch, gfs2_make_fs_rw called init_threads to initialize the quotad and logd threads. That is a problem if the system needs to withdraw due to IO errors early in the mount sequence, for example, while initializing the system statfs inode: 1. An IO error causes the statfs glock to not sync properly after recovery, and leaves items on the ail list. 2. The leftover items on the ail list causes its do_xmote call to fail, which makes it want to withdraw. But since the glock code cannot withdraw (because the withdraw sequence uses glocks) it relies upon the logd daemon to initiate the withdraw. 3. The withdraw can never be performed by the logd daemon because all this takes place before the logd daemon is started. This patch moves function init_threads from super.c to ops_fstype.c and it changes gfs2_fill_super to start its threads before holding the freeze lock, and if there's an error, stop its threads after releasing it. This allows the logd to run unblocked by the freeze lock. Thus, the logd daemon can perform its withdraw sequence properly. Fixes: 96b1454 ("gfs2: move freeze glock outside the make_fs_rw and _ro functions") Signed-off-by: Bob Peterson <rpeterso@redhat.com> (cherry picked from commit a28dc12) Signed-off-by: Jonathan Maple <jmaple@ciq.com>
1 parent 31deac6 commit e4199dc

File tree

2 files changed

+48
-55
lines changed

2 files changed

+48
-55
lines changed

fs/gfs2/ops_fstype.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,34 @@ void gfs2_online_uevent(struct gfs2_sbd *sdp)
10761076
kobject_uevent_env(&sdp->sd_kobj, KOBJ_ONLINE, envp);
10771077
}
10781078

1079+
static int init_threads(struct gfs2_sbd *sdp)
1080+
{
1081+
struct task_struct *p;
1082+
int error = 0;
1083+
1084+
p = kthread_run(gfs2_logd, sdp, "gfs2_logd");
1085+
if (IS_ERR(p)) {
1086+
error = PTR_ERR(p);
1087+
fs_err(sdp, "can't start logd thread: %d\n", error);
1088+
return error;
1089+
}
1090+
sdp->sd_logd_process = p;
1091+
1092+
p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad");
1093+
if (IS_ERR(p)) {
1094+
error = PTR_ERR(p);
1095+
fs_err(sdp, "can't start quotad thread: %d\n", error);
1096+
goto fail;
1097+
}
1098+
sdp->sd_quotad_process = p;
1099+
return 0;
1100+
1101+
fail:
1102+
kthread_stop(sdp->sd_logd_process);
1103+
sdp->sd_logd_process = NULL;
1104+
return error;
1105+
}
1106+
10791107
/**
10801108
* gfs2_fill_super - Read in superblock
10811109
* @sb: The VFS superblock
@@ -1208,6 +1236,14 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
12081236
goto fail_per_node;
12091237
}
12101238

1239+
if (!sb_rdonly(sb)) {
1240+
error = init_threads(sdp);
1241+
if (error) {
1242+
gfs2_withdraw_delayed(sdp);
1243+
goto fail_per_node;
1244+
}
1245+
}
1246+
12111247
error = gfs2_freeze_lock(sdp, &freeze_gh, 0);
12121248
if (error)
12131249
goto fail_per_node;
@@ -1217,6 +1253,12 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
12171253

12181254
gfs2_freeze_unlock(&freeze_gh);
12191255
if (error) {
1256+
if (sdp->sd_quotad_process)
1257+
kthread_stop(sdp->sd_quotad_process);
1258+
sdp->sd_quotad_process = NULL;
1259+
if (sdp->sd_logd_process)
1260+
kthread_stop(sdp->sd_logd_process);
1261+
sdp->sd_logd_process = NULL;
12201262
fs_err(sdp, "can't make FS RW: %d\n", error);
12211263
goto fail_per_node;
12221264
}

fs/gfs2/super.c

Lines changed: 6 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -122,34 +122,6 @@ int gfs2_jdesc_check(struct gfs2_jdesc *jd)
122122
return 0;
123123
}
124124

125-
static int init_threads(struct gfs2_sbd *sdp)
126-
{
127-
struct task_struct *p;
128-
int error = 0;
129-
130-
p = kthread_run(gfs2_logd, sdp, "gfs2_logd");
131-
if (IS_ERR(p)) {
132-
error = PTR_ERR(p);
133-
fs_err(sdp, "can't start logd thread: %d\n", error);
134-
return error;
135-
}
136-
sdp->sd_logd_process = p;
137-
138-
p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad");
139-
if (IS_ERR(p)) {
140-
error = PTR_ERR(p);
141-
fs_err(sdp, "can't start quotad thread: %d\n", error);
142-
goto fail;
143-
}
144-
sdp->sd_quotad_process = p;
145-
return 0;
146-
147-
fail:
148-
kthread_stop(sdp->sd_logd_process);
149-
sdp->sd_logd_process = NULL;
150-
return error;
151-
}
152-
153125
/**
154126
* gfs2_make_fs_rw - Turn a Read-Only FS into a Read-Write one
155127
* @sdp: the filesystem
@@ -164,47 +136,26 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
164136
struct gfs2_log_header_host head;
165137
int error;
166138

167-
error = init_threads(sdp);
168-
if (error) {
169-
gfs2_withdraw_delayed(sdp);
170-
return error;
171-
}
172-
173139
j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
174-
if (gfs2_withdrawn(sdp)) {
175-
error = -EIO;
176-
goto fail;
177-
}
140+
if (gfs2_withdrawn(sdp))
141+
return -EIO;
178142

179143
error = gfs2_find_jhead(sdp->sd_jdesc, &head, false);
180144
if (error || gfs2_withdrawn(sdp))
181-
goto fail;
145+
return error;
182146

183147
if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) {
184148
gfs2_consist(sdp);
185-
error = -EIO;
186-
goto fail;
149+
return -EIO;
187150
}
188151

189152
/* Initialize some head of the log stuff */
190153
sdp->sd_log_sequence = head.lh_sequence + 1;
191154
gfs2_log_pointers_init(sdp, head.lh_blkno);
192155

193156
error = gfs2_quota_init(sdp);
194-
if (error || gfs2_withdrawn(sdp))
195-
goto fail;
196-
197-
set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
198-
199-
return 0;
200-
201-
fail:
202-
if (sdp->sd_quotad_process)
203-
kthread_stop(sdp->sd_quotad_process);
204-
sdp->sd_quotad_process = NULL;
205-
if (sdp->sd_logd_process)
206-
kthread_stop(sdp->sd_logd_process);
207-
sdp->sd_logd_process = NULL;
157+
if (!error && !gfs2_withdrawn(sdp))
158+
set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
208159
return error;
209160
}
210161

0 commit comments

Comments
 (0)