Merge tag 'gfs2-v5.14-rc2-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 31 Aug 2021 17:20:14 +0000 (10:20 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 31 Aug 2021 17:20:14 +0000 (10:20 -0700)
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

13 files changed:
fs/gfs2/aops.c
fs/gfs2/glock.c
fs/gfs2/glops.c
fs/gfs2/incore.h
fs/gfs2/lock_dlm.c
fs/gfs2/log.c
fs/gfs2/lops.c
fs/gfs2/meta_io.c
fs/gfs2/ops_fstype.c
fs/gfs2/super.c
fs/gfs2/super.h
fs/gfs2/util.c
fs/gfs2/util.h

index 81d8f06..005e920 100644 (file)
@@ -574,10 +574,9 @@ void adjust_fs_space(struct inode *inode)
 {
        struct gfs2_sbd *sdp = GFS2_SB(inode);
        struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
-       struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
        struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
        struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
-       struct buffer_head *m_bh, *l_bh;
+       struct buffer_head *m_bh;
        u64 fs_total, new_free;
 
        if (gfs2_trans_begin(sdp, 2 * RES_STATFS, 0) != 0)
@@ -600,11 +599,7 @@ void adjust_fs_space(struct inode *inode)
                (unsigned long long)new_free);
        gfs2_statfs_change(sdp, new_free, new_free, 0);
 
-       if (gfs2_meta_inode_buffer(l_ip, &l_bh) != 0)
-               goto out2;
-       update_statfs(sdp, m_bh, l_bh);
-       brelse(l_bh);
-out2:
+       update_statfs(sdp, m_bh);
        brelse(m_bh);
 out:
        sdp->sd_rindex_uptodate = 0;
index 1f3902e..e0eaa9c 100644 (file)
@@ -1494,12 +1494,11 @@ void gfs2_glock_dq(struct gfs2_holder *gh)
 
        list_del_init(&gh->gh_list);
        clear_bit(HIF_HOLDER, &gh->gh_iflags);
-       if (find_first_holder(gl) == NULL) {
-               if (list_empty(&gl->gl_holders) &&
-                   !test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
-                   !test_bit(GLF_DEMOTE, &gl->gl_flags))
-                       fast_path = 1;
-       }
+       if (list_empty(&gl->gl_holders) &&
+           !test_bit(GLF_PENDING_DEMOTE, &gl->gl_flags) &&
+           !test_bit(GLF_DEMOTE, &gl->gl_flags))
+               fast_path = 1;
+
        if (!test_bit(GLF_LFLUSH, &gl->gl_flags) && demote_ok(gl))
                gfs2_glock_add_to_lru(gl);
 
@@ -2077,8 +2076,6 @@ static const char *hflags2str(char *buf, u16 flags, unsigned long iflags)
                *p++ = 'H';
        if (test_bit(HIF_WAIT, &iflags))
                *p++ = 'W';
-       if (test_bit(HIF_FIRST, &iflags))
-               *p++ = 'F';
        *p = 0;
        return buf;
 }
index 54d3fbe..79c621c 100644 (file)
@@ -33,16 +33,18 @@ extern struct workqueue_struct *gfs2_control_wq;
 
 static void gfs2_ail_error(struct gfs2_glock *gl, const struct buffer_head *bh)
 {
-       fs_err(gl->gl_name.ln_sbd,
+       struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
+
+       fs_err(sdp,
               "AIL buffer %p: blocknr %llu state 0x%08lx mapping %p page "
               "state 0x%lx\n",
               bh, (unsigned long long)bh->b_blocknr, bh->b_state,
               bh->b_page->mapping, bh->b_page->flags);
-       fs_err(gl->gl_name.ln_sbd, "AIL glock %u:%llu mapping %p\n",
+       fs_err(sdp, "AIL glock %u:%llu mapping %p\n",
               gl->gl_name.ln_type, gl->gl_name.ln_number,
               gfs2_glock2aspace(gl));
-       gfs2_lm(gl->gl_name.ln_sbd, "AIL error\n");
-       gfs2_withdraw(gl->gl_name.ln_sbd);
+       gfs2_lm(sdp, "AIL error\n");
+       gfs2_withdraw_delayed(sdp);
 }
 
 /**
@@ -610,16 +612,13 @@ static int freeze_go_xmote_bh(struct gfs2_glock *gl)
                j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
 
                error = gfs2_find_jhead(sdp->sd_jdesc, &head, false);
-               if (error)
-                       gfs2_consist(sdp);
-               if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT))
-                       gfs2_consist(sdp);
-
-               /*  Initialize some head of the log stuff  */
-               if (!gfs2_withdrawn(sdp)) {
-                       sdp->sd_log_sequence = head.lh_sequence + 1;
-                       gfs2_log_pointers_init(sdp, head.lh_blkno);
-               }
+               if (gfs2_assert_withdraw_delayed(sdp, !error))
+                       return error;
+               if (gfs2_assert_withdraw_delayed(sdp, head.lh_flags &
+                                                GFS2_LOG_HEAD_UNMOUNT))
+                       return -EIO;
+               sdp->sd_log_sequence = head.lh_sequence + 1;
+               gfs2_log_pointers_init(sdp, head.lh_blkno);
        }
        return 0;
 }
index e6f820f..0fe4977 100644 (file)
@@ -253,7 +253,6 @@ struct gfs2_lkstats {
 enum {
        /* States */
        HIF_HOLDER              = 6,  /* Set for gh that "holds" the glock */
-       HIF_FIRST               = 7,
        HIF_WAIT                = 10,
 };
 
@@ -768,6 +767,7 @@ struct gfs2_sbd {
        struct gfs2_glock *sd_jinode_gl;
 
        struct gfs2_holder sd_sc_gh;
+       struct buffer_head *sd_sc_bh;
        struct gfs2_holder sd_qc_gh;
 
        struct completion sd_journal_ready;
index dac0401..50578f8 100644 (file)
@@ -299,6 +299,11 @@ static void gdlm_put_lock(struct gfs2_glock *gl)
        gfs2_sbstats_inc(gl, GFS2_LKS_DCOUNT);
        gfs2_update_request_times(gl);
 
+       /* don't want to call dlm if we've unmounted the lock protocol */
+       if (test_bit(DFL_UNMOUNT, &ls->ls_recover_flags)) {
+               gfs2_glock_free(gl);
+               return;
+       }
        /* don't want to skip dlm_unlock writing the lvb when lock has one */
 
        if (test_bit(SDF_SKIP_DLM_UNLOCK, &sdp->sd_flags) &&
index 42c15cf..f0ee3ff 100644 (file)
@@ -594,7 +594,7 @@ void gfs2_log_reserve(struct gfs2_sbd *sdp, struct gfs2_trans *tr,
 {
        unsigned int blks = tr->tr_reserved;
        unsigned int revokes = tr->tr_revokes;
-       unsigned int revoke_blks = 0;
+       unsigned int revoke_blks;
 
        *extra_revokes = 0;
        if (revokes) {
index 8ee05d2..ca0bb3a 100644 (file)
@@ -761,6 +761,32 @@ static void buf_lo_before_scan(struct gfs2_jdesc *jd,
        jd->jd_replayed_blocks = 0;
 }
 
+#define obsolete_rgrp_replay \
+"Replaying 0x%llx from jid=%d/0x%llx but we already have a bh!\n"
+#define obsolete_rgrp_replay2 \
+"busy:%d, pinned:%d rg_gen:0x%llx, j_gen:0x%llx\n"
+
+static void obsolete_rgrp(struct gfs2_jdesc *jd, struct buffer_head *bh_log,
+                         u64 blkno)
+{
+       struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
+       struct gfs2_rgrpd *rgd;
+       struct gfs2_rgrp *jrgd = (struct gfs2_rgrp *)bh_log->b_data;
+
+       rgd = gfs2_blk2rgrpd(sdp, blkno, false);
+       if (rgd && rgd->rd_addr == blkno &&
+           rgd->rd_bits && rgd->rd_bits->bi_bh) {
+               fs_info(sdp, obsolete_rgrp_replay, (unsigned long long)blkno,
+                       jd->jd_jid, bh_log->b_blocknr);
+               fs_info(sdp, obsolete_rgrp_replay2,
+                       buffer_busy(rgd->rd_bits->bi_bh) ? 1 : 0,
+                       buffer_pinned(rgd->rd_bits->bi_bh),
+                       rgd->rd_igeneration,
+                       be64_to_cpu(jrgd->rg_igeneration));
+               gfs2_dump_glock(NULL, rgd->rd_gl, true);
+       }
+}
+
 static int buf_lo_scan_elements(struct gfs2_jdesc *jd, u32 start,
                                struct gfs2_log_descriptor *ld, __be64 *ptr,
                                int pass)
@@ -799,21 +825,9 @@ static int buf_lo_scan_elements(struct gfs2_jdesc *jd, u32 start,
                        struct gfs2_meta_header *mh =
                                (struct gfs2_meta_header *)bh_ip->b_data;
 
-                       if (mh->mh_type == cpu_to_be32(GFS2_METATYPE_RG)) {
-                               struct gfs2_rgrpd *rgd;
-
-                               rgd = gfs2_blk2rgrpd(sdp, blkno, false);
-                               if (rgd && rgd->rd_addr == blkno &&
-                                   rgd->rd_bits && rgd->rd_bits->bi_bh) {
-                                       fs_info(sdp, "Replaying 0x%llx but we "
-                                               "already have a bh!\n",
-                                               (unsigned long long)blkno);
-                                       fs_info(sdp, "busy:%d, pinned:%d\n",
-                                               buffer_busy(rgd->rd_bits->bi_bh) ? 1 : 0,
-                                               buffer_pinned(rgd->rd_bits->bi_bh));
-                                       gfs2_dump_glock(NULL, rgd->rd_gl, true);
-                               }
-                       }
+                       if (mh->mh_type == cpu_to_be32(GFS2_METATYPE_RG))
+                               obsolete_rgrp(jd, bh_log, blkno);
+
                        mark_buffer_dirty(bh_ip);
                }
                brelse(bh_log);
index 7c96199..72d30a6 100644 (file)
@@ -258,8 +258,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
        struct buffer_head *bh, *bhs[2];
        int num = 0;
 
-       if (unlikely(gfs2_withdrawn(sdp)) &&
-           (!sdp->sd_jdesc || gl != sdp->sd_jinode_gl)) {
+       if (unlikely(gfs2_withdrawn(sdp)) && !gfs2_withdraw_in_prog(sdp)) {
                *bhp = NULL;
                return -EIO;
        }
@@ -317,7 +316,7 @@ int gfs2_meta_read(struct gfs2_glock *gl, u64 blkno, int flags,
 
 int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh)
 {
-       if (unlikely(gfs2_withdrawn(sdp)))
+       if (unlikely(gfs2_withdrawn(sdp)) && !gfs2_withdraw_in_prog(sdp))
                return -EIO;
 
        wait_on_buffer(bh);
@@ -328,7 +327,7 @@ int gfs2_meta_wait(struct gfs2_sbd *sdp, struct buffer_head *bh)
                        gfs2_io_error_bh_wd(sdp, bh);
                return -EIO;
        }
-       if (unlikely(gfs2_withdrawn(sdp)))
+       if (unlikely(gfs2_withdrawn(sdp)) && !gfs2_withdraw_in_prog(sdp))
                return -EIO;
 
        return 0;
index 5f4504d..7f8410d 100644 (file)
@@ -614,6 +614,7 @@ static int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh)
                        break;
                }
 
+               d_mark_dontcache(jd->jd_inode);
                spin_lock(&sdp->sd_jindex_spin);
                jd->jd_jid = sdp->sd_journals++;
                jip = GFS2_I(jd->jd_inode);
@@ -677,6 +678,7 @@ static int init_statfs(struct gfs2_sbd *sdp)
                        error = PTR_ERR(lsi->si_sc_inode);
                        fs_err(sdp, "can't find local \"sc\" file#%u: %d\n",
                               jd->jd_jid, error);
+                       kfree(lsi);
                        goto free_local;
                }
                lsi->si_jid = jd->jd_jid;
@@ -695,8 +697,16 @@ static int init_statfs(struct gfs2_sbd *sdp)
                fs_err(sdp, "can't lock local \"sc\" file: %d\n", error);
                goto free_local;
        }
+       /* read in the local statfs buffer - other nodes don't change it. */
+       error = gfs2_meta_inode_buffer(ip, &sdp->sd_sc_bh);
+       if (error) {
+               fs_err(sdp, "Cannot read in local statfs: %d\n", error);
+               goto unlock_sd_gh;
+       }
        return 0;
 
+unlock_sd_gh:
+       gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
 free_local:
        free_local_statfs_inodes(sdp);
        iput(pn);
@@ -710,6 +720,7 @@ out:
 static void uninit_statfs(struct gfs2_sbd *sdp)
 {
        if (!sdp->sd_args.ar_spectator) {
+               brelse(sdp->sd_sc_bh);
                gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
                free_local_statfs_inodes(sdp);
        }
@@ -1088,6 +1099,34 @@ void gfs2_online_uevent(struct gfs2_sbd *sdp)
        kobject_uevent_env(&sdp->sd_kobj, KOBJ_ONLINE, envp);
 }
 
+static int init_threads(struct gfs2_sbd *sdp)
+{
+       struct task_struct *p;
+       int error = 0;
+
+       p = kthread_run(gfs2_logd, sdp, "gfs2_logd");
+       if (IS_ERR(p)) {
+               error = PTR_ERR(p);
+               fs_err(sdp, "can't start logd thread: %d\n", error);
+               return error;
+       }
+       sdp->sd_logd_process = p;
+
+       p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad");
+       if (IS_ERR(p)) {
+               error = PTR_ERR(p);
+               fs_err(sdp, "can't start quotad thread: %d\n", error);
+               goto fail;
+       }
+       sdp->sd_quotad_process = p;
+       return 0;
+
+fail:
+       kthread_stop(sdp->sd_logd_process);
+       sdp->sd_logd_process = NULL;
+       return error;
+}
+
 /**
  * gfs2_fill_super - Read in superblock
  * @sb: The VFS superblock
@@ -1216,6 +1255,14 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
                goto fail_per_node;
        }
 
+       if (!sb_rdonly(sb)) {
+               error = init_threads(sdp);
+               if (error) {
+                       gfs2_withdraw_delayed(sdp);
+                       goto fail_per_node;
+               }
+       }
+
        error = gfs2_freeze_lock(sdp, &freeze_gh, 0);
        if (error)
                goto fail_per_node;
@@ -1225,6 +1272,12 @@ static int gfs2_fill_super(struct super_block *sb, struct fs_context *fc)
 
        gfs2_freeze_unlock(&freeze_gh);
        if (error) {
+               if (sdp->sd_quotad_process)
+                       kthread_stop(sdp->sd_quotad_process);
+               sdp->sd_quotad_process = NULL;
+               if (sdp->sd_logd_process)
+                       kthread_stop(sdp->sd_logd_process);
+               sdp->sd_logd_process = NULL;
                fs_err(sdp, "can't make FS RW: %d\n", error);
                goto fail_per_node;
        }
index 4d4ceb0..6e00d15 100644 (file)
@@ -119,34 +119,6 @@ int gfs2_jdesc_check(struct gfs2_jdesc *jd)
        return 0;
 }
 
-static int init_threads(struct gfs2_sbd *sdp)
-{
-       struct task_struct *p;
-       int error = 0;
-
-       p = kthread_run(gfs2_logd, sdp, "gfs2_logd");
-       if (IS_ERR(p)) {
-               error = PTR_ERR(p);
-               fs_err(sdp, "can't start logd thread: %d\n", error);
-               return error;
-       }
-       sdp->sd_logd_process = p;
-
-       p = kthread_run(gfs2_quotad, sdp, "gfs2_quotad");
-       if (IS_ERR(p)) {
-               error = PTR_ERR(p);
-               fs_err(sdp, "can't start quotad thread: %d\n", error);
-               goto fail;
-       }
-       sdp->sd_quotad_process = p;
-       return 0;
-
-fail:
-       kthread_stop(sdp->sd_logd_process);
-       sdp->sd_logd_process = NULL;
-       return error;
-}
-
 /**
  * gfs2_make_fs_rw - Turn a Read-Only FS into a Read-Write one
  * @sdp: the filesystem
@@ -161,26 +133,17 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
        struct gfs2_log_header_host head;
        int error;
 
-       error = init_threads(sdp);
-       if (error) {
-               gfs2_withdraw_delayed(sdp);
-               return error;
-       }
-
        j_gl->gl_ops->go_inval(j_gl, DIO_METADATA);
-       if (gfs2_withdrawn(sdp)) {
-               error = -EIO;
-               goto fail;
-       }
+       if (gfs2_withdrawn(sdp))
+               return -EIO;
 
        error = gfs2_find_jhead(sdp->sd_jdesc, &head, false);
        if (error || gfs2_withdrawn(sdp))
-               goto fail;
+               return error;
 
        if (!(head.lh_flags & GFS2_LOG_HEAD_UNMOUNT)) {
                gfs2_consist(sdp);
-               error = -EIO;
-               goto fail;
+               return -EIO;
        }
 
        /*  Initialize some head of the log stuff  */
@@ -188,20 +151,8 @@ int gfs2_make_fs_rw(struct gfs2_sbd *sdp)
        gfs2_log_pointers_init(sdp, head.lh_blkno);
 
        error = gfs2_quota_init(sdp);
-       if (error || gfs2_withdrawn(sdp))
-               goto fail;
-
-       set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
-
-       return 0;
-
-fail:
-       if (sdp->sd_quotad_process)
-               kthread_stop(sdp->sd_quotad_process);
-       sdp->sd_quotad_process = NULL;
-       if (sdp->sd_logd_process)
-               kthread_stop(sdp->sd_logd_process);
-       sdp->sd_logd_process = NULL;
+       if (!error && !gfs2_withdrawn(sdp))
+               set_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
        return error;
 }
 
@@ -227,9 +178,8 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp)
 {
        struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
        struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
-       struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
        struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
-       struct buffer_head *m_bh, *l_bh;
+       struct buffer_head *m_bh;
        struct gfs2_holder gh;
        int error;
 
@@ -248,21 +198,15 @@ int gfs2_statfs_init(struct gfs2_sbd *sdp)
                                      sizeof(struct gfs2_dinode));
                spin_unlock(&sdp->sd_statfs_spin);
        } else {
-               error = gfs2_meta_inode_buffer(l_ip, &l_bh);
-               if (error)
-                       goto out_m_bh;
-
                spin_lock(&sdp->sd_statfs_spin);
                gfs2_statfs_change_in(m_sc, m_bh->b_data +
                                      sizeof(struct gfs2_dinode));
-               gfs2_statfs_change_in(l_sc, l_bh->b_data +
+               gfs2_statfs_change_in(l_sc, sdp->sd_sc_bh->b_data +
                                      sizeof(struct gfs2_dinode));
                spin_unlock(&sdp->sd_statfs_spin);
 
-               brelse(l_bh);
        }
 
-out_m_bh:
        brelse(m_bh);
 out:
        gfs2_glock_dq_uninit(&gh);
@@ -275,22 +219,17 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
        struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
        struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
        struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
-       struct buffer_head *l_bh;
        s64 x, y;
        int need_sync = 0;
-       int error;
-
-       error = gfs2_meta_inode_buffer(l_ip, &l_bh);
-       if (error)
-               return;
 
-       gfs2_trans_add_meta(l_ip->i_gl, l_bh);
+       gfs2_trans_add_meta(l_ip->i_gl, sdp->sd_sc_bh);
 
        spin_lock(&sdp->sd_statfs_spin);
        l_sc->sc_total += total;
        l_sc->sc_free += free;
        l_sc->sc_dinodes += dinodes;
-       gfs2_statfs_change_out(l_sc, l_bh->b_data + sizeof(struct gfs2_dinode));
+       gfs2_statfs_change_out(l_sc, sdp->sd_sc_bh->b_data +
+                              sizeof(struct gfs2_dinode));
        if (sdp->sd_args.ar_statfs_percent) {
                x = 100 * l_sc->sc_free;
                y = m_sc->sc_free * sdp->sd_args.ar_statfs_percent;
@@ -299,20 +238,18 @@ void gfs2_statfs_change(struct gfs2_sbd *sdp, s64 total, s64 free,
        }
        spin_unlock(&sdp->sd_statfs_spin);
 
-       brelse(l_bh);
        if (need_sync)
                gfs2_wake_up_statfs(sdp);
 }
 
-void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
-                  struct buffer_head *l_bh)
+void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh)
 {
        struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
        struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
        struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
        struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
 
-       gfs2_trans_add_meta(l_ip->i_gl, l_bh);
+       gfs2_trans_add_meta(l_ip->i_gl, sdp->sd_sc_bh);
        gfs2_trans_add_meta(m_ip->i_gl, m_bh);
 
        spin_lock(&sdp->sd_statfs_spin);
@@ -320,7 +257,7 @@ void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
        m_sc->sc_free += l_sc->sc_free;
        m_sc->sc_dinodes += l_sc->sc_dinodes;
        memset(l_sc, 0, sizeof(struct gfs2_statfs_change));
-       memset(l_bh->b_data + sizeof(struct gfs2_dinode),
+       memset(sdp->sd_sc_bh->b_data + sizeof(struct gfs2_dinode),
               0, sizeof(struct gfs2_statfs_change));
        gfs2_statfs_change_out(m_sc, m_bh->b_data + sizeof(struct gfs2_dinode));
        spin_unlock(&sdp->sd_statfs_spin);
@@ -330,11 +267,10 @@ int gfs2_statfs_sync(struct super_block *sb, int type)
 {
        struct gfs2_sbd *sdp = sb->s_fs_info;
        struct gfs2_inode *m_ip = GFS2_I(sdp->sd_statfs_inode);
-       struct gfs2_inode *l_ip = GFS2_I(sdp->sd_sc_inode);
        struct gfs2_statfs_change_host *m_sc = &sdp->sd_statfs_master;
        struct gfs2_statfs_change_host *l_sc = &sdp->sd_statfs_local;
        struct gfs2_holder gh;
-       struct buffer_head *m_bh, *l_bh;
+       struct buffer_head *m_bh;
        int error;
 
        error = gfs2_glock_nq_init(m_ip->i_gl, LM_ST_EXCLUSIVE, GL_NOCACHE,
@@ -355,21 +291,15 @@ int gfs2_statfs_sync(struct super_block *sb, int type)
        }
        spin_unlock(&sdp->sd_statfs_spin);
 
-       error = gfs2_meta_inode_buffer(l_ip, &l_bh);
-       if (error)
-               goto out_bh;
-
        error = gfs2_trans_begin(sdp, 2 * RES_DINODE, 0);
        if (error)
-               goto out_bh2;
+               goto out_bh;
 
-       update_statfs(sdp, m_bh, l_bh);
+       update_statfs(sdp, m_bh);
        sdp->sd_statfs_force_sync = 0;
 
        gfs2_trans_end(sdp);
 
-out_bh2:
-       brelse(l_bh);
 out_bh:
        brelse(m_bh);
 out_unlock:
@@ -675,6 +605,7 @@ restart:
                        gfs2_glock_dq_uninit(&sdp->sd_journal_gh);
                if (gfs2_holder_initialized(&sdp->sd_jinode_gh))
                        gfs2_glock_dq_uninit(&sdp->sd_jinode_gh);
+               brelse(sdp->sd_sc_bh);
                gfs2_glock_dq_uninit(&sdp->sd_sc_gh);
                gfs2_glock_dq_uninit(&sdp->sd_qc_gh);
                free_local_statfs_inodes(sdp);
@@ -1016,7 +947,7 @@ static int gfs2_drop_inode(struct inode *inode)
                gfs2_glock_hold(gl);
                if (!gfs2_queue_delete_work(gl, 0))
                        gfs2_glock_queue_put(gl);
-               return false;
+               return 0;
        }
 
        return generic_drop_inode(inode);
index ec4affb..58d13fd 100644 (file)
@@ -43,8 +43,7 @@ extern void gfs2_statfs_change_in(struct gfs2_statfs_change_host *sc,
                                  const void *buf);
 extern void gfs2_statfs_change_out(const struct gfs2_statfs_change_host *sc,
                                   void *buf);
-extern void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh,
-                         struct buffer_head *l_bh);
+extern void update_statfs(struct gfs2_sbd *sdp, struct buffer_head *m_bh);
 extern int gfs2_statfs_sync(struct super_block *sb, int type);
 extern void gfs2_freeze_func(struct work_struct *work);
 
index f4325b4..cf345a8 100644 (file)
@@ -278,6 +278,7 @@ static void signal_our_withdraw(struct gfs2_sbd *sdp)
                goto skip_recovery;
        }
        sdp->sd_jdesc->jd_inode = inode;
+       d_mark_dontcache(inode);
 
        /*
         * Now wait until recovery is complete.
@@ -295,7 +296,7 @@ skip_recovery:
                fs_warn(sdp, "Journal recovery complete for jid %d.\n",
                        sdp->sd_lockstruct.ls_jid);
        else
-               fs_warn(sdp, "Journal recovery skipped for %d until next "
+               fs_warn(sdp, "Journal recovery skipped for jid %d until next "
                        "mount.\n", sdp->sd_lockstruct.ls_jid);
        fs_warn(sdp, "Glock dequeues delayed: %lu\n", sdp->sd_glock_dqs_held);
        sdp->sd_glock_dqs_held = 0;
index 69e1a0a..78ec190 100644 (file)
@@ -218,6 +218,11 @@ static inline bool gfs2_withdrawing(struct gfs2_sbd *sdp)
               !test_bit(SDF_WITHDRAWN, &sdp->sd_flags);
 }
 
+static inline bool gfs2_withdraw_in_prog(struct gfs2_sbd *sdp)
+{
+       return test_bit(SDF_WITHDRAW_IN_PROG, &sdp->sd_flags);
+}
+
 #define gfs2_tune_get(sdp, field) \
 gfs2_tune_get_i(&(sdp)->sd_tune, &(sdp)->sd_tune.field)