Merge tag 'xfs-6.7-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 8 Nov 2023 21:22:16 +0000 (13:22 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 8 Nov 2023 21:22:16 +0000 (13:22 -0800)
Pull xfs updates from Chandan Babu:

 - Realtime device subsystem:
    - Cleanup usage of xfs_rtblock_t and xfs_fsblock_t data types
    - Replace open coded conversions between rt blocks and rt extents
      with calls to static inline helpers
    - Replace open coded realtime geometry compuation and macros with
      helper functions
    - CPU usage optimizations for realtime allocator
    - Misc bug fixes associated with Realtime device

 - Allow read operations to execute while an FICLONE ioctl is being
   serviced

 - Misc bug fixes:
    - Alert user when xfs_droplink() encounters an inode with a link
      count of zero
    - Handle the case where the allocator could return zero extents when
      servicing an fallocate request

* tag 'xfs-6.7-merge-2' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: (40 commits)
  xfs: allow read IO and FICLONE to run concurrently
  xfs: handle nimaps=0 from xfs_bmapi_write in xfs_alloc_file_space
  xfs: introduce protection for drop nlink
  xfs: don't look for end of extent further than necessary in xfs_rtallocate_extent_near()
  xfs: don't try redundant allocations in xfs_rtallocate_extent_near()
  xfs: limit maxlen based on available space in xfs_rtallocate_extent_near()
  xfs: return maximum free size from xfs_rtany_summary()
  xfs: invert the realtime summary cache
  xfs: simplify rt bitmap/summary block accessor functions
  xfs: simplify xfs_rtbuf_get calling conventions
  xfs: cache last bitmap block in realtime allocator
  xfs: use accessor functions for summary info words
  xfs: consolidate realtime allocation arguments
  xfs: create helpers for rtsummary block/wordcount computations
  xfs: use accessor functions for bitmap words
  xfs: create helpers for rtbitmap block/wordcount computations
  xfs: create a helper to handle logging parts of rt bitmap/summary blocks
  xfs: convert rt summary macros to helpers
  xfs: convert open-coded xfs_rtword_t pointer accesses to helper
  xfs: remove XFS_BLOCKWSIZE and XFS_BLOCKWMASK macros
  ...

1  2 
fs/xfs/libxfs/xfs_rtbitmap.c
fs/xfs/xfs_bmap_util.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_mount.h
fs/xfs/xfs_rtalloc.c
fs/xfs/xfs_super.c

index 396648acb5be169dc54f98c657780a34d164f1f3,b332ab490a4875e32c542c885f2b0d9bfeb202a4..c269d704314d7d5afc0497985f46c936ea275f27
@@@ -960,19 -931,18 +931,19 @@@ xfs_rtcheck_alloc_range
   * Free an extent in the realtime subvolume.  Length is expressed in
   * realtime extents, as is the block number.
   */
- int                                   /* error */
+ int
  xfs_rtfree_extent(
-       xfs_trans_t     *tp,            /* transaction pointer */
-       xfs_rtblock_t   bno,            /* starting block number to free */
-       xfs_extlen_t    len)            /* length of extent freed */
+       struct xfs_trans        *tp,    /* transaction pointer */
+       xfs_rtxnum_t            start,  /* starting rtext number to free */
+       xfs_rtxlen_t            len)    /* length of extent freed */
  {
-       int             error;          /* error value */
-       xfs_mount_t     *mp;            /* file system mount structure */
-       xfs_fsblock_t   sb;             /* summary file block number */
-       struct xfs_buf  *sumbp = NULL;  /* summary file block buffer */
-       struct timespec64 atime;
-       mp = tp->t_mountp;
+       struct xfs_mount        *mp = tp->t_mountp;
+       struct xfs_rtalloc_args args = {
+               .mp             = mp,
+               .tp             = tp,
+       };
+       int                     error;
++      struct timespec64       atime;
  
        ASSERT(mp->m_rbmip->i_itemp != NULL);
        ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
            mp->m_sb.sb_rextents) {
                if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM))
                        mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM;
 -              *(uint64_t *)&VFS_I(mp->m_rbmip)->i_atime = 0;
 +
 +              atime = inode_get_atime(VFS_I(mp->m_rbmip));
-               *((uint64_t *)&atime) = 0;
++              atime.tv_sec = 0;
 +              inode_set_atime_to_ts(VFS_I(mp->m_rbmip), atime);
                xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
        }
-       return 0;
+       error = 0;
+ out:
+       xfs_rtbuf_cache_relse(&args);
+       return error;
+ }
+ /*
+  * Free some blocks in the realtime subvolume.  rtbno and rtlen are in units of
+  * rt blocks, not rt extents; must be aligned to the rt extent size; and rtlen
+  * cannot exceed XFS_MAX_BMBT_EXTLEN.
+  */
+ int
+ xfs_rtfree_blocks(
+       struct xfs_trans        *tp,
+       xfs_fsblock_t           rtbno,
+       xfs_filblks_t           rtlen)
+ {
+       struct xfs_mount        *mp = tp->t_mountp;
+       xfs_rtxnum_t            start;
+       xfs_filblks_t           len;
+       xfs_extlen_t            mod;
+       ASSERT(rtlen <= XFS_MAX_BMBT_EXTLEN);
+       len = xfs_rtb_to_rtxrem(mp, rtlen, &mod);
+       if (mod) {
+               ASSERT(mod == 0);
+               return -EIO;
+       }
+       start = xfs_rtb_to_rtxrem(mp, rtbno, &mod);
+       if (mod) {
+               ASSERT(mod == 0);
+               return -EIO;
+       }
+       return xfs_rtfree_extent(tp, start, len);
  }
  
  /* Find all the free records within a given range. */
Simple merge
Simple merge
Simple merge
Simple merge
index 2e1a4e5cd03def7495310d7213d2b99dbe617a51,ba66442910b1f1c81f90604d8a40356441dc0356..88c48de5c9c810c97e38170ecb4bf84fe42c7b35
@@@ -1418,28 -1412,27 +1412,28 @@@ xfs_rtunmount_inodes
   * of rtextents and the fraction.
   * The fraction sequence is 0, 1/2, 1/4, 3/4, 1/8, ..., 7/8, 1/16, ...
   */
--int                                   /* error */
++int                                           /* error */
  xfs_rtpick_extent(
 -      xfs_mount_t     *mp,            /* file system mount point */
 -      xfs_trans_t     *tp,            /* transaction pointer */
 -      xfs_rtxlen_t    len,            /* allocation length (rtextents) */
 -      xfs_rtxnum_t    *pick)          /* result rt extent */
 +      xfs_mount_t             *mp,            /* file system mount point */
 +      xfs_trans_t             *tp,            /* transaction pointer */
-       xfs_extlen_t            len,            /* allocation length (rtextents) */
-       xfs_rtblock_t           *pick)          /* result rt extent */
-       {
-       xfs_rtblock_t           b;              /* result block */
++      xfs_rtxlen_t            len,            /* allocation length (rtextents) */
++      xfs_rtxnum_t            *pick)          /* result rt extent */
+ {
 -      xfs_rtxnum_t    b;              /* result rtext */
 -      int             log2;           /* log of sequence number */
 -      uint64_t        resid;          /* residual after log removed */
 -      uint64_t        seq;            /* sequence number of file creation */
 -      uint64_t        *seqp;          /* pointer to seqno in inode */
++      xfs_rtxnum_t            b;              /* result rtext */
 +      int                     log2;           /* log of sequence number */
 +      uint64_t                resid;          /* residual after log removed */
 +      uint64_t                seq;            /* sequence number of file creation */
-       struct timespec64       ts;             /* temporary timespec64 storage */
++      struct timespec64       ts;             /* timespec in inode */
  
        ASSERT(xfs_isilocked(mp->m_rbmip, XFS_ILOCK_EXCL));
  
 -      seqp = (uint64_t *)&VFS_I(mp->m_rbmip)->i_atime;
++      ts = inode_get_atime(VFS_I(mp->m_rbmip));
        if (!(mp->m_rbmip->i_diflags & XFS_DIFLAG_NEWRTBM)) {
                mp->m_rbmip->i_diflags |= XFS_DIFLAG_NEWRTBM;
 -              *seqp = 0;
 +              seq = 0;
 +      } else {
-               ts = inode_get_atime(VFS_I(mp->m_rbmip));
-               seq = (uint64_t)ts.tv_sec;
++              seq = ts.tv_sec;
        }
 -      seq = *seqp;
        if ((log2 = xfs_highbit64(seq)) == -1)
                b = 0;
        else {
                if (b + len > mp->m_sb.sb_rextents)
                        b = mp->m_sb.sb_rextents - len;
        }
-       ts.tv_sec = (time64_t)seq + 1;
 -      *seqp = seq + 1;
++      ts.tv_sec = seq + 1;
 +      inode_set_atime_to_ts(VFS_I(mp->m_rbmip), ts);
        xfs_trans_log_inode(tp, mp->m_rbmip, XFS_ILOG_CORE);
        *pick = b;
        return 0;
Simple merge