Merge tag 'gfs2-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/steve...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 4 Jun 2014 15:30:10 +0000 (08:30 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 4 Jun 2014 15:30:10 +0000 (08:30 -0700)
Pull gfs2 updates from Steven Whitehouse:
 "This must be about the smallest merge window patch set ever for GFS2.
  It is probably also the first one without a single patch from me.
  That is down to a combination of factors, and I have some things in
  the works that are not quite ready yet, that I hope to put in next
  time around.

  Returning to what is here this time...  we have 3 patches which fix
  various warnings.  Two are bug fixes (for quotas and also a rare
  recovery race condition).  The final patch, from Ben Marzinski, is an
  important change in the freeze code which has been in progress for
  some time.  This removes the need to take and drop the transaction
  lock for every single transaction, when the only time it was used, was
  at file system freeze time.  Ben's patch integrates the freeze
  operation into the journal flush code as an alternative with lower
  overheads and also lands up resolving some difficult to fix races at
  the same time"

* tag 'gfs2-merge-window' of git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-3.0-nmw:
  GFS2: Prevent recovery before the local journal is set
  GFS2: fs/gfs2/file.c: kernel-doc warning fixes
  GFS2: fs/gfs2/bmap.c: kernel-doc warning fixes
  GFS2: remove transaction glock
  GFS2: lops.c: replace 0 by NULL for pointers
  GFS2: quotas not being refreshed in gfs2_adjust_quota

1  2 
fs/gfs2/glops.c
fs/gfs2/recovery.c
fs/gfs2/sys.c

diff --combined fs/gfs2/glops.c
index 74d9a3dbf16fe868826cff848f9fbb1c6e008f17,0b527939c46fe0594f70308d711daf79efda9df4..fc1100781bbc1c954aebfd0d5a0ee317eb707012
@@@ -89,18 -89,23 +89,23 @@@ static void gfs2_ail_empty_gl(struct gf
        if (!tr.tr_revokes)
                return;
  
-       /* A shortened, inline version of gfs2_trans_begin() */
+       /* A shortened, inline version of gfs2_trans_begin()
+          * tr->alloced is not set since the transaction structure is
+          * on the stack */
        tr.tr_reserved = 1 + gfs2_struct2blk(sdp, tr.tr_revokes, sizeof(u64));
        tr.tr_ip = (unsigned long)__builtin_return_address(0);
        sb_start_intwrite(sdp->sd_vfs);
-       gfs2_log_reserve(sdp, tr.tr_reserved);
+       if (gfs2_log_reserve(sdp, tr.tr_reserved) < 0) {
+               sb_end_intwrite(sdp->sd_vfs);
+               return;
+       }
        WARN_ON_ONCE(current->journal_info);
        current->journal_info = &tr;
  
        __gfs2_ail_flush(gl, 0, tr.tr_revokes);
  
        gfs2_trans_end(sdp);
-       gfs2_log_flush(sdp, NULL);
+       gfs2_log_flush(sdp, NULL, NORMAL_FLUSH);
  }
  
  void gfs2_ail_flush(struct gfs2_glock *gl, bool fsync)
                return;
        __gfs2_ail_flush(gl, fsync, max_revokes);
        gfs2_trans_end(sdp);
-       gfs2_log_flush(sdp, NULL);
+       gfs2_log_flush(sdp, NULL, NORMAL_FLUSH);
  }
  
  /**
@@@ -144,7 -149,7 +149,7 @@@ static void rgrp_go_sync(struct gfs2_gl
                return;
        GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE);
  
-       gfs2_log_flush(sdp, gl);
+       gfs2_log_flush(sdp, gl, NORMAL_FLUSH);
        filemap_fdatawrite_range(mapping, gl->gl_vm.start, gl->gl_vm.end);
        error = filemap_fdatawait_range(mapping, gl->gl_vm.start, gl->gl_vm.end);
        mapping_set_error(mapping, error);
@@@ -206,7 -211,7 +211,7 @@@ static void inode_go_sync(struct gfs2_g
  
        GLOCK_BUG_ON(gl, gl->gl_state != LM_ST_EXCLUSIVE);
  
-       gfs2_log_flush(gl->gl_sbd, gl);
+       gfs2_log_flush(gl->gl_sbd, gl, NORMAL_FLUSH);
        filemap_fdatawrite(metamapping);
        if (ip) {
                struct address_space *mapping = ip->i_inode.i_mapping;
         * Writeback of the data mapping may cause the dirty flag to be set
         * so we have to clear it again here.
         */
 -      smp_mb__before_clear_bit();
 +      smp_mb__before_atomic();
        clear_bit(GLF_DIRTY, &gl->gl_flags);
  }
  
@@@ -253,7 -258,7 +258,7 @@@ static void inode_go_inval(struct gfs2_
        }
  
        if (ip == GFS2_I(gl->gl_sbd->sd_rindex)) {
-               gfs2_log_flush(gl->gl_sbd, NULL);
+               gfs2_log_flush(gl->gl_sbd, NULL, NORMAL_FLUSH);
                gl->gl_sbd->sd_rindex_uptodate = 0;
        }
        if (ip && S_ISREG(ip->i_inode.i_mode))
@@@ -455,31 -460,39 +460,39 @@@ static void inode_go_dump(struct seq_fi
  }
  
  /**
-  * trans_go_sync - promote/demote the transaction glock
+  * freeze_go_sync - promote/demote the freeze glock
   * @gl: the glock
   * @state: the requested state
   * @flags:
   *
   */
  
- static void trans_go_sync(struct gfs2_glock *gl)
+ static void freeze_go_sync(struct gfs2_glock *gl)
  {
        struct gfs2_sbd *sdp = gl->gl_sbd;
+       DEFINE_WAIT(wait);
  
-       if (gl->gl_state != LM_ST_UNLOCKED &&
+       if (gl->gl_state == LM_ST_SHARED &&
            test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags)) {
-               gfs2_meta_syncfs(sdp);
-               gfs2_log_shutdown(sdp);
+               atomic_set(&sdp->sd_log_freeze, 1);
+               wake_up(&sdp->sd_logd_waitq);
+               do {
+                       prepare_to_wait(&sdp->sd_log_frozen_wait, &wait,
+                                       TASK_UNINTERRUPTIBLE);
+                       if (atomic_read(&sdp->sd_log_freeze))
+                               io_schedule();
+               } while(atomic_read(&sdp->sd_log_freeze));
+               finish_wait(&sdp->sd_log_frozen_wait, &wait);
        }
  }
  
  /**
-  * trans_go_xmote_bh - After promoting/demoting the transaction glock
+  * freeze_go_xmote_bh - After promoting/demoting the freeze glock
   * @gl: the glock
   *
   */
  
- static int trans_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh)
+ static int freeze_go_xmote_bh(struct gfs2_glock *gl, struct gfs2_holder *gh)
  {
        struct gfs2_sbd *sdp = gl->gl_sbd;
        struct gfs2_inode *ip = GFS2_I(sdp->sd_jdesc->jd_inode);
   * Always returns 0
   */
  
- static int trans_go_demote_ok(const struct gfs2_glock *gl)
+ static int freeze_go_demote_ok(const struct gfs2_glock *gl)
  {
        return 0;
  }
@@@ -563,10 -576,10 +576,10 @@@ const struct gfs2_glock_operations gfs2
        .go_flags = GLOF_LVB,
  };
  
- const struct gfs2_glock_operations gfs2_trans_glops = {
-       .go_sync = trans_go_sync,
-       .go_xmote_bh = trans_go_xmote_bh,
-       .go_demote_ok = trans_go_demote_ok,
+ const struct gfs2_glock_operations gfs2_freeze_glops = {
+       .go_sync = freeze_go_sync,
+       .go_xmote_bh = freeze_go_xmote_bh,
+       .go_demote_ok = freeze_go_demote_ok,
        .go_type = LM_TYPE_NONDISK,
  };
  
diff --combined fs/gfs2/recovery.c
index fe7a56fb608476215aaba6188885ee70e9c44341,a4ed78b5f47e844c87307490bd9c3bef320f48ac..94555d4c5698ac6d4b35aff6ede657e4c432f386
@@@ -454,7 -454,7 +454,7 @@@ void gfs2_recover_func(struct work_stru
        struct gfs2_inode *ip = GFS2_I(jd->jd_inode);
        struct gfs2_sbd *sdp = GFS2_SB(jd->jd_inode);
        struct gfs2_log_header_host head;
-       struct gfs2_holder j_gh, ji_gh, t_gh;
+       struct gfs2_holder j_gh, ji_gh, thaw_gh;
        unsigned long t;
        int ro = 0;
        unsigned int pass;
  
                t = jiffies;
  
-               /* Acquire a shared hold on the transaction lock */
+               /* Acquire a shared hold on the freeze lock */
  
-               error = gfs2_glock_nq_init(sdp->sd_trans_gl, LM_ST_SHARED,
-                                          LM_FLAG_NOEXP | LM_FLAG_PRIORITY |
-                                          GL_NOCACHE, &t_gh);
+               error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_SHARED,
+                                          LM_FLAG_NOEXP | LM_FLAG_PRIORITY,
+                                          &thaw_gh);
                if (error)
                        goto fail_gunlock_ji;
  
                        fs_warn(sdp, "jid=%u: Can't replay: read-only block "
                                "device\n", jd->jd_jid);
                        error = -EROFS;
-                       goto fail_gunlock_tr;
+                       goto fail_gunlock_thaw;
                }
  
                fs_info(sdp, "jid=%u: Replaying journal...\n", jd->jd_jid);
                                                   head.lh_blkno, pass);
                        lops_after_scan(jd, error, pass);
                        if (error)
-                               goto fail_gunlock_tr;
+                               goto fail_gunlock_thaw;
                }
  
                error = clean_journal(jd, &head);
                if (error)
-                       goto fail_gunlock_tr;
+                       goto fail_gunlock_thaw;
  
-               gfs2_glock_dq_uninit(&t_gh);
+               gfs2_glock_dq_uninit(&thaw_gh);
                t = DIV_ROUND_UP(jiffies - t, HZ);
                fs_info(sdp, "jid=%u: Journal replayed in %lus\n",
                        jd->jd_jid, t);
        fs_info(sdp, "jid=%u: Done\n", jd->jd_jid);
        goto done;
  
- fail_gunlock_tr:
-       gfs2_glock_dq_uninit(&t_gh);
+ fail_gunlock_thaw:
+       gfs2_glock_dq_uninit(&thaw_gh);
  fail_gunlock_ji:
        if (jlocked) {
                gfs2_glock_dq_uninit(&ji_gh);
@@@ -587,7 -587,7 +587,7 @@@ fail
        gfs2_recovery_done(sdp, jd->jd_jid, LM_RD_GAVEUP);
  done:
        clear_bit(JDF_RECOVERY, &jd->jd_flags);
 -      smp_mb__after_clear_bit();
 +      smp_mb__after_atomic();
        wake_up_bit(&jd->jd_flags, JDF_RECOVERY);
  }
  
diff --combined fs/gfs2/sys.c
index 529d9a9eb89765093969837fba6cf44fb374f38e,0e049f9574b565a53f1137036568d62ddcb0d7c8..3ab566ba5696eb73db835f237a26a4334a4dbccc
@@@ -240,8 -240,8 +240,8 @@@ static ssize_t demote_rq_store(struct g
  
        if (gltype > LM_TYPE_JOURNAL)
                return -EINVAL;
-       if (gltype == LM_TYPE_NONDISK && glnum == GFS2_TRANS_LOCK)
-               glops = &gfs2_trans_glops;
+       if (gltype == LM_TYPE_NONDISK && glnum == GFS2_FREEZE_LOCK)
+               glops = &gfs2_freeze_glops;
        else
                glops = gfs2_glops_list[gltype];
        if (glops == NULL)
@@@ -333,7 -333,7 +333,7 @@@ static ssize_t block_store(struct gfs2_
                set_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
        else if (val == 0) {
                clear_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
 -              smp_mb__after_clear_bit();
 +              smp_mb__after_atomic();
                gfs2_glock_thaw(sdp);
        } else {
                ret = -EINVAL;
@@@ -407,6 -407,9 +407,9 @@@ int gfs2_recover_set(struct gfs2_sbd *s
        struct gfs2_jdesc *jd;
        int rv;
  
+       /* Wait for our primary journal to be initialized */
+       wait_for_completion(&sdp->sd_journal_ready);
        spin_lock(&sdp->sd_jindex_spin);
        rv = -EBUSY;
        if (sdp->sd_jdesc->jd_jid == jid)
@@@ -482,7 -485,7 +485,7 @@@ static ssize_t jid_store(struct gfs2_sb
                rv = jid = -EINVAL;
        sdp->sd_lockstruct.ls_jid = jid;
        clear_bit(SDF_NOJOURNALID, &sdp->sd_flags);
 -      smp_mb__after_clear_bit();
 +      smp_mb__after_atomic();
        wake_up_bit(&sdp->sd_flags, SDF_NOJOURNALID);
  out:
        spin_unlock(&sdp->sd_jindex_spin);