gfs2: Merge branch 'for-next.nopid' into for-next
authorAndreas Gruenbacher <agruenba@redhat.com>
Sun, 9 Oct 2022 20:56:28 +0000 (22:56 +0200)
committerAndreas Gruenbacher <agruenba@redhat.com>
Sun, 9 Oct 2022 20:56:28 +0000 (22:56 +0200)
Resolves a conflict in gfs2_inode_lookup() between the following commits:

    gfs2: Use TRY lock in gfs2_inode_lookup for UNLINKED inodes

    gfs2: Mark the remaining process-independent glock holders as GL_NOPID

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
1  2 
fs/gfs2/file.c
fs/gfs2/glock.c
fs/gfs2/glock.h
fs/gfs2/inode.c
fs/gfs2/ops_fstype.c
fs/gfs2/super.c
fs/gfs2/util.c

diff --combined fs/gfs2/file.c
index 892006fbbb09f636e632bce3f5b1b4d911eb8e8a,1383f9598011d03cffb3b2581e84785c9403d0b2..60c6fb91fb589d4f26ada676a31a883a5145484e
@@@ -780,7 -780,7 +780,7 @@@ static inline bool should_fault_in_page
  
        if (!count)
                return false;
 -      if (!iter_is_iovec(i))
 +      if (!user_backed_iter(i))
                return false;
  
        size = PAGE_SIZE;
@@@ -1066,7 -1066,8 +1066,7 @@@ out_unlock
                gfs2_glock_dq(gh);
  out_uninit:
        gfs2_holder_uninit(gh);
 -      if (statfs_gh)
 -              kfree(statfs_gh);
 +      kfree(statfs_gh);
        from->count = orig_count - written;
        return written ? written : ret;
  }
@@@ -1443,6 -1444,22 +1443,22 @@@ static int gfs2_lock(struct file *file
                return dlm_posix_lock(ls->ls_dlm, ip->i_no_addr, file, cmd, fl);
  }
  
+ static void __flock_holder_uninit(struct file *file, struct gfs2_holder *fl_gh)
+ {
+       struct gfs2_glock *gl = fl_gh->gh_gl;
+       /*
+        * Make sure gfs2_glock_put() won't sleep under the file->f_lock
+        * spinlock.
+        */
+       gfs2_glock_hold(gl);
+       spin_lock(&file->f_lock);
+       gfs2_holder_uninit(fl_gh);
+       spin_unlock(&file->f_lock);
+       gfs2_glock_put(gl);
+ }
  static int do_flock(struct file *file, int cmd, struct file_lock *fl)
  {
        struct gfs2_file *fp = file->private_data;
        int sleeptime;
  
        state = (fl->fl_type == F_WRLCK) ? LM_ST_EXCLUSIVE : LM_ST_SHARED;
-       flags = (IS_SETLKW(cmd) ? 0 : LM_FLAG_TRY_1CB) | GL_EXACT;
+       flags = GL_EXACT | GL_NOPID;
+       if (!IS_SETLKW(cmd))
+               flags |= LM_FLAG_TRY_1CB;
  
        mutex_lock(&fp->f_fl_mutex);
  
                                       &gfs2_flock_glops, CREATE, &gl);
                if (error)
                        goto out;
+               spin_lock(&file->f_lock);
                gfs2_holder_init(gl, state, flags, fl_gh);
+               spin_unlock(&file->f_lock);
                gfs2_glock_put(gl);
        }
        for (sleeptime = 1; sleeptime <= 4; sleeptime <<= 1) {
                error = gfs2_glock_nq(fl_gh);
                if (error != GLR_TRYFAILED)
                        break;
-               fl_gh->gh_flags = LM_FLAG_TRY | GL_EXACT;
+               fl_gh->gh_flags &= ~LM_FLAG_TRY_1CB;
+               fl_gh->gh_flags |= LM_FLAG_TRY;
                msleep(sleeptime);
        }
        if (error) {
-               gfs2_holder_uninit(fl_gh);
+               __flock_holder_uninit(file, fl_gh);
                if (error == GLR_TRYFAILED)
                        error = -EAGAIN;
        } else {
@@@ -1507,7 -1529,7 +1528,7 @@@ static void do_unflock(struct file *fil
        locks_lock_file_wait(file, fl);
        if (gfs2_holder_initialized(fl_gh)) {
                gfs2_glock_dq(fl_gh);
-               gfs2_holder_uninit(fl_gh);
+               __flock_holder_uninit(file, fl_gh);
        }
        mutex_unlock(&fp->f_fl_mutex);
  }
diff --combined fs/gfs2/glock.c
index dca2cbf0338c856160244408d281cff59d72ab66,f80fba5d1d4d92945eacdccfd99c7fda6e02bed9..df335c258eb0832c6bbcfbda2db4e9dd1aa4161d
@@@ -33,6 -33,9 +33,9 @@@
  #include <linux/list_sort.h>
  #include <linux/lockref.h>
  #include <linux/rhashtable.h>
+ #include <linux/pid_namespace.h>
+ #include <linux/fdtable.h>
+ #include <linux/file.h>
  
  #include "gfs2.h"
  #include "incore.h"
@@@ -59,8 -62,6 +62,8 @@@ typedef void (*glock_examiner) (struct 
  
  static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int target);
  static void __gfs2_glock_dq(struct gfs2_holder *gh);
 +static void handle_callback(struct gfs2_glock *gl, unsigned int state,
 +                          unsigned long delay, bool remote);
  
  static struct dentry *gfs2_root;
  static struct workqueue_struct *glock_workqueue;
@@@ -407,13 -408,10 +410,13 @@@ static void do_error(struct gfs2_glock 
  /**
   * demote_incompat_holders - demote incompatible demoteable holders
   * @gl: the glock we want to promote
 - * @new_gh: the new holder to be promoted
 + * @current_gh: the newly promoted holder
 + *
 + * We're passing the newly promoted holder in @current_gh, but actually, any of
 + * the strong holders would do.
   */
  static void demote_incompat_holders(struct gfs2_glock *gl,
 -                                  struct gfs2_holder *new_gh)
 +                                  struct gfs2_holder *current_gh)
  {
        struct gfs2_holder *gh, *tmp;
  
                 */
                if (!test_bit(HIF_HOLDER, &gh->gh_iflags))
                        return;
 +              if (gh == current_gh)
 +                      continue;
                if (test_bit(HIF_MAY_DEMOTE, &gh->gh_iflags) &&
 -                  !may_grant(gl, new_gh, gh)) {
 +                  !may_grant(gl, current_gh, gh)) {
                        /*
                         * We should not recurse into do_promote because
                         * __gfs2_glock_dq only calls handle_callback,
@@@ -485,7 -481,8 +488,7 @@@ find_first_strong_holder(struct gfs2_gl
   * gfs2_instantiate - Call the glops instantiate function
   * @gh: The glock holder
   *
 - * Returns: 0 if instantiate was successful, 2 if type specific operation is
 - * underway, or error.
 + * Returns: 0 if instantiate was successful, or error.
   */
  int gfs2_instantiate(struct gfs2_holder *gh)
  {
  
  again:
        if (!test_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags))
 -              return 0;
 +              goto done;
  
        /*
         * Since we unlock the lockref lock, we set a flag to indicate
                goto again;
        }
  
 -      ret = glops->go_instantiate(gh);
 +      ret = glops->go_instantiate(gl);
        if (!ret)
                clear_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags);
        clear_and_wake_up_bit(GLF_INSTANTIATE_IN_PROG, &gl->gl_flags);
 -      return ret;
 +      if (ret)
 +              return ret;
 +
 +done:
 +      if (glops->go_held)
 +              return glops->go_held(gh);
 +      return 0;
  }
  
  /**
   * do_promote - promote as many requests as possible on the current queue
   * @gl: The glock
   * 
 - * Returns: 1 if there is a blocked holder at the head of the list, or 2
 - *          if a type specific operation is underway.
 + * Returns: 1 if there is a blocked holder at the head of the list
   */
  
  static int do_promote(struct gfs2_glock *gl)
 -__releases(&gl->gl_lockref.lock)
 -__acquires(&gl->gl_lockref.lock)
  {
 -      struct gfs2_holder *gh, *tmp, *first_gh;
 +      struct gfs2_holder *gh, *current_gh;
        bool incompat_holders_demoted = false;
 -      bool lock_released;
 -      int ret;
  
 -restart:
 -      first_gh = find_first_strong_holder(gl);
 -      list_for_each_entry_safe(gh, tmp, &gl->gl_holders, gh_list) {
 -              lock_released = false;
 +      current_gh = find_first_strong_holder(gl);
 +      list_for_each_entry(gh, &gl->gl_holders, gh_list) {
                if (test_bit(HIF_HOLDER, &gh->gh_iflags))
                        continue;
 -              if (!may_grant(gl, first_gh, gh)) {
 +              if (!may_grant(gl, current_gh, gh)) {
                        /*
 -                       * If we get here, it means we may not grant this holder for
 -                       * some reason. If this holder is the head of the list, it
 -                       * means we have a blocked holder at the head, so return 1.
 +                       * If we get here, it means we may not grant this
 +                       * holder for some reason. If this holder is at the
 +                       * head of the list, it means we have a blocked holder
 +                       * at the head, so return 1.
                         */
                        if (list_is_first(&gh->gh_list, &gl->gl_holders))
                                return 1;
                        do_error(gl, 0);
                        break;
                }
 -              if (!incompat_holders_demoted) {
 -                      demote_incompat_holders(gl, first_gh);
 -                      incompat_holders_demoted = true;
 -                      first_gh = gh;
 -              }
 -              if (test_bit(GLF_INSTANTIATE_NEEDED, &gl->gl_flags) &&
 -                  !(gh->gh_flags & GL_SKIP) && gl->gl_ops->go_instantiate) {
 -                      lock_released = true;
 -                      spin_unlock(&gl->gl_lockref.lock);
 -                      ret = gfs2_instantiate(gh);
 -                      spin_lock(&gl->gl_lockref.lock);
 -                      if (ret) {
 -                              if (ret == 1)
 -                                      return 2;
 -                              gh->gh_error = ret;
 -                              list_del_init(&gh->gh_list);
 -                              trace_gfs2_glock_queue(gh, 0);
 -                              gfs2_holder_wake(gh);
 -                              goto restart;
 -                      }
 -              }
                set_bit(HIF_HOLDER, &gh->gh_iflags);
                trace_gfs2_promote(gh);
                gfs2_holder_wake(gh);
 -              /*
 -               * If we released the gl_lockref.lock the holders list may have
 -               * changed. For that reason, we start again at the start of
 -               * the holders queue.
 -               */
 -              if (lock_released)
 -                      goto restart;
 +              if (!incompat_holders_demoted) {
 +                      current_gh = gh;
 +                      demote_incompat_holders(gl, current_gh);
 +                      incompat_holders_demoted = true;
 +              }
        }
        return 0;
  }
@@@ -640,6 -660,7 +643,6 @@@ static void finish_xmote(struct gfs2_gl
        const struct gfs2_glock_operations *glops = gl->gl_ops;
        struct gfs2_holder *gh;
        unsigned state = ret & LM_OUT_ST_MASK;
 -      int rv;
  
        spin_lock(&gl->gl_lockref.lock);
        trace_gfs2_glock_state_change(gl, state);
@@@ -697,8 -718,6 +700,8 @@@ retry
                gfs2_demote_wake(gl);
        if (state != LM_ST_UNLOCKED) {
                if (glops->go_xmote_bh) {
 +                      int rv;
 +
                        spin_unlock(&gl->gl_lockref.lock);
                        rv = glops->go_xmote_bh(gl);
                        spin_lock(&gl->gl_lockref.lock);
                                goto out;
                        }
                }
 -              rv = do_promote(gl);
 -              if (rv == 2)
 -                      goto out_locked;
 +              do_promote(gl);
        }
  out:
        clear_bit(GLF_LOCK, &gl->gl_flags);
 -out_locked:
        spin_unlock(&gl->gl_lockref.lock);
  }
  
@@@ -732,8 -754,7 +735,8 @@@ static bool is_system_glock(struct gfs2
   *
   */
  
 -static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh, unsigned int target)
 +static void do_xmote(struct gfs2_glock *gl, struct gfs2_holder *gh,
 +                                       unsigned int target)
  __releases(&gl->gl_lockref.lock)
  __acquires(&gl->gl_lockref.lock)
  {
  
        if (target != LM_ST_UNLOCKED && glock_blocked_by_withdraw(gl) &&
            gh && !(gh->gh_flags & LM_FLAG_NOEXP))
 -              return;
 +              goto skip_inval;
 +
        lck_flags &= (LM_FLAG_TRY | LM_FLAG_TRY_1CB | LM_FLAG_NOEXP |
                      LM_FLAG_PRIORITY);
        GLOCK_BUG_ON(gl, gl->gl_state == target);
@@@ -830,20 -850,6 +833,20 @@@ skip_inval
            (target != LM_ST_UNLOCKED ||
             test_bit(SDF_WITHDRAW_RECOVERY, &sdp->sd_flags))) {
                if (!is_system_glock(gl)) {
 +                      handle_callback(gl, LM_ST_UNLOCKED, 0, false); /* sets demote */
 +                      /*
 +                       * Ordinarily, we would call dlm and its callback would call
 +                       * finish_xmote, which would call state_change() to the new state.
 +                       * Since we withdrew, we won't call dlm, so call state_change
 +                       * manually, but to the UNLOCKED state we desire.
 +                       */
 +                      state_change(gl, LM_ST_UNLOCKED);
 +                      /*
 +                       * We skip telling dlm to do the locking, so we won't get a
 +                       * reply that would otherwise clear GLF_LOCK. So we clear it here.
 +                       */
 +                      clear_bit(GLF_LOCK, &gl->gl_flags);
 +                      clear_bit(GLF_DEMOTE_IN_PROGRESS, &gl->gl_flags);
                        gfs2_glock_queue_work(gl, GL_GLOCK_DFT_HOLD);
                        goto out;
                } else {
@@@ -883,6 -889,7 +886,6 @@@ __releases(&gl->gl_lockref.lock
  __acquires(&gl->gl_lockref.lock)
  {
        struct gfs2_holder *gh = NULL;
 -      int ret;
  
        if (test_and_set_bit(GLF_LOCK, &gl->gl_flags))
                return;
        } else {
                if (test_bit(GLF_DEMOTE, &gl->gl_flags))
                        gfs2_demote_wake(gl);
 -              ret = do_promote(gl);
 -              if (ret == 0)
 +              if (do_promote(gl) == 0)
                        goto out_unlock;
 -              if (ret == 2)
 -                      goto out;
                gh = find_first_waiter(gl);
                gl->gl_target = gh->gh_state;
                if (!(gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)))
                        do_error(gl, 0); /* Fail queued try locks */
        }
        do_xmote(gl, gh, gl->gl_target);
 -out:
        return;
  
  out_sched:
@@@ -1036,18 -1047,16 +1039,18 @@@ static void delete_work_func(struct wor
                        if (gfs2_queue_delete_work(gl, 5 * HZ))
                                return;
                }
 -              goto out;
        }
  
        inode = gfs2_lookup_by_inum(sdp, no_addr, gl->gl_no_formal_ino,
                                    GFS2_BLKST_UNLINKED);
 -      if (!IS_ERR_OR_NULL(inode)) {
 +      if (IS_ERR(inode)) {
 +              if (PTR_ERR(inode) == -EAGAIN &&
 +                      (gfs2_queue_delete_work(gl, 5 * HZ)))
 +                              return;
 +      } else {
                d_prune_aliases(inode);
                iput(inode);
        }
 -out:
        gfs2_glock_put(gl);
  }
  
@@@ -1307,25 -1316,6 +1310,25 @@@ static void gfs2_glock_update_hold_time
        }
  }
  
 +/**
 + * gfs2_glock_holder_ready - holder is ready and its error code can be collected
 + * @gh: the glock holder
 + *
 + * Called when a glock holder no longer needs to be waited for because it is
 + * now either held (HIF_HOLDER set; gh_error == 0), or acquiring the lock has
 + * failed (gh_error != 0).
 + */
 +
 +int gfs2_glock_holder_ready(struct gfs2_holder *gh)
 +{
 +      if (gh->gh_error || (gh->gh_flags & GL_SKIP))
 +              return gh->gh_error;
 +      gh->gh_error = gfs2_instantiate(gh);
 +      if (gh->gh_error)
 +              gfs2_glock_dq(gh);
 +      return gh->gh_error;
 +}
 +
  /**
   * gfs2_glock_wait - wait on a glock acquisition
   * @gh: the glock holder
@@@ -1340,7 -1330,7 +1343,7 @@@ int gfs2_glock_wait(struct gfs2_holder 
        might_sleep();
        wait_on_bit(&gh->gh_iflags, HIF_WAIT, TASK_UNINTERRUPTIBLE);
        gfs2_glock_update_hold_time(gh->gh_gl, start_time);
 -      return gh->gh_error;
 +      return gfs2_glock_holder_ready(gh);
  }
  
  static int glocks_pending(unsigned int num_gh, struct gfs2_holder *ghs)
@@@ -1368,6 -1358,7 +1371,6 @@@ int gfs2_glock_async_wait(unsigned int 
        struct gfs2_sbd *sdp = ghs[0].gh_gl->gl_name.ln_sbd;
        int i, ret = 0, timeout = 0;
        unsigned long start_time = jiffies;
 -      bool keep_waiting;
  
        might_sleep();
        /*
        for (i = 0; i < num_gh; i++)
                timeout += ghs[i].gh_gl->gl_hold_time << 1;
  
 -wait_for_dlm:
        if (!wait_event_timeout(sdp->sd_async_glock_wait,
 -                              !glocks_pending(num_gh, ghs), timeout))
 +                              !glocks_pending(num_gh, ghs), timeout)) {
                ret = -ESTALE; /* request timed out. */
 +              goto out;
 +      }
  
 -      /*
 -       * If dlm granted all our requests, we need to adjust the glock
 -       * minimum hold time values according to how long we waited.
 -       *
 -       * If our request timed out, we need to repeatedly release any held
 -       * glocks we acquired thus far to allow dlm to acquire the remaining
 -       * glocks without deadlocking.  We cannot currently cancel outstanding
 -       * glock acquisitions.
 -       *
 -       * The HIF_WAIT bit tells us which requests still need a response from
 -       * dlm.
 -       *
 -       * If dlm sent us any errors, we return the first error we find.
 -       */
 -      keep_waiting = false;
        for (i = 0; i < num_gh; i++) {
 -              /* Skip holders we have already dequeued below. */
 -              if (!gfs2_holder_queued(&ghs[i]))
 -                      continue;
 -              /* Skip holders with a pending DLM response. */
 -              if (test_bit(HIF_WAIT, &ghs[i].gh_iflags)) {
 -                      keep_waiting = true;
 -                      continue;
 -              }
 +              struct gfs2_holder *gh = &ghs[i];
 +              int ret2;
  
 -              if (test_bit(HIF_HOLDER, &ghs[i].gh_iflags)) {
 -                      if (ret == -ESTALE)
 -                              gfs2_glock_dq(&ghs[i]);
 -                      else
 -                              gfs2_glock_update_hold_time(ghs[i].gh_gl,
 -                                                          start_time);
 +              if (test_bit(HIF_HOLDER, &gh->gh_iflags)) {
 +                      gfs2_glock_update_hold_time(gh->gh_gl,
 +                                                  start_time);
                }
 +              ret2 = gfs2_glock_holder_ready(gh);
                if (!ret)
 -                      ret = ghs[i].gh_error;
 +                      ret = ret2;
        }
  
 -      if (keep_waiting)
 -              goto wait_for_dlm;
 +out:
 +      if (ret) {
 +              for (i = 0; i < num_gh; i++) {
 +                      struct gfs2_holder *gh = &ghs[i];
  
 -      /*
 -       * At this point, we've either acquired all locks or released them all.
 -       */
 +                      gfs2_glock_dq(gh);
 +              }
 +      }
        return ret;
  }
  
@@@ -1456,6 -1467,15 +1459,15 @@@ void gfs2_print_dbg(struct seq_file *se
        va_end(args);
  }
  
+ static inline bool pid_is_meaningful(const struct gfs2_holder *gh)
+ {
+         if (!(gh->gh_flags & GL_NOPID))
+                 return true;
+         if (gh->gh_state == LM_ST_UNLOCKED)
+                 return true;
+         return false;
+ }
  /**
   * add_to_queue - Add a holder to the wait queue (but look for recursion)
   * @gh: the holder structure to add
@@@ -1482,20 -1502,27 +1494,27 @@@ __acquires(&gl->gl_lockref.lock
  
        if (gh->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB)) {
                if (test_bit(GLF_LOCK, &gl->gl_flags)) {
 -                      struct gfs2_holder *first_gh;
 +                      struct gfs2_holder *current_gh;
  
 -                      first_gh = find_first_strong_holder(gl);
 -                      try_futile = !may_grant(gl, first_gh, gh);
 +                      current_gh = find_first_strong_holder(gl);
 +                      try_futile = !may_grant(gl, current_gh, gh);
                }
                if (test_bit(GLF_INVALIDATE_IN_PROGRESS, &gl->gl_flags))
                        goto fail;
        }
  
        list_for_each_entry(gh2, &gl->gl_holders, gh_list) {
-               if (unlikely(gh2->gh_owner_pid == gh->gh_owner_pid &&
-                   (gh->gh_gl->gl_ops->go_type != LM_TYPE_FLOCK) &&
-                   !test_bit(HIF_MAY_DEMOTE, &gh2->gh_iflags)))
-                       goto trap_recursive;
+               if (likely(gh2->gh_owner_pid != gh->gh_owner_pid))
+                       continue;
+               if (gh->gh_gl->gl_ops->go_type == LM_TYPE_FLOCK)
+                       continue;
+               if (test_bit(HIF_MAY_DEMOTE, &gh2->gh_iflags))
+                       continue;
+               if (!pid_is_meaningful(gh2))
+                       continue;
+               goto trap_recursive;
+       }
+       list_for_each_entry(gh2, &gl->gl_holders, gh_list) {
                if (try_futile &&
                    !(gh2->gh_flags & (LM_FLAG_TRY | LM_FLAG_TRY_1CB))) {
  fail:
@@@ -1771,7 -1798,7 +1790,7 @@@ static int glock_compare(const void *ar
  }
  
  /**
 - * nq_m_sync - synchonously acquire more than one glock in deadlock free order
 + * nq_m_sync - synchronously acquire more than one glock in deadlock free order
   * @num_gh: the number of structures
   * @ghs: an array of struct gfs2_holder structures
   * @p: placeholder for the holder structure to pass back
@@@ -1792,6 -1819,8 +1811,6 @@@ static int nq_m_sync(unsigned int num_g
        sort(p, num_gh, sizeof(struct gfs2_holder *), glock_compare, NULL);
  
        for (x = 0; x < num_gh; x++) {
 -              p[x]->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC);
 -
                error = gfs2_glock_nq(p[x]);
                if (error) {
                        while (x--)
   * @num_gh: the number of structures
   * @ghs: an array of struct gfs2_holder structures
   *
 - *
   * Returns: 0 on success (all glocks acquired),
   *          errno on failure (no glocks acquired)
   */
@@@ -1822,6 -1852,7 +1841,6 @@@ int gfs2_glock_nq_m(unsigned int num_gh
        case 0:
                return 0;
        case 1:
 -              ghs->gh_flags &= ~(LM_FLAG_TRY | GL_ASYNC);
                return gfs2_glock_nq(ghs);
        default:
                if (num_gh <= 4)
@@@ -2214,20 -2245,6 +2233,20 @@@ static void dump_glock_func(struct gfs2
        dump_glock(NULL, gl, true);
  }
  
 +static void withdraw_dq(struct gfs2_glock *gl)
 +{
 +      spin_lock(&gl->gl_lockref.lock);
 +      if (!__lockref_is_dead(&gl->gl_lockref) &&
 +          glock_blocked_by_withdraw(gl))
 +              do_error(gl, LM_OUT_ERROR); /* remove pending waiters */
 +      spin_unlock(&gl->gl_lockref.lock);
 +}
 +
 +void gfs2_gl_dq_holders(struct gfs2_sbd *sdp)
 +{
 +      glock_hash_walk(withdraw_dq, sdp);
 +}
 +
  /**
   * gfs2_gl_hash_clear - Empty out the glock hash table
   * @sdp: the filesystem
@@@ -2247,6 -2264,20 +2266,6 @@@ void gfs2_gl_hash_clear(struct gfs2_sb
        glock_hash_walk(dump_glock_func, sdp);
  }
  
 -void gfs2_glock_finish_truncate(struct gfs2_inode *ip)
 -{
 -      struct gfs2_glock *gl = ip->i_gl;
 -      int ret;
 -
 -      ret = gfs2_truncatei_resume(ip);
 -      gfs2_glock_assert_withdraw(gl, ret == 0);
 -
 -      spin_lock(&gl->gl_lockref.lock);
 -      clear_bit(GLF_LOCK, &gl->gl_flags);
 -      run_queue(gl, 1);
 -      spin_unlock(&gl->gl_lockref.lock);
 -}
 -
  static const char *state2str(unsigned state)
  {
        switch(state) {
@@@ -2306,19 -2337,24 +2325,24 @@@ static const char *hflags2str(char *buf
  static void dump_holder(struct seq_file *seq, const struct gfs2_holder *gh,
                        const char *fs_id_buf)
  {
-       struct task_struct *gh_owner = NULL;
+       const char *comm = "(none)";
+       pid_t owner_pid = 0;
        char flags_buf[32];
  
        rcu_read_lock();
-       if (gh->gh_owner_pid)
+       if (pid_is_meaningful(gh)) {
+               struct task_struct *gh_owner;
+               comm = "(ended)";
+               owner_pid = pid_nr(gh->gh_owner_pid);
                gh_owner = pid_task(gh->gh_owner_pid, PIDTYPE_PID);
+               if (gh_owner)
+                       comm = gh_owner->comm;
+       }
        gfs2_print_dbg(seq, "%s H: s:%s f:%s e:%d p:%ld [%s] %pS\n",
                       fs_id_buf, state2str(gh->gh_state),
                       hflags2str(flags_buf, gh->gh_flags, gh->gh_iflags),
-                      gh->gh_error,
-                      gh->gh_owner_pid ? (long)pid_nr(gh->gh_owner_pid) : -1,
-                      gh_owner ? gh_owner->comm : "(ended)",
-                      (void *)gh->gh_ip);
+                      gh->gh_error, (long)owner_pid, comm, (void *)gh->gh_ip);
        rcu_read_unlock();
  }
  
@@@ -2521,7 -2557,7 +2545,7 @@@ int __init gfs2_glock_init(void
                return -ENOMEM;
        }
  
 -      ret = register_shrinker(&glock_shrinker);
 +      ret = register_shrinker(&glock_shrinker, "gfs2-glock");
        if (ret) {
                destroy_workqueue(gfs2_delete_workqueue);
                destroy_workqueue(glock_workqueue);
@@@ -2733,6 -2769,172 +2757,172 @@@ static const struct file_operations gfs
        .release = gfs2_glocks_release,
  };
  
+ struct gfs2_glockfd_iter {
+       struct super_block *sb;
+       unsigned int tgid;
+       struct task_struct *task;
+       unsigned int fd;
+       struct file *file;
+ };
+ static struct task_struct *gfs2_glockfd_next_task(struct gfs2_glockfd_iter *i)
+ {
+       struct pid_namespace *ns = task_active_pid_ns(current);
+       struct pid *pid;
+       if (i->task)
+               put_task_struct(i->task);
+       rcu_read_lock();
+ retry:
+       i->task = NULL;
+       pid = find_ge_pid(i->tgid, ns);
+       if (pid) {
+               i->tgid = pid_nr_ns(pid, ns);
+               i->task = pid_task(pid, PIDTYPE_TGID);
+               if (!i->task) {
+                       i->tgid++;
+                       goto retry;
+               }
+               get_task_struct(i->task);
+       }
+       rcu_read_unlock();
+       return i->task;
+ }
+ static struct file *gfs2_glockfd_next_file(struct gfs2_glockfd_iter *i)
+ {
+       if (i->file) {
+               fput(i->file);
+               i->file = NULL;
+       }
+       rcu_read_lock();
+       for(;; i->fd++) {
+               struct inode *inode;
+               i->file = task_lookup_next_fd_rcu(i->task, &i->fd);
+               if (!i->file) {
+                       i->fd = 0;
+                       break;
+               }
+               inode = file_inode(i->file);
+               if (inode->i_sb != i->sb)
+                       continue;
+               if (get_file_rcu(i->file))
+                       break;
+       }
+       rcu_read_unlock();
+       return i->file;
+ }
+ static void *gfs2_glockfd_seq_start(struct seq_file *seq, loff_t *pos)
+ {
+       struct gfs2_glockfd_iter *i = seq->private;
+       if (*pos)
+               return NULL;
+       while (gfs2_glockfd_next_task(i)) {
+               if (gfs2_glockfd_next_file(i))
+                       return i;
+               i->tgid++;
+       }
+       return NULL;
+ }
+ static void *gfs2_glockfd_seq_next(struct seq_file *seq, void *iter_ptr,
+                                  loff_t *pos)
+ {
+       struct gfs2_glockfd_iter *i = seq->private;
+       (*pos)++;
+       i->fd++;
+       do {
+               if (gfs2_glockfd_next_file(i))
+                       return i;
+               i->tgid++;
+       } while (gfs2_glockfd_next_task(i));
+       return NULL;
+ }
+ static void gfs2_glockfd_seq_stop(struct seq_file *seq, void *iter_ptr)
+ {
+       struct gfs2_glockfd_iter *i = seq->private;
+       if (i->file)
+               fput(i->file);
+       if (i->task)
+               put_task_struct(i->task);
+ }
+ static void gfs2_glockfd_seq_show_flock(struct seq_file *seq,
+                                       struct gfs2_glockfd_iter *i)
+ {
+       struct gfs2_file *fp = i->file->private_data;
+       struct gfs2_holder *fl_gh = &fp->f_fl_gh;
+       struct lm_lockname gl_name = { .ln_type = LM_TYPE_RESERVED };
+       if (!READ_ONCE(fl_gh->gh_gl))
+               return;
+       spin_lock(&i->file->f_lock);
+       if (gfs2_holder_initialized(fl_gh))
+               gl_name = fl_gh->gh_gl->gl_name;
+       spin_unlock(&i->file->f_lock);
+       if (gl_name.ln_type != LM_TYPE_RESERVED) {
+               seq_printf(seq, "%d %u %u/%llx\n",
+                          i->tgid, i->fd, gl_name.ln_type,
+                          (unsigned long long)gl_name.ln_number);
+       }
+ }
+ static int gfs2_glockfd_seq_show(struct seq_file *seq, void *iter_ptr)
+ {
+       struct gfs2_glockfd_iter *i = seq->private;
+       struct inode *inode = file_inode(i->file);
+       struct gfs2_glock *gl;
+       inode_lock_shared(inode);
+       gl = GFS2_I(inode)->i_iopen_gh.gh_gl;
+       if (gl) {
+               seq_printf(seq, "%d %u %u/%llx\n",
+                          i->tgid, i->fd, gl->gl_name.ln_type,
+                          (unsigned long long)gl->gl_name.ln_number);
+       }
+       gfs2_glockfd_seq_show_flock(seq, i);
+       inode_unlock_shared(inode);
+       return 0;
+ }
+ static const struct seq_operations gfs2_glockfd_seq_ops = {
+       .start = gfs2_glockfd_seq_start,
+       .next  = gfs2_glockfd_seq_next,
+       .stop  = gfs2_glockfd_seq_stop,
+       .show  = gfs2_glockfd_seq_show,
+ };
+ static int gfs2_glockfd_open(struct inode *inode, struct file *file)
+ {
+       struct gfs2_glockfd_iter *i;
+       struct gfs2_sbd *sdp = inode->i_private;
+       i = __seq_open_private(file, &gfs2_glockfd_seq_ops,
+                              sizeof(struct gfs2_glockfd_iter));
+       if (!i)
+               return -ENOMEM;
+       i->sb = sdp->sd_vfs;
+       return 0;
+ }
+ static const struct file_operations gfs2_glockfd_fops = {
+       .owner   = THIS_MODULE,
+       .open    = gfs2_glockfd_open,
+       .read    = seq_read,
+       .llseek  = seq_lseek,
+       .release = seq_release_private,
+ };
  DEFINE_SEQ_ATTRIBUTE(gfs2_sbstats);
  
  void gfs2_create_debugfs_file(struct gfs2_sbd *sdp)
        debugfs_create_file("glocks", S_IFREG | S_IRUGO, sdp->debugfs_dir, sdp,
                            &gfs2_glocks_fops);
  
+       debugfs_create_file("glockfd", S_IFREG | S_IRUGO, sdp->debugfs_dir, sdp,
+                           &gfs2_glockfd_fops);
        debugfs_create_file("glstats", S_IFREG | S_IRUGO, sdp->debugfs_dir, sdp,
                            &gfs2_glstats_fops);
  
diff --combined fs/gfs2/glock.h
index 0199a3dcb11406f56611c9ca56c9ab46f15ff749,e764ebeba54c4f73d3fcdd9875cec6397d075b3d..0d068f4fd7d6737c85ea35a0ed22a46c22bc9801
@@@ -91,6 -91,7 +91,7 @@@ enum 
  #define GL_ASYNC              0x0040
  #define GL_EXACT              0x0080
  #define GL_SKIP                       0x0100
+ #define GL_NOPID              0x0200
  #define GL_NOCACHE            0x0400
    
  /*
@@@ -213,7 -214,6 +214,7 @@@ extern void gfs2_holder_uninit(struct g
  extern int gfs2_glock_nq(struct gfs2_holder *gh);
  extern int gfs2_glock_poll(struct gfs2_holder *gh);
  extern int gfs2_instantiate(struct gfs2_holder *gh);
 +extern int gfs2_glock_holder_ready(struct gfs2_holder *gh);
  extern int gfs2_glock_wait(struct gfs2_holder *gh);
  extern int gfs2_glock_async_wait(unsigned int num_gh, struct gfs2_holder *ghs);
  extern void gfs2_glock_dq(struct gfs2_holder *gh);
@@@ -274,7 -274,7 +275,7 @@@ extern void gfs2_cancel_delete_work(str
  extern bool gfs2_delete_work_queued(const struct gfs2_glock *gl);
  extern void gfs2_flush_delete_work(struct gfs2_sbd *sdp);
  extern void gfs2_gl_hash_clear(struct gfs2_sbd *sdp);
 -extern void gfs2_glock_finish_truncate(struct gfs2_inode *ip);
 +extern void gfs2_gl_dq_holders(struct gfs2_sbd *sdp);
  extern void gfs2_glock_thaw(struct gfs2_sbd *sdp);
  extern void gfs2_glock_add_to_lru(struct gfs2_glock *gl);
  extern void gfs2_glock_free(struct gfs2_glock *gl);
diff --combined fs/gfs2/inode.c
index 56ded979988cac324a8a17e2ee06755bc327cee5,e211ed8636b5b1e525a7b7f2741130ee494aca20..04a201584fa7c70d6403257f2ef17e282d86827d
@@@ -130,7 -130,6 +130,7 @@@ struct inode *gfs2_inode_lookup(struct 
        if (inode->i_state & I_NEW) {
                struct gfs2_sbd *sdp = GFS2_SB(inode);
                struct gfs2_glock *io_gl;
 +              int extra_flags = 0;
  
                error = gfs2_glock_get(sdp, no_addr, &gfs2_inode_glops, CREATE,
                                       &ip->i_gl);
                if (unlikely(error))
                        goto fail;
  
 -              if (blktype != GFS2_BLKST_UNLINKED)
 +              if (blktype == GFS2_BLKST_UNLINKED)
 +                      extra_flags |= LM_FLAG_TRY;
 +              else
                        gfs2_cancel_delete_work(io_gl);
                error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED,
-                                          GL_EXACT | extra_flags,
 -                                         GL_EXACT | GL_NOPID,
++                                         GL_EXACT | GL_NOPID | extra_flags,
                                           &ip->i_iopen_gh);
                gfs2_glock_put(io_gl);
                if (unlikely(error))
        return inode;
  
  fail:
 +      if (error == GLR_TRYFAILED)
 +              error = -EAGAIN;
        if (gfs2_holder_initialized(&ip->i_iopen_gh))
                gfs2_glock_dq_uninit(&ip->i_iopen_gh);
        if (gfs2_holder_initialized(&i_gh))
@@@ -726,7 -721,8 +726,8 @@@ static int gfs2_create_inode(struct ino
        error = insert_inode_locked4(inode, ip->i_no_addr, iget_test, &ip->i_no_addr);
        BUG_ON(error);
  
-       error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT, &ip->i_iopen_gh);
+       error = gfs2_glock_nq_init(io_gl, LM_ST_SHARED, GL_EXACT | GL_NOPID,
+                                  &ip->i_iopen_gh);
        if (error)
                goto fail_gunlock2;
  
diff --combined fs/gfs2/ops_fstype.c
index c7e2e623836685d73587a7352a04681151b54405,904a2d47c4b3710e4b9a9b731984371f7a2bfe46..c0cf1d2d0ef5b3fa6a311775e471189fb9693f68
@@@ -106,6 -106,8 +106,6 @@@ static struct gfs2_sbd *init_sbd(struc
        mutex_init(&sdp->sd_quota_mutex);
        mutex_init(&sdp->sd_quota_sync_mutex);
        init_waitqueue_head(&sdp->sd_quota_wait);
 -      INIT_LIST_HEAD(&sdp->sd_trunc_list);
 -      spin_lock_init(&sdp->sd_trunc_lock);
        spin_lock_init(&sdp->sd_bitmap_lock);
  
        INIT_LIST_HEAD(&sdp->sd_sc_inodes_list);
@@@ -178,10 -180,7 +178,10 @@@ static int gfs2_check_sb(struct gfs2_sb
                pr_warn("Invalid block size\n");
                return -EINVAL;
        }
 -
 +      if (sb->sb_bsize_shift != ffs(sb->sb_bsize) - 1) {
 +              pr_warn("Invalid block size shift\n");
 +              return -EINVAL;
 +      }
        return 0;
  }
  
@@@ -384,10 -383,8 +384,10 @@@ static int init_names(struct gfs2_sbd *
        if (!table[0])
                table = sdp->sd_vfs->s_id;
  
 -      strlcpy(sdp->sd_proto_name, proto, GFS2_FSNAME_LEN);
 -      strlcpy(sdp->sd_table_name, table, GFS2_FSNAME_LEN);
 +      BUILD_BUG_ON(GFS2_LOCKNAME_LEN > GFS2_FSNAME_LEN);
 +
 +      strscpy(sdp->sd_proto_name, proto, GFS2_LOCKNAME_LEN);
 +      strscpy(sdp->sd_table_name, table, GFS2_LOCKNAME_LEN);
  
        table = sdp->sd_table_name;
        while ((table = strchr(table, '/')))
@@@ -406,7 -403,8 +406,8 @@@ static int init_locking(struct gfs2_sb
  
        error = gfs2_glock_nq_num(sdp,
                                  GFS2_MOUNT_LOCK, &gfs2_nondisk_glops,
-                                 LM_ST_EXCLUSIVE, LM_FLAG_NOEXP | GL_NOCACHE,
+                                 LM_ST_EXCLUSIVE,
+                                 LM_FLAG_NOEXP | GL_NOCACHE | GL_NOPID,
                                  mount_gh);
        if (error) {
                fs_err(sdp, "can't acquire mount glock: %d\n", error);
        error = gfs2_glock_nq_num(sdp,
                                  GFS2_LIVE_LOCK, &gfs2_nondisk_glops,
                                  LM_ST_SHARED,
-                                 LM_FLAG_NOEXP | GL_EXACT,
+                                 LM_FLAG_NOEXP | GL_EXACT | GL_NOPID,
                                  &sdp->sd_live_gh);
        if (error) {
                fs_err(sdp, "can't acquire live glock: %d\n", error);
@@@ -692,7 -690,7 +693,7 @@@ static int init_statfs(struct gfs2_sbd 
        iput(pn);
        pn = NULL;
        ip = GFS2_I(sdp->sd_sc_inode);
-       error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0,
+       error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_NOPID,
                                   &sdp->sd_sc_gh);
        if (error) {
                fs_err(sdp, "can't lock local \"sc\" file: %d\n", error);
@@@ -781,7 -779,7 +782,7 @@@ static int init_journal(struct gfs2_sb
                error = gfs2_glock_nq_num(sdp, sdp->sd_lockstruct.ls_jid,
                                          &gfs2_journal_glops,
                                          LM_ST_EXCLUSIVE,
-                                         LM_FLAG_NOEXP | GL_NOCACHE,
+                                         LM_FLAG_NOEXP | GL_NOCACHE | GL_NOPID,
                                          &sdp->sd_journal_gh);
                if (error) {
                        fs_err(sdp, "can't acquire journal glock: %d\n", error);
                ip = GFS2_I(sdp->sd_jdesc->jd_inode);
                sdp->sd_jinode_gl = ip->i_gl;
                error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED,
-                                          LM_FLAG_NOEXP | GL_EXACT | GL_NOCACHE,
+                                          LM_FLAG_NOEXP | GL_EXACT |
+                                          GL_NOCACHE | GL_NOPID,
                                           &sdp->sd_jinode_gh);
                if (error) {
                        fs_err(sdp, "can't acquire journal inode glock: %d\n",
@@@ -962,7 -961,7 +964,7 @@@ static int init_per_node(struct gfs2_sb
        pn = NULL;
  
        ip = GFS2_I(sdp->sd_qc_inode);
-       error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0,
+       error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_NOPID,
                                   &sdp->sd_qc_gh);
        if (error) {
                fs_err(sdp, "can't lock local \"qc\" file: %d\n", error);
@@@ -1444,13 -1443,13 +1446,13 @@@ static int gfs2_parse_param(struct fs_c
  
        switch (o) {
        case Opt_lockproto:
 -              strlcpy(args->ar_lockproto, param->string, GFS2_LOCKNAME_LEN);
 +              strscpy(args->ar_lockproto, param->string, GFS2_LOCKNAME_LEN);
                break;
        case Opt_locktable:
 -              strlcpy(args->ar_locktable, param->string, GFS2_LOCKNAME_LEN);
 +              strscpy(args->ar_locktable, param->string, GFS2_LOCKNAME_LEN);
                break;
        case Opt_hostdata:
 -              strlcpy(args->ar_hostdata, param->string, GFS2_LOCKNAME_LEN);
 +              strscpy(args->ar_hostdata, param->string, GFS2_LOCKNAME_LEN);
                break;
        case Opt_spectator:
                args->ar_spectator = 1;
diff --combined fs/gfs2/super.c
index b5b0f285b27f8f85fb3997e9b4932c6eb6081ba4,90db4a2892695a192b383e9b348d588baf1bb21b..b018957a1bb2449307417e3a1dd6411245d62e9c
@@@ -346,7 -346,8 +346,8 @@@ static int gfs2_lock_fs_check_clean(str
        }
  
        error = gfs2_glock_nq_init(sdp->sd_freeze_gl, LM_ST_EXCLUSIVE,
-                                  LM_FLAG_NOEXP, &sdp->sd_freeze_gh);
+                                  LM_FLAG_NOEXP | GL_NOPID,
+                                  &sdp->sd_freeze_gh);
        if (error)
                goto out;
  
@@@ -1196,7 -1197,7 +1197,7 @@@ static bool gfs2_upgrade_iopen_glock(st
                gfs2_glock_dq(gh);
                return false;
        }
 -      return true;
 +      return gfs2_glock_holder_ready(gh) == 0;
  }
  
  /**
diff --combined fs/gfs2/util.c
index 88185a341504007c6d045d561023708c9de4c35a,95d733dd3c25467f9865e00234acbfcee02296a0..7a6aeffcdf5cae60b6b1926b02e17753b557611a
@@@ -164,11 -164,6 +164,11 @@@ static void signal_our_withdraw(struct 
                }
                if (!ret)
                        gfs2_make_fs_ro(sdp);
 +              /*
 +               * Dequeue any pending non-system glock holders that can no
 +               * longer be granted because the file system is withdrawn.
 +               */
 +              gfs2_gl_dq_holders(sdp);
                gfs2_freeze_unlock(&freeze_gh);
        }
  
         * exception code in glock_dq.
         */
        iput(inode);
 +      sdp->sd_jdesc->jd_inode = NULL;
        /*
         * Wait until the journal inode's glock is freed. This allows try locks
         * on other nodes to be successful, otherwise we remain the owner of
         */
        fs_warn(sdp, "Requesting recovery of jid %d.\n",
                sdp->sd_lockstruct.ls_jid);
-       gfs2_holder_reinit(LM_ST_EXCLUSIVE, LM_FLAG_TRY_1CB | LM_FLAG_NOEXP,
+       gfs2_holder_reinit(LM_ST_EXCLUSIVE,
+                          LM_FLAG_TRY_1CB | LM_FLAG_NOEXP | GL_NOPID,
                           &sdp->sd_live_gh);
        msleep(GL_GLOCK_MAX_HOLD);
        /*
                        fs_warn(sdp, "Unable to recover our journal jid %d.\n",
                                sdp->sd_lockstruct.ls_jid);
                gfs2_glock_dq_wait(&sdp->sd_live_gh);
-               gfs2_holder_reinit(LM_ST_SHARED, LM_FLAG_NOEXP | GL_EXACT,
+               gfs2_holder_reinit(LM_ST_SHARED,
+                                  LM_FLAG_NOEXP | GL_EXACT | GL_NOPID,
                                   &sdp->sd_live_gh);
                gfs2_glock_nq(&sdp->sd_live_gh);
        }