From: Ruben Porras <ruben.porras@linworks.de>
Cc: xfs@oss.sgi.com
Subject: Re: [PATCH] Implement ioctl to mark AGs as "don't use/use"
Date: Thu, 28 Jun 2007 12:25:50 +0200 [thread overview]
Message-ID: <46838CAE.9030808@linworks.de> (raw)
In-Reply-To: <20070628045049.GF989688@sgi.com>
[-- Attachment #1: Type: text/plain, Size: 1886 bytes --]
David Chinner wrote:
> It's a good first cut - comments are inline in the patch below.
>
>
>
> Looks like some whitespace problems there (mixing spaces and tabs).
> Also, can you include empty lines either side of a unique hunk of code
> like this?
>
> I wonder how many other places we are going to have to put this check?
> I haven't looked myself, but this is a good place to start ;)
>
>
I'm still wondering how should I educate emacs to introduce alsways tabs ;)
> You shouldn't renumber the existing ioctls - that changes the
> interfaces to userspace and so will break lots of stuff :( Just put
> them at the end as 126/127. (Oh, you've got two "111" ioctls in
> there, anyway ;)
>
> IOWs, the flag passed to xfs_trans_alloc() defines the type of the
> transaction and the flag passed to xfs_alloc_log_agf() defines what
> has been modified within the transaction.
>
>
Ok, thank you for the explanation, I think that now I got it right.
Attached is a new patch.
There is one question that I would like to ask: when you sketched the
xfs_alloc_set_flag_ag function, you put inside it the call to the
funcintion xfs_alloc_log_agf (see next code snippet).
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); <-- ***** FROM HERE
}
is it required to do the transaction log right after the change or can it be
done in the caller function right after calling xfs_alloc_set_flag_ag?
For example
caller(...)
{
xfs_alloc_set_flag_ag(tp, bp, pag, XFS_AGFLAG_ALLOC_DENY);
<-- **** TO HERE
xfs_trans_set_sync(tp);
xfs_trans_commit(tp, 0);
}
Thanks
--
Rubén Porras
LinWorks GmbH
[-- Attachment #2: patch_markags1.diff --]
[-- Type: text/x-patch, Size: 7385 bytes --]
Index: fs/xfs/xfs_ag.h
===================================================================
RCS file: /cvs/linux-2.6-xfs/fs/xfs/xfs_ag.h,v
retrieving revision 1.59
diff -u -r1.59 xfs_ag.h
--- fs/xfs/xfs_ag.h 22 May 2007 15:50:48 -0000 1.59
+++ fs/xfs/xfs_ag.h 28 Jun 2007 09:47:41 -0000
@@ -69,6 +69,7 @@
__be32 agf_freeblks; /* total free blocks */
__be32 agf_longest; /* longest free space */
__be32 agf_btreeblks; /* # of blocks held in AGF btrees */
+ __be32 agf_flags; /* persistent AG state flags */
} xfs_agf_t;
#define XFS_AGF_MAGICNUM 0x00000001
@@ -83,7 +84,8 @@
#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 */
@@ -196,8 +198,17 @@
lock_t pagb_lock; /* lock for pagb_list */
#endif
xfs_perag_busy_t *pagb_list; /* unstable blocks */
+ __u32 pagf_flags; /* persistent AG state flags */
} xfs_perag_t;
+typedef struct xfs_ioc_agflags
+{
+ xfs_agnumber_t ag;
+ __u32 flags;
+} xfs_ioc_agflags_t;
+
+#define XFS_AGF_FLAGS_ALLOC_DENY (1<<0)
+
#define XFS_AG_MAXLEVELS(mp) ((mp)->m_ag_maxlevels)
#define XFS_MIN_FREELIST_RAW(bl,cl,mp) \
(MIN(bl + 1, XFS_AG_MAXLEVELS(mp)) + MIN(cl + 1, XFS_AG_MAXLEVELS(mp)))
Index: fs/xfs/xfs_alloc.c
===================================================================
RCS file: /cvs/linux-2.6-xfs/fs/xfs/xfs_alloc.c,v
retrieving revision 1.186
diff -u -r1.186 xfs_alloc.c
--- fs/xfs/xfs_alloc.c 22 May 2007 15:50:48 -0000 1.186
+++ fs/xfs/xfs_alloc.c 28 Jun 2007 09:47:44 -0000
@@ -549,6 +549,7 @@
xfs_alloc_arg_t *args) /* argument structure for allocation */
{
int error=0;
+ xfs_perag_t *pag;
#ifdef XFS_ALLOC_TRACE
static char fname[] = "xfs_alloc_ag_vextent";
#endif
@@ -558,6 +559,17 @@
ASSERT(args->minlen <= args->maxlen);
ASSERT(args->mod < args->prod);
ASSERT(args->alignment > 0);
+
+ /*
+ * Return an error if the a.g. should not be allocated.
+ * This happens normally during a shrink operation.
+ */
+ pag = (args->pag);
+ if (unlikely(pag->pagf_flags & XFS_AGF_FLAGS_ALLOC_DENY)) {
+ args->agbno = NULLAGBLOCK;
+ return 0;
+ }
+
/*
* Branch to correct routine based on the type.
*/
@@ -2085,6 +2097,7 @@
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)
};
Index: fs/xfs/xfs_fs.h
===================================================================
RCS file: /cvs/linux-2.6-xfs/fs/xfs/xfs_fs.h,v
retrieving revision 1.33
diff -u -r1.33 xfs_fs.h
--- fs/xfs/xfs_fs.h 22 May 2007 15:50:48 -0000 1.33
+++ fs/xfs/xfs_fs.h 28 Jun 2007 09:47:44 -0000
@@ -492,6 +492,8 @@
#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_GET_AGF_FLAGS _IOWR('X', 126, struct xfs_ioc_agflags)
+#define XFS_IOC_SET_AGF_FLAGS _IOW ('X', 127, struct xfs_ioc_agflags)
/* XFS_IOC_GETFSUUID ---------- deprecated 140 */
Index: fs/xfs/xfs_fsops.c
===================================================================
RCS file: /cvs/linux-2.6-xfs/fs/xfs/xfs_fsops.c,v
retrieving revision 1.126
diff -u -r1.126 xfs_fsops.c
--- fs/xfs/xfs_fsops.c 8 Jun 2007 16:03:59 -0000 1.126
+++ fs/xfs/xfs_fsops.c 28 Jun 2007 09:47:45 -0000
@@ -649,3 +649,79 @@
return 0;
}
+
+STATIC void
+xfs_ag_set_flags_private(
+ xfs_trans_t *tp,
+ xfs_buf_t *agbp, /* buffer for a.g. freelist header */
+ xfs_perag_t *pag,
+ __u32 flags)
+{
+ xfs_agf_t *agf; /* a.g. freespace structure */
+
+ agf = XFS_BUF_TO_AGF(agbp);
+ pag->pagf_flags |= flags;
+ agf->agf_flags = cpu_to_be32(pag->pagf_flags);
+
+ xfs_alloc_log_agf(tp, agbp, XFS_AGF_FLAGS);
+}
+
+__u32
+xfs_ag_get_flags_private(
+ xfs_perag_t *pag)
+{
+ return pag->pagf_flags;
+}
+
+int
+xfs_ag_set_flags(
+ xfs_mount_t *mp,
+ xfs_ioc_agflags_t *ioc_flags)
+{
+ xfs_agnumber_t agno;
+ xfs_perag_t *pag;
+ xfs_buf_t *bp;
+ int error;
+ xfs_trans_t *tp;
+
+ agno = ioc_flags->ag;
+ if (agno >= mp->m_sb.sb_agcount)
+ return -EINVAL;
+
+ tp = xfs_trans_alloc(mp, XFS_TRANS_AGF_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_ag_set_flags_private(tp, bp, pag, ioc_flags->flags);
+
+ xfs_trans_set_sync(tp);
+ xfs_trans_commit(tp, 0);
+
+ return 0;
+
+}
+
+int
+xfs_ag_get_flags(
+ xfs_mount_t *mp,
+ xfs_ioc_agflags_t *ioc_flags)
+{
+ xfs_agnumber_t agno;
+ xfs_perag_t *pag;
+
+ agno = ioc_flags->ag;
+ if (agno >= mp->m_sb.sb_agcount)
+ return -EINVAL;
+
+ pag = &mp->m_perag[agno];
+ ioc_flags->flags = xfs_ag_get_flags_private(pag);
+ return 0;
+}
Index: fs/xfs/xfs_fsops.h
===================================================================
RCS file: /cvs/linux-2.6-xfs/fs/xfs/xfs_fsops.h,v
retrieving revision 1.29
diff -u -r1.29 xfs_fsops.h
--- fs/xfs/xfs_fsops.h 21 Nov 2005 14:42:36 -0000 1.29
+++ fs/xfs/xfs_fsops.h 28 Jun 2007 09:47:45 -0000
@@ -27,4 +27,7 @@
extern int xfs_fs_goingdown(xfs_mount_t *mp, __uint32_t inflags);
extern void xfs_fs_log_dummy(xfs_mount_t *mp);
+extern int xfs_ag_set_flags(xfs_mount_t *mp, xfs_ioc_agflags_t *ioc_flags);
+extern int xfs_ag_get_flags(xfs_mount_t *mp, xfs_ioc_agflags_t *ioc_flags);
+
#endif /* __XFS_FSOPS_H__ */
Index: fs/xfs/xfs_trans.h
===================================================================
RCS file: /cvs/linux-2.6-xfs/fs/xfs/xfs_trans.h,v
retrieving revision 1.145
diff -u -r1.145 xfs_trans.h
--- fs/xfs/xfs_trans.h 22 May 2007 15:50:48 -0000 1.145
+++ fs/xfs/xfs_trans.h 28 Jun 2007 09:47:46 -0000
@@ -95,7 +95,8 @@
#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_AGF_FLAGS 42
+#define XFS_TRANS_TYPE_MAX 42
/* new transaction types need to be reflected in xfs_logprint(8) */
Index: fs/xfs/linux-2.6/xfs_ioctl.c
===================================================================
RCS file: /cvs/linux-2.6-xfs/fs/xfs/linux-2.6/xfs_ioctl.c,v
retrieving revision 1.144
diff -u -r1.144 xfs_ioctl.c
--- fs/xfs/linux-2.6/xfs_ioctl.c 7 Feb 2007 02:50:13 -0000 1.144
+++ fs/xfs/linux-2.6/xfs_ioctl.c 28 Jun 2007 09:47:46 -0000
@@ -860,6 +860,37 @@
return 0;
}
+ case XFS_IOC_GET_AGF_FLAGS: {
+ xfs_ioc_agflags_t inout;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ if (copy_from_user(&inout, arg, sizeof(inout)))
+ return -XFS_ERROR(EFAULT);
+
+ error = xfs_ag_get_flags(mp, &inout);
+ if (error)
+ return -error;
+
+ if (copy_to_user(arg, &inout, sizeof(inout)))
+ return -XFS_ERROR(EFAULT);
+ return 0;
+ }
+
+ case XFS_IOC_SET_AGF_FLAGS: {
+ xfs_ioc_agflags_t in;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ if (copy_from_user(&in, arg, sizeof(in)))
+ return -XFS_ERROR(EFAULT);
+
+ error = xfs_ag_set_flags(mp, &in);
+ return -error;
+ }
+
case XFS_IOC_FSGROWFSDATA: {
xfs_growfs_data_t in;
next prev parent reply other threads:[~2007-06-28 10:52 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-06-27 10:15 [PATCH] Implement ioctl to mark AGs as "don't use/use" Ruben Porras
2007-06-28 4:50 ` David Chinner
2007-06-28 10:25 ` Ruben Porras [this message]
2007-06-29 0:35 ` David Chinner
2007-06-29 0:54 ` David Chinner
2007-09-03 9:20 ` 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=46838CAE.9030808@linworks.de \
--to=ruben.porras@linworks.de \
--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.