public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Ruben Porras <nahoo82@gmail.com>
To: xfs@oss.sgi.com
Subject: [PATCH] Implement ioctl to mark AGs as "don't use/use"
Date: Wed, 27 Jun 2007 12:15:25 +0200	[thread overview]
Message-ID: <1182939325.5313.12.camel@localhost> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 341 bytes --]

The patch has the following parts:

- Necessary changes to xfs_ag.h
- two new ioctls
- Changes to the allocation functions to avoid using marked AGs
- Extension to xfs_alloc_log_agf

This should implement the second step on the requirement list to shrink
an xfs filesystem. Comment are welcome.

-- 
Rubén Porras
LinWorks GmbH

[-- Attachment #1.2: patch_markags.diff --]
[-- Type: text/x-patch, Size: 9592 bytes --]

Index: 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
--- xfs/xfs_ag.h	22 May 2007 15:50:48 -0000	1.59
+++ xfs/xfs_ag.h	27 Jun 2007 09:06:39 -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;      /* the AGF is allocatable */
 } xfs_agf_t;
 
 #define	XFS_AGF_MAGICNUM	0x00000001
@@ -196,8 +197,17 @@
 	lock_t		pagb_lock;	/* lock for pagb_list */
 #endif
 	xfs_perag_busy_t *pagb_list;	/* unstable blocks */
+	__u32		 pagf_flags;	/* the AGF is allocatable */
 } 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: 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
--- xfs/xfs_alloc.c	22 May 2007 15:50:48 -0000	1.186
+++ xfs/xfs_alloc.c	27 Jun 2007 09:06:40 -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
@@ -559,6 +560,15 @@
 	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.
 	 */
 	args->wasfromfl = 0;
@@ -2085,6 +2095,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: 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
--- xfs/xfs_fs.h	22 May 2007 15:50:48 -0000	1.33
+++ xfs/xfs_fs.h	27 Jun 2007 09:06:40 -0000
@@ -476,22 +476,24 @@
 #define XFS_IOC_OPEN_BY_HANDLE	     _IOWR('X', 107, struct xfs_fsop_handlereq)
 #define XFS_IOC_READLINK_BY_HANDLE   _IOWR('X', 108, struct xfs_fsop_handlereq)
 #define XFS_IOC_SWAPEXT		     _IOWR('X', 109, struct xfs_swapext)
-#define XFS_IOC_FSGROWFSDATA	     _IOW ('X', 110, struct xfs_growfs_data)
-#define XFS_IOC_FSGROWFSLOG	     _IOW ('X', 111, struct xfs_growfs_log)
-#define XFS_IOC_FSGROWFSRT	     _IOW ('X', 112, struct xfs_growfs_rt)
-#define XFS_IOC_FSCOUNTS	     _IOR ('X', 113, struct xfs_fsop_counts)
-#define XFS_IOC_SET_RESBLKS	     _IOWR('X', 114, struct xfs_fsop_resblks)
-#define XFS_IOC_GET_RESBLKS	     _IOR ('X', 115, struct xfs_fsop_resblks)
-#define XFS_IOC_ERROR_INJECTION	     _IOW ('X', 116, struct xfs_error_injection)
-#define XFS_IOC_ERROR_CLEARALL	     _IOW ('X', 117, struct xfs_error_injection)
-/*	XFS_IOC_ATTRCTL_BY_HANDLE -- deprecated 118	 */
-#define XFS_IOC_FREEZE		     _IOWR('X', 119, int)
-#define XFS_IOC_THAW		     _IOWR('X', 120, int)
-#define XFS_IOC_FSSETDM_BY_HANDLE    _IOW ('X', 121, struct xfs_fsop_setdm_handlereq)
-#define XFS_IOC_ATTRLIST_BY_HANDLE   _IOW ('X', 122, struct xfs_fsop_attrlist_handlereq)
-#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       _IOW ('X', 110, struct xfs_ioc_agflags)
+#define XFS_IOC_SET_AGF_FLAGS       _IOW ('X', 111, struct xfs_ioc_agflags)
+#define XFS_IOC_FSGROWFSDATA	     _IOW ('X', 111, struct xfs_growfs_data)
+#define XFS_IOC_FSGROWFSLOG	     _IOW ('X', 112, struct xfs_growfs_log)
+#define XFS_IOC_FSGROWFSRT	     _IOW ('X', 113, struct xfs_growfs_rt)
+#define XFS_IOC_FSCOUNTS	     _IOR ('X', 114, struct xfs_fsop_counts)
+#define XFS_IOC_SET_RESBLKS	     _IOWR('X', 115, struct xfs_fsop_resblks)
+#define XFS_IOC_GET_RESBLKS	     _IOR ('X', 116, struct xfs_fsop_resblks)
+#define XFS_IOC_ERROR_INJECTION	     _IOW ('X', 117, struct xfs_error_injection)
+#define XFS_IOC_ERROR_CLEARALL	     _IOW ('X', 118, struct xfs_error_injection)
+/*	XFS_IOC_ATTRCTL_BY_HANDLE -- deprecated 119	 */
+#define XFS_IOC_FREEZE		     _IOWR('X', 120, int)
+#define XFS_IOC_THAW		     _IOWR('X', 121, int)
+#define XFS_IOC_FSSETDM_BY_HANDLE    _IOW ('X', 122, struct xfs_fsop_setdm_handlereq)
+#define XFS_IOC_ATTRLIST_BY_HANDLE   _IOW ('X', 123, struct xfs_fsop_attrlist_handlereq)
+#define XFS_IOC_ATTRMULTI_BY_HANDLE  _IOW ('X', 124, struct xfs_fsop_attrmulti_handlereq)
+#define XFS_IOC_FSGEOMETRY	     _IOR ('X', 125, struct xfs_fsop_geom)
+#define XFS_IOC_GOINGDOWN	     _IOR ('X', 126, __uint32_t)
 /*	XFS_IOC_GETFSUUID ---------- deprecated 140	 */
 
 
Index: 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
--- xfs/xfs_fsops.c	8 Jun 2007 16:03:59 -0000	1.126
+++ xfs/xfs_fsops.c	27 Jun 2007 09:06:40 -0000
@@ -649,3 +649,80 @@
 
 	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_TRANS_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,
+	__u32			*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];
+	*flags = xfs_ag_get_flags_private(pag);
+	return 0;
+}
Index: 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
--- xfs/xfs_fsops.h	21 Nov 2005 14:42:36 -0000	1.29
+++ xfs/xfs_fsops.h	27 Jun 2007 09:06:40 -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, __u32 *flags);
+
 #endif	/* __XFS_FSOPS_H__ */
Index: 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
--- xfs/xfs_trans.h	22 May 2007 15:50:48 -0000	1.145
+++ xfs/xfs_trans.h	27 Jun 2007 09:06:41 -0000
@@ -418,6 +418,10 @@
 #define	XFS_TRANS_SB_REXTENTS		0x00001000
 #define	XFS_TRANS_SB_REXTSLOG		0x00002000
 
+/*
+ * Value for xfs_trans_mod_agf
+ */
+#define XFS_TRANS_AGF_FLAGS             0x00004000
 
 /*
  * Various log reservation values.
Index: 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
--- xfs/linux-2.6/xfs_ioctl.c	7 Feb 2007 02:50:13 -0000	1.144
+++ xfs/linux-2.6/xfs_ioctl.c	27 Jun 2007 09:06:41 -0000
@@ -860,6 +860,38 @@
 		return 0;
 	}
 
+	case XFS_IOC_GET_AGF_FLAGS: {
+		xfs_ioc_agflags_t in;
+               __u32 out;
+
+		if (!capable(CAP_SYS_ADMIN))
+			return -EPERM;
+
+		if (copy_from_user(&in, arg, sizeof(in)))
+			return -XFS_ERROR(EFAULT);
+
+		error = xfs_ag_get_flags(mp, &in, &out);
+		if (error)
+			return -error;
+
+		if (copy_to_user(arg, &out, sizeof(out)))
+			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;
 

[-- Attachment #2: Dies ist ein digital signierter Nachrichtenteil --]
[-- Type: application/pgp-signature, Size: 189 bytes --]

             reply	other threads:[~2007-06-27 10:15 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-27 10:15 Ruben Porras [this message]
2007-06-28  4:50 ` [PATCH] Implement ioctl to mark AGs as "don't use/use" David Chinner
2007-06-28 10:25   ` Ruben Porras
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=1182939325.5313.12.camel@localhost \
    --to=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