public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: David Chinner <dgc@sgi.com>
To: Ruben Porras <nahoo82@gmail.com>
Cc: David Chinner <dgc@sgi.com>,
	xfs@oss.sgi.com, cw@f00f.org, iusty@k1024.org
Subject: Re: XFS shrink functionality
Date: Thu, 14 Jun 2007 19:14:26 +1000	[thread overview]
Message-ID: <20070614091426.GB86004887@sgi.com> (raw)
In-Reply-To: <1181810127.6539.13.camel@localhost>

On Thu, Jun 14, 2007 at 10:35:27AM +0200, Ruben Porras wrote:
> > > I took a look at both items since this discussion started. And honestly,
> > > I think 1) is harder that 4), so you're welcome to work on it :) The
> > > points that make it harder is that, per David's suggestion, there needs
> > > to be:
> > >  - define two new transaction types
> > 
> > one new transaction type:
> > 
> > XFS_TRANS_AGF_FLAGS
> 
> done
> 
> > and and extension to xfs_alloc_log_agf(). Is about all that is
> > needed there.
> 
> still to do. Will come after the ioctls.
> 
> > See the patch here:
> > 
> > http://oss.sgi.com/archives/xfs/2007-04/msg00103.html
> > 
> > For an example of a very simlar transaction to what is needed
> > (look at xfs_log_sbcount()) and very similar addition to
> > the AGF (xfs_btreeblks).
> > 
> > >  - define two new ioctls
> > 
> > XFS_IOC_ALLOC_ALLOW_AG, parameter xfsagnumber_t.
> > XFS_IOC_ALLOC_DENY_AG, parameter xfsagnumber_t.
> 
> almost done.

FWIW, I've had second thoughts on this ioctl interface. It's
horribly specific, considering all we are doing are setting
or clearing a flag in an AG.

Perhaps a better interface is:

XFS_IOC_GET_AGF_FLAGS
XFS_IOC_SET_AGF_FLAGS

with:

struct xfs_ioc_agflags {
	xfs_agnumber_t	ag;
	__u32		flags;
}

As the parameter structure and:

#define XFS_AGF_FLAGS_ALLOC_DENY	(1<<0)


> How I'm should I obtain a pointer to an xfs_agf_t from
> inside the ioctls?
> 
> I guess that the first step is to get a *bp with xfs_getsb and then an *sbp,
> but, which function/macro gives me the xfs_agf_t pointer? Sorry, I can't
> find the way greeping through the code.

I've attached the quick hack I did when thinking this through
initially. It'll give you an idea of how to do this and a bit more.
FWIW, it was this hack that made me think the above interface
is a better way to go....

Cheers,

Dave.
-- 
Dave Chinner
Principal Engineer
SGI Australian Software Group

---
 fs/xfs/linux-2.6/xfs_ioctl.c |   27 +++++++++++
 fs/xfs/xfs_ag.h              |    7 ++
 fs/xfs/xfs_alloc.c           |  103 +++++++++++++++++++++++++++++++++++++++++++
 fs/xfs/xfs_fs.h              |    2 
 fs/xfs/xfs_trans.h           |    3 -
 5 files changed, 140 insertions(+), 2 deletions(-)

Index: 2.6.x-xfs-new/fs/xfs/linux-2.6/xfs_ioctl.c
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/linux-2.6/xfs_ioctl.c	2007-06-08 21:34:37.000000000 +1000
+++ 2.6.x-xfs-new/fs/xfs/linux-2.6/xfs_ioctl.c	2007-06-08 22:22:59.305412098 +1000
@@ -899,6 +899,33 @@ xfs_ioctl(
 		return -error;
 	}
 
+	case XFS_IOC_ALLOC_DENY_AG: {
+		xfs_agnumber_t in;
+
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+
+		if (copy_from_user(&in, arg, sizeof(in)))
+			return -XFS_ERROR(EFAULT);
+
+		error = xfs_alloc_deny_ag(mp, &in);
+		return -error;
+
+	}
+	case XFS_IOC_ALLOC_ALLOW_AG: {
+		xfs_agnumber_t in;
+
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+
+		if (copy_from_user(&in, arg, sizeof(in)))
+			return -XFS_ERROR(EFAULT);
+
+		error = xfs_alloc_allow_ag(mp, &in);
+		return -error;
+
+	}
+
 	case XFS_IOC_FREEZE:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EPERM;
Index: 2.6.x-xfs-new/fs/xfs/xfs_ag.h
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/xfs_ag.h	2007-06-08 21:46:28.000000000 +1000
+++ 2.6.x-xfs-new/fs/xfs/xfs_ag.h	2007-06-08 22:09:18.323606142 +1000
@@ -69,6 +69,7 @@ typedef struct xfs_agf {
 	__be32		agf_freeblks;	/* total free blocks */
 	__be32		agf_longest;	/* longest free space */
 	__be32		agf_btreeblks;	/* # of blocks held in AGF btrees */
+	__be32		agf_flags;	/* status flags */
 } xfs_agf_t;
 
 #define	XFS_AGF_MAGICNUM	0x00000001
@@ -83,9 +84,12 @@ typedef struct xfs_agf {
 #define	XFS_AGF_FREEBLKS	0x00000200
 #define	XFS_AGF_LONGEST		0x00000400
 #define	XFS_AGF_BTREEBLKS	0x00000800
-#define	XFS_AGF_NUM_BITS	12
+#define	XFS_AGF_FLAGS		0x00001000
+#define	XFS_AGF_NUM_BITS	13
 #define	XFS_AGF_ALL_BITS	((1 << XFS_AGF_NUM_BITS) - 1)
 
+
+
 /* disk block (xfs_daddr_t) in the AG */
 #define XFS_AGF_DADDR(mp)	((xfs_daddr_t)(1 << (mp)->m_sectbb_log))
 #define	XFS_AGF_BLOCK(mp)	XFS_HDR_BLOCK(mp, XFS_AGF_DADDR(mp))
@@ -189,6 +193,7 @@ typedef struct xfs_perag
 	xfs_extlen_t	pagf_freeblks;	/* total free blocks */
 	xfs_extlen_t	pagf_longest;	/* longest free space */
 	__uint32_t	pagf_btreeblks;	/* # of blocks held in AGF btrees */
+	__uint32_t	pagf_flags;	/* status flags for AG */
 	xfs_agino_t	pagi_freecount;	/* number of free inodes */
 	xfs_agino_t	pagi_count;	/* number of allocated inodes */
 	int		pagb_count;	/* pagb slots in use */
Index: 2.6.x-xfs-new/fs/xfs/xfs_alloc.c
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/xfs_alloc.c	2007-06-05 22:12:50.000000000 +1000
+++ 2.6.x-xfs-new/fs/xfs/xfs_alloc.c	2007-06-08 23:12:51.256348632 +1000
@@ -2085,6 +2085,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_flags),
 		sizeof(xfs_agf_t)
 	};
 
@@ -2112,6 +2113,107 @@ xfs_alloc_pagf_init(
 	return 0;
 }
 
+#define XFS_AGFLAG_ALLOC_DENY	1
+STATIC void
+xfs_alloc_set_flag_ag(
+	xfs_trans_t	*tp,
+	xfs_buf_t	*agbp,	/* buffer for a.g. freelist header */
+	xfs_perag_t	*pag,
+	int		flag)
+{
+	xfs_agf_t		*agf;	/* a.g. freespace structure */
+
+	agf = XFS_BUF_TO_AGF(agbp);
+	pag->pagf_flags |= flag;
+	agf->agf_flags = cpu_to_be32(pag->pagf_flags);
+
+	xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLAGS);
+}
+
+STATIC void
+xfs_alloc_clear_flag_ag(
+	xfs_trans_t	*tp,
+	xfs_buf_t	*agbp,	/* buffer for a.g. freelist header */
+	xfs_perag_t	*pag,
+	int		flag)
+{
+	xfs_agf_t		*agf;	/* a.g. freespace structure */
+
+	agf = XFS_BUF_TO_AGF(agbp);
+	pag->pagf_flags &= ~flag;
+	agf->agf_flags = cpu_to_be32(pag->pagf_flags);
+
+	xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLAGS);
+}
+
+int
+xfs_alloc_allow_ag(
+	xfs_mount_t	*mp,
+	xfs_agnumber_t	agno)
+{
+	xfs_perag_t	*pag;
+	xfs_buf_t	*bp;
+	int		error;
+	xfs_trans_t	*tp;
+
+	if (agno >= mp->m_sb.sb_agcount)
+		return -EINVAL;
+
+	tp = xfs_trans_alloc(mp, XFS_TRANS_ALLOC_FLAGS);
+	error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 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)
+		return error;
+
+	pag = &mp->m_perag[agno];
+	xfs_alloc_clear_flag_ag(tp, bp, pag, XFS_AGFLAG_ALLOC_DENY);
+
+	xfs_trans_set_sync(tp);
+	xfs_trans_commit(tp, 0);
+
+	return 0;
+
+}
+
+int
+xfs_alloc_deny_ag(
+	xfs_mount_t	*mp,
+	xfs_agnumber_t	agno)
+{
+	xfs_perag_t	*pag;
+	xfs_buf_t	*bp;
+	int		error;
+	xfs_trans_t	*tp;
+
+	if (agno >= mp->m_sb.sb_agcount)
+		return -EINVAL;
+
+	tp = xfs_trans_alloc(mp, XFS_TRANS_ALLOC_FLAGS);
+	error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 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)
+		return error;
+
+	pag = &mp->m_perag[agno];
+	xfs_alloc_set_flag_ag(tp, bp, pag, XFS_AGFLAG_ALLOC_DENY);
+
+	xfs_trans_set_sync(tp);
+	xfs_trans_commit(tp, 0);
+
+	return 0;
+
+}
+
 /*
  * Put the block on the freelist for the allocation group.
  */
@@ -2226,6 +2328,7 @@ xfs_alloc_read_agf(
 		pag->pagf_btreeblks = be32_to_cpu(agf->agf_btreeblks);
 		pag->pagf_flcount = be32_to_cpu(agf->agf_flcount);
 		pag->pagf_longest = be32_to_cpu(agf->agf_longest);
+		pag->pagf_flags = be32_to_cpu(agf->agf_flags);
 		pag->pagf_levels[XFS_BTNUM_BNOi] =
 			be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNOi]);
 		pag->pagf_levels[XFS_BTNUM_CNTi] =
Index: 2.6.x-xfs-new/fs/xfs/xfs_trans.h
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/xfs_trans.h	2007-06-08 21:41:32.000000000 +1000
+++ 2.6.x-xfs-new/fs/xfs/xfs_trans.h	2007-06-08 22:50:46.449405162 +1000
@@ -95,7 +95,8 @@ typedef struct xfs_trans_header {
 #define	XFS_TRANS_GROWFSRT_FREE		39
 #define	XFS_TRANS_SWAPEXT		40
 #define	XFS_TRANS_SB_COUNT		41
-#define	XFS_TRANS_TYPE_MAX		41
+#define	XFS_TRANS_ALLOC_FLAGS		42
+#define	XFS_TRANS_TYPE_MAX		42
 /* new transaction types need to be reflected in xfs_logprint(8) */
 
 
Index: 2.6.x-xfs-new/fs/xfs/xfs_fs.h
===================================================================
--- 2.6.x-xfs-new.orig/fs/xfs/xfs_fs.h	2007-06-08 21:46:29.000000000 +1000
+++ 2.6.x-xfs-new/fs/xfs/xfs_fs.h	2007-06-08 23:15:31.755284394 +1000
@@ -493,6 +493,8 @@ 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_ALLOC_DENY_AG	     _IOR ('X', 126, __uint32_t)
+#define XFS_IOC_ALLOC_ALLOW_AG	     _IOR ('X', 127, __uint32_t)
 /*	XFS_IOC_GETFSUUID ---------- deprecated 140	 */
 
 

  reply	other threads:[~2007-06-14  9:14 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-01 16:39 XFS shrink functionality Ruben Porras
2007-06-04  0:16 ` David Chinner
2007-06-04  8:41   ` Iustin Pop
2007-06-04  9:21     ` David Chinner
2007-06-05  8:00       ` Iustin Pop
2007-06-06  1:50         ` Nathan Scott
2007-06-07  8:18         ` David Chinner
2007-06-08  8:23     ` Ruben Porras
2007-06-08 10:15       ` Iustin Pop
2007-06-08 15:12         ` David Chinner
2007-06-08 16:03           ` Iustin Pop
2007-06-09  2:15             ` David Chinner
2007-06-08 19:47           ` Ruben Porras
2007-06-14  8:35           ` Ruben Porras
2007-06-14  9:14             ` David Chinner [this message]
2007-06-08 14:44       ` David Chinner
2007-06-19 22:22   ` XFS shrink (step 0) Ruben Porras
2007-06-19 23:42     ` David Chinner
2007-06-28 10:38       ` Ruben Porras
2007-06-29  6:55         ` David Chinner
2007-07-30 17:30           ` Ruben Porras

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=20070614091426.GB86004887@sgi.com \
    --to=dgc@sgi.com \
    --cc=cw@f00f.org \
    --cc=iusty@k1024.org \
    --cc=nahoo82@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox