Skip to content

Commit 4529fb1

Browse files
committed
Merge tag 'gfs2-v5.14-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2
Pull gfs2 updates from Andreas Gruenbacher: - Various withdraw related fixes (freeze glock recursion, thread initialization / destruction order, journal recovery, glock cleanup, withdraw under journal lock). - Some error message improvements. - Various minor cleanups. * tag 'gfs2-v5.14-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2: gfs2: Remove redundant check from gfs2_glock_dq gfs2: Delay withdraw from atomic context gfs2: Don't call dlm after protocol is unmounted gfs2: don't stop reads while withdraw in progress gfs2: Mark journal inodes as "don't cache" gfs2: nit: gfs2_drop_inode shouldn't return bool gfs2: Eliminate vestigial HIF_FIRST gfs2: Make recovery error more readable gfs2: Don't release and reacquire local statfs bh gfs2: init system threads before freeze lock gfs2: tiny cleanup in gfs2_log_reserve gfs2: trivial clean up of gfs2_ail_error gfs2: be more verbose replaying invalid rgrp blocks gfs2: Fix glock recursion in freeze_go_xmote_bh gfs2: Fix memory leak of object lsi on error return path
2 parents cd35820 + 08d7366 commit 4529fb1

File tree

13 files changed

+139
-141
lines changed

13 files changed

+139
-141
lines changed

fs/gfs2/aops.c

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -574,10 +574,9 @@ void adjust_fs_space(struct inode *inode)
574574
{
575575
struct gfs2_sbd *sdp = GFS2_SB(inode);
576576
struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
577-
struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
578577
struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
579578
struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
580-
struct buffer_head *m_bh, *l_bh;
579+
struct buffer_head *m_bh;
581580
u64 fs_total, new_free;
582581

583582
if (gfs2_trans_begin(sdp, 2 * RES_STATFS, 0) != 0)
@@ -600,11 +599,7 @@ void adjust_fs_space(struct inode *inode)
600599
(unsigned long long)new_free);
601600
gfs2_statfs_change(sdp, new_free, new_free, 0);
602601

603-
if (gfs2_meta_inode_buffer(l_ip, &l_bh) != 0)
604-
goto out2;
605-
update_statfs(sdp, m_bh, l_bh);
606-
brelse(l_bh);
607-
out2:
602+
update_statfs(sdp, m_bh);
608603
brelse(m_bh);
609604
out:
610605
sdp->sd_rindex_uptodate = 0;

fs/gfs2/glock.c

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,12 +1494,11 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
14941494

14951495
list_del_init(&gh->gh_list);
14961496
clear_bit(HIF_HOLDER, &gh->gh_iflags);
1497-
if (find_first_holder(gl) == NULL) {
1498-
if (list_empty(&gl->gl_holders) &&
1499-
!test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
1500-
!test_bit(GLF_DEMOTE, &gl->gl_flags))
1501-
fast_path = 1;
1502-
}
1497+
if (list_empty(&gl->gl_holders) &&
1498+
!test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
1499+
!test_bit(GLF_DEMOTE, &gl->gl_flags))
1500+
fast_path = 1;
1501+
15031502
if (!test_bit(GLF_LFLUSH, &gl->gl_flags) && demote_ok(gl))
15041503
gfs2_glock_add_to_lru(gl);
15051504

@@ -2077,8 +2076,6 @@ static const char *hflags2str(char *buf, u16 flags, unsigned long iflags)
20772076
*p++ = 'H';
20782077
if (test_bit(HIF_WAIT, &iflags))
20792078
*p++ = 'W';
2080-
if (test_bit(HIF_FIRST, &iflags))
2081-
*p++ = 'F';
20822079
*p = 0;
20832080
return buf;
20842081
}

fs/gfs2/glops.c

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,16 +33,18 @@ extern struct workqueue_struct *gfs2_control_wq;
3333

3434
static void gfs2_ail_error(struct gfs2_glock *gl, const struct buffer_head *bh)
3535
{
36-
fs_err(gl->gl_name.ln_sbd,
36+
struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
37+
38+
fs_err(sdp,
3739
"AIL buffer %p: blocknr %llu state 0x%08lx mapping %p page "
3840
"state 0x%lx\n",
3941
bh, (unsigned long long)bh->b_blocknr, bh->b_state,
4042
bh->b_page->mapping, bh->b_page->flags);
41-
fs_err(gl->gl_name.ln_sbd, "AIL glock %u:%llu mapping %p\n",
43+
fs_err(sdp, "AIL glock %u:%llu mapping %p\n",
4244
gl->gl_name.ln_type, gl->gl_name.ln_number,
4345
gfs2_glock2aspace(gl));
44-
gfs2_lm(gl->gl_name.ln_sbd, "AIL error\n");
45-
gfs2_withdraw(gl->gl_name.ln_sbd);
46+
gfs2_lm(sdp, "AIL error\n");
47+
gfs2_withdraw_delayed(sdp);
4648
}
4749

4850
/**
@@ -610,16 +612,13 @@ static int freeze_go_xmote_bh(struct gfs2_glock *gl)
610612
j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
611613

612614
error = gfs2_find_jhead(sdp->sd_jdesc, &head, false);
613-
if (error)
614-
gfs2_consist(sdp);
615-
if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT))
616-
gfs2_consist(sdp);
617-
618-
/* Initialize some head of the log stuff */
619-
if (!gfs2_withdrawn(sdp)) {
620-
sdp->sd_log_sequence = head.lh_sequence + 1;
621-
gfs2_log_pointers_init(sdp, head.lh_blkno);
622-
}
615+
if (gfs2_assert_withdraw_delayed(sdp, !error))
616+
return error;
617+
if (gfs2_assert_withdraw_delayed(sdp, head.lh_flags &
618+
GFS2_LOG_HEAD_UNMOUNT))
619+
return -EIO;
620+
sdp->sd_log_sequence = head.lh_sequence + 1;
621+
gfs2_log_pointers_init(sdp, head.lh_blkno);
623622
}
624623
return 0;
625624
}

fs/gfs2/incore.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,6 @@ struct gfs2_lkstats {
253253
enum {
254254
/* States */
255255
HIF_HOLDER = 6, /* Set for gh that "holds" the glock */
256-
HIF_FIRST = 7,
257256
HIF_WAIT = 10,
258257
};
259258

@@ -768,6 +767,7 @@ struct gfs2_sbd {
768767
struct gfs2_glock *sd_jinode_gl;
769768

770769
struct gfs2_holder sd_sc_gh;
770+
struct buffer_head *sd_sc_bh;
771771
struct gfs2_holder sd_qc_gh;
772772

773773
struct completion sd_journal_ready;

fs/gfs2/lock_dlm.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,11 @@ static void gdlm_put_lock(struct gfs2_glock *gl)
299299
gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT);
300300
gfs2_update_request_times(gl);
301301

302+
/* don't want to call dlm if we've unmounted the lock protocol */
303+
if (test_bit(DFL_UNMOUNT, &ls->ls_recover_flags)) {
304+
gfs2_glock_free(gl);
305+
return;
306+
}
302307
/* don't want to skip dlm_unlock writing the lvb when lock has one */
303308

304309
if (test_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags) &&

fs/gfs2/log.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ void gfs2_log_reserve(struct gfs2_sbd *sdp, struct gfs2_trans *tr,
594594
{
595595
unsigned int blks = tr->tr_reserved;
596596
unsigned int revokes = tr->tr_revokes;
597-
unsigned int revoke_blks = 0;
597+
unsigned int revoke_blks;
598598

599599
*extra_revokes = 0;
600600
if (revokes) {

fs/gfs2/lops.c

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,32 @@ static void buf_lo_before_scan(struct gfs2_jdesc *jd,
761761
jd->jd_replayed_blocks = 0;
762762
}
763763

764+
#define obsolete_rgrp_replay \
765+
"Replaying 0x%llx from jid=%d/0x%llx but we already have a bh!\n"
766+
#define obsolete_rgrp_replay2 \
767+
"busy:%d, pinned:%d rg_gen:0x%llx, j_gen:0x%llx\n"
768+
769+
static void obsolete_rgrp(struct gfs2_jdesc *jd, struct buffer_head *bh_log,
770+
u64 blkno)
771+
{
772+
struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
773+
struct gfs2_rgrpd *rgd;
774+
struct gfs2_rgrp *jrgd = (struct gfs2_rgrp *)bh_log->b_data;
775+
776+
rgd = gfs2_blk2rgrpd(sdp, blkno, false);
777+
if (rgd && rgd->rd_addr == blkno &&
778+
rgd->rd_bits && rgd->rd_bits->bi_bh) {
779+
fs_info(sdp, obsolete_rgrp_replay, (unsigned long long)blkno,
780+
jd->jd_jid, bh_log->b_blocknr);
781+
fs_info(sdp, obsolete_rgrp_replay2,
782+
buffer_busy(rgd->rd_bits->bi_bh) ? 1 : 0,
783+
buffer_pinned(rgd->rd_bits->bi_bh),
784+
rgd->rd_igeneration,
785+
be64_to_cpu(jrgd->rg_igeneration));
786+
gfs2_dump_glock(NULL, rgd->rd_gl, true);
787+
}
788+
}
789+
764790
static int buf_lo_scan_elements(struct gfs2_jdesc *jd, u32 start,
765791
struct gfs2_log_descriptor *ld, __be64 *ptr,
766792
int pass)
@@ -799,21 +825,9 @@ static int buf_lo_scan_elements(struct gfs2_jdesc *jd, u32 start,
799825
struct gfs2_meta_header *mh =
800826
(struct gfs2_meta_header *)bh_ip->b_data;
801827

802-
if (mh->mh_type == cpu_to_be32(GFS2_METATYPE_RG)) {
803-
struct gfs2_rgrpd *rgd;
804-
805-
rgd = gfs2_blk2rgrpd(sdp, blkno, false);
806-
if (rgd && rgd->rd_addr == blkno &&
807-
rgd->rd_bits && rgd->rd_bits->bi_bh) {
808-
fs_info(sdp, "Replaying 0x%llx but we "
809-
"already have a bh!\n",
810-
(unsigned long long)blkno);
811-
fs_info(sdp, "busy:%d, pinned:%d\n",
812-
buffer_busy(rgd->rd_bits->bi_bh) ? 1 : 0,
813-
buffer_pinned(rgd->rd_bits->bi_bh));
814-
gfs2_dump_glock(NULL, rgd->rd_gl, true);
815-
}
816-
}
828+
if (mh->mh_type == cpu_to_be32(GFS2_METATYPE_RG))
829+
obsolete_rgrp(jd, bh_log, blkno);
830+
817831
mark_buffer_dirty(bh_ip);
818832
}
819833
brelse(bh_log);

fs/gfs2/meta_io.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
258258
struct buffer_head *bh, *bhs[2];
259259
int num = 0;
260260

261-
if (unlikely(gfs2_withdrawn(sdp)) &&
262-
(!sdp->sd_jdesc || gl != sdp->sd_jinode_gl)) {
261+
if (unlikely(gfs2_withdrawn(sdp)) && !gfs2_withdraw_in_prog(sdp)) {
263262
*bhp = NULL;
264263
return -EIO;
265264
}
@@ -317,7 +316,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
317316

318317
int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh)
319318
{
320-
if (unlikely(gfs2_withdrawn(sdp)))
319+
if (unlikely(gfs2_withdrawn(sdp)) && !gfs2_withdraw_in_prog(sdp))
321320
return -EIO;
322321

323322
wait_on_buffer(bh);
@@ -328,7 +327,7 @@ int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh)
328327
gfs2_io_error_bh_wd(sdp, bh);
329328
return -EIO;
330329
}
331-
if (unlikely(gfs2_withdrawn(sdp)))
330+
if (unlikely(gfs2_withdrawn(sdp)) && !gfs2_withdraw_in_prog(sdp))
332331
return -EIO;
333332

334333
return 0;

fs/gfs2/ops_fstype.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -614,6 +614,7 @@ static int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
614614
break;
615615
}
616616

617+
d_mark_dontcache(jd->jd_inode);
617618
spin_lock(&sdp->sd_jindex_spin);
618619
jd->jd_jid = sdp->sd_journals++;
619620
jip = GFS2_I(jd->jd_inode);
@@ -677,6 +678,7 @@ static int init_statfs(struct gfs2_sbd *sdp)
677678
error = PTR_ERR(lsi->si_sc_inode);
678679
fs_err(sdp, "can't find local \"sc\" file#%u: %d\n",
679680
jd->jd_jid, error);
681+
kfree(lsi);
680682
goto free_local;
681683
}
682684
lsi->si_jid = jd->jd_jid;
@@ -695,8 +697,16 @@ static int init_statfs(struct gfs2_sbd *sdp)
695697
fs_err(sdp, "can't lock local \"sc\" file: %d\n", error);
696698
goto free_local;
697699
}
700+
/* read in the local statfs buffer - other nodes don't change it. */
701+
error = gfs2_meta_inode_buffer(ip, &sdp->sd_sc_bh);
702+
if (error) {
703+
fs_err(sdp, "Cannot read in local statfs: %d\n", error);
704+
goto unlock_sd_gh;
705+
}
698706
return 0;
699707

708+
unlock_sd_gh:
709+
gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
700710
free_local:
701711
free_local_statfs_inodes(sdp);
702712
iput(pn);
@@ -710,6 +720,7 @@ static int init_statfs(struct gfs2_sbd *sdp)
710720
static void uninit_statfs(struct gfs2_sbd *sdp)
711721
{
712722
if (!sdp->sd_args.ar_spectator) {
723+
brelse(sdp->sd_sc_bh);
713724
gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
714725
free_local_statfs_inodes(sdp);
715726
}
@@ -1088,6 +1099,34 @@ void gfs2_online_uevent(struct gfs2_sbd *sdp)
10881099
kobject_uevent_env(&sdp->sd_kobj, KOBJ_ONLINE, envp);
10891100
}
10901101

1102+
static int init_threads(struct gfs2_sbd *sdp)
1103+
{
1104+
struct task_struct *p;
1105+
int error = 0;
1106+
1107+
p = kthread_run(gfs2_logd, sdp, "gfs2_logd");
1108+
if (IS_ERR(p)) {
1109+
error = PTR_ERR(p);
1110+
fs_err(sdp, "can't start logd thread: %d\n", error);
1111+
return error;
1112+
}
1113+
sdp->sd_logd_process = p;
1114+
1115+
p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad");
1116+
if (IS_ERR(p)) {
1117+
error = PTR_ERR(p);
1118+
fs_err(sdp, "can't start quotad thread: %d\n", error);
1119+
goto fail;
1120+
}
1121+
sdp->sd_quotad_process = p;
1122+
return 0;
1123+
1124+
fail:
1125+
kthread_stop(sdp->sd_logd_process);
1126+
sdp->sd_logd_process = NULL;
1127+
return error;
1128+
}
1129+
10911130
/**
10921131
* gfs2_fill_super - Read in superblock
10931132
* @sb: The VFS superblock
@@ -1216,6 +1255,14 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
12161255
goto fail_per_node;
12171256
}
12181257

1258+
if (!sb_rdonly(sb)) {
1259+
error = init_threads(sdp);
1260+
if (error) {
1261+
gfs2_withdraw_delayed(sdp);
1262+
goto fail_per_node;
1263+
}
1264+
}
1265+
12191266
error = gfs2_freeze_lock(sdp, &freeze_gh, 0);
12201267
if (error)
12211268
goto fail_per_node;
@@ -1225,6 +1272,12 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
12251272

12261273
gfs2_freeze_unlock(&freeze_gh);
12271274
if (error) {
1275+
if (sdp->sd_quotad_process)
1276+
kthread_stop(sdp->sd_quotad_process);
1277+
sdp->sd_quotad_process = NULL;
1278+
if (sdp->sd_logd_process)
1279+
kthread_stop(sdp->sd_logd_process);
1280+
sdp->sd_logd_process = NULL;
12281281
fs_err(sdp, "can't make FS RW: %d\n", error);
12291282
goto fail_per_node;
12301283
}

0 commit comments

Comments
 (0)