1. 15 10月, 2020 1 次提交
    • A
      gfs2: Fix NULL pointer dereference in gfs2_rgrp_dump · 0e539ca1
      Andrew Price 提交于
      When an rindex entry is found to be corrupt, compute_bitstructs() calls
      gfs2_consist_rgrpd() which calls gfs2_rgrp_dump() like this:
      
          gfs2_rgrp_dump(NULL, rgd->rd_gl, fs_id_buf);
      
      gfs2_rgrp_dump then dereferences the gl without checking it and we get
      
          BUG: KASAN: null-ptr-deref in gfs2_rgrp_dump+0x28/0x280
      
      because there's no rgrp glock involved while reading the rindex on mount.
      
      Fix this by changing gfs2_rgrp_dump to take an rgrp argument.
      
      Reported-by: syzbot+43fa87986bdd31df9de6@syzkaller.appspotmail.com
      Signed-off-by: NAndrew Price <anprice@redhat.com>
      Signed-off-by: NAndreas Gruenbacher <agruenba@redhat.com>
      0e539ca1
  2. 03 7月, 2020 1 次提交
    • B
      gfs2: freeze should work on read-only mounts · 541656d3
      Bob Peterson 提交于
      Before this patch, function freeze_go_sync, called when promoting
      the freeze glock, was testing for the SDF_JOURNAL_LIVE superblock flag.
      That's only set for read-write mounts. Read-only mounts don't use a
      journal, so the bit is never set, so the freeze never happened.
      
      This patch removes the check for SDF_JOURNAL_LIVE for freeze requests
      but still checks it when deciding whether to flush a journal.
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      541656d3
  3. 06 6月, 2020 3 次提交
  4. 03 6月, 2020 1 次提交
    • B
      gfs2: Don't ignore inode write errors during inode_go_sync · bbae10fa
      Bob Peterson 提交于
      Before for this patch, function inode_go_sync ignored io errors
      during inode_go_sync, overwriting them with metadata write errors:
      
      		error = filemap_fdatawait(mapping);
      		mapping_set_error(mapping, error);
      	}
      	error = filemap_fdatawait(metamapping);
      	...
      	return error;
      
      So any errors returned by the inode write would be forgotten if the
      metadata write succeeded. This patch still does both writes, but
      only sets error if it's still zero. That way, any errors will be
      reported by to the caller, do_xmote, which will take appropriate
      action and report the error.
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      Signed-off-by: NAndreas Gruenbacher <agruenba@redhat.com>
      bbae10fa
  5. 27 2月, 2020 4 次提交
    • B
      gfs2: Do proper error checking for go_sync family of glops functions · 1c634f94
      Bob Peterson 提交于
      Before this patch, function do_xmote would try to sync out the glock
      dirty data by calling the appropriate glops function XXX_go_sync()
      but it did not check for a good return code. If the sync was not
      possible due to an io error or whatever, do_xmote would continue on
      and call go_inval and release the glock to other cluster nodes.
      When those nodes go to replay the journal, they may already be holding
      glocks for the journal records that should have been synced, but were
      not due to the ignored error.
      
      This patch introduces proper error code checking to the go_sync
      family of glops functions.
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      Reviewed-by: NAndreas Gruenbacher <agruenba@redhat.com>
      1c634f94
    • B
      gfs2: Do log_flush in gfs2_ail_empty_gl even if ail list is empty · 9ff78289
      Bob Peterson 提交于
      Before this patch, if gfs2_ail_empty_gl saw there was nothing on
      the ail list, it would return and not flush the log. The problem
      is that there could still be a revoke for the rgrp sitting on the
      sd_log_le_revoke list that's been recently taken off the ail list.
      But that revoke still needs to be written, and the rgrp_go_inval
      still needs to call log_flush_wait to ensure the revokes are all
      properly written to the journal before we relinquish control of
      the glock to another node. If we give the glock to another node
      before we have this knowledge, the node might crash and its journal
      replayed, in which case the missing revoke would allow the journal
      replay to replay the rgrp over top of the rgrp we already gave to
      another node, thus overwriting its changes and corrupting the
      file system.
      
      This patch makes gfs2_ail_empty_gl still call gfs2_log_flush rather
      than returning.
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      Reviewed-by: NAndreas Gruenbacher <agruenba@redhat.com>
      9ff78289
    • B
      gfs2: fix infinite loop when checking ail item count before go_inval · 33dbd1e4
      Bob Peterson 提交于
      Before this patch, the rgrp_go_inval and inode_go_inval functions each
      checked if there were any items left on the ail count (by way of a
      count), and if so, did a withdraw. But the withdraw code now uses
      glocks when changing the file system to read-only status. So we can
      not have glock functions withdrawing or a hang will likely result:
      The glocks can't be serviced by the work_func if the work_func is
      busy doing its own withdraw.
      
      This patch removes the checks from the go_inval functions and adds
      a centralized check in do_xmote to warn about the problem and not
      withdraw, but flag the error so it's eventually caught when the logd
      daemon eventually runs.
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      Reviewed-by: NAndreas Gruenbacher <agruenba@redhat.com>
      33dbd1e4
    • B
      gfs2: Force withdraw to replay journals and wait for it to finish · 601ef0d5
      Bob Peterson 提交于
      When a node withdraws from a file system, it often leaves its journal
      in an incomplete state. This is especially true when the withdraw is
      caused by io errors writing to the journal. Before this patch, a
      withdraw would try to write a "shutdown" record to the journal, tell
      dlm it's done with the file system, and none of the other nodes
      know about the problem. Later, when the problem is fixed and the
      withdrawn node is rebooted, it would then discover that its own
      journal was incomplete, and replay it. However, replaying it at this
      point is almost guaranteed to introduce corruption because the other
      nodes are likely to have used affected resource groups that appeared
      in the journal since the time of the withdraw. Replaying the journal
      later will overwrite any changes made, and not through any fault of
      dlm, which was instructed during the withdraw to release those
      resources.
      
      This patch makes file system withdraws seen by the entire cluster.
      Withdrawing nodes dequeue their journal glock to allow recovery.
      
      The remaining nodes check all the journals to see if they are
      clean or in need of replay. They try to replay dirty journals, but
      only the journals of withdrawn nodes will be "not busy" and
      therefore available for replay.
      
      Until the journal replay is complete, no i/o related glocks may be
      given out, to ensure that the replay does not cause the
      aforementioned corruption: We cannot allow any journal replay to
      overwrite blocks associated with a glock once it is held.
      
      The "live" glock which is now used to signal when a withdraw
      occurs. When a withdraw occurs, the node signals its withdraw by
      dequeueing the "live" glock and trying to enqueue it in EX mode,
      thus forcing the other nodes to all see a demote request, by way
      of a "1CB" (one callback) try lock. The "live" glock is not
      granted in EX; the callback is only just used to indicate a
      withdraw has occurred.
      
      Note that all nodes in the cluster must wait for the recovering
      node to finish replaying the withdrawing node's journal before
      continuing. To this end, it checks that the journals are clean
      multiple times in a retry loop.
      
      Also note that the withdraw function may be called from a wide
      variety of situations, and therefore, we need to take extra
      precautions to make sure pointers are valid before using them in
      many circumstances.
      
      We also need to take care when glocks decide to withdraw, since
      the withdraw code now uses glocks.
      
      Also, before this patch, if a process encountered an error and
      decided to withdraw, if another process was already withdrawing,
      the second withdraw would be silently ignored, which set it free
      to unlock its glocks. That's correct behavior if the original
      withdrawer encounters further errors down the road. But if
      secondary waiters don't wait for the journal replay, unlocking
      glocks will allow other nodes to use them, despite the fact that
      the journal containing those blocks is being replayed. The
      replay needs to finish before our glocks are released to other
      nodes. IOW, secondary withdraws need to wait for the first
      withdraw to finish.
      
      For example, if an rgrp glock is unlocked by a process that didn't
      wait for the first withdraw, a journal replay could introduce file
      system corruption by replaying a rgrp block that has already been
      granted to a different cluster node.
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      601ef0d5
  6. 21 2月, 2020 1 次提交
    • B
      gfs2: Allow some glocks to be used during withdraw · a72d2401
      Bob Peterson 提交于
      We need to allow some glocks to be enqueued, dequeued, promoted, and demoted
      when we're withdrawn. For example, to maintain metadata integrity, we should
      disallow the use of inode and rgrp glocks when withdrawn. Other glocks, like
      iopen or the transaction glocks may be safely used because none of their
      metadata goes through the journal. So in general, we should disallow all
      glocks with an address space, and allow all the others. One exception is:
      we need to allow our active journal to be demoted so others may recover it.
      
      Allowing glocks after withdraw gives us the ability to take appropriate
      action (in a following patch) to have our journal properly replayed by
      another node rather than just abandoning the current transactions and
      pretending nothing bad happened, leaving the other nodes free to modify
      the blocks we had in our journal, which may result in file system
      corruption.
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      a72d2401
  7. 10 2月, 2020 2 次提交
    • B
      gfs2: Rework how rgrp buffer_heads are managed · b3422cac
      Bob Peterson 提交于
      Before this patch, the rgrp code had a serious problem related to
      how it managed buffer_heads for resource groups. The problem caused
      file system corruption, especially in cases of journal replay.
      
      When an rgrp glock was demoted to transfer ownership to a
      different cluster node, do_xmote() first calls rgrp_go_sync and then
      rgrp_go_inval, as expected. When it calls rgrp_go_sync, that called
      gfs2_rgrp_brelse() that dropped the buffer_head reference count.
      In most cases, the reference count went to zero, which is right.
      However, there were other places where the buffers are handled
      differently.
      
      After rgrp_go_sync, do_xmote called rgrp_go_inval which called
      gfs2_rgrp_brelse a second time, then rgrp_go_inval's call to
      truncate_inode_pages_range would get rid of the pages in memory,
      but only if the reference count drops to 0.
      
      Unfortunately, gfs2_rgrp_brelse was setting bi->bi_bh = NULL.
      So when rgrp_go_sync called gfs2_rgrp_brelse, it lost the pointer
      to the buffer_heads in cases where the reference count was still 1.
      Therefore, when rgrp_go_inval called gfs2_rgrp_brelse a second time,
      it failed the check for "if (bi->bi_bh)" and thus failed to call
      brelse a second time. Because of that, the reference count on those
      buffers sometimes failed to drop from 1 to 0. And that caused
      function truncate_inode_pages_range to keep the pages in page cache
      rather than freeing them.
      
      The next time the rgrp glock was acquired, the metadata read of
      the rgrp buffers re-used the pages in memory, which were now
      wrong because they were likely modified by the other node who
      acquired the glock in EX (which is why we demoted the glock).
      This re-use of the page cache caused corruption because changes
      made by the other nodes were never seen, so the bitmaps were
      inaccurate.
      
      For some reason, the problem became most apparent when journal
      replay forced the replay of rgrps in memory, which caused newer
      rgrp data to be overwritten by the older in-core pages.
      
      A big part of the problem was that the rgrp buffer were released
      in multiple places: The go_unlock function would release them when
      the glock was released rather than when the glock is demoted,
      which is clearly wrong because our intent was to cache them until
      the glock is demoted from SH or EX.
      
      This patch attempts to clean up the mess and make one consistent
      and centralized mechanism for managing the rgrp buffer_heads by
      implementing several changes:
      
      1. It eliminates the call to gfs2_rgrp_brelse() from rgrp_go_sync.
         We don't want to release the buffers or zero the pointers when
         syncing for the reasons stated above. It only makes sense to
         release them when the glock is actually invalidated (go_inval).
         And when we do, then we set the bh pointers to NULL.
      2. The go_unlock function (which was only used for rgrps) is
         eliminated, as we've talked about doing many times before.
         The go_unlock function was called too early in the glock dq
         process, and should not happen until the glock is invalidated.
      3. It also eliminates the call to rgrp_brelse in gfs2_clear_rgrpd.
         That will now happen automatically when the rgrp glocks are
         demoted, and shouldn't happen any sooner or later than that.
         Instead, function gfs2_clear_rgrpd has been modified to demote
         the rgrp glocks, and therefore, free those pages, before the
         remaining glocks are culled by gfs2_gl_hash_clear. This
         prevents the gl_object from hanging around when the glocks are
         culled.
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      Reviewed-by: NAndreas Gruenbacher <agruenba@redhat.com>
      b3422cac
    • A
      gfs2: Split gfs2_lm_withdraw into two functions · badb55ec
      Andreas Gruenbacher 提交于
      Split gfs2_lm_withdraw into a function that prints an error message and a
      function that withdraws the filesystem.
      Signed-off-by: NAndreas Gruenbacher <agruenba@redhat.com>
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      badb55ec
  8. 08 1月, 2020 1 次提交
  9. 15 11月, 2019 1 次提交
  10. 30 10月, 2019 1 次提交
  11. 28 6月, 2019 3 次提交
  12. 05 6月, 2019 1 次提交
  13. 08 5月, 2019 1 次提交
  14. 15 2月, 2019 1 次提交
  15. 12 12月, 2018 2 次提交
  16. 06 6月, 2018 1 次提交
    • D
      vfs: change inode times to use struct timespec64 · 95582b00
      Deepa Dinamani 提交于
      struct timespec is not y2038 safe. Transition vfs to use
      y2038 safe struct timespec64 instead.
      
      The change was made with the help of the following cocinelle
      script. This catches about 80% of the changes.
      All the header file and logic changes are included in the
      first 5 rules. The rest are trivial substitutions.
      I avoid changing any of the function signatures or any other
      filesystem specific data structures to keep the patch simple
      for review.
      
      The script can be a little shorter by combining different cases.
      But, this version was sufficient for my usecase.
      
      virtual patch
      
      @ depends on patch @
      identifier now;
      @@
      - struct timespec
      + struct timespec64
        current_time ( ... )
        {
      - struct timespec now = current_kernel_time();
      + struct timespec64 now = current_kernel_time64();
        ...
      - return timespec_trunc(
      + return timespec64_trunc(
        ... );
        }
      
      @ depends on patch @
      identifier xtime;
      @@
       struct \( iattr \| inode \| kstat \) {
       ...
      -       struct timespec xtime;
      +       struct timespec64 xtime;
       ...
       }
      
      @ depends on patch @
      identifier t;
      @@
       struct inode_operations {
       ...
      int (*update_time) (...,
      -       struct timespec t,
      +       struct timespec64 t,
      ...);
       ...
       }
      
      @ depends on patch @
      identifier t;
      identifier fn_update_time =~ "update_time$";
      @@
       fn_update_time (...,
      - struct timespec *t,
      + struct timespec64 *t,
       ...) { ... }
      
      @ depends on patch @
      identifier t;
      @@
      lease_get_mtime( ... ,
      - struct timespec *t
      + struct timespec64 *t
        ) { ... }
      
      @te depends on patch forall@
      identifier ts;
      local idexpression struct inode *inode_node;
      identifier i_xtime =~ "^i_[acm]time$";
      identifier ia_xtime =~ "^ia_[acm]time$";
      identifier fn_update_time =~ "update_time$";
      identifier fn;
      expression e, E3;
      local idexpression struct inode *node1;
      local idexpression struct inode *node2;
      local idexpression struct iattr *attr1;
      local idexpression struct iattr *attr2;
      local idexpression struct iattr attr;
      identifier i_xtime1 =~ "^i_[acm]time$";
      identifier i_xtime2 =~ "^i_[acm]time$";
      identifier ia_xtime1 =~ "^ia_[acm]time$";
      identifier ia_xtime2 =~ "^ia_[acm]time$";
      @@
      (
      (
      - struct timespec ts;
      + struct timespec64 ts;
      |
      - struct timespec ts = current_time(inode_node);
      + struct timespec64 ts = current_time(inode_node);
      )
      
      <+... when != ts
      (
      - timespec_equal(&inode_node->i_xtime, &ts)
      + timespec64_equal(&inode_node->i_xtime, &ts)
      |
      - timespec_equal(&ts, &inode_node->i_xtime)
      + timespec64_equal(&ts, &inode_node->i_xtime)
      |
      - timespec_compare(&inode_node->i_xtime, &ts)
      + timespec64_compare(&inode_node->i_xtime, &ts)
      |
      - timespec_compare(&ts, &inode_node->i_xtime)
      + timespec64_compare(&ts, &inode_node->i_xtime)
      |
      ts = current_time(e)
      |
      fn_update_time(..., &ts,...)
      |
      inode_node->i_xtime = ts
      |
      node1->i_xtime = ts
      |
      ts = inode_node->i_xtime
      |
      <+... attr1->ia_xtime ...+> = ts
      |
      ts = attr1->ia_xtime
      |
      ts.tv_sec
      |
      ts.tv_nsec
      |
      btrfs_set_stack_timespec_sec(..., ts.tv_sec)
      |
      btrfs_set_stack_timespec_nsec(..., ts.tv_nsec)
      |
      - ts = timespec64_to_timespec(
      + ts =
      ...
      -)
      |
      - ts = ktime_to_timespec(
      + ts = ktime_to_timespec64(
      ...)
      |
      - ts = E3
      + ts = timespec_to_timespec64(E3)
      |
      - ktime_get_real_ts(&ts)
      + ktime_get_real_ts64(&ts)
      |
      fn(...,
      - ts
      + timespec64_to_timespec(ts)
      ,...)
      )
      ...+>
      (
      <... when != ts
      - return ts;
      + return timespec64_to_timespec(ts);
      ...>
      )
      |
      - timespec_equal(&node1->i_xtime1, &node2->i_xtime2)
      + timespec64_equal(&node1->i_xtime2, &node2->i_xtime2)
      |
      - timespec_equal(&node1->i_xtime1, &attr2->ia_xtime2)
      + timespec64_equal(&node1->i_xtime2, &attr2->ia_xtime2)
      |
      - timespec_compare(&node1->i_xtime1, &node2->i_xtime2)
      + timespec64_compare(&node1->i_xtime1, &node2->i_xtime2)
      |
      node1->i_xtime1 =
      - timespec_trunc(attr1->ia_xtime1,
      + timespec64_trunc(attr1->ia_xtime1,
      ...)
      |
      - attr1->ia_xtime1 = timespec_trunc(attr2->ia_xtime2,
      + attr1->ia_xtime1 =  timespec64_trunc(attr2->ia_xtime2,
      ...)
      |
      - ktime_get_real_ts(&attr1->ia_xtime1)
      + ktime_get_real_ts64(&attr1->ia_xtime1)
      |
      - ktime_get_real_ts(&attr.ia_xtime1)
      + ktime_get_real_ts64(&attr.ia_xtime1)
      )
      
      @ depends on patch @
      struct inode *node;
      struct iattr *attr;
      identifier fn;
      identifier i_xtime =~ "^i_[acm]time$";
      identifier ia_xtime =~ "^ia_[acm]time$";
      expression e;
      @@
      (
      - fn(node->i_xtime);
      + fn(timespec64_to_timespec(node->i_xtime));
      |
       fn(...,
      - node->i_xtime);
      + timespec64_to_timespec(node->i_xtime));
      |
      - e = fn(attr->ia_xtime);
      + e = fn(timespec64_to_timespec(attr->ia_xtime));
      )
      
      @ depends on patch forall @
      struct inode *node;
      struct iattr *attr;
      identifier i_xtime =~ "^i_[acm]time$";
      identifier ia_xtime =~ "^ia_[acm]time$";
      identifier fn;
      @@
      {
      + struct timespec ts;
      <+...
      (
      + ts = timespec64_to_timespec(node->i_xtime);
      fn (...,
      - &node->i_xtime,
      + &ts,
      ...);
      |
      + ts = timespec64_to_timespec(attr->ia_xtime);
      fn (...,
      - &attr->ia_xtime,
      + &ts,
      ...);
      )
      ...+>
      }
      
      @ depends on patch forall @
      struct inode *node;
      struct iattr *attr;
      struct kstat *stat;
      identifier ia_xtime =~ "^ia_[acm]time$";
      identifier i_xtime =~ "^i_[acm]time$";
      identifier xtime =~ "^[acm]time$";
      identifier fn, ret;
      @@
      {
      + struct timespec ts;
      <+...
      (
      + ts = timespec64_to_timespec(node->i_xtime);
      ret = fn (...,
      - &node->i_xtime,
      + &ts,
      ...);
      |
      + ts = timespec64_to_timespec(node->i_xtime);
      ret = fn (...,
      - &node->i_xtime);
      + &ts);
      |
      + ts = timespec64_to_timespec(attr->ia_xtime);
      ret = fn (...,
      - &attr->ia_xtime,
      + &ts,
      ...);
      |
      + ts = timespec64_to_timespec(attr->ia_xtime);
      ret = fn (...,
      - &attr->ia_xtime);
      + &ts);
      |
      + ts = timespec64_to_timespec(stat->xtime);
      ret = fn (...,
      - &stat->xtime);
      + &ts);
      )
      ...+>
      }
      
      @ depends on patch @
      struct inode *node;
      struct inode *node2;
      identifier i_xtime1 =~ "^i_[acm]time$";
      identifier i_xtime2 =~ "^i_[acm]time$";
      identifier i_xtime3 =~ "^i_[acm]time$";
      struct iattr *attrp;
      struct iattr *attrp2;
      struct iattr attr ;
      identifier ia_xtime1 =~ "^ia_[acm]time$";
      identifier ia_xtime2 =~ "^ia_[acm]time$";
      struct kstat *stat;
      struct kstat stat1;
      struct timespec64 ts;
      identifier xtime =~ "^[acmb]time$";
      expression e;
      @@
      (
      ( node->i_xtime2 \| attrp->ia_xtime2 \| attr.ia_xtime2 \) = node->i_xtime1  ;
      |
       node->i_xtime2 = \( node2->i_xtime1 \| timespec64_trunc(...) \);
      |
       node->i_xtime2 = node->i_xtime1 = node->i_xtime3 = \(ts \| current_time(...) \);
      |
       node->i_xtime1 = node->i_xtime3 = \(ts \| current_time(...) \);
      |
       stat->xtime = node2->i_xtime1;
      |
       stat1.xtime = node2->i_xtime1;
      |
      ( node->i_xtime2 \| attrp->ia_xtime2 \) = attrp->ia_xtime1  ;
      |
      ( attrp->ia_xtime1 \| attr.ia_xtime1 \) = attrp2->ia_xtime2;
      |
      - e = node->i_xtime1;
      + e = timespec64_to_timespec( node->i_xtime1 );
      |
      - e = attrp->ia_xtime1;
      + e = timespec64_to_timespec( attrp->ia_xtime1 );
      |
      node->i_xtime1 = current_time(...);
      |
       node->i_xtime2 = node->i_xtime1 = node->i_xtime3 =
      - e;
      + timespec_to_timespec64(e);
      |
       node->i_xtime1 = node->i_xtime3 =
      - e;
      + timespec_to_timespec64(e);
      |
      - node->i_xtime1 = e;
      + node->i_xtime1 = timespec_to_timespec64(e);
      )
      Signed-off-by: NDeepa Dinamani <deepa.kernel@gmail.com>
      Cc: <anton@tuxera.com>
      Cc: <balbi@kernel.org>
      Cc: <bfields@fieldses.org>
      Cc: <darrick.wong@oracle.com>
      Cc: <dhowells@redhat.com>
      Cc: <dsterba@suse.com>
      Cc: <dwmw2@infradead.org>
      Cc: <hch@lst.de>
      Cc: <hirofumi@mail.parknet.co.jp>
      Cc: <hubcap@omnibond.com>
      Cc: <jack@suse.com>
      Cc: <jaegeuk@kernel.org>
      Cc: <jaharkes@cs.cmu.edu>
      Cc: <jslaby@suse.com>
      Cc: <keescook@chromium.org>
      Cc: <mark@fasheh.com>
      Cc: <miklos@szeredi.hu>
      Cc: <nico@linaro.org>
      Cc: <reiserfs-devel@vger.kernel.org>
      Cc: <richard@nod.at>
      Cc: <sage@redhat.com>
      Cc: <sfrench@samba.org>
      Cc: <swhiteho@redhat.com>
      Cc: <tj@kernel.org>
      Cc: <trond.myklebust@primarydata.com>
      Cc: <tytso@mit.edu>
      Cc: <viro@zeniv.linux.org.uk>
      95582b00
  17. 23 1月, 2018 2 次提交
  18. 10 8月, 2017 1 次提交
  19. 21 7月, 2017 1 次提交
    • W
      GFS2: fix code parameter error in inode_go_lock · e7cb550d
      Wang Xibo 提交于
      In inode_go_lock() function, the parameter order of list_add() is error.
      According to the define of list_add(), the first parameter is new entry
      and the second is the list head, so ip->i_trunc_list should be the
      first parameter and the sdp->sd_trunc_list should be second.
      
      Signed-off-by: Wang Xibo<wang.xibo@zte.com.cn>
      Signed-off-by: Xiao Likun<xiao.likun@zte.com.cn>
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      e7cb550d
  20. 17 7月, 2017 1 次提交
    • D
      VFS: Convert sb->s_flags & MS_RDONLY to sb_rdonly(sb) · bc98a42c
      David Howells 提交于
      Firstly by applying the following with coccinelle's spatch:
      
      	@@ expression SB; @@
      	-SB->s_flags & MS_RDONLY
      	+sb_rdonly(SB)
      
      to effect the conversion to sb_rdonly(sb), then by applying:
      
      	@@ expression A, SB; @@
      	(
      	-(!sb_rdonly(SB)) && A
      	+!sb_rdonly(SB) && A
      	|
      	-A != (sb_rdonly(SB))
      	+A != sb_rdonly(SB)
      	|
      	-A == (sb_rdonly(SB))
      	+A == sb_rdonly(SB)
      	|
      	-!(sb_rdonly(SB))
      	+!sb_rdonly(SB)
      	|
      	-A && (sb_rdonly(SB))
      	+A && sb_rdonly(SB)
      	|
      	-A || (sb_rdonly(SB))
      	+A || sb_rdonly(SB)
      	|
      	-(sb_rdonly(SB)) != A
      	+sb_rdonly(SB) != A
      	|
      	-(sb_rdonly(SB)) == A
      	+sb_rdonly(SB) == A
      	|
      	-(sb_rdonly(SB)) && A
      	+sb_rdonly(SB) && A
      	|
      	-(sb_rdonly(SB)) || A
      	+sb_rdonly(SB) || A
      	)
      
      	@@ expression A, B, SB; @@
      	(
      	-(sb_rdonly(SB)) ? 1 : 0
      	+sb_rdonly(SB)
      	|
      	-(sb_rdonly(SB)) ? A : B
      	+sb_rdonly(SB) ? A : B
      	)
      
      to remove left over excess bracketage and finally by applying:
      
      	@@ expression A, SB; @@
      	(
      	-(A & MS_RDONLY) != sb_rdonly(SB)
      	+(bool)(A & MS_RDONLY) != sb_rdonly(SB)
      	|
      	-(A & MS_RDONLY) == sb_rdonly(SB)
      	+(bool)(A & MS_RDONLY) == sb_rdonly(SB)
      	)
      
      to make comparisons against the result of sb_rdonly() (which is a bool)
      work correctly.
      Signed-off-by: NDavid Howells <dhowells@redhat.com>
      bc98a42c
  21. 05 7月, 2017 2 次提交
  22. 05 4月, 2016 1 次提交
  23. 25 12月, 2015 1 次提交
  24. 30 10月, 2015 1 次提交
  25. 04 9月, 2015 1 次提交
  26. 19 6月, 2015 2 次提交
    • B
      GFS2: Don't brelse rgrp buffer_heads every allocation · 39b0f1e9
      Bob Peterson 提交于
      This patch allows the block allocation code to retain the buffers
      for the resource groups so they don't need to be re-read from buffer
      cache with every request. This is a performance improvement that's
      especially noticeable when resource groups are very large. For
      example, with 2GB resource groups and 4K blocks, there can be 33
      blocks for every resource group. This patch allows those 33 buffers
      to be kept around and not read in and thrown away with every
      operation. The buffers are released when the resource group is
      either synced or invalidated.
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      Reviewed-by: NSteven Whitehouse <swhiteho@redhat.com>
      Reviewed-by: NBenjamin Marzinski <bmarzins@redhat.com>
      39b0f1e9
    • B
      GFS2: Don't add all glocks to the lru · e7ccaf5f
      Bob Peterson 提交于
      The glocks used for resource groups often come and go hundreds of
      thousands of times per second. Adding them to the lru list just
      adds unnecessary contention for the lru_lock spin_lock, especially
      considering we're almost certainly going to re-use the glock and
      take it back off the lru microseconds later. We never want the
      glock shrinker to cull them anyway. This patch adds a new bit in
      the glops that determines which glock types get put onto the lru
      list and which ones don't.
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      Acked-by: NSteven Whitehouse <swhiteho@redhat.com>
      e7ccaf5f
  27. 17 11月, 2014 1 次提交
    • B
      GFS2: update freeze code to use freeze/thaw_super on all nodes · 2e60d768
      Benjamin Marzinski 提交于
      The current gfs2 freezing code is considerably more complicated than it
      should be because it doesn't use the vfs freezing code on any node except
      the one that begins the freeze.  This is because it needs to acquire a
      cluster glock before calling the vfs code to prevent a deadlock, and
      without the new freeze_super and thaw_super hooks, that was impossible. To
      deal with the issue, gfs2 had to do some hacky locking tricks to make sure
      that a frozen node couldn't be holding on a lock it needed to do the
      unfreeze ioctl.
      
      This patch makes use of the new hooks to simply the gfs2 locking code. Now,
      all the nodes in the cluster freeze and thaw in exactly the same way. Every
      node in the cluster caches the freeze glock in the shared state.  The new
      freeze_super hook allows the freezing node to grab this freeze glock in
      the exclusive state without first calling the vfs freeze_super function.
      All the nodes in the cluster see this lock change, and call the vfs
      freeze_super function. The vfs locking code guarantees that the nodes can't
      get stuck holding the glocks necessary to unfreeze the system.  To
      unfreeze, the freezing node uses the new thaw_super hook to drop the freeze
      glock. Again, all the nodes notice this, reacquire the glock in shared mode
      and call the vfs thaw_super function.
      Signed-off-by: NBenjamin Marzinski <bmarzins@redhat.com>
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      2e60d768
  28. 08 10月, 2014 1 次提交