]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs: refactor remote attr value buffer invalidation
authorDarrick J. Wong <darrick.wong@oracle.com>
Sat, 14 Mar 2020 03:00:22 +0000 (23:00 -0400)
committerEric Sandeen <sandeen@sandeen.net>
Sat, 14 Mar 2020 03:00:22 +0000 (23:00 -0400)
Source kernel commit: 8edbb26b06023de31ad7d4c9b984d99f66577929

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: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
libxfs/libxfs_priv.h
libxfs/xfs_attr_remote.c
libxfs/xfs_attr_remote.h

index 5d6dd06339d74bf0ea31ddb38c0dc638f29c11f1..763880134528f7c3174bed0f8b56533bb0c02722 100644 (file)
@@ -370,13 +370,7 @@ roundup_64(uint64_t x, uint32_t y)
 #define XFS_BUF_SET_BDSTRAT_FUNC(a,b)  ((void) 0)
 
 /* avoid gcc warning */
-#define xfs_buf_incore(bt,blkno,len,lockit) ({         \
-       typeof(blkno) __foo = (blkno);                  \
-       typeof(len) __bar = (len);                      \
-       (blkno) = __foo;                                \
-       (len) = __bar; /* no set-but-unused warning */  \
-       NULL;                                           \
-})
+#define xfs_buf_incore(bt,blkno,len,lockit)    NULL
 #define xfs_buf_oneshot(bp)            ((void) 0)
 
 #define XBRW_READ                      LIBXFS_BREAD
index 958f8f6166ca60f9798bf66b5d98302fff7ae83d..8a409f21befa4b10264788f4ca9fd691c0e1fac6 100644 (file)
@@ -551,6 +551,33 @@ xfs_attr_rmtval_set(
        return 0;
 }
 
+/* Mark stale any incore buffers for the remote value. */
+int
+xfs_attr_rmtval_stale(
+       struct xfs_inode        *ip,
+       struct xfs_bmbt_irec    *map,
+       xfs_buf_flags_t         incore_flags)
+{
+       struct xfs_mount        *mp = ip->i_mount;
+       struct xfs_buf          *bp;
+
+       ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
+
+       if (XFS_IS_CORRUPT(mp, map->br_startblock == DELAYSTARTBLOCK) ||
+           XFS_IS_CORRUPT(mp, map->br_startblock == HOLESTARTBLOCK))
+               return -EFSCORRUPTED;
+
+       bp = xfs_buf_incore(mp->m_ddev_targp,
+                       XFS_FSB_TO_DADDR(mp, map->br_startblock),
+                       XFS_FSB_TO_BB(mp, map->br_blockcount), incore_flags);
+       if (bp) {
+               xfs_buf_stale(bp);
+               xfs_buf_relse(bp);
+       }
+
+       return 0;
+}
+
 /*
  * Remove the value associated with an attribute by deleting the
  * out-of-line buffer that it is stored on.
@@ -559,7 +586,6 @@ int
 xfs_attr_rmtval_remove(
        struct xfs_da_args      *args)
 {
-       struct xfs_mount        *mp = args->dp->i_mount;
        xfs_dablk_t             lblkno;
        int                     blkcnt;
        int                     error;
@@ -574,9 +600,6 @@ xfs_attr_rmtval_remove(
        blkcnt = args->rmtblkcnt;
        while (blkcnt > 0) {
                struct xfs_bmbt_irec    map;
-               struct xfs_buf          *bp;
-               xfs_daddr_t             dblkno;
-               int                     dblkcnt;
                int                     nmap;
 
                /*
@@ -587,22 +610,11 @@ xfs_attr_rmtval_remove(
                                       blkcnt, &map, &nmap, XFS_BMAPI_ATTRFORK);
                if (error)
                        return error;
-               ASSERT(nmap == 1);
-               ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
-                      (map.br_startblock != HOLESTARTBLOCK));
-
-               dblkno = XFS_FSB_TO_DADDR(mp, map.br_startblock),
-               dblkcnt = XFS_FSB_TO_BB(mp, map.br_blockcount);
-
-               /*
-                * If the "remote" value is in the cache, remove it.
-                */
-               bp = xfs_buf_incore(mp->m_ddev_targp, dblkno, dblkcnt, XBF_TRYLOCK);
-               if (bp) {
-                       xfs_buf_stale(bp);
-                       xfs_buf_relse(bp);
-                       bp = NULL;
-               }
+               if (XFS_IS_CORRUPT(args->dp->i_mount, nmap != 1))
+                       return -EFSCORRUPTED;
+               error = xfs_attr_rmtval_stale(args->dp, &map, XBF_TRYLOCK);
+               if (error)
+                       return error;
 
                lblkno += map.br_blockcount;
                blkcnt -= map.br_blockcount;
index 9d20b66ad379e776e70fd420f88af77d0b69d435..6fb4572845ce8ef7482cd9890c2f71e54172929e 100644 (file)
@@ -11,5 +11,7 @@ int xfs_attr3_rmt_blocks(struct xfs_mount *mp, int attrlen);
 int xfs_attr_rmtval_get(struct xfs_da_args *args);
 int xfs_attr_rmtval_set(struct xfs_da_args *args);
 int xfs_attr_rmtval_remove(struct xfs_da_args *args);
+int xfs_attr_rmtval_stale(struct xfs_inode *ip, struct xfs_bmbt_irec *map,
+               xfs_buf_flags_t incore_flags);
 
 #endif /* __XFS_ATTR_REMOTE_H__ */