From: Darrick J. Wong Date: Wed, 24 Jul 2019 19:54:06 +0000 (-0400) Subject: xfs: add a new ioctl to describe allocation group geometry X-Git-Tag: v5.2.0-rc0~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=debdc163756ac2715d3db792769960b583704192;p=thirdparty%2Fxfsprogs-dev.git xfs: add a new ioctl to describe allocation group geometry Source kernel commit: 7cd5006bdb6f6d9d9d7e68aa1d96b6e4a8b68bc5 Add a new ioctl to describe an allocation group's geometry. Signed-off-by: Darrick J. Wong Reviewed-by: Brian Foster Signed-off-by: Eric Sandeen --- diff --git a/libxfs/xfs_ag.c b/libxfs/xfs_ag.c index 014e2ada5..5fed507ea 100644 --- a/libxfs/xfs_ag.c +++ b/libxfs/xfs_ag.c @@ -20,6 +20,7 @@ #include "xfs_ialloc.h" #include "xfs_rmap.h" #include "xfs_ag.h" +#include "xfs_ag_resv.h" static struct xfs_buf * xfs_get_aghdr_buf( @@ -462,3 +463,54 @@ xfs_ag_extend_space( len, &XFS_RMAP_OINFO_SKIP_UPDATE, XFS_AG_RESV_NONE); } + +/* Retrieve AG geometry. */ +int +xfs_ag_get_geometry( + struct xfs_mount *mp, + xfs_agnumber_t agno, + struct xfs_ag_geometry *ageo) +{ + struct xfs_buf *agi_bp; + struct xfs_buf *agf_bp; + struct xfs_agi *agi; + struct xfs_agf *agf; + struct xfs_perag *pag; + unsigned int freeblks; + int error; + + if (agno >= mp->m_sb.sb_agcount) + return -EINVAL; + + /* Lock the AG headers. */ + error = xfs_ialloc_read_agi(mp, NULL, agno, &agi_bp); + if (error) + return error; + error = xfs_alloc_read_agf(mp, NULL, agno, 0, &agf_bp); + if (error) + goto out_agi; + pag = xfs_perag_get(mp, agno); + + /* Fill out form. */ + memset(ageo, 0, sizeof(*ageo)); + ageo->ag_number = agno; + + agi = XFS_BUF_TO_AGI(agi_bp); + ageo->ag_icount = be32_to_cpu(agi->agi_count); + ageo->ag_ifree = be32_to_cpu(agi->agi_freecount); + + agf = XFS_BUF_TO_AGF(agf_bp); + ageo->ag_length = be32_to_cpu(agf->agf_length); + freeblks = pag->pagf_freeblks + + pag->pagf_flcount + + pag->pagf_btreeblks - + xfs_ag_resv_needed(pag, XFS_AG_RESV_NONE); + ageo->ag_freeblks = freeblks; + + /* Release resources. */ + xfs_perag_put(pag); + xfs_buf_relse(agf_bp); +out_agi: + xfs_buf_relse(agi_bp); + return error; +} diff --git a/libxfs/xfs_ag.h b/libxfs/xfs_ag.h index 412702e23..516632280 100644 --- a/libxfs/xfs_ag.h +++ b/libxfs/xfs_ag.h @@ -26,5 +26,7 @@ struct aghdr_init_data { int xfs_ag_init_headers(struct xfs_mount *mp, struct aghdr_init_data *id); int xfs_ag_extend_space(struct xfs_mount *mp, struct xfs_trans *tp, struct aghdr_init_data *id, xfs_extlen_t len); +int xfs_ag_get_geometry(struct xfs_mount *mp, xfs_agnumber_t agno, + struct xfs_ag_geometry *ageo); #endif /* __LIBXFS_AG_H */ diff --git a/libxfs/xfs_fs.h b/libxfs/xfs_fs.h index 85c99d250..f944ced77 100644 --- a/libxfs/xfs_fs.h +++ b/libxfs/xfs_fs.h @@ -288,6 +288,19 @@ typedef struct xfs_fsop_resblks { #define XFS_MIN_DBLOCKS(s) ((xfs_rfsblock_t)((s)->sb_agcount - 1) * \ (s)->sb_agblocks + XFS_MIN_AG_BLOCKS) +/* + * Output for XFS_IOC_AG_GEOMETRY + */ +struct xfs_ag_geometry { + uint32_t ag_number; /* i/o: AG number */ + uint32_t ag_length; /* o: length in blocks */ + uint32_t ag_freeblks; /* o: free space */ + uint32_t ag_icount; /* o: inodes allocated */ + uint32_t ag_ifree; /* o: inodes free */ + uint32_t ag_reserved32; /* o: zero */ + uint64_t ag_reserved[13];/* o: zero */ +}; + /* * Structures for XFS_IOC_FSGROWFSDATA, XFS_IOC_FSGROWFSLOG & XFS_IOC_FSGROWFSRT */ @@ -640,6 +653,7 @@ struct xfs_scrub_metadata { #define XFS_IOC_FREE_EOFBLOCKS _IOR ('X', 58, struct xfs_fs_eofblocks) /* XFS_IOC_GETFSMAP ------ hoisted 59 */ #define XFS_IOC_SCRUB_METADATA _IOWR('X', 60, struct xfs_scrub_metadata) +#define XFS_IOC_AG_GEOMETRY _IOWR('X', 61, struct xfs_ag_geometry) /* * ioctl commands that replace IRIX syssgi()'s