]> www.infradead.org Git - users/hch/xfsprogs.git/commitdiff
xfs: enable userspace to hide an AG from allocation
authorDarrick J. Wong <djwong@kernel.org>
Wed, 7 Aug 2024 22:54:51 +0000 (15:54 -0700)
committerDarrick J. Wong <djwong@kernel.org>
Wed, 14 Aug 2024 03:08:25 +0000 (20:08 -0700)
Add an administrative interface so that userspace can hide an allocation
group from block allocation.

Signed-off-by: Darrick J. Wong <djwong@kernel.org>
libxfs/xfs_ag.c
libxfs/xfs_fs.h

index e885a7c0160471c714cc00fd0fef39a86471eb3e..f530bebd52bab6134adb773c62b6a93d0ca152bb 100644 (file)
@@ -1101,6 +1101,54 @@ xfs_ag_extend_space(
        return 0;
 }
 
+/* Compute the AG geometry flags. */
+static inline uint32_t
+xfs_ag_calc_geoflags(
+       struct xfs_perag        *pag)
+{
+       uint32_t                ret = 0;
+
+       if (xfs_perag_prohibits_alloc(pag))
+               ret |= XFS_AG_FLAG_NOALLOC;
+
+       return ret;
+}
+
+/*
+ * Compare the current AG geometry flags against the flags in the AG geometry
+ * structure and update the AG state to reflect any changes, then update the
+ * struct to reflect the current status.
+ */
+static inline int
+xfs_ag_update_geoflags(
+       struct xfs_perag        *pag,
+       struct xfs_ag_geometry  *ageo,
+       uint32_t                new_flags)
+{
+       uint32_t                old_flags = xfs_ag_calc_geoflags(pag);
+       int                     error;
+
+       if (!(new_flags & XFS_AG_FLAG_UPDATE)) {
+               ageo->ag_flags = old_flags;
+               return 0;
+       }
+
+       if ((old_flags & XFS_AG_FLAG_NOALLOC) &&
+           !(new_flags & XFS_AG_FLAG_NOALLOC)) {
+               xfs_ag_clear_noalloc(pag);
+       }
+
+       if (!(old_flags & XFS_AG_FLAG_NOALLOC) &&
+           (new_flags & XFS_AG_FLAG_NOALLOC)) {
+               error = xfs_ag_set_noalloc(pag);
+               if (error)
+                       return error;
+       }
+
+       ageo->ag_flags = xfs_ag_calc_geoflags(pag);
+       return 0;
+}
+
 /* Retrieve AG geometry. */
 int
 xfs_ag_get_geometry(
@@ -1112,6 +1160,7 @@ xfs_ag_get_geometry(
        struct xfs_agi          *agi;
        struct xfs_agf          *agf;
        unsigned int            freeblks;
+       uint32_t                inflags = ageo->ag_flags;
        int                     error;
 
        /* Lock the AG headers. */
@@ -1122,6 +1171,10 @@ xfs_ag_get_geometry(
        if (error)
                goto out_agi;
 
+       error = xfs_ag_update_geoflags(pag, ageo, inflags);
+       if (error)
+               goto out;
+
        /* Fill out form. */
        memset(ageo, 0, sizeof(*ageo));
        ageo->ag_number = pag->pag_agno;
@@ -1139,6 +1192,7 @@ xfs_ag_get_geometry(
        ageo->ag_freeblks = freeblks;
        xfs_ag_geom_health(pag, ageo);
 
+out:
        /* Release resources. */
        xfs_buf_relse(agf_bp);
 out_agi:
index 94c0d50467e35418c7944a52497bb4d8127e3fe7..2c2c83b06c88f7e68e71da2f30f7ecafff84b921 100644 (file)
@@ -304,6 +304,11 @@ struct xfs_ag_geometry {
 #define XFS_AG_GEOM_SICK_REFCNTBT (1 << 9)  /* reference counts */
 #define XFS_AG_GEOM_SICK_INODES        (1 << 10) /* bad inodes were seen */
 
+#define XFS_AG_FLAG_UPDATE     (1 << 0)  /* update flags */
+#define XFS_AG_FLAG_NOALLOC    (1 << 1)  /* do not allocate from this AG */
+#define XFS_AG_FLAG_ALL                (XFS_AG_FLAG_UPDATE | \
+                                XFS_AG_FLAG_NOALLOC)
+
 /*
  * Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT
  */