1. 15 1月, 2014 6 次提交
    • S
      GFS2: Fix kbuild test robot reported warning · 1e3d3620
      Steven Whitehouse 提交于
      Well I don't get the same warning locally as the kbuild
      robot, but I guess this should fix the problem, anyway.
      Here is the warning:
      
      head:   2d9e7230
      commit: ee2411a8 [19/20] GFS2: Clean up quota slot allocation
      config: make ARCH=powerpc allmodconfig
      
      All error/warnings:
      
         fs/gfs2/quota.c: In function 'gfs2_quota_init':
      >> fs/gfs2/quota.c:1246:3: error: implicit declaration of function '__vmalloc' [-Werror=implicit-function-declaration]
            sdp->sd_quota_bitmap = __vmalloc(bm_size, GFP_NOFS, PAGE_KERNEL);
            ^
      >> fs/gfs2/quota.c:1246:24: warning: assignment makes pointer from integer without a cast [enabled by default]
            sdp->sd_quota_bitmap = __vmalloc(bm_size, GFP_NOFS, PAGE_KERNEL);
                                 ^
         fs/gfs2/quota.c: In function 'gfs2_quota_cleanup':
      >> fs/gfs2/quota.c:1361:4: error: implicit declaration of function 'vfree' [-Werror=implicit-function-declaration]
             vfree(sdp->sd_quota_bitmap);
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      1e3d3620
    • S
      GFS2: Move quota bitmap operations under their own lock · 2d9e7230
      Steven Whitehouse 提交于
      Gradually, the global qd_lock is being used for less and less.
      After this patch it will only be used for the per super block
      list whose purpose is to allow syncing of changes back to the
      master quota file from the local quota changes file. Fixing
      up that process to make it more efficient will be the subject
      of a later patch, however this patch removes another barrier
      to doing that.
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      Cc: Abhijith Das <adas@redhat.com>
      2d9e7230
    • S
      GFS2: Clean up quota slot allocation · ee2411a8
      Steven Whitehouse 提交于
      Quota slot allocation has historically used a vector of pages
      and a set of homegrown find/test/set/clear bit functions. Since
      the size of the bitmap is likely to be based on the default
      qc file size, thats a couple of pages at most. So we ought
      to be able to allocate that as a single chunk, with a vmalloc
      fallback, just in case of memory fragmentation.
      
      We are then able to use the kernel's own find/test/set/clear
      bit functions, rather than rolling our own.
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      Cc: Abhijith Das <adas@redhat.com>
      ee2411a8
    • S
      GFS2: Only run logd and quota when mounted read/write · 8ad151c2
      Steven Whitehouse 提交于
      While investigating a rather strange bit of code in the quota
      clean up function, I spotted that the reason for its existence
      was that when remounting read only, we were not stopping the
      quotad thread, and thus it was possible for it to still have
      a reference to some of the quotas in that case.
      
      This patch moves the logd and quota thread start and stop into
      the make_fs_rw/ro functions, so that we now stop those threads
      when mounted read only.
      
      This means that quotad will always be stopped before we call
      the quota clean up function, and we can thus dispose of the
      (rather hackish) code that waits for it to give up its
      reference on the quotas.
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      Cc: Abhijith Das <adas@redhat.com>
      8ad151c2
    • S
      GFS2: Use RCU/hlist_bl based hash for quotas · c754fbbb
      Steven Whitehouse 提交于
      Prior to this patch, GFS2 kept all the quotas for each
      super block in a single linked list. This is rather slow
      when there are large numbers of quotas.
      
      This patch introduces a hlist_bl based hash table, similar
      to the one used for glocks. The initial look up of the quota
      is now lockless in the case where it is already cached,
      although we still have to take the per quota spinlock in
      order to bump the ref count. Either way though, this is a
      big improvement on what was there before.
      
      The qd_lock and the per super block list is preserved, for
      the time being. However it is intended that since this is no
      longer used for its original role, it should be possible to
      shrink the number of items on that list in due course and
      remove the requirement to take qd_lock in qd_get.
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      Cc: Abhijith Das <adas@redhat.com>
      Cc: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
      c754fbbb
    • S
      GFS2: No need to invalidate pages for a dio read · 086352f1
      Steven Whitehouse 提交于
      We recently fixed the writeback of pages prior to performing
      direct i/o, however the initial fix was perhaps a bit heavy
      handed. There is no need to invalidate pages if the direct i/o
      is only a read, since they will be identical to what has been
      flushed to disk anyway.
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      086352f1
  2. 10 1月, 2014 1 次提交
  3. 08 1月, 2014 2 次提交
    • S
      GFS2: Add hints to directory leaf blocks · 01bcb0de
      Steven Whitehouse 提交于
      This patch adds four new fields to directory leaf blocks.
      The intent is not to use them in the kernel itself, although
      perhaps we may be able to use them as hints at some later date,
      but instead to provide more information for debug/fsck use.
      
      One new field adds a pointer to the inode to which the leaf
      belongs. This can be useful if the pointer to the leaf block
      has become corrupt, as it will allow us to know which inode
      this block should be associated with. This field is set when
      the leaf is created and never changed over its lifetime.
      
      The second field is a "distance from the hash table" field.
      The meaning is as follows:
       0  = An old leaf in which this value has not been set
       1  = This leaf is pointed to directly from the hash table
       2+ = This leaf is part of a chain, pointed to by another leaf
            block, the value gives the position in the chain.
      
      The third and fourth fields combine to give a time stamp of
      the most recent directory insertion or deletion from this
      leaf block. The time stamp is not updated when a new leaf
      block is chained from the current one. The code is currently
      written such that the timestamp on the dir inode will match
      that of the leaf block for the most recent insertion/deletion.
      
      For backwards compatibility, any of these new fields which is
      zero should be considered to be "unknown".
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      01bcb0de
    • S
      GFS2: For exhash conversion, only one block is needed · 22b5a6c0
      Steven Whitehouse 提交于
      For most cases, only a single new block is needed when we reach
      the point of converting from stuffed to exhash directory. The
      exception being when the file name is so long that it will not
      fit within the new leaf block.
      
      So this patch adds a simple test for that situation so that we
      do not need to request the full reservation size in this case.
      
      Potentially we could calculate more accurately the value to use
      in other cases too, but that is much more complicated to do and
      it is doubtful that the benefit would outweigh the extra cost
      in code complexity.
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      22b5a6c0
  4. 07 1月, 2014 1 次提交
  5. 06 1月, 2014 3 次提交
    • S
      GFS2: Remember directory insert point · 2b47dad8
      Steven Whitehouse 提交于
      When we look to see if there is enough space to add a dir
      entry without allocation, we have then been repeating the
      same search later when we do the actual insertion. This
      patch caches the details of the location in the gfs2_diradd
      structure, so that we do not have to repeat the search.
      
      This will provide a performance improvement which will be
      greater as the size of the directory increases.
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      2b47dad8
    • S
      GFS2: Consolidate transaction blocks calculation for dir add · 534cf9ca
      Steven Whitehouse 提交于
      There are three cases where we need to calculate the number of
      blocks to reserve in a transaction involving linking an inode
      into a directory. The one in rename is a bit more complicated,
      but the basis of it is the same as for link and create. So it
      makes sense to move this calculation into a single function
      rather than repeating it three times.
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      534cf9ca
    • S
      GFS2: Add directory addition info structure · 3c1c0ae1
      Steven Whitehouse 提交于
      The intent is that this structure will hold the information
      required when adding entries to a directory (linking). To
      start with, it will contain only the number of blocks which
      are required to link the new entry into the directory. The
      current calculation returns either 0 or the maximim number of
      blocks that can ever be requested by such a transaction.
      
      The intent is that in a later patch, we can update the dir
      code to calculate this value more accurately. In addition
      further patches will also add further fields to the new
      structure to increase its utility.
      
      In addition this patch fixes a bug where the link used during
      inode creation was adding requesting too many blocks in
      some cases. This is harmless unless the fs is close to being
      full.
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      3c1c0ae1
  6. 03 1月, 2014 8 次提交
    • S
      GFS2: Use only a single address space for rgrps · 70d4ee94
      Steven Whitehouse 提交于
      Prior to this patch, GFS2 had one address space for each rgrp,
      stored in the glock. This patch changes them to use a single
      address space in the super block. This therefore saves
      (sizeof(struct address_space) * nr_of_rgrps) bytes of memory
      and for large filesystems, that can be significant.
      
      It would be nice to be able to do something similar and merge
      the inode metadata address space into the same global
      address space. However, that is rather more complicated as the
      on-disk location doesn't have a 1:1 mapping with the inodes in
      general. So while it could be done, it will be a more complicated
      operation as it requires changing a lot more code paths.
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      70d4ee94
    • S
      GFS2: Use range based functions for rgrp sync/invalidation · 7005c3e4
      Steven Whitehouse 提交于
      Each rgrp header is represented as a single extent on disk, so we
      can calculate the position within the address space, since we are
      using address spaces mapped 1:1 to the disk. This means that it
      is possible to use the range based versions of filemap_fdatawrite/wait
      and for invalidating the page cache.
      
      Our eventual intent is to then be able to merge the address spaces
      used for rgrps into a single address space, rather than to have
      one for each glock, saving memory and reducing complexity.
      
      Since during umount, the rgrp structures are disposed of before
      the glocks, we need to store the extent information in the glock
      so that is is available for a final invalidation. This patch uses
      a field which is otherwise unused in rgrp glocks to do that, so
      that we do not have to expand the size of a glock.
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      7005c3e4
    • S
      GFS2: Remove test which is always true · 7de41d36
      Steven Whitehouse 提交于
      Since gfs2_inplace_reserve() is always called with a valid
      alloc parms structure, there is no need to test for this
      within the function itself - and in any case, after we've
      all ready dereferenced it anyway.
      Reported-by: NDan Carpenter <dan.carpenter@oracle.com>
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      7de41d36
    • S
      GFS2: Remove gfs2_quota_change_host structure · 7aed98fb
      Steven Whitehouse 提交于
      There is only one place this is used, when reading in the quota
      changes at mount time. It is not really required and much
      simpler to just convert the fields from the on-disk structure
      as required.
      
      There should be no functional change as a result of this patch.
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      7aed98fb
    • S
      GFS2: Clean up releasepage · e4f29206
      Steven Whitehouse 提交于
      For historical reasons, we drop and retake the log lock in ->releasepage()
      however, since there is no reason why we cannot hold the log lock over
      the whole function, this allows some simplification. In particular,
      pinning a buffer is only ever done under the log lock, so it is possible
      here to remove the test for pinned buffers in the second loop, since it
      is impossible for that to happen (it is also tested in the first loop).
      
      As a result, two tests made later in the second loop become constants
      and can also be reduced to the only possible branch. So the net result
      is to remove various bits of unreachable code and make this more
      readable.
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      e4f29206
    • B
      GFS2: Implement a "rgrp has no extents longer than X" scheme · 5ea5050c
      Bob Peterson 提交于
      With the preceding patch, we started accepting block reservations
      smaller than the ideal size, which requires a lot more parsing of the
      bitmaps. To reduce the amount of bitmap searching, this patch
      implements a scheme whereby each rgrp keeps track of the point
      at this multi-block reservations will fail.
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      5ea5050c
    • B
      GFS2: Drop inadequate rgrps from the reservation tree · 1330edbe
      Bob Peterson 提交于
      This is just basically a resend of a patch I posted earlier.
      It didn't change from its original, except in diff offsets, etc:
      
      This patch fixes a bug in the GFS2 block allocation code. The problem
      starts if a process already has a multi-block reservation, but for
      some reason, another process disqualifies it from further allocations.
      For example, the other process might set on the GFS2_RDF_ERROR bit.
      The process holding the reservation jumps to label skip_rgrp, but
      that label comes after the code that removes the reservation from the
      tree. Therefore, the no longer usable reservation is not removed from
      the rgrp's reservations tree; it's lost. Eventually, the lost reservation
      causes the count of reserved blocks to get off, and eventually that
      causes a BUG_ON(rs->rs_rbm.rgd->rd_reserved < rs->rs_free) to trigger.
      This patch moves the call to after label skip_rgrp so that the
      disqualified reservation is properly removed from the tree, thus keeping
      the rgrp rd_reserved count sane.
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      1330edbe
    • B
      GFS2: If requested is too large, use the largest extent in the rgrp · 5ce13431
      Bob Peterson 提交于
      Here is a second try at a patch I posted earlier, which also implements
      suggestions Steve made:
      
      Before this patch, GFS2 would keep searching through all the rgrps
      until it found one that had a chunk of free blocks big enough to
      satisfy the size hint, which is based on the file write size,
      regardless of whether the chunk was big enough to perform the write.
      However, when doing big writes there may not be a large enough
      chunk of free blocks in any rgrp, due to file system fragmentation.
      The largest chunk may be big enough to satisfy the write request,
      but it may not meet the ideal reservation size from the "size hint".
      The writes would slow to a crawl because every write would search
      every rgrp, then finally give up and default to a single-block write.
      In my case, performance would drop from 425MB/s to 18KB/s, or 24000
      times slower.
      
      This patch basically makes it so that if we can't find a contiguous
      chunk of blocks big enough to satisfy the sizehint, we'll use the
      largest chunk of blocks we found that will still contain the write.
      It does so by keeping track of the largest run of blocks within the
      rgrp.
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      5ce13431
  7. 02 1月, 2014 1 次提交
  8. 20 12月, 2013 2 次提交
    • S
      GFS2: Wait for async DIO in glock state changes · 582d2f7a
      Steven Whitehouse 提交于
      We need to wait for any outstanding DIO to complete in a couple
      of situations. Firstly, in case we are changing out of deferred
      mode (in inode_go_sync) where GLF_DIRTY will not be set. That
      call could be prefixed with a test for gl_state == LM_ST_DEFERRED
      but it doesn't seem worth it bearing in mind that the test for
      outstanding DIO is very quick anyway, in the usual case that there
      is none.
      
      The second case is in inode_go_lock which will catch the cases
      where we have a cached EX lock, but where we grant deferred locks
      against it so that there is no glock state transistion. We only
      need to wait if the state is not deferred, since DIO is valid
      anyway in that state.
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      582d2f7a
    • S
      GFS2: Fix incorrect invalidation for DIO/buffered I/O · dfd11184
      Steven Whitehouse 提交于
      In patch 209806ab we allowed
      local deferred locks to be granted against a cached exclusive
      lock. That opened up a corner case which this patch now
      fixes.
      
      The solution to the problem is to check whether we have cached
      pages each time we do direct I/O and if so to unmap, flush
      and invalidate those pages. Since the glock state machine
      normally does that for us, mostly the code will be a no-op.
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      dfd11184
  9. 14 12月, 2013 3 次提交
    • B
      GFS2: Fix slab memory leak in gfs2_bufdata · 502be2a3
      Bob Peterson 提交于
      This patch fixes a slab memory leak that sometimes can occur
      for files with a very short lifespan. The problem occurs when
      a dinode is deleted before it has gotten to the journal properly.
      In the leak scenario, the bd object is pinned for journal
      committment (queued to the metadata buffers queue: sd_log_le_buf)
      but is subsequently unpinned and dequeued before it finds its way
      to the ail or the revoke queue. In this rare circumstance, the bd
      object needs to be freed from slab memory, or it is forgotten.
      We have to be very careful how we do it, though, because
      multiple processes can call gfs2_remove_from_journal. In order to
      avoid double-frees, only the process that does the unpinning is
      allowed to free the bd.
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      502be2a3
    • B
      GFS2: Fix use-after-free race when calling gfs2_remove_from_ail · 9290a9a7
      Bob Peterson 提交于
      Function gfs2_remove_from_ail drops the reference on the bh via
      brelse. This patch fixes a race condition whereby bh is deferenced
      after the brelse when setting bd->bd_blkno = bh->b_blocknr;
      Under certain rare circumstances, bh might be gone or reused,
      and bd->bd_blkno is set to whatever that memory happens to be,
      which is often 0. Later, in gfs2_trans_add_unrevoke, that bd fails
      the test "bd->bd_blkno >= blkno" which causes it to never be freed.
      The end result is that the bd is never freed from the bufdata cache,
      which results in this error:
      slab error in kmem_cache_destroy(): cache `gfs2_bufdata': Can't free all objects
      Signed-off-by: NBob Peterson <rpeterso@redhat.com>
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      9290a9a7
    • S
      GFS2: don't hold s_umount over blkdev_put · dfe5b9ad
      Steven Whitehouse 提交于
      This is a GFS2 version of Tejun's patch:
      4f331f01
      vfs: don't hold s_umount over close_bdev_exclusive() call
      
      In this case its blkdev_put itself that is the issue and this
      patch uses the same solution of dropping and retaking s_umount.
      Reported-by: NTejun Heo <tj@kernel.org>
      Reported-by: NAl Viro <viro@ZenIV.linux.org.uk>
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      dfe5b9ad
  10. 22 11月, 2013 1 次提交
  11. 21 11月, 2013 1 次提交
  12. 16 11月, 2013 1 次提交
  13. 04 11月, 2013 3 次提交
  14. 25 10月, 2013 1 次提交
  15. 15 10月, 2013 1 次提交
    • S
      GFS2: Use lockref for glocks · e66cf161
      Steven Whitehouse 提交于
      Currently glocks have an atomic reference count and also a spinlock
      which covers various internal fields, such as the state. This intent of
      this patch is to replace the spinlock and the atomic reference count
      with a lockref structure. This contains a spinlock which we can continue
      to use as before, and a reference counter which is used in conjuction
      with the spinlock to replace the previous atomic counter.
      
      As a result of this there are some new rules for reference counting on
      glocks. We need to distinguish between reference count changes under
      gl_spin (which are now just increment or decrement of the new counter,
      provided the count cannot hit zero) and those which are outside of
      gl_spin, but which now take gl_spin internally.
      
      The conversion is relatively straight forward. There is probably some
      further clean up which can be done, but the priority at this stage is to
      make the change in as simple a manner as possible.
      
      A consequence of this change is that the reference count is being
      decoupled from the lru list processing. This should allow future
      adoption of the lru_list code with glocks in due course.
      
      The reason for using the "dead" state and not just relying on 0 being
      the "invalid state" is so that in due course 0 ref counts can be
      allowable. The intent is to eventually be able to remove the ref count
      changes which are currently hidden away in state_change().
      Signed-off-by: NSteven Whitehouse <swhiteho@redhat.com>
      e66cf161
  16. 04 10月, 2013 4 次提交
  17. 02 10月, 2013 1 次提交