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 */
next prev parent 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 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.