1. Jun 23, 2015
    • Dave Chinner's avatar
      de50e16f
    • Dave Chinner's avatar
      3d238b7e
    • Brian Foster's avatar
      xfs: don't truncate attribute extents if no extents exist · f66bf042
      Brian Foster authored
      The xfs_attr3_root_inactive() call from xfs_attr_inactive() assumes that
      attribute blocks exist to invalidate. It is possible to have an
      attribute fork without extents, however. Consider the case where the
      attribute fork is created towards the beginning of xfs_attr_set() but
      some part of the subsequent attribute set fails.
      
      If an inode in such a state hits xfs_attr_inactive(), it eventually
      calls xfs_dabuf_map() and possibly xfs_bmapi_read(). The former emits a
      filesystem corruption warning, returns an error that bubbles back up to
      xfs_attr_inactive(), and leads to destruction of the in-core attribute
      fork without an on-disk reset. If the inode happens to make it back
      through xfs_inactive() in this state (e.g., via a concurrent bulkstat
      that cycles the inode from the reclaim state and releases it), i_afp
      might not exist when xfs_bmapi_read() is called and causes a NULL
      dereference panic.
      
      A '-p 2' fsstress run to ENOSPC on a relatively small fs (1GB)
      reproduces these problems. The behavior is a regression caused by:
      
      6dfe5a04
      
       xfs: xfs_attr_inactive leaves inconsistent attr fork state behind
      
      ... which removed logic that avoided the attribute extent truncate when
      no extents exist. Restore this logic to ensure the attribute fork is
      destroyed and reset correctly if it exists without any allocated
      extents.
      
      cc: stable@vger.kernel.org # 3.12 to 4.0.x
      Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
      Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
      Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
      f66bf042
  2. Jun 22, 2015
  3. Jun 04, 2015
  4. Jun 01, 2015
    • Dave Chinner's avatar
      b9a350a1
    • Dave Chinner's avatar
      e01c025f
    • Nan Jia's avatar
      xfs: Clean up xfs_trans_dup_dqinfo · 339e4f66
      Nan Jia authored
      
      
      Fixed two missing spaces.
      
      Signed-off-by: default avatarNan Jia <jiananmail@gmail.com>
      Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
      Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
      339e4f66
    • Fanael Linithien's avatar
      xfs: fix kernel version in docs · 4d66ea09
      Fanael Linithien authored
      
      
      Linux v3.20 was released as v4.0.
      
      Signed-off-by: default avatarFanael Linithien <fanael4@gmail.com>
      Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
      Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
      
      4d66ea09
    • Eric Sandeen's avatar
      xfs: don't cast string literals · 39e56d92
      Eric Sandeen authored
      The commit:
      
      a9273ca5
      
       xfs: convert attr to use unsigned names
      
      added these (unsigned char *) casts, but then the _SIZE macros
      return "7" - size of a pointer minus one - not the length of
      the string.  This is harmless in the kernel, because the _SIZE
      macros are not used, but as we sync up with userspace, this will
      matter.
      
      I don't think the cast is necessary; i.e. assigning the string
      literal to an unsigned char *, or passing it to a function
      expecting an unsigned char *, should be ok, right?
      
      Signed-off-by: default avatarEric Sandeen <sandeen@redhat.com>
      Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
      Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
      
      39e56d92
    • Brian Foster's avatar
      xfs: fix quota block reservation leak when tp allocates and frees blocks · 7f884dc1
      Brian Foster authored
      Al Viro reports that generic/231 fails frequently on XFS and bisected
      the problem to the following commit:
      
      	5d11fb4b
      
       xfs: rework zero range to prevent invalid i_size updates
      
      ... which is just the first commit that happens to cause fsx to
      reproduce the problem. fsx reproduces via zero range calls. The
      aforementioned commit overhauls zero range to use hole punch and
      fallocate. As it turns out, the problem is reproducible on demand using
      basic hole punch as follows:
      
      $ mkfs.xfs -f -m crc=1,finobt=1 <dev>
      $ mount <dev> /mnt -o uquota
      $ xfs_io -f -c "falloc 0 50m" /mnt/file
      $ for i in $(seq 1 20); do xfs_io -c "fpunch ${i}m 32k" /mnt/file; done
      $ rm -f /mnt/file
      $ repquota -us /mnt
      ...
      User            used    soft    hard  grace    used  soft  hard  grace
      ----------------------------------------------------------------------
      root      --     32K      0K      0K              3     0     0
      
      A file is allocated with a single 50m extent. The extent count increases
      via hole punches until the bmap converts to btree format. The file is
      removed but quota reports 32k of space usage for the user. This
      reservation is effectively leaked for the lifetime of the mount.
      
      The reason this occurs is because the quota block reservation tracking
      is confused when a transaction happens to free and allocate blocks at
      the same time. Consider the following sequence of events:
      
      - tp is allocated from xfs_free_file_space() and reserves several blocks
        for btree management. Blocks are reserved against the dquot and marked
        as such in the transaction (qtrx->qt_blk_res).
      - 8 blocks are accounted free when the 32k range is punched out.
        xfs_trans_mod_dquot() is called with XFS_TRANS_DQ_BCOUNT and sets
        ->qt_bcount_delta to -8.
      - Subsequently, a block is allocated against the same transaction by
        xfs_bmap_extents_to_btree() for btree conversion. A call to
        xfs_trans_mod_dquot() increases qt_blk_res_used to 1 and qt_bcount_delta
        to -7.
      - The transaction is dup'd and committed by xfs_bmap_finish().
        xfs_trans_dup_dqinfo() sets the first transaction up such that it has a
        matching qt_blk_res and qt_blk_res_used of 1. The remaining unused
        reservation is transferred to the duplicate tp.
      
      When the transactions are committed, the dquots are fixed up in
      xfs_trans_apply_dquot_deltas() according to one of two methods:
      
      1.) If the transaction holds a block reservation (->qt_blk_res != 0),
      _only_ the unused portion reservation is unaccounted from the dquot.
      Note that the tp duplication behavior of xfs_bmap_finish() makes it such
      that qt_blk_res is typically 0 for tp's with unused reservation.
      2.) Otherwise, the dquot is fixed up based on the block delta
      (->qt_bcount_delta) created by the transaction.
      
      Therefore, if a transaction has a negative qt_bcount_delta and positive
      qt_blk_res_used, the former set of blocks that have been removed from
      the file are never factored out of the in-core dquot reservation.
      Instead, *_apply_dquot_deltas() sees 1 block used out of a 1 block
      reservation and believes there is nothing to fix up. The on-disk
      d_bcount is updated independently from qt_bcount_delta, and thus is
      correct (and allows the quota usage to correct on remount).
      
      To deal with this situation, we effectively want the "used reservation"
      part of the transaction to be consistent with any freed blocks with
      respect to quota tracking. For example, if 8 blocks are freed, the
      subsequent single block allocation does not need to consume the initial
      reservation made by the tp. Instead, it simply borrows one from the
      previously freed. One possible implementation of such borrowing is to
      avoid the blks_res_used increment when bcount_delta is negative. This
      alone is flawed logic in that it only handles the case where blocks are
      freed before allocated, however.
      
      Rather than add more complexity to manage synchronization between
      bcount_delta and blks_res_used, kill the latter entirely. blk_res_used
      is only updated in one place and always in sync with delta_bcount.
      Therefore, the net block reservation consumption of the transaction is
      always available from bcount_delta. Calculate the reservation
      consumption on the fly where necessary based on whether the tp has a
      reservation and results in a positive net block delta on the inode.
      
      Reported-by: default avatarAl Viro <viro@ZenIV.linux.org.uk>
      Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
      Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
      Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
      
      7f884dc1
    • Brian Foster's avatar
      xfs: always log the inode on unwritten extent conversion · 2e588a46
      Brian Foster authored
      
      
      The fsync() requirements for crash consistency on XFS are to flush file
      data and force any in-core inode updates to the log. We currently check
      whether the inode is pinned to identify whether the log needs to be
      forced, since a non-zero pin count generally represents an inode that
      has transactions awaiting a flush to the on-disk log.
      
      This is not sufficient in all cases, however. Reports of xfstests test
      generic/311 failures on ppc64/s390x hosts have identified failures to
      fsync outstanding inode modifications due to the inode not being pinned
      at the time of the fsync. This occurs because certain bmap updates can
      complete by logging bmapbt buffers but without ever dirtying (and thus
      pinning) the core inode. The following is a specific incarnation of this
      problem:
      
      $ mount $dev /mnt -o noatime,nobarrier
      $ for i in $(seq 0 2 31); do \
              xfs_io -f -c "falloc $((i * 32768)) 32k" -c fsync /mnt/file; \
      	done
      $ xfs_io -c "pwrite -S 0 80k 16k" -c fsync -c "pwrite 76k 4k" -c fsync /mnt/file; \
      	hexdump /mnt/file; \
      	./xfstests-dev/src/godown /mnt
      ...
      0000000 0000 0000 0000 0000 0000 0000 0000 0000
      *
      0013000 cdcd cdcd cdcd cdcd cdcd cdcd cdcd cdcd
      *
      0014000 0000 0000 0000 0000 0000 0000 0000 0000
      *
      00f8000
      $ umount /mnt; mount ...
      $ hexdump /mnt/file
      0000000 0000 0000 0000 0000 0000 0000 0000 0000
      *
      00f8000
      
      In short, the unwritten extent conversion for the last write is lost
      despite the fact that an fsync executed before the filesystem was
      shutdown. Note that this is impossible to reproduce on v5 supers due to
      unconditional time callbacks for di_changecount and highly difficult to
      reproduce on CONFIG_HZ=1000 kernels due to those same callbacks
      frequently updating cmtime prior to the bmap update. CONFIG_HZ=100
      reduces timer granularity enough to increase the odds that time updates
      are skipped and allows this to reproduce within a handful of attempts.
      
      To deal with this problem, unconditionally log the core in the unwritten
      extent conversion path. Fix up logflags after the extent conversion to
      keep the extent update code consistent with the other extent update
      helpers. This fixup is not necessary for the other (hole, delay) extent
      helpers because they execute in the block allocation codepath, which
      already logs the inode for other reasons (e.g., for di_nblocks).
      
      Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
      Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
      Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
      
      2e588a46
  5. May 29, 2015
    • Brian Foster's avatar
      xfs: enable sparse inode chunks for v5 superblocks · 22ce1e14
      Brian Foster authored
      
      
      Enable mounting of filesystems with sparse inode support enabled. Add
      the incompat. feature bit to the *_ALL mask.
      
      Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
      Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
      Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
      22ce1e14
    • Brian Foster's avatar
      xfs: skip unallocated regions of inode chunks in xfs_ifree_cluster() · 09b56604
      Brian Foster authored
      
      
      xfs_ifree_cluster() is called to mark all in-memory inodes and inode
      buffers as stale. This occurs after we've removed the inobt records and
      dropped any references of inobt data. xfs_ifree_cluster() uses the
      starting inode number to walk the namespace of inodes expected for a
      single chunk a cluster buffer at a time. The cluster buffer disk
      addresses are calculated by decoding the sequential inode numbers
      expected from the chunk.
      
      The problem with this approach is that if the inode chunk being removed
      is a sparse chunk, not all of the buffer addresses that are calculated
      as part of this sequence may be inode clusters. Attempting to acquire
      the buffer based on expected inode characterstics (i.e., cluster length)
      can lead to errors and is generally incorrect.
      
      We already use a couple variables to carry requisite state from
      xfs_difree() to xfs_ifree_cluster(). Rather than add a third, define a
      new internal structure to carry the existing parameters through these
      functions. Add an alloc field that represents the physical allocation
      bitmap of inodes in the chunk being removed. Modify xfs_ifree_cluster()
      to check each inode against the bitmap and skip the clusters that were
      never allocated as real inodes on disk.
      
      Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
      Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
      Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
      09b56604