Skip to content

Commit 8334890

Browse files
author
Andreas Gruenbacher
committed
gfs2: Clean up SDF_JOURNAL_LIVE flag handling
Change do_withdraw() to clear the SDF_JOURNAL_LIVE flag under the log flush lock. In addition, change __gfs2_trans_begin() to check if the filesystem is already known to be withdrawn using gfs2_withdrawn(). Then, once we are holding the log flush lock, check if the SDF_JOURNAL_LIVE flag is still set. This second check ensures that the filesystem will remain live until the transaction is submitted. With these changes, it is no longer useful to clear SDF_JOURNAL_LIVE in gfs2_end_log_write() after calling gfs2_withdraw(). Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
1 parent 16c3197 commit 8334890

3 files changed

Lines changed: 33 additions & 36 deletions

File tree

fs/gfs2/lops.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,9 +210,6 @@ static void gfs2_end_log_write(struct bio *bio)
210210
fs_err(sdp, "Error %d writing to journal, jid=%u\n",
211211
err, sdp->sd_jdesc->jd_jid);
212212
gfs2_withdraw(sdp);
213-
/* prevent more writes to the journal */
214-
clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
215-
wake_up(&sdp->sd_logd_waitq);
216213
}
217214

218215
bio_for_each_segment_all(bvec, bio, iter_all) {

fs/gfs2/trans.c

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ int __gfs2_trans_begin(struct gfs2_trans *tr, struct gfs2_sbd *sdp,
4949
}
5050
BUG_ON(blocks == 0 && revokes == 0);
5151

52-
if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))
52+
if (gfs2_withdrawn(sdp))
5353
return -EROFS;
5454

5555
tr->tr_ip = ip;
@@ -85,25 +85,30 @@ int __gfs2_trans_begin(struct gfs2_trans *tr, struct gfs2_sbd *sdp,
8585
*/
8686

8787
down_read(&sdp->sd_log_flush_lock);
88+
if (unlikely(!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)))
89+
goto out_not_live;
8890
if (gfs2_log_try_reserve(sdp, tr, &extra_revokes))
8991
goto reserved;
92+
9093
up_read(&sdp->sd_log_flush_lock);
9194
gfs2_log_reserve(sdp, tr, &extra_revokes);
9295
down_read(&sdp->sd_log_flush_lock);
93-
94-
reserved:
95-
gfs2_log_release_revokes(sdp, extra_revokes);
9696
if (unlikely(!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))) {
97-
gfs2_log_release_revokes(sdp, tr->tr_revokes);
98-
up_read(&sdp->sd_log_flush_lock);
97+
revokes = tr->tr_revokes + extra_revokes;
98+
gfs2_log_release_revokes(sdp, revokes);
9999
gfs2_log_release(sdp, tr->tr_reserved);
100-
sb_end_intwrite(sdp->sd_vfs);
101-
return -EROFS;
100+
goto out_not_live;
102101
}
103102

103+
reserved:
104+
gfs2_log_release_revokes(sdp, extra_revokes);
104105
current->journal_info = tr;
105-
106106
return 0;
107+
108+
out_not_live:
109+
up_read(&sdp->sd_log_flush_lock);
110+
sb_end_intwrite(sdp->sd_vfs);
111+
return -EROFS;
107112
}
108113

109114
int gfs2_trans_begin(struct gfs2_sbd *sdp, unsigned int blocks,

fs/gfs2/util.c

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -117,35 +117,30 @@ void gfs2_freeze_unlock(struct gfs2_sbd *sdp)
117117

118118
static void do_withdraw(struct gfs2_sbd *sdp)
119119
{
120+
down_write(&sdp->sd_log_flush_lock);
121+
if (!test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
122+
up_write(&sdp->sd_log_flush_lock);
123+
return;
124+
}
125+
clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
126+
up_write(&sdp->sd_log_flush_lock);
127+
120128
gfs2_ail_drain(sdp); /* frees all transactions */
121129

122-
/*
123-
* Don't tell dlm we're bailing until we have no more buffers in the
124-
* wind. If journal had an IO error, the log code should just purge
125-
* the outstanding buffers rather than submitting new IO.
126-
*
127-
* During a normal unmount, gfs2_make_fs_ro calls gfs2_log_shutdown
128-
* which clears SDF_JOURNAL_LIVE. In a withdraw, we must not write
129-
* any UNMOUNT log header, so we can't call gfs2_log_shutdown, and
130-
* therefore we need to clear SDF_JOURNAL_LIVE manually.
131-
*/
132-
clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
133-
if (!sb_rdonly(sdp->sd_vfs)) {
134-
wake_up(&sdp->sd_logd_waitq);
135-
wake_up(&sdp->sd_quota_wait);
130+
wake_up(&sdp->sd_logd_waitq);
131+
wake_up(&sdp->sd_quota_wait);
136132

137-
wait_event_timeout(sdp->sd_log_waitq,
138-
gfs2_log_is_empty(sdp),
139-
HZ * 5);
133+
wait_event_timeout(sdp->sd_log_waitq,
134+
gfs2_log_is_empty(sdp),
135+
HZ * 5);
140136

141-
sdp->sd_vfs->s_flags |= SB_RDONLY;
137+
sdp->sd_vfs->s_flags |= SB_RDONLY;
142138

143-
/*
144-
* Dequeue any pending non-system glock holders that can no
145-
* longer be granted because the file system is withdrawn.
146-
*/
147-
gfs2_withdraw_glocks(sdp);
148-
}
139+
/*
140+
* Dequeue any pending non-system glock holders that can no
141+
* longer be granted because the file system is withdrawn.
142+
*/
143+
gfs2_withdraw_glocks(sdp);
149144
}
150145

151146
void gfs2_lm(struct gfs2_sbd *sdp, const char *fmt, ...)

0 commit comments

Comments
 (0)