1. 03 3月, 2020 14 次提交
  2. 27 1月, 2020 9 次提交
  3. 17 1月, 2020 4 次提交
    • D
      xfs: make struct xfs_buf_log_format have a consistent size · b7df5e92
      Darrick J. Wong 提交于
      Increase XFS_BLF_DATAMAP_SIZE by 1 to fill in the implied padding at the
      end of struct xfs_buf_log_format.  This makes the size consistent so
      that we can check it in xfs_ondisk.h, and will be needed once we start
      logging attribute values.
      
      On amd64 we get the following pahole:
      
      struct xfs_buf_log_format {
              short unsigned int         blf_type;       /*     0     2 */
              short unsigned int         blf_size;       /*     2     2 */
              short unsigned int         blf_flags;      /*     4     2 */
              short unsigned int         blf_len;        /*     6     2 */
              long long int              blf_blkno;      /*     8     8 */
              unsigned int               blf_map_size;   /*    16     4 */
              unsigned int               blf_data_map[16]; /*    20    64 */
              /* --- cacheline 1 boundary (64 bytes) was 20 bytes ago --- */
      
              /* size: 88, cachelines: 2, members: 7 */
              /* padding: 4 */
              /* last cacheline: 24 bytes */
      };
      
      But on i386 we get the following:
      
      struct xfs_buf_log_format {
              short unsigned int         blf_type;       /*     0     2 */
              short unsigned int         blf_size;       /*     2     2 */
              short unsigned int         blf_flags;      /*     4     2 */
              short unsigned int         blf_len;        /*     6     2 */
              long long int              blf_blkno;      /*     8     8 */
              unsigned int               blf_map_size;   /*    16     4 */
              unsigned int               blf_data_map[16]; /*    20    64 */
              /* --- cacheline 1 boundary (64 bytes) was 20 bytes ago --- */
      
              /* size: 84, cachelines: 2, members: 7 */
              /* last cacheline: 20 bytes */
      };
      
      Notice how the amd64 compiler inserts 4 bytes of padding to the end of
      the structure to ensure 8-byte alignment.  Prior to "xfs: fix memory
      corruption during remote attr value buffer invalidation" we would try to
      write to blf_data_map[17], which is harmless on amd64 but really bad on
      i386.
      
      This shouldn't cause any changes in the ondisk logging formats because
      the log code writes out the log vectors with the appropriate size for
      the log item's map_size, and log recovery treats the data_map array as a
      VLA.
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      b7df5e92
    • D
      xfs: streamline xfs_attr3_leaf_inactive · 0bb9d159
      Darrick J. Wong 提交于
      Now that we know we don't have to take a transaction to stale the incore
      buffers for a remote value, get rid of the unnecessary memory allocation
      in the leaf walker and call the rmt_stale function directly.  Flatten
      the loop while we're at it.
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      0bb9d159
    • D
      xfs: fix memory corruption during remote attr value buffer invalidation · e8db2aaf
      Darrick J. Wong 提交于
      While running generic/103, I observed what looks like memory corruption
      and (with slub debugging turned on) a slub redzone warning on i386 when
      inactivating an inode with a 64k remote attr value.
      
      On a v5 filesystem, maximally sized remote attr values require one block
      more than 64k worth of space to hold both the remote attribute value
      header (64 bytes).  On a 4k block filesystem this results in a 68k
      buffer; on a 64k block filesystem, this would be a 128k buffer.  Note
      that even though we'll never use more than 65,600 bytes of this buffer,
      XFS_MAX_BLOCKSIZE is 64k.
      
      This is a problem because the definition of struct xfs_buf_log_format
      allows for XFS_MAX_BLOCKSIZE worth of dirty bitmap (64k).  On i386 when we
      invalidate a remote attribute, xfs_trans_binval zeroes all 68k worth of
      the dirty map, writing right off the end of the log item and corrupting
      memory.  We've gotten away with this on x86_64 for years because the
      compiler inserts a u32 padding on the end of struct xfs_buf_log_format.
      
      Fortunately for us, remote attribute values are written to disk with
      xfs_bwrite(), which is to say that they are not logged.  Fix the problem
      by removing all places where we could end up creating a buffer log item
      for a remote attribute value and leave a note explaining why.  Next,
      replace the open-coded buffer invalidation with a call to the helper we
      created in the previous patch that does better checking for bad metadata
      before marking the buffer stale.
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      e8db2aaf
    • D
      xfs: refactor remote attr value buffer invalidation · 8edbb26b
      Darrick J. Wong 提交于
      Hoist the code that invalidates remote extended attribute value buffers
      into a separate helper function.  This prepares us for a memory
      corruption fix in the next patch.
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Reviewed-by: NChristoph Hellwig <hch@lst.de>
      8edbb26b
  4. 16 1月, 2020 1 次提交
    • V
      xfs: Add __packed to xfs_dir2_sf_entry_t definition · ca78eee7
      Vincenzo Frascino 提交于
      xfs_check_ondisk_structs() verifies that the sizes of the data types
      used by xfs are correct via the XFS_CHECK_STRUCT_SIZE() macro.
      
      Since the structures padding can vary depending on the ABI (e.g. on
      ARM OABI structures are padded to multiple of 32 bits), it may happen
      that xfs_dir2_sf_entry_t size check breaks the compilation with the
      assertion below:
      
      In file included from linux/include/linux/string.h:6,
                       from linux/include/linux/uuid.h:12,
                       from linux/fs/xfs/xfs_linux.h:10,
                       from linux/fs/xfs/xfs.h:22,
                       from linux/fs/xfs/xfs_super.c:7:
      In function ‘xfs_check_ondisk_structs’,
          inlined from ‘init_xfs_fs’ at linux/fs/xfs/xfs_super.c:2025:2:
      linux/include/linux/compiler.h:350:38:
          error: call to ‘__compiletime_assert_107’ declared with attribute
          error: XFS: sizeof(xfs_dir2_sf_entry_t) is wrong, expected 3
          _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
      
      Restore the correct behavior adding __packed to the structure definition.
      
      Cc: Darrick J. Wong <darrick.wong@oracle.com>
      Suggested-by: NChristoph Hellwig <hch@lst.de>
      Signed-off-by: NVincenzo Frascino <vincenzo.frascino@arm.com>
      Reviewed-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      ca78eee7
  5. 15 1月, 2020 1 次提交
  6. 10 1月, 2020 3 次提交
  7. 08 1月, 2020 1 次提交
  8. 21 12月, 2019 1 次提交
  9. 19 12月, 2019 3 次提交
  10. 18 12月, 2019 1 次提交
  11. 12 12月, 2019 1 次提交
    • B
      xfs: stabilize insert range start boundary to avoid COW writeback race · d0c22041
      Brian Foster 提交于
      generic/522 (fsx) occasionally fails with a file corruption due to
      an insert range operation. The primary characteristic of the
      corruption is a misplaced insert range operation that differs from
      the requested target offset. The reason for this behavior is a race
      between the extent shift sequence of an insert range and a COW
      writeback completion that causes a front merge with the first extent
      in the shift.
      
      The shift preparation function flushes and unmaps from the target
      offset of the operation to the end of the file to ensure no
      modifications can be made and page cache is invalidated before file
      data is shifted. An insert range operation then splits the extent at
      the target offset, if necessary, and begins to shift the start
      offset of each extent starting from the end of the file to the start
      offset. The shift sequence operates at extent level and so depends
      on the preparation sequence to guarantee no changes can be made to
      the target range during the shift. If the block immediately prior to
      the target offset was dirty and shared, however, it can undergo
      writeback and move from the COW fork to the data fork at any point
      during the shift. If the block is contiguous with the block at the
      start offset of the insert range, it can front merge and alter the
      start offset of the extent. Once the shift sequence reaches the
      target offset, it shifts based on the latest start offset and
      silently changes the target offset of the operation and corrupts the
      file.
      
      To address this problem, update the shift preparation code to
      stabilize the start boundary along with the full range of the
      insert. Also update the existing corruption check to fail if any
      extent is shifted with a start offset behind the target offset of
      the insert range. This prevents insert from racing with COW
      writeback completion and fails loudly in the event of an unexpected
      extent shift.
      Signed-off-by: NBrian Foster <bfoster@redhat.com>
      Reviewed-by: NDarrick J. Wong <darrick.wong@oracle.com>
      Signed-off-by: NDarrick J. Wong <darrick.wong@oracle.com>
      d0c22041
  12. 03 12月, 2019 1 次提交