]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
Merge tag 'gfs2-4.13.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 5 Jul 2017 23:57:08 +0000 (16:57 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 5 Jul 2017 23:57:08 +0000 (16:57 -0700)
Pull GFS2 updates from Bob Peterson:
 "We've got eight GFS2 patches for this merge window:

   - Andreas Gruenbacher has four patches related to cleaning up the
     GFS2 inode evict process. This is about half of his patches
     designed to fix a long-standing GFS2 hang related to the inode
     shrinker: Shrinker calls gfs2 evict, evict calls DLM, DLM requires
     memory and blocks on the shrinker.

     These four patches have been well tested. His second set of patches
     are still being tested, so I plan to hold them until the next merge
     window, after we have more weeks of testing. The first patch
     eliminates the flush_delayed_work, which can block.

   - Andreas's second patch protects setting of gl_object for rgrps with
     a spin_lock to prevent proven races.

   - His third patch introduces a centralized mechanism for queueing
     glock work with better reference counting, to prevent more races.

    -His fourth patch retains a reference to inode glocks when an error
     occurs while creating an inode. This keeps the subsequent evict
     from needing to reacquire the glock, which might call into DLM and
     block in low memory conditions.

   - Arvind Yadav has a patch to add const to attribute_group
     structures.

   - I have a patch to detect directory entry inconsistencies and
     withdraw the file system if any are found. Better that than silent
     corruption.

   - I have a patch to remove a vestigial variable from glock
     structures, saving some slab space.

   - I have another patch to remove a vestigial variable from the GFS2
     in-core superblock structure"

* tag 'gfs2-4.13.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/gfs2/linux-gfs2:
  GFS2: constify attribute_group structures.
  gfs2: gfs2_create_inode: Keep glock across iput
  gfs2: Clean up glock work enqueuing
  gfs2: Protect gl->gl_object by spin lock
  gfs2: Get rid of flush_delayed_work in gfs2_evict_inode
  GFS2: Eliminate vestigial sd_log_flush_wrapped
  GFS2: Remove gl_list from glock structure
  GFS2: Withdraw when directory entry inconsistencies are detected

1  2 
fs/gfs2/bmap.c
fs/gfs2/incore.h
fs/gfs2/log.c
fs/gfs2/lops.c
fs/gfs2/sys.c

diff --combined fs/gfs2/bmap.c
index 4d810be532ddcb6d9d18b234383c5167b0780e32,56e2943ff994ce371f51cd5a1665684857ca0993..9fa3aef9a5b358ec7f78fa6fd08f8c6d008611f6
@@@ -970,7 -970,7 +970,7 @@@ more_rgrps
                        continue;
                bn = be64_to_cpu(*p);
                if (gfs2_holder_initialized(rd_gh)) {
-                       rgd = (struct gfs2_rgrpd *)rd_gh->gh_gl->gl_object;
+                       rgd = gfs2_glock2rgrp(rd_gh->gh_gl);
                        gfs2_assert_withdraw(sdp,
                                     gfs2_glock_is_locked_by_me(rd_gh->gh_gl));
                } else {
@@@ -1072,7 -1072,7 +1072,7 @@@ out_unlock
                        /* Every transaction boundary, we rewrite the dinode
                           to keep its di_blocks current in case of failure. */
                        ip->i_inode.i_mtime = ip->i_inode.i_ctime =
 -                              CURRENT_TIME;
 +                              current_time(&ip->i_inode);
                        gfs2_trans_add_meta(ip->i_gl, dibh);
                        gfs2_dinode_out(ip, dibh->b_data);
                        up_write(&ip->i_rw_mutex);
@@@ -1293,7 -1293,7 +1293,7 @@@ static int trunc_dealloc(struct gfs2_in
                gfs2_statfs_change(sdp, 0, +btotal, 0);
                gfs2_quota_change(ip, -(s64)btotal, ip->i_inode.i_uid,
                                  ip->i_inode.i_gid);
 -              ip->i_inode.i_mtime = ip->i_inode.i_ctime = CURRENT_TIME;
 +              ip->i_inode.i_mtime = ip->i_inode.i_ctime = current_time(&ip->i_inode);
                gfs2_trans_add_meta(ip->i_gl, dibh);
                gfs2_dinode_out(ip, dibh->b_data);
                up_write(&ip->i_rw_mutex);
diff --combined fs/gfs2/incore.h
index aa3d44527fa2e92a9372761cc727e3b5c404e785,de4238493d80ef8ad26684c11fbf4eaa46b25662..790e73984288776140fb89036f46ca4dbd4ba837
@@@ -336,7 -336,6 +336,6 @@@ enum 
  };
  
  struct gfs2_glock {
-       struct hlist_bl_node gl_list;
        unsigned long gl_flags;         /* GLF_... */
        struct lm_lockname gl_name;
  
@@@ -386,6 -385,7 +385,7 @@@ enum 
        GIF_SW_PAGED            = 3,
        GIF_ORDERED             = 4,
        GIF_FREE_VFS_INODE      = 5,
+       GIF_GLOP_PENDING        = 6,
  };
  
  struct gfs2_inode {
@@@ -815,12 -815,12 +815,11 @@@ struct gfs2_sbd 
        atomic_t sd_log_in_flight;
        struct bio *sd_log_bio;
        wait_queue_head_t sd_log_flush_wait;
 -      int sd_log_error;
  
        atomic_t sd_reserving_log;
        wait_queue_head_t sd_reserving_log_wait;
  
        unsigned int sd_log_flush_head;
-       u64 sd_log_flush_wrapped;
  
        spinlock_t sd_ail_lock;
        struct list_head sd_ail1_list;
@@@ -857,5 -857,7 +856,7 @@@ static inline void gfs2_sbstats_inc(con
        preempt_enable();
  }
  
+ extern struct gfs2_rgrpd *gfs2_glock2rgrp(struct gfs2_glock *gl);
  #endif /* __INCORE_DOT_H__ */
  
diff --combined fs/gfs2/log.c
index d2955daf17a4fcefa2ded3a412f67732315de12a,32aa1f05c7ea640a6b00a2a79c514f3f3000e338..9a624f6944002af70b75c32c93fc6da1924986f7
@@@ -659,7 -659,7 +659,7 @@@ static void log_write_header(struct gfs
        struct gfs2_log_header *lh;
        unsigned int tail;
        u32 hash;
 -      int op_flags = REQ_PREFLUSH | REQ_FUA | REQ_META;
 +      int op_flags = REQ_PREFLUSH | REQ_FUA | REQ_META | REQ_SYNC;
        struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO);
        enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state);
        lh = page_address(page);
@@@ -722,7 -722,6 +722,6 @@@ void gfs2_log_flush(struct gfs2_sbd *sd
                clear_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags);
  
        sdp->sd_log_flush_head = sdp->sd_log_head;
-       sdp->sd_log_flush_wrapped = 0;
        tr = sdp->sd_log_tr;
        if (tr) {
                sdp->sd_log_tr = NULL;
                        }
                        atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */
                        trace_gfs2_log_blocks(sdp, -1);
-                       sdp->sd_log_flush_wrapped = 0;
                        log_write_header(sdp, 0);
                        sdp->sd_log_head = sdp->sd_log_flush_head;
                }
@@@ -880,7 -878,6 +878,6 @@@ void gfs2_log_shutdown(struct gfs2_sbd 
        gfs2_assert_withdraw(sdp, list_empty(&sdp->sd_ail1_list));
  
        sdp->sd_log_flush_head = sdp->sd_log_head;
-       sdp->sd_log_flush_wrapped = 0;
  
        log_write_header(sdp, GFS2_LOG_HEAD_UNMOUNT);
  
diff --combined fs/gfs2/lops.c
index 885d36e7a29f4ad44e3b9458c158349776fecd50,b50106bf2902dd6413472ba414e59375b328c849..e5259cd92ea4a241081ff593cf125566684bc648
@@@ -71,7 -71,7 +71,7 @@@ static void maybe_release_space(struct 
  {
        struct gfs2_glock *gl = bd->bd_gl;
        struct gfs2_sbd *sdp = gl->gl_name.ln_sbd;
-       struct gfs2_rgrpd *rgd = gl->gl_object;
+       struct gfs2_rgrpd *rgd = gfs2_glock2rgrp(gl);
        unsigned int index = bd->bd_bh->b_blocknr - gl->gl_name.ln_number;
        struct gfs2_bitmap *bi = rgd->rd_bits + index;
  
@@@ -134,10 -134,8 +134,8 @@@ static void gfs2_log_incr_head(struct g
        BUG_ON((sdp->sd_log_flush_head == sdp->sd_log_tail) &&
               (sdp->sd_log_flush_head != sdp->sd_log_head));
  
-       if (++sdp->sd_log_flush_head == sdp->sd_jdesc->jd_blocks) {
+       if (++sdp->sd_log_flush_head == sdp->sd_jdesc->jd_blocks)
                sdp->sd_log_flush_head = 0;
-               sdp->sd_log_flush_wrapped = 1;
-       }
  }
  
  static u64 gfs2_log_bmap(struct gfs2_sbd *sdp)
   */
  
  static void gfs2_end_log_write_bh(struct gfs2_sbd *sdp, struct bio_vec *bvec,
 -                                int error)
 +                                blk_status_t error)
  {
        struct buffer_head *bh, *next;
        struct page *page = bvec->bv_page;
@@@ -209,13 -207,15 +207,13 @@@ static void gfs2_end_log_write(struct b
        struct page *page;
        int i;
  
 -      if (bio->bi_error) {
 -              sdp->sd_log_error = bio->bi_error;
 -              fs_err(sdp, "Error %d writing to log\n", bio->bi_error);
 -      }
 +      if (bio->bi_status)
 +              fs_err(sdp, "Error %d writing to log\n", bio->bi_status);
  
        bio_for_each_segment_all(bvec, bio, i) {
                page = bvec->bv_page;
                if (page_has_buffers(page))
 -                      gfs2_end_log_write_bh(sdp, bvec, bio->bi_error);
 +                      gfs2_end_log_write_bh(sdp, bvec, bio->bi_status);
                else
                        mempool_free(page, gfs2_page_pool);
        }
diff --combined fs/gfs2/sys.c
index e77bc52b468f24b407bb19a4783959ce981be163,01dc027b47388e9e23017d8749c6769b257a1f16..ca1f97ff898c951f495b555cf067203d3365ff43
@@@ -71,14 -71,25 +71,14 @@@ static ssize_t fsname_show(struct gfs2_
        return snprintf(buf, PAGE_SIZE, "%s\n", sdp->sd_fsname);
  }
  
 -static int gfs2_uuid_valid(const u8 *uuid)
 -{
 -      int i;
 -
 -      for (i = 0; i < 16; i++) {
 -              if (uuid[i])
 -                      return 1;
 -      }
 -      return 0;
 -}
 -
  static ssize_t uuid_show(struct gfs2_sbd *sdp, char *buf)
  {
        struct super_block *s = sdp->sd_vfs;
 -      const u8 *uuid = s->s_uuid;
 +
        buf[0] = '\0';
 -      if (!gfs2_uuid_valid(uuid))
 +      if (uuid_is_null(&s->s_uuid))
                return 0;
 -      return snprintf(buf, PAGE_SIZE, "%pUB\n", uuid);
 +      return snprintf(buf, PAGE_SIZE, "%pUB\n", &s->s_uuid);
  }
  
  static ssize_t freeze_show(struct gfs2_sbd *sdp, char *buf)
@@@ -626,12 -637,12 +626,12 @@@ static struct attribute *tune_attrs[] 
        NULL,
  };
  
- static struct attribute_group tune_group = {
+ static const struct attribute_group tune_group = {
        .name = "tune",
        .attrs = tune_attrs,
  };
  
- static struct attribute_group lock_module_group = {
+ static const struct attribute_group lock_module_group = {
        .name = "lock_module",
        .attrs = lock_module_attrs,
  };
@@@ -701,13 -712,14 +701,13 @@@ static int gfs2_uevent(struct kset *kse
  {
        struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);
        struct super_block *s = sdp->sd_vfs;
 -      const u8 *uuid = s->s_uuid;
  
        add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name);
        add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name);
        if (!test_bit(SDF_NOJOURNALID, &sdp->sd_flags))
                add_uevent_var(env, "JOURNALID=%d", sdp->sd_lockstruct.ls_jid);
 -      if (gfs2_uuid_valid(uuid))
 -              add_uevent_var(env, "UUID=%pUB", uuid);
 +      if (!uuid_is_null(&s->s_uuid))
 +              add_uevent_var(env, "UUID=%pUB", &s->s_uuid);
        return 0;
  }