[PATCH 04/15] xfs: Introduce a new ioctl(2) to get AG state
Jeff Liu
jeff.liu at oracle.com
Fri Nov 16 00:45:24 CST 2012
Introduce a new ioctl(2) to get a.g. state.
Signed-off-by: Jie Liu <jeff.liu at oracle.com>
---
fs/xfs/xfs_ag.h | 2 +
fs/xfs/xfs_fs.h | 1 +
fs/xfs/xfs_fsops.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
fs/xfs/xfs_ioctl.c | 19 ++++++++++++++++++
4 files changed, 75 insertions(+), 0 deletions(-)
diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
index e2588d9..7ec7dba 100644
--- a/fs/xfs/xfs_ag.h
+++ b/fs/xfs/xfs_ag.h
@@ -248,6 +248,8 @@ typedef struct xfs_ioc_agstate {
#define XFS_AG_STATE_ALLOC_DENY (1 << 0)
#define XFS_AG_ALL_STATE (XFS_AG_STATE_ALLOC_DENY)
+extern int xfs_get_agstate(struct xfs_mount *mp,
+ struct xfs_ioc_agstate *agstate);
extern int xfs_set_agstate(struct xfs_mount *mp,
struct xfs_ioc_agstate *agstate);
diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
index 991c09e..e306b8f 100644
--- a/fs/xfs/xfs_fs.h
+++ b/fs/xfs/xfs_fs.h
@@ -487,6 +487,7 @@ typedef struct xfs_handle {
#define XFS_IOC_FSGEOMETRY _IOR ('X', 124, struct xfs_fsop_geom)
#define XFS_IOC_GOINGDOWN _IOR ('X', 125, __uint32_t)
#define XFS_IOC_SET_AGSTATE _IOW('X', 126, struct xfs_ioc_agstate)
+#define XFS_IOC_GET_AGSTATE _IOR('X', 127, struct xfs_ioc_agstate)
/* XFS_IOC_GETFSUUID ---------- deprecated 140 */
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 3742511..029ab6d 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -182,6 +182,59 @@ error0:
}
static int
+xfs_get_agstate_private(
+ xfs_mount_t *mp,
+ xfs_agnumber_t agno,
+ __uint32_t *state)
+{
+ xfs_perag_t *pag;
+ xfs_agf_t *agf;
+ xfs_buf_t *bp;
+ int error = 0;
+
+ pag = xfs_perag_get(mp, agno);
+ if (pag) {
+ *state = pag->pag_state;
+ goto out_put_perag;
+ }
+
+ bp = xfs_buf_get(mp->m_ddev_targp,
+ XFS_AG_DADDR(mp, agno, XFS_AGF_DADDR(mp)),
+ XFS_FSS_TO_BB(mp, 1), 0);
+ if (!bp) {
+ error = ENOMEM;
+ goto out_put_perag;
+ }
+ agf = XFS_BUF_TO_AGF(bp);
+ *state = agf->agf_state;
+
+out_put_perag:
+ xfs_perag_put(pag);
+ return error;
+}
+
+int
+xfs_get_agstate(
+ xfs_mount_t *mp,
+ xfs_ioc_agstate_t *agstate)
+{
+ xfs_agnumber_t agno;
+ __uint32_t state;
+ int error;
+
+ agno = agstate->agno;
+ if (agno >= mp->m_sb.sb_agcount)
+ return XFS_ERROR(EINVAL);
+
+ error = xfs_get_agstate_private(mp, agno, &state);
+ if (error)
+ return error;
+
+ agstate->state = state;
+ return 0;
+}
+
+static int
xfs_growfs_data_private(
xfs_mount_t *mp, /* mount point for filesystem */
xfs_growfs_data_t *in) /* growfs data input struct */
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
index efe39ef..4d3a705 100644
--- a/fs/xfs/xfs_ioctl.c
+++ b/fs/xfs/xfs_ioctl.c
@@ -1615,6 +1615,25 @@ xfs_file_ioctl(
return -error;
}
+ case XFS_IOC_GET_AGSTATE: {
+ xfs_ioc_agstate_t inout;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ if (copy_from_user(&inout, arg, sizeof(inout)))
+ return -XFS_ERROR(EFAULT);
+
+ error = xfs_get_agstate(mp, &inout);
+ if (error)
+ return -error;
+
+ if (copy_to_user(arg, &inout, sizeof(inout)))
+ return -XFS_ERROR(EFAULT);
+
+ return 0;
+ }
+
default:
return -ENOTTY;
}
--
1.7.4.1
More information about the xfs
mailing list