xfs: Introduce a new ioctl(2) to set AG state
PATCH 3/15 xfs: Introduce a new ioctl(2) to set AG state
Introduce a new ioctl(2) for setting a.g. state.
- Add a new structure xfs_ioc_agstate.
- Add a macro to indicate an a.g. is offline.
- Add XFS_IOC_SET_AGSTATE for ioctl(2).
- Teach xfs_alloc_log_agf() aware of agf_state.
--- fs/xfs/xfs_ag.h | 17 ++++++++++++ fs/xfs/xfs_alloc.c | 1 + fs/xfs/xfs_fs.h | 1 + fs/xfs/xfs_fsops.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++- fs/xfs/xfs_ioctl.c | 13 +++++++++ fs/xfs/xfs_trans.h | 2 +- 6 files changed, 104 insertions(+), 3 deletions(-)
fs/xfs/xfs_ag.h +17 -0
@@ -235,6 +235,23 @@ typedef struct xfs_perag { } xfs_perag_t;/* +* Structure for ioctl per a.g. state get/set. +*/ +typedef struct xfs_ioc_agstate { +xfs_agnumber_t agno; +__uint32_t state; +}xfs_ioc_agstate_t ; + +/* +* Skip an AG with below state for inodes/blocks allocation. +*/ +#define XFS_AG_STATE_ALLOC_DENY (1 << 0) +#define XFS_AG_ALL_STATE (XFS_AG_STATE_ALLOC_DENY) + +extern int xfs_set_agstate (struct xfs_mount *mp, +struct xfs_ioc_agstate *agstate); + +/* * tags for inode radix tree */ #define XFS_ICI_NO_TAG (-1)/* special flag for an untagged lookup
fs/xfs/xfs_alloc.c +1 -0
@@ -2005,6 +2005,7 @@ xfs_alloc_log_agf( offsetof(xfs_agf_t , agf_freeblks), offsetof(xfs_agf_t , agf_longest), offsetof(xfs_agf_t , agf_btreeblks), + offsetof(xfs_agf_t , agf_state), sizeof(xfs_agf_t) };
fs/xfs/xfs_fs.h +1 -0
@@ -486,6 +486,7 @@ typedef struct xfs_handle {#define XFS_IOC_ATTRMULTI_BY_HANDLE _IOW ('X', 123, struct xfs_fsop_attrmulti_handlereq)#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)/* XFS_IOC_GETFSUUID ---------- deprecated 140 */
fs/xfs/xfs_fsops.c +71 -2
81 lines not on this page · raw message
fs/xfs/xfs_ioctl.c +13 -0
@@ -1602,6 +1602,19 @@ xfs_file_ioctl( error =xfs_errortag_clearall (mp,1 );return -error; +case XFS_IOC_SET_AGSTATE : { +xfs_ioc_agstate_t in; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; + +if (copy_from_user (&in, arg,sizeof (in))) +return -XFS_ERROR (EFAULT ); + + error =xfs_set_agstate (mp, &in); +return -error; + } +default :return -ENOTTY ; }
fs/xfs/xfs_trans.h +1 -1
@@ -264,7 +264,7 @@ struct xfs_log_item_desc { (128 * (ext + (ext * XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)))))#define XFS_ATTRRM_LOG_RES (mp) ((mp)->m_reservations.tr_attrrm)#define XFS_CLEAR_AGI_BUCKET_LOG_RES (mp) ((mp)->m_reservations.tr_clearagi) -#define XFS_SETAGSTATE_LOG_RES ((mp)->m_reservations.tr_setagstate) +#define XFS_SETAGSTATE_LOG_RES (mp) ((mp)->m_reservations.tr_setagstate)/* * Various log count values.
Signature · 6 lines
1.7.4.1 _______________________________________________ xfs mailing list [email protected] http://oss.sgi.com/mailman/listinfo/xfs
Quoted 111 lines · Jeff Liu
Introduce a new ioctl(2) for setting a.g. state.
- Add a new structure
xfs_ioc_agstate.
- Add a macro to indicate an a.g. is offline.
- AddXFS_IOC_SET_AGSTATEfor ioctl(2).
- Teachxfs_alloc_log_agf()aware ofagf_state.Signed-off-by Jie Liu <[email protected]>--- fs/xfs/xfs_ag.h | 17 ++++++++++++ fs/xfs/xfs_alloc.c | 1 + fs/xfs/xfs_fs.h | 1 + fs/xfs/xfs_fsops.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++- fs/xfs/xfs_ioctl.c | 13 +++++++++ fs/xfs/xfs_trans.h | 2 +- 6 files changed, 104 insertions(+), 3 deletions(-)fs/xfs/xfs_ag.h +17
-0@@ -235,6 +235,23 @@ typedef struct xfs_perag { } xfs_perag_t;/* +* Structure for ioctl per a.g. state get/set. +*/ +typedef struct xfs_ioc_agstate { +xfs_agnumber_t agno; +__uint32_t state; +}xfs_ioc_agstate_t ; + +/* +* Skip an AG with below state for inodes/blocks allocation. +*/ +#define XFS_AG_STATE_ALLOC_DENY (1 << 0) +#define XFS_AG_ALL_STATE (XFS_AG_STATE_ALLOC_DENY) + +extern int xfs_set_agstate (struct xfs_mount *mp, +struct xfs_ioc_agstate *agstate); + +/* * tags for inode radix tree */ #define XFS_ICI_NO_TAG (-1)/* special flag for an untagged lookup fs/xfs/xfs_alloc.c +1
-0@@ -2005,6 +2005,7 @@ xfs_alloc_log_agf( offsetof(xfs_agf_t , agf_freeblks), offsetof(xfs_agf_t , agf_longest), offsetof(xfs_agf_t , agf_btreeblks), + offsetof(xfs_agf_t , agf_state), sizeof(xfs_agf_t) };fs/xfs/xfs_fs.h +1
-0@@ -486,6 +486,7 @@ typedef struct xfs_handle {#define XFS_IOC_ATTRMULTI_BY_HANDLE _IOW ('X', 123, struct xfs_fsop_attrmulti_handlereq)#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)/* XFS_IOC_GETFSUUID ---------- deprecated 140 */ fs/xfs/xfs_fsops.c +33
-0@@ -112,10 +112,79 @@ xfs_fs_geometry(return 0 ; } +/* +* Setting a.g. persistent state as well as perag incore state. +*/ +static void +xfs_set_agstate_private ( +xfs_trans_t *tp,/* transaction pointer */ +xfs_buf_t *agbp,/* buffer for a.g. freelist header */ +xfs_perag_t *pag,/* incore perag structure */ +__uint32_t state)/* a.g. state to be set */ +{ +xfs_agf_t *agf;/* a.g. free space */ + + agf =XFS_BUF_TO_AGF (agbp); + agf->agf_state |=cpu_to_be32 (state); + pag->pag_state |= state; + +xfs_alloc_log_agf (tp, agbp,XFS_AGF_STATE ); +} + +/* +* Setting the state of the given AG. +* +* For now, we can set a given AG to be offline or online, and +* allocaters will skip an AG being offline to allocate inodes +* or free space. +*/ +int +xfs_set_agstate ( +xfs_mount_t *mp, +xfs_ioc_agstate_t *agstate) +{ +xfs_agnumber_t agno; +xfs_perag_t *pag;
fs/xfs/xfs_fsops.c xfs_fs_geometry( · line 157
Quoted 10 lines
fs/xfs/xfs_fsops.c +10
-0+xfs_trans_t *tp; +xfs_buf_t *bp; +int error; + + agno = agstate->agno; +if (agno >= mp->m_sb.sb_agcount) +return XFS_ERROR (EINVAL ); + +if ((agstate->state &XFS_AG_ALL_STATE ) != agstate->state) +return XFS_ERROR (EINVAL );
Maybe it's better to rename XFS_AG_ALL_STATE to XFS_AG_STATS_VALID, and do this check as below:
if (agstate->state &~ XFS_AG_STATES_VALID) return XFS_ERROR(EINVAL);
Quoted 65 lines
fs/xfs/xfs_fsops.c +28
-2+ + tp =xfs_trans_alloc (mp,XFS_TRANS_SET_AGSTATE ); + error =xfs_trans_reserve (tp,0 ,XFS_SETAGSTATE_LOG_RES (mp),0 ,0 , +XFS_DEFAULT_LOG_COUNT ); +if (error) { +xfs_trans_cancel (tp,0 ); +return error; + } + + error =xfs_alloc_read_agf (mp, tp, agno,0 , &bp); +if (error) + goto error0; + + pag =xfs_perag_get (mp, agno); +xfs_set_agstate_private (tp, bp, pag, agstate->state); +xfs_perag_put (pag); + +xfs_trans_set_sync (tp); +xfs_trans_commit (tp,0 ); +return error; + +error0: +xfs_trans_cancel (tp,XFS_TRANS_ABORT ); +return error; +} +static int xfs_growfs_data_private ( -xfs_mount_t *mp,/* mount point for filesystem */ -xfs_growfs_data_t *in)/* growfs data input struct */ +xfs_mount_t *mp,/* mount point for filesystem */ +xfs_growfs_data_t *in)/* growfs data input struct */ {xfs_agf_t *agf;xfs_agi_t *agi;fs/xfs/xfs_ioctl.c +13
-0@@ -1602,6 +1602,19 @@ xfs_file_ioctl( error =xfs_errortag_clearall (mp,1 );return -error; +case XFS_IOC_SET_AGSTATE : { +xfs_ioc_agstate_t in; + +if (!capable (CAP_SYS_ADMIN )) +return -EPERM ; + +if (copy_from_user (&in, arg,sizeof (in))) +return -XFS_ERROR (EFAULT ); + + error =xfs_set_agstate (mp, &in); +return -error; + } +default :return -ENOTTY ; }fs/xfs/xfs_trans.h +0
-0
fs/xfs/xfs_trans.h struct xfs_log_item_desc { · line 270
Quoted 8 lines
fs/xfs/xfs_trans.h +1
-1@@ -264,7 +264,7 @@ struct xfs_log_item_desc { (128 * (ext + (ext * XFS_BM_MAXLEVELS(mp, XFS_ATTR_FORK)))))#define XFS_ATTRRM_LOG_RES (mp) ((mp)->m_reservations.tr_attrrm)#define XFS_CLEAR_AGI_BUCKET_LOG_RES (mp) ((mp)->m_reservations.tr_clearagi) -#define XFS_SETAGSTATE_LOG_RES ((mp)->m_reservations.tr_setagstate) +#define XFS_SETAGSTATE_LOG_RES (mp) ((mp)->m_reservations.tr_setagstate)/* * Various log count values.
_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs