Various gfs2 fixes

-----BEGIN PGP SIGNATURE-----
 
 iQJIBAABCAAyFiEEJZs3krPW0xkhLMTc1b+f6wMTZToFAmBLgwEUHGFncnVlbmJh
 QHJlZGhhdC5jb20ACgkQ1b+f6wMTZTpzCxAAhp5mbg+/oQ6c4wULu/q0nm2gaPdN
 Bq8DnkOKLAs3Ncd7Ft3nrGkQZQzwCvu3LVxu4zU6hdylCtZnBsYRWI8nOCn4eQKd
 Le2qZcb00awxd/XqzNmtNZwDAfyCLXaPhZJ1mFUL+IWLm/eCW9/Vi0W6YGb4Egs9
 nKCVmBdnvJSeqSSM5RJ2C6bLSwrWLe98n5r5O2uNeBtmvy2fX6A/dbM+3K03YJYJ
 JAwn1awcnSRyOD+UKSYV1mBz6mHaEKGaGmI3TKhpFGEeyOLWi8EASt2O1NDRkllC
 z9UN6H9V70Fuci8pEkP3ju0T4jbVDMv6PfX17Ah7YfHChgH70Rx64NVyCaftNMyu
 zHxHgn4PmSBgF3J5MxMO7kQUjL8OipbvPEMOTwFT4iBC10O2X7/w+hCPI+coEIB8
 w9KsZPl/5ESWdkrlxzQM3fgFUPosp5z0c3rj0gXR6aWbyumSBNWytJogp72LNfX5
 W+w1OH8nmsSJjlzbYrZjcgBsf9RCPBgyWcePL/7t+kKgjG6LlAumFh1cK+seJXBb
 tYp1WFRP2bztXz57rMD5glOc9mysbgUWwgKbvUgj9PPWyT1S/7f4EZhN/GfZWg/h
 fx+dYtlWgLWQkQwEJ1aE8Hqc+hjYxIqnAHo2h725jKpfOIvWPxBZEvztX2SL3wXO
 DtKPBhmyFtPkbR0=
 =6g8z
 -----END PGP SIGNATURE-----

Merge tag 'gfs2-v5.12-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2

Pull gfs2 fixes from Andreas Gruenbacher:
 "Various gfs2 fixes"

* tag 'gfs2-v5.12-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2:
  gfs2: bypass log flush if the journal is not live
  gfs2: bypass signal_our_withdraw if no journal
  gfs2: fix use-after-free in trans_drain
  gfs2: make function gfs2_make_fs_ro() to void type
This commit is contained in:
Linus Torvalds 2021-03-12 11:46:09 -08:00
commit b77b5fdd05
6 changed files with 22 additions and 19 deletions

View file

@ -998,12 +998,16 @@ static void trans_drain(struct gfs2_trans *tr)
while (!list_empty(head)) { while (!list_empty(head)) {
bd = list_first_entry(head, struct gfs2_bufdata, bd_list); bd = list_first_entry(head, struct gfs2_bufdata, bd_list);
list_del_init(&bd->bd_list); list_del_init(&bd->bd_list);
if (!list_empty(&bd->bd_ail_st_list))
gfs2_remove_from_ail(bd);
kmem_cache_free(gfs2_bufdata_cachep, bd); kmem_cache_free(gfs2_bufdata_cachep, bd);
} }
head = &tr->tr_databuf; head = &tr->tr_databuf;
while (!list_empty(head)) { while (!list_empty(head)) {
bd = list_first_entry(head, struct gfs2_bufdata, bd_list); bd = list_first_entry(head, struct gfs2_bufdata, bd_list);
list_del_init(&bd->bd_list); list_del_init(&bd->bd_list);
if (!list_empty(&bd->bd_ail_st_list))
gfs2_remove_from_ail(bd);
kmem_cache_free(gfs2_bufdata_cachep, bd); kmem_cache_free(gfs2_bufdata_cachep, bd);
} }
} }
@ -1032,7 +1036,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)
* Do this check while holding the log_flush_lock to prevent new * Do this check while holding the log_flush_lock to prevent new
* buffers from being added to the ail via gfs2_pin() * buffers from being added to the ail via gfs2_pin()
*/ */
if (gfs2_withdrawn(sdp)) if (gfs2_withdrawn(sdp) || !test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))
goto out; goto out;
/* Log might have been flushed while we waited for the flush lock */ /* Log might have been flushed while we waited for the flush lock */

View file

@ -1539,9 +1539,7 @@ static int gfs2_reconfigure(struct fs_context *fc)
return -EINVAL; return -EINVAL;
if (fc->sb_flags & SB_RDONLY) { if (fc->sb_flags & SB_RDONLY) {
error = gfs2_make_fs_ro(sdp); gfs2_make_fs_ro(sdp);
if (error)
errorfc(fc, "unable to remount read-only");
} else { } else {
error = gfs2_make_fs_rw(sdp); error = gfs2_make_fs_rw(sdp);
if (error) if (error)

View file

@ -587,9 +587,8 @@ static void gfs2_dirty_inode(struct inode *inode, int flags)
* Returns: errno * Returns: errno
*/ */
int gfs2_make_fs_ro(struct gfs2_sbd *sdp) void gfs2_make_fs_ro(struct gfs2_sbd *sdp)
{ {
int error = 0;
int log_write_allowed = test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); int log_write_allowed = test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
gfs2_flush_delete_work(sdp); gfs2_flush_delete_work(sdp);
@ -624,8 +623,6 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
if (!log_write_allowed) if (!log_write_allowed)
sdp->sd_vfs->s_flags |= SB_RDONLY; sdp->sd_vfs->s_flags |= SB_RDONLY;
return error;
} }
/** /**
@ -637,7 +634,6 @@ int gfs2_make_fs_ro(struct gfs2_sbd *sdp)
static void gfs2_put_super(struct super_block *sb) static void gfs2_put_super(struct super_block *sb)
{ {
struct gfs2_sbd *sdp = sb->s_fs_info; struct gfs2_sbd *sdp = sb->s_fs_info;
int error;
struct gfs2_jdesc *jd; struct gfs2_jdesc *jd;
/* No more recovery requests */ /* No more recovery requests */
@ -658,9 +654,7 @@ static void gfs2_put_super(struct super_block *sb)
spin_unlock(&sdp->sd_jindex_spin); spin_unlock(&sdp->sd_jindex_spin);
if (!sb_rdonly(sb)) { if (!sb_rdonly(sb)) {
error = gfs2_make_fs_ro(sdp); gfs2_make_fs_ro(sdp);
if (error)
gfs2_io_error(sdp);
} }
WARN_ON(gfs2_withdrawing(sdp)); WARN_ON(gfs2_withdrawing(sdp));

View file

@ -34,7 +34,7 @@ extern int gfs2_lookup_in_master_dir(struct gfs2_sbd *sdp, char *filename,
struct gfs2_inode **ipp); struct gfs2_inode **ipp);
extern int gfs2_make_fs_rw(struct gfs2_sbd *sdp); extern int gfs2_make_fs_rw(struct gfs2_sbd *sdp);
extern int gfs2_make_fs_ro(struct gfs2_sbd *sdp); extern void gfs2_make_fs_ro(struct gfs2_sbd *sdp);
extern void gfs2_online_uevent(struct gfs2_sbd *sdp); extern void gfs2_online_uevent(struct gfs2_sbd *sdp);
extern int gfs2_statfs_init(struct gfs2_sbd *sdp); extern int gfs2_statfs_init(struct gfs2_sbd *sdp);
extern void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free, extern void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,

View file

@ -169,6 +169,8 @@ static struct gfs2_bufdata *gfs2_alloc_bufdata(struct gfs2_glock *gl,
bd->bd_bh = bh; bd->bd_bh = bh;
bd->bd_gl = gl; bd->bd_gl = gl;
INIT_LIST_HEAD(&bd->bd_list); INIT_LIST_HEAD(&bd->bd_list);
INIT_LIST_HEAD(&bd->bd_ail_st_list);
INIT_LIST_HEAD(&bd->bd_ail_gl_list);
bh->b_private = bd; bh->b_private = bd;
return bd; return bd;
} }

View file

@ -119,17 +119,22 @@ void gfs2_freeze_unlock(struct gfs2_holder *freeze_gh)
static void signal_our_withdraw(struct gfs2_sbd *sdp) static void signal_our_withdraw(struct gfs2_sbd *sdp)
{ {
struct gfs2_glock *live_gl = sdp->sd_live_gh.gh_gl; struct gfs2_glock *live_gl = sdp->sd_live_gh.gh_gl;
struct inode *inode = sdp->sd_jdesc->jd_inode; struct inode *inode;
struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_inode *ip;
struct gfs2_glock *i_gl = ip->i_gl; struct gfs2_glock *i_gl;
u64 no_formal_ino = ip->i_no_formal_ino; u64 no_formal_ino;
int log_write_allowed = test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags); int log_write_allowed = test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
int ret = 0; int ret = 0;
int tries; int tries;
if (test_bit(SDF_NORECOVERY, &sdp->sd_flags)) if (test_bit(SDF_NORECOVERY, &sdp->sd_flags) || !sdp->sd_jdesc)
return; return;
inode = sdp->sd_jdesc->jd_inode;
ip = GFS2_I(inode);
i_gl = ip->i_gl;
no_formal_ino = ip->i_no_formal_ino;
/* Prevent any glock dq until withdraw recovery is complete */ /* Prevent any glock dq until withdraw recovery is complete */
set_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags); set_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags);
/* /*
@ -156,7 +161,7 @@ static void signal_our_withdraw(struct gfs2_sbd *sdp)
ret = 0; ret = 0;
} }
if (!ret) if (!ret)
ret = gfs2_make_fs_ro(sdp); gfs2_make_fs_ro(sdp);
gfs2_freeze_unlock(&freeze_gh); gfs2_freeze_unlock(&freeze_gh);
} }