All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Liu <jeff.liu@oracle.com>
To: xfs@oss.sgi.com
Cc: jeff.liu@oracle.com
Subject: Re: [PATCH 03/15] xfs: Introduce a new ioctl(2) to set AG state
Date: Fri, 16 Nov 2012 17:06:35 +0800	[thread overview]
Message-ID: <50A6021B.2000101@oracle.com> (raw)
In-Reply-To: <50A5E0FB.5060201@oracle.com>

On 11/16/2012 02:45 PM, Jeff Liu wrote:
> 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.
> 
> 
> Signed-off-by: Jie Liu <jeff.liu@oracle.com>
> ---
>  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(-)
> 
> diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h
> index fd578e6..e2588d9 100644
> --- a/fs/xfs/xfs_ag.h
> +++ b/fs/xfs/xfs_ag.h
> @@ -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
> diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c
> index 4f33c32..bd9cc41 100644
> --- a/fs/xfs/xfs_alloc.c
> +++ b/fs/xfs/xfs_alloc.c
> @@ -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)
>  	};
>  
> diff --git a/fs/xfs/xfs_fs.h b/fs/xfs/xfs_fs.h
> index c13fed8..991c09e 100644
> --- a/fs/xfs/xfs_fs.h
> +++ b/fs/xfs/xfs_fs.h
> @@ -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	 */
>  
>  
> diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
> index c25b094..3742511 100644
> --- a/fs/xfs/xfs_fsops.c
> +++ b/fs/xfs/xfs_fsops.c
> @@ -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;
> +	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);
> +
> +	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;
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index 8305f2a..efe39ef 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -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;
>  	}
> diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h
> index a4f4092..14f897d 100644
> --- a/fs/xfs/xfs_trans.h
> +++ b/fs/xfs/xfs_trans.h
> @@ -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
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

      reply	other threads:[~2012-11-16  9:04 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-11-16  6:45 [PATCH 03/15] xfs: Introduce a new ioctl(2) to set AG state Jeff Liu
2012-11-16  9:06 ` Jeff Liu [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=50A6021B.2000101@oracle.com \
    --to=jeff.liu@oracle.com \
    --cc=xfs@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.