public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
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;
 

  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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox