summaryrefslogtreecommitdiff
path: root/fs/xfs/libxfs/xfs_ag.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/libxfs/xfs_ag.c')
-rw-r--r--fs/xfs/libxfs/xfs_ag.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/fs/xfs/libxfs/xfs_ag.c b/fs/xfs/libxfs/xfs_ag.c
index 69b138dffd92..208e82ec9dd6 100644
--- a/fs/xfs/libxfs/xfs_ag.c
+++ b/fs/xfs/libxfs/xfs_ag.c
@@ -544,6 +544,55 @@ xfs_ag_extend_space(
XFS_AG_RESV_NONE);
}
+/* Compute the AG geometry flags. */
+static inline uint32_t
+xfs_ag_calc_geoflags(
+ struct xfs_perag *pag)
+{
+ uint32_t ret = 0;
+
+ if (pag->pagf_noalloc)
+ 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)) {
+ error = xfs_ag_clear_noalloc(pag);
+ if (error)
+ return error;
+ }
+ 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(
@@ -557,6 +606,7 @@ xfs_ag_get_geometry(
struct xfs_agf *agf;
struct xfs_perag *pag;
unsigned int freeblks;
+ uint32_t inflags = ageo->ag_flags;
int error;
if (agno >= mp->m_sb.sb_agcount)
@@ -572,6 +622,10 @@ xfs_ag_get_geometry(
pag = agi_bp->b_pag;
+ error = xfs_ag_update_geoflags(pag, ageo, inflags);
+ if (error)
+ goto out;
+
/* Fill out form. */
memset(ageo, 0, sizeof(*ageo));
ageo->ag_number = agno;
@@ -589,6 +643,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: