diff --git a/SOURCES/xfsprogs-5.10.0-xfs_quota-document-how-the-default-quota-is-stored.patch b/SOURCES/xfsprogs-5.10.0-xfs_quota-document-how-the-default-quota-is-stored.patch
new file mode 100644
index 0000000..bfb71e3
--- /dev/null
+++ b/SOURCES/xfsprogs-5.10.0-xfs_quota-document-how-the-default-quota-is-stored.patch
@@ -0,0 +1,35 @@
+From 0d7b09ac95e4cde766a534fdb7ea8dd46451ad53 Mon Sep 17 00:00:00 2001
+From: Eric Sandeen <sandeen@redhat.com>
+Date: Fri, 4 Dec 2020 12:17:12 -0500
+Subject: [PATCH] xfs_quota: document how the default quota is stored
+
+Nowhere in the man page is the default quota described; what it
+does or where it is stored.  Add some brief information about this.
+
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
+---
+ man/man8/xfs_quota.8 | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/man/man8/xfs_quota.8 b/man/man8/xfs_quota.8
+index dd0479cd..6ead7ee9 100644
+--- a/man/man8/xfs_quota.8
++++ b/man/man8/xfs_quota.8
+@@ -178,6 +178,12 @@ to a file on
+ where the user's quota has not been exceeded.
+ Then after rectifying the quota situation, the file can be moved back to the
+ filesystem it belongs on.
++.SS Default Quotas
++The XFS quota subsystem allows a default quota to be enforced
++for any user, group or project which does not have a quota limit
++explicitly set.
++These limits are stored in and displayed as ID 0's limits, although they
++do not actually limit ID 0.
+ .SH USER COMMANDS
+ .TP
+ .B print
+-- 
+2.29.2
+
diff --git a/SOURCES/xfsprogs-5.10.0-xfs_repair-Use-proper-min-max-values-in-compute_level_geometry.patch b/SOURCES/xfsprogs-5.10.0-xfs_repair-Use-proper-min-max-values-in-compute_level_geometry.patch
new file mode 100644
index 0000000..5a07f04
--- /dev/null
+++ b/SOURCES/xfsprogs-5.10.0-xfs_repair-Use-proper-min-max-values-in-compute_level_geometry.patch
@@ -0,0 +1,92 @@
+xfs_repair: Use proper min/max values in compute_level_geometry
+
+When compute_level_geometry was added it exclusively uses
+m_alloc_mnr/m_alloc_mxr but the rmap btree should be using
+m_rmap_mnr/m_rmap_mxr.  Pass those in directly to fix the
+problem.
+
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+---
+
+diff --git a/repair/phase5.c b/repair/phase5.c
+index 0b8a55ff..dff342c8 100644
+--- a/repair/phase5.c
++++ b/repair/phase5.c
+@@ -355,12 +355,12 @@ compute_level_geometry(
+ 	struct bt_stat_level	*lptr,
+ 	uint64_t		nr_this_level,
+ 	int			slack,
+-	bool			leaf)
++	uint			maxrecs,
++	uint			minrecs)
+ {
+-	unsigned int		maxrecs = mp->m_alloc_mxr[!leaf];
+ 	unsigned int		desired_npb;
+ 
+-	desired_npb = max(mp->m_alloc_mnr[!leaf], maxrecs - slack);
++	desired_npb = max(minrecs, maxrecs - slack);
+ 	lptr->num_recs_tot = nr_this_level;
+ 	lptr->num_blocks = max(1ULL, nr_this_level / desired_npb);
+ 
+@@ -410,7 +410,8 @@ calculate_freespace_cursor(xfs_mount_t *mp, xfs_agnumber_t agno,
+ 	 * of the tree and set up the cursor for the leaf level
+ 	 * (note that the same code is duplicated further down)
+ 	 */
+-	compute_level_geometry(mp, lptr, num_extents, 2, true);
++	compute_level_geometry(mp, lptr, num_extents, 2,
++			mp->m_alloc_mxr[0], mp->m_alloc_mnr[0]);
+ 	level = 1;
+ 
+ #ifdef XR_BLD_FREE_TRACE
+@@ -429,7 +430,8 @@ calculate_freespace_cursor(xfs_mount_t *mp, xfs_agnumber_t agno,
+ 		lptr = &btree_curs->level[level];
+ 
+ 		compute_level_geometry(mp, lptr,
+-				p_lptr->num_blocks, 0, false);
++				p_lptr->num_blocks, 0,
++				mp->m_alloc_mxr[1], mp->m_alloc_mnr[1]);
+ #ifdef XR_BLD_FREE_TRACE
+ 		fprintf(stderr, "%s %d %d %d %d %d\n", __func__,
+ 				level,
+@@ -509,7 +511,8 @@ calculate_freespace_cursor(xfs_mount_t *mp, xfs_agnumber_t agno,
+ 	 * of the number of extents changing
+ 	 */
+ 	old_blocks = btree_curs->level[0].num_blocks;
+-	compute_level_geometry(mp, &btree_curs->level[0], num_extents, 2, true);
++	compute_level_geometry(mp, &btree_curs->level[0], num_extents, 2,
++				mp->m_alloc_mxr[0], mp->m_alloc_mnr[0]);
+ 	extra_blocks = 0;
+ 
+ 	if (old_blocks != btree_curs->level[0].num_blocks)  {
+@@ -578,7 +581,8 @@ calculate_freespace_cursor(xfs_mount_t *mp, xfs_agnumber_t agno,
+ 			lptr = &btree_curs->level[level++];
+ 
+ 			compute_level_geometry(mp, lptr,
+-					p_lptr->num_blocks, 0, false);
++					p_lptr->num_blocks, 0,
++					mp->m_alloc_mxr[1], mp->m_alloc_mnr[1]);
+ 		}
+ 		ASSERT(level < XFS_BTREE_MAXLEVELS);
+ 		ASSERT(lptr->num_blocks == 1);
+@@ -1399,7 +1403,8 @@ init_rmapbt_cursor(
+ 	 * metadata AG entries without too many splits.
+ 	 */
+ 	compute_level_geometry(mp, lptr, num_recs,
+-			num_recs > mp->m_rmap_mxr[0] ? 10 : 0, true);
++			num_recs > mp->m_rmap_mxr[0] ? 10 : 0,
++			mp->m_rmap_mxr[0], mp->m_rmap_mnr[0]);
+ 	blocks_allocated = lptr->num_blocks;
+ 	level = 1;
+ 
+@@ -1408,7 +1413,8 @@ init_rmapbt_cursor(
+ 		lptr = &btree_curs->level[level++];
+ 
+ 		compute_level_geometry(mp, lptr,
+-				p_lptr->num_blocks, 0, false);
++				p_lptr->num_blocks, 0,
++				mp->m_rmap_mxr[1], mp->m_rmap_mnr[1]);
+ 		blocks_allocated += lptr->num_blocks;
+ 	}
+ 	ASSERT(level < XFS_BTREE_MAXLEVELS);
+
+
diff --git a/SOURCES/xfsprogs-5.7.0-xfs_quota-allow-individual-timer-extension.patch b/SOURCES/xfsprogs-5.7.0-xfs_quota-allow-individual-timer-extension.patch
new file mode 100644
index 0000000..92a2149
--- /dev/null
+++ b/SOURCES/xfsprogs-5.7.0-xfs_quota-allow-individual-timer-extension.patch
@@ -0,0 +1,227 @@
+From 36dc471cc9bb17868b79cf8dea8151b207387539 Mon Sep 17 00:00:00 2001
+From: Eric Sandeen <sandeen@redhat.com>
+Date: Tue, 26 May 2020 14:36:26 -0400
+Subject: [PATCH] xfs_quota: allow individual timer extension
+
+The only grace period which can be set via xfs_quota today is for id 0,
+i.e. the default grace period for all users.  However, setting an
+individual grace period is useful; for example:
+
+ Alice has a soft quota of 100 inodes, and a hard quota of 200 inodes
+ Alice uses 150 inodes, and enters a short grace period
+ Alice really needs to use those 150 inodes past the grace period
+ The administrator extends Alice's grace period until next Monday
+
+vfs quota users such as ext4 can do this today, with setquota -T
+
+xfs_quota can now accept an optional user id or name (symmetric with
+how warn limits are specified), in which case that user's grace period
+is extended to expire the given amount of time from now().
+
+To maintain compatibility with old command lines, if none of
+[-d|id|name] are specified, default limits are set as before.
+
+(kernelspace requires updates to enable all this as well.)
+
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
+---
+ man/man8/xfs_quota.8 | 36 +++++++++++++++++--
+ quota/edit.c         | 83 +++++++++++++++++++++++++++++++++++++-------
+ 2 files changed, 104 insertions(+), 15 deletions(-)
+
+Index: xfsprogs-5.0.0/man/man8/xfs_quota.8
+===================================================================
+--- xfsprogs-5.0.0.orig/man/man8/xfs_quota.8
++++ xfsprogs-5.0.0/man/man8/xfs_quota.8
+@@ -460,14 +460,46 @@ must be specified.
+ .B \-bir
+ ]
+ .I value
++[
++.B -d
++|
++.I id
++|
++.I name
++]
+ .br
+ Allows the quota enforcement timeout (i.e. the amount of time allowed
+ to pass before the soft limits are enforced as the hard limits) to
+ be modified. The current timeout setting can be displayed using the
+ .B state
+-command. The value argument is a number of seconds, but units of
+-\&'minutes', 'hours', 'days', and 'weeks' are also understood
++command.
++.br
++When setting the default timer via the
++.B \-d
++option, or for
++.B id
++0, or if no argument is given after
++.I value
++the
++.I value
++argument is a number of seconds indicating the relative amount of time after
++soft limits are exceeded, before hard limits are enforced.
++.br
++When setting any other individual timer by
++.I id
++or
++.I name,
++the
++.I value
++is the number of seconds from now, at which time the hard limits will be enforced.
++This allows extending the grace time of an individual user who has exceeded soft
++limits.
++.br
++For
++.I value,
++units of \&'minutes', 'hours', 'days', and 'weeks' are also understood
+ (as are their abbreviations 'm', 'h', 'd', and 'w').
++.br
+ .HP
+ .B warn
+ [
+Index: xfsprogs-5.0.0/quota/edit.c
+===================================================================
+--- xfsprogs-5.0.0.orig/quota/edit.c
++++ xfsprogs-5.0.0/quota/edit.c
+@@ -419,6 +419,7 @@ restore_f(
+ 
+ static void
+ set_timer(
++	uint32_t	id,
+ 	uint		type,
+ 	uint		mask,
+ 	char		*dev,
+@@ -427,14 +428,43 @@ set_timer(
+ 	fs_disk_quota_t	d;
+ 
+ 	memset(&d, 0, sizeof(d));
++
++	/*
++	 * If id is specified we are extending grace time by value
++	 * Otherwise we are setting the default grace time
++	 */
++	if (id) {
++		time_t	now;
++
++		/* Get quota to find out whether user is past soft limits */
++		if (xfsquotactl(XFS_GETQUOTA, dev, type, id, (void *)&d) < 0) {
++			exitcode = 1;
++			fprintf(stderr, _("%s: cannot get quota: %s\n"),
++					progname, strerror(errno));
++				return;
++		}
++
++		time(&now);
++
++		/* Only set grace time if user is already past soft limit */
++		if (d.d_blk_softlimit && d.d_bcount > d.d_blk_softlimit)
++			d.d_btimer = now + value;
++		if (d.d_ino_softlimit && d.d_icount > d.d_ino_softlimit)
++			d.d_itimer = now + value;
++		if (d.d_rtb_softlimit && d.d_rtbcount > d.d_rtb_softlimit)
++			d.d_rtbtimer = now + value;
++	} else {
++		d.d_btimer = value;
++		d.d_itimer = value;
++		d.d_rtbtimer = value;
++	}
++
+ 	d.d_version = FS_DQUOT_VERSION;
+ 	d.d_flags = type;
+ 	d.d_fieldmask = mask;
+-	d.d_itimer = value;
+-	d.d_btimer = value;
+-	d.d_rtbtimer = value;
++	d.d_id = id;
+ 
+-	if (xfsquotactl(XFS_SETQLIM, dev, type, 0, (void *)&d) < 0) {
++	if (xfsquotactl(XFS_SETQLIM, dev, type, id, (void *)&d) < 0) {
+ 		exitcode = 1;
+ 		fprintf(stderr, _("%s: cannot set timer: %s\n"),
+ 				progname, strerror(errno));
+@@ -447,10 +477,15 @@ timer_f(
+ 	char		**argv)
+ {
+ 	uint		value;
+-	int		c, type = 0, mask = 0;
++	char		*name = NULL;
++	uint32_t	id = 0;
++	int		c, flags = 0, type = 0, mask = 0;
+ 
+-	while ((c = getopt(argc, argv, "bgipru")) != EOF) {
++	while ((c = getopt(argc, argv, "bdgipru")) != EOF) {
+ 		switch (c) {
++		case 'd':
++			flags |= DEFAULTS_FLAG;
++			break;
+ 		case 'b':
+ 			mask |= FS_DQ_BTIMER;
+ 			break;
+@@ -474,23 +509,45 @@ timer_f(
+ 		}
+ 	}
+ 
+-	if (argc != optind + 1)
++	 /*
++	 * Older versions of the command did not accept -d|id|name,
++	 * so in that case we assume we're setting default timer,
++	 * and the last arg is the timer value.
++	 *
++	 * Otherwise, if the defaults flag is set, we expect 1 more arg for
++	 * timer value ; if not, 2 more args: 1 for value, one for id/name.
++	 */
++	if (!(flags & DEFAULTS_FLAG) && (argc == optind + 1)) {
++		value = cvttime(argv[optind++]);
++	} else if (flags & DEFAULTS_FLAG) {
++		if (argc != optind + 1)
++			return command_usage(&timer_cmd);
++		value = cvttime(argv[optind++]);
++	} else if (argc == optind + 2) {
++		value = cvttime(argv[optind++]);
++		name = (flags & DEFAULTS_FLAG) ? "0" : argv[optind++];
++	} else
+ 		return command_usage(&timer_cmd);
+ 
+-	value = cvttime(argv[optind++]);
+ 
++	/* if none of -bir specified, set them all */
+ 	if (!mask)
+ 		mask = FS_DQ_TIMER_MASK;
+ 
+ 	if (!type) {
+ 		type = XFS_USER_QUOTA;
+ 	} else if (type != XFS_GROUP_QUOTA &&
+-	           type != XFS_PROJ_QUOTA &&
+-	           type != XFS_USER_QUOTA) {
++		   type != XFS_PROJ_QUOTA &&
++		   type != XFS_USER_QUOTA) {
+ 		return command_usage(&timer_cmd);
+ 	}
+ 
+-	set_timer(type, mask, fs_path->fs_name, value);
++	if (name)
++		id = id_from_string(name, type);
++
++	if (id >= 0)
++		set_timer(id, type, mask, fs_path->fs_name, value);
++
+ 	return 0;
+ }
+ 
+@@ -616,9 +673,9 @@ edit_init(void)
+ 
+ 	timer_cmd.name = "timer";
+ 	timer_cmd.cfunc = timer_f;
+-	timer_cmd.argmin = 2;
++	timer_cmd.argmin = 1;
+ 	timer_cmd.argmax = -1;
+-	timer_cmd.args = _("[-bir] [-g|-p|-u] value");
++	timer_cmd.args = _("[-bir] [-g|-p|-u] value [-d|id|name]");
+ 	timer_cmd.oneline = _("set quota enforcement timeouts");
+ 	timer_cmd.help = timer_help;
+ 	timer_cmd.flags = CMD_FLAG_FOREIGN_OK;
diff --git a/SOURCES/xfsprogs-5.7.0-xfs_quota-fix-unsigned-int-id-comparisons.patch b/SOURCES/xfsprogs-5.7.0-xfs_quota-fix-unsigned-int-id-comparisons.patch
new file mode 100644
index 0000000..33a8860
--- /dev/null
+++ b/SOURCES/xfsprogs-5.7.0-xfs_quota-fix-unsigned-int-id-comparisons.patch
@@ -0,0 +1,69 @@
+From eaa5b0b79bcf2eb36f7a5e1a5b7171ad5ced7bac Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <darrick.wong@oracle.com>
+Date: Fri, 10 Jul 2020 15:33:36 -0400
+Subject: [PATCH] xfs_quota: fix unsigned int id comparisons
+
+Fix compiler warnings about unsigned int comparisons by replacing them
+with an explicit check for the one possible invalid value (-1U).
+id_from_string sets exitcode to nonzero when it sees this value, so the
+call sites don't have to do that.
+
+Coverity-id: 1463855, 1463856, 1463857
+Fixes: 67a73d6139d0 ("xfs_quota: refactor code to generate id from name")
+Fixes: 36dc471cc9bb ("xfs_quota: allow individual timer extension")
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
+---
+ quota/edit.c | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+Index: xfsprogs-5.0.0/quota/edit.c
+===================================================================
+--- xfsprogs-5.0.0.orig/quota/edit.c
++++ xfsprogs-5.0.0/quota/edit.c
+@@ -307,11 +307,11 @@ limit_f(
+ 
+ 
+ 	id = id_from_string(name, type);
+-	if (id >= 0)
+-		set_limits(id, type, mask, fs_path->fs_name,
+-			   &bsoft, &bhard, &isoft, &ihard, &rtbsoft, &rtbhard);
+-	else
+-		exitcode = -1;
++	if (id == -1)
++		return 0;
++
++	set_limits(id, type, mask, fs_path->fs_name,
++		   &bsoft, &bhard, &isoft, &ihard, &rtbsoft, &rtbhard);
+ 	return 0;
+ }
+ 
+@@ -545,9 +545,10 @@ timer_f(
+ 	if (name)
+ 		id = id_from_string(name, type);
+ 
+-	if (id >= 0)
+-		set_timer(id, type, mask, fs_path->fs_name, value);
++	if (id == -1)
++		return 0;
+ 
++	set_timer(id, type, mask, fs_path->fs_name, value);
+ 	return 0;
+ }
+ 
+@@ -642,11 +643,10 @@ warn_f(
+ 	}
+ 
+ 	id = id_from_string(name, type);
+-	if (id >= 0)
+-		set_warnings(id, type, mask, fs_path->fs_name, value);
+-	else
+-		exitcode = -1;
++	if (id == -1)
++		return 0;
+ 
++	set_warnings(id, type, mask, fs_path->fs_name, value);
+ 	return 0;
+ }
+ 
diff --git a/SOURCES/xfsprogs-5.7.0-xfs_quota-refactor-code-to-generate-id-from-name.patch b/SOURCES/xfsprogs-5.7.0-xfs_quota-refactor-code-to-generate-id-from-name.patch
new file mode 100644
index 0000000..0223f44
--- /dev/null
+++ b/SOURCES/xfsprogs-5.7.0-xfs_quota-refactor-code-to-generate-id-from-name.patch
@@ -0,0 +1,271 @@
+From 67a73d6139d0336eb7ced05bd78a26b57f408187 Mon Sep 17 00:00:00 2001
+From: Eric Sandeen <sandeen@redhat.com>
+Date: Tue, 26 May 2020 14:36:04 -0400
+Subject: [PATCH] xfs_quota: refactor code to generate id from name
+
+There's boilerplate for setting limits and warnings, where we have
+a case statement for each of the 3 quota types, and from there call
+3 different functions to configure each of the 3 types, each of which
+calls its own version of id to string function...
+
+Refactor this so that the main function can call a generic id to string
+conversion routine, and then call a common action.  This save a lot of
+LOC.
+
+I was looking at allowing xfs to bump out individual grace periods like
+setquota can do, and this refactoring allows us to add new actions like
+that without copying all the boilerplate again.
+
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
+---
+ quota/edit.c | 194 +++++++++++++--------------------------------------
+ 1 file changed, 49 insertions(+), 145 deletions(-)
+
+Index: xfsprogs-5.0.0/quota/edit.c
+===================================================================
+--- xfsprogs-5.0.0.orig/quota/edit.c
++++ xfsprogs-5.0.0/quota/edit.c
+@@ -101,6 +101,40 @@ warn_help(void)
+ "\n"));
+ }
+ 
++static uint32_t
++id_from_string(
++	char	*name,
++	int	type)
++{
++	uint32_t	id = -1;
++	const char	*type_name = "unknown type";
++
++	switch (type) {
++	case XFS_USER_QUOTA:
++		type_name = "user";
++		id = uid_from_string(name);
++		break;
++	case XFS_GROUP_QUOTA:
++		type_name = "group";
++		id = gid_from_string(name);
++		break;
++	case XFS_PROJ_QUOTA:
++		type_name = "project";
++		id = prid_from_string(name);
++		break;
++	default:
++		ASSERT(0);
++		break;
++	}
++
++	if (id == -1) {
++		fprintf(stderr, _("%s: invalid %s name: %s\n"),
++			type_name, progname, name);
++		exitcode = 1;
++	}
++	return id;
++}
++
+ static void
+ set_limits(
+ 	uint32_t	id,
+@@ -135,75 +169,6 @@ set_limits(
+ 	}
+ }
+ 
+-static void
+-set_user_limits(
+-	char		*name,
+-	uint		type,
+-	uint		mask,
+-	uint64_t	*bsoft,
+-	uint64_t	*bhard,
+-	uint64_t	*isoft,
+-	uint64_t	*ihard,
+-	uint64_t	*rtbsoft,
+-	uint64_t	*rtbhard)
+-{
+-	uid_t		uid = uid_from_string(name);
+-
+-	if (uid == -1) {
+-		exitcode = 1;
+-		fprintf(stderr, _("%s: invalid user name: %s\n"),
+-				progname, name);
+-	} else
+-		set_limits(uid, type, mask, fs_path->fs_name,
+-				bsoft, bhard, isoft, ihard, rtbsoft, rtbhard);
+-}
+-
+-static void
+-set_group_limits(
+-	char		*name,
+-	uint		type,
+-	uint		mask,
+-	uint64_t	*bsoft,
+-	uint64_t	*bhard,
+-	uint64_t	*isoft,
+-	uint64_t	*ihard,
+-	uint64_t	*rtbsoft,
+-	uint64_t	*rtbhard)
+-{
+-	gid_t		gid = gid_from_string(name);
+-
+-	if (gid == -1) {
+-		exitcode = 1;
+-		fprintf(stderr, _("%s: invalid group name: %s\n"),
+-				progname, name);
+-	} else
+-		set_limits(gid, type, mask, fs_path->fs_name,
+-				bsoft, bhard, isoft, ihard, rtbsoft, rtbhard);
+-}
+-
+-static void
+-set_project_limits(
+-	char		*name,
+-	uint		type,
+-	uint		mask,
+-	uint64_t	*bsoft,
+-	uint64_t	*bhard,
+-	uint64_t	*isoft,
+-	uint64_t	*ihard,
+-	uint64_t	*rtbsoft,
+-	uint64_t	*rtbhard)
+-{
+-	prid_t		prid = prid_from_string(name);
+-
+-	if (prid == -1) {
+-		exitcode = 1;
+-		fprintf(stderr, _("%s: invalid project name: %s\n"),
+-				progname, name);
+-	} else
+-		set_limits(prid, type, mask, fs_path->fs_name,
+-				bsoft, bhard, isoft, ihard, rtbsoft, rtbhard);
+-}
+-
+ /* extract number of blocks from an ascii string */
+ static int
+ extractb(
+@@ -258,6 +223,7 @@ limit_f(
+ 	char		**argv)
+ {
+ 	char		*name;
++	uint32_t	id;
+ 	uint64_t	bsoft, bhard, isoft, ihard, rtbsoft, rtbhard;
+ 	int		c, type = 0, mask = 0, flags = 0;
+ 	uint		bsize, ssize, endoptions;
+@@ -339,20 +305,13 @@ limit_f(
+ 		return command_usage(&limit_cmd);
+ 	}
+ 
+-	switch (type) {
+-	case XFS_USER_QUOTA:
+-		set_user_limits(name, type, mask,
+-			&bsoft, &bhard, &isoft, &ihard, &rtbsoft, &rtbhard);
+-		break;
+-	case XFS_GROUP_QUOTA:
+-		set_group_limits(name, type, mask,
+-			&bsoft, &bhard, &isoft, &ihard, &rtbsoft, &rtbhard);
+-		break;
+-	case XFS_PROJ_QUOTA:
+-		set_project_limits(name, type, mask,
+-			&bsoft, &bhard, &isoft, &ihard, &rtbsoft, &rtbhard);
+-		break;
+-	}
++
++	id = id_from_string(name, type);
++	if (id >= 0)
++		set_limits(id, type, mask, fs_path->fs_name,
++			   &bsoft, &bhard, &isoft, &ihard, &rtbsoft, &rtbhard);
++	else
++		exitcode = -1;
+ 	return 0;
+ }
+ 
+@@ -561,63 +520,13 @@ set_warnings(
+ 	}
+ }
+ 
+-static void
+-set_user_warnings(
+-	char		*name,
+-	uint		type,
+-	uint		mask,
+-	uint		value)
+-{
+-	uid_t		uid = uid_from_string(name);
+-
+-	if (uid == -1) {
+-		exitcode = 1;
+-		fprintf(stderr, _("%s: invalid user name: %s\n"),
+-				progname, name);
+-	} else
+-		set_warnings(uid, type, mask, fs_path->fs_name, value);
+-}
+-
+-static void
+-set_group_warnings(
+-	char		*name,
+-	uint		type,
+-	uint		mask,
+-	uint		value)
+-{
+-	gid_t		gid = gid_from_string(name);
+-
+-	if (gid == -1) {
+-		exitcode = 1;
+-		fprintf(stderr, _("%s: invalid group name: %s\n"),
+-				progname, name);
+-	} else
+-		set_warnings(gid, type, mask, fs_path->fs_name, value);
+-}
+-
+-static void
+-set_project_warnings(
+-	char		*name,
+-	uint		type,
+-	uint		mask,
+-	uint		value)
+-{
+-	prid_t		prid = prid_from_string(name);
+-
+-	if (prid == -1) {
+-		exitcode = 1;
+-		fprintf(stderr, _("%s: invalid project name: %s\n"),
+-				progname, name);
+-	} else
+-		set_warnings(prid, type, mask, fs_path->fs_name, value);
+-}
+-
+ static int
+ warn_f(
+ 	int		argc,
+ 	char		**argv)
+ {
+ 	char		*name;
++	uint32_t	id;
+ 	uint		value;
+ 	int		c, flags = 0, type = 0, mask = 0;
+ 
+@@ -675,17 +584,12 @@ warn_f(
+ 		return command_usage(&warn_cmd);
+ 	}
+ 
+-	switch (type) {
+-	case XFS_USER_QUOTA:
+-		set_user_warnings(name, type, mask, value);
+-		break;
+-	case XFS_GROUP_QUOTA:
+-		set_group_warnings(name, type, mask, value);
+-		break;
+-	case XFS_PROJ_QUOTA:
+-		set_project_warnings(name, type, mask, value);
+-		break;
+-	}
++	id = id_from_string(name, type);
++	if (id >= 0)
++		set_warnings(id, type, mask, fs_path->fs_name, value);
++	else
++		exitcode = -1;
++
+ 	return 0;
+ }
+ 
diff --git a/SOURCES/xfsprogs-5.7.0-xfs_repair-check-for-AG-btree-records-that-would-wra.patch b/SOURCES/xfsprogs-5.7.0-xfs_repair-check-for-AG-btree-records-that-would-wra.patch
new file mode 100644
index 0000000..a0afd5c
--- /dev/null
+++ b/SOURCES/xfsprogs-5.7.0-xfs_repair-check-for-AG-btree-records-that-would-wra.patch
@@ -0,0 +1,54 @@
+From cae4fd291266c32441c6a7fcca49929fe11c391c Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <darrick.wong@oracle.com>
+Date: Fri, 10 Jul 2020 15:35:44 -0400
+Subject: [PATCH] xfs_repair: check for AG btree records that would wrap around
+
+For AG btree types, make sure that each record's length is not so huge
+that integer wraparound would happen.
+
+Found via xfs/358 fuzzing recs[1].blockcount = ones.
+
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
+---
+ repair/scan.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+diff --git a/repair/scan.c b/repair/scan.c
+index 5c8d8b23..1ddb5763 100644
+--- a/repair/scan.c
++++ b/repair/scan.c
+@@ -684,7 +684,8 @@ _("%s freespace btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
+ 					b, i, name, agno, bno);
+ 				continue;
+ 			}
+-			if (len == 0 || !verify_agbno(mp, agno, end - 1)) {
++			if (len == 0 || end <= b ||
++			    !verify_agbno(mp, agno, end - 1)) {
+ 				do_warn(
+ 	_("invalid length %u in record %u of %s btree block %u/%u\n"),
+ 					len, i, name, agno, bno);
+@@ -1066,7 +1067,8 @@ _("%s rmap btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
+ 					b, i, name, agno, bno);
+ 				continue;
+ 			}
+-			if (len == 0 || !verify_agbno(mp, agno, end - 1)) {
++			if (len == 0 || end <= b ||
++			    !verify_agbno(mp, agno, end - 1)) {
+ 				do_warn(
+ 	_("invalid length %u in record %u of %s btree block %u/%u\n"),
+ 					len, i, name, agno, bno);
+@@ -1353,7 +1355,8 @@ _("leftover CoW extent has invalid startblock in record %u of %s btree block %u/
+ 					b, i, name, agno, bno);
+ 				continue;
+ 			}
+-			if (len == 0 || !verify_agbno(mp, agno, end - 1)) {
++			if (len == 0 || end <= agb ||
++			    !verify_agbno(mp, agno, end - 1)) {
+ 				do_warn(
+ 	_("invalid length %u in record %u of %s btree block %u/%u\n"),
+ 					len, i, name, agno, bno);
+-- 
+2.29.2
+
diff --git a/SOURCES/xfsprogs-5.7.0-xfs_repair-complain-about-bad-interior-btree-pointer.patch b/SOURCES/xfsprogs-5.7.0-xfs_repair-complain-about-bad-interior-btree-pointer.patch
new file mode 100644
index 0000000..62255ce
--- /dev/null
+++ b/SOURCES/xfsprogs-5.7.0-xfs_repair-complain-about-bad-interior-btree-pointer.patch
@@ -0,0 +1,124 @@
+From 320cc3b263542e692c4978fb327efa591892ab37 Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <darrick.wong@oracle.com>
+Date: Fri, 10 Jul 2020 15:35:45 -0400
+Subject: [PATCH] xfs_repair: complain about bad interior btree pointers
+
+Actually complain about garbage btree node pointers, don't just silently
+ignore them.
+
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
+---
+ libxfs/libxfs_api_defs.h |  1 +
+ repair/scan.c            | 55 +++++++++++++++++++++++++++++-----------
+ 2 files changed, 41 insertions(+), 15 deletions(-)
+
+Index: xfsprogs-5.0.0/libxfs/libxfs_api_defs.h
+===================================================================
+--- xfsprogs-5.0.0.orig/libxfs/libxfs_api_defs.h
++++ xfsprogs-5.0.0/libxfs/libxfs_api_defs.h
+@@ -118,6 +118,7 @@
+ #define xfs_symlink_blocks		libxfs_symlink_blocks
+ #define xfs_symlink_hdr_ok		libxfs_symlink_hdr_ok
+ 
++#define xfs_verify_agbno		libxfs_verify_agbno
+ #define xfs_verify_cksum		libxfs_verify_cksum
+ #define xfs_dinode_verify		libxfs_dinode_verify
+ 
+Index: xfsprogs-5.0.0/repair/scan.c
+===================================================================
+--- xfsprogs-5.0.0.orig/repair/scan.c
++++ xfsprogs-5.0.0/repair/scan.c
+@@ -743,6 +743,14 @@ _("%s freespace btree block claimed (sta
+ 	for (i = 0; i < numrecs; i++)  {
+ 		xfs_agblock_t		agbno = be32_to_cpu(pp[i]);
+ 
++		if (!libxfs_verify_agbno(mp, agno, agbno)) {
++			do_warn(
++	_("bad btree pointer (%u) in %sbt block %u/%u\n"),
++				agbno, name, agno, bno);
++			suspect++;
++			return;
++		}
++
+ 		/*
+ 		 * XXX - put sibling detection right here.
+ 		 * we know our sibling chain is good.  So as we go,
+@@ -752,10 +760,8 @@ _("%s freespace btree block claimed (sta
+ 		 * pointer mismatch, try and extract as much data
+ 		 * as possible.
+ 		 */
+-		if (agbno != 0 && verify_agbno(mp, agno, agbno)) {
+-			scan_sbtree(agbno, level, agno, suspect, scan_allocbt,
+-				    0, magic, priv, ops);
+-		}
++		scan_sbtree(agbno, level, agno, suspect, scan_allocbt, 0,
++				magic, priv, ops);
+ 	}
+ }
+ 
+@@ -1196,10 +1202,16 @@ advance:
+ 			continue;
+ 		}
+ 
+-		if (agbno != 0 && verify_agbno(mp, agno, agbno)) {
+-			scan_sbtree(agbno, level, agno, suspect, scan_rmapbt, 0,
+-				    magic, priv, ops);
++		if (!libxfs_verify_agbno(mp, agno, agbno)) {
++			do_warn(
++	_("bad btree pointer (%u) in %sbt block %u/%u\n"),
++				agbno, name, agno, bno);
++			suspect++;
++			return;
+ 		}
++
++		scan_sbtree(agbno, level, agno, suspect, scan_rmapbt, 0, magic,
++				priv, ops);
+ 	}
+ 
+ out:
+@@ -1416,10 +1428,16 @@ _("extent (%u/%u) len %u claimed, state
+ 	for (i = 0; i < numrecs; i++)  {
+ 		xfs_agblock_t		agbno = be32_to_cpu(pp[i]);
+ 
+-		if (agbno != 0 && verify_agbno(mp, agno, agbno)) {
+-			scan_sbtree(agbno, level, agno, suspect, scan_refcbt, 0,
+-				    magic, priv, ops);
++		if (!libxfs_verify_agbno(mp, agno, agbno)) {
++			do_warn(
++	_("bad btree pointer (%u) in %sbt block %u/%u\n"),
++				agbno, name, agno, bno);
++			suspect++;
++			return;
+ 		}
++
++		scan_sbtree(agbno, level, agno, suspect, scan_refcbt, 0, magic,
++				priv, ops);
+ 	}
+ out:
+ 	if (suspect)
+@@ -2083,11 +2101,18 @@ _("inode btree block claimed (state %d),
+ 	}
+ 
+ 	for (i = 0; i < numrecs; i++)  {
+-		if (be32_to_cpu(pp[i]) != 0 && verify_agbno(mp, agno,
+-							be32_to_cpu(pp[i])))
+-			scan_sbtree(be32_to_cpu(pp[i]), level, agno,
+-					suspect, scan_inobt, 0, magic, priv,
+-					ops);
++		xfs_agblock_t	agbno = be32_to_cpu(pp[i]);
++
++		if (!libxfs_verify_agbno(mp, agno, agbno)) {
++			do_warn(
++	_("bad btree pointer (%u) in %sbt block %u/%u\n"),
++				agbno, name, agno, bno);
++			suspect++;
++			return;
++		}
++
++		scan_sbtree(be32_to_cpu(pp[i]), level, agno, suspect,
++				scan_inobt, 0, magic, priv, ops);
+ 	}
+ }
+ 
diff --git a/SOURCES/xfsprogs-5.7.0-xfs_repair-convert-to-libxfs_verify_agbno.patch b/SOURCES/xfsprogs-5.7.0-xfs_repair-convert-to-libxfs_verify_agbno.patch
new file mode 100644
index 0000000..1787328
--- /dev/null
+++ b/SOURCES/xfsprogs-5.7.0-xfs_repair-convert-to-libxfs_verify_agbno.patch
@@ -0,0 +1,209 @@
+From dcd6c2e1490ba5c59c14ca8ea843ca36048888b8 Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <darrick.wong@oracle.com>
+Date: Fri, 10 Jul 2020 15:35:45 -0400
+Subject: [PATCH] xfs_repair: convert to libxfs_verify_agbno
+
+Convert the homegrown verify_agbno callers to use the libxfs function,
+as needed.  In some places we drop the "bno != 0" checks because those
+conditionals are checking btree roots; btree roots should never be
+zero if the corresponding feature bit is set; and repair skips the if
+clause entirely if the feature bit is disabled.
+
+In effect, this strengthens repair to validate that AG btree pointers
+neither point to the AG headers nor past the end of the AG.
+
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
+---
+ libxfs/libxfs_api_defs.h |  1 +
+ repair/dinode.c          | 11 -----------
+ repair/dinode.h          |  5 -----
+ repair/scan.c            | 36 +++++++++++++++++++++++-------------
+ 4 files changed, 24 insertions(+), 29 deletions(-)
+
+Index: xfsprogs-5.0.0/libxfs/libxfs_api_defs.h
+===================================================================
+--- xfsprogs-5.0.0.orig/libxfs/libxfs_api_defs.h
++++ xfsprogs-5.0.0/libxfs/libxfs_api_defs.h
+@@ -121,6 +121,7 @@
+ #define xfs_verify_agbno		libxfs_verify_agbno
+ #define xfs_verify_cksum		libxfs_verify_cksum
+ #define xfs_dinode_verify		libxfs_dinode_verify
++#define xfs_ag_block_count		libxfs_ag_block_count
+ 
+ #define xfs_alloc_ag_max_usable		libxfs_alloc_ag_max_usable
+ #define xfs_allocbt_maxrecs		libxfs_allocbt_maxrecs
+Index: xfsprogs-5.0.0/repair/dinode.c
+===================================================================
+--- xfsprogs-5.0.0.orig/repair/dinode.c
++++ xfsprogs-5.0.0/repair/dinode.c
+@@ -284,17 +284,6 @@ verify_dfsbno_range(xfs_mount_t	*mp,
+ 	return (XR_DFSBNORANGE_VALID);
+ }
+ 
+-int
+-verify_agbno(xfs_mount_t	*mp,
+-		xfs_agnumber_t	agno,
+-		xfs_agblock_t	agbno)
+-{
+-	xfs_sb_t	*sbp = &mp->m_sb;;
+-
+-	/* range check ag #, ag block.  range-checking offset is pointless */
+-	return verify_ag_bno(sbp, agno, agbno) == 0;
+-}
+-
+ static int
+ process_rt_rec(
+ 	xfs_mount_t		*mp,
+Index: xfsprogs-5.0.0/repair/dinode.h
+===================================================================
+--- xfsprogs-5.0.0.orig/repair/dinode.h
++++ xfsprogs-5.0.0/repair/dinode.h
+@@ -10,11 +10,6 @@ struct blkmap;
+ struct prefetch_args;
+ 
+ int
+-verify_agbno(xfs_mount_t	*mp,
+-		xfs_agnumber_t	agno,
+-		xfs_agblock_t	agbno);
+-
+-int
+ verify_dfsbno(xfs_mount_t	*mp,
+ 		xfs_fsblock_t	fsbno);
+ 
+Index: xfsprogs-5.0.0/repair/scan.c
+===================================================================
+--- xfsprogs-5.0.0.orig/repair/scan.c
++++ xfsprogs-5.0.0/repair/scan.c
+@@ -642,14 +642,14 @@ _("%s freespace btree block claimed (sta
+ 			len = be32_to_cpu(rp[i].ar_blockcount);
+ 			end = b + len;
+ 
+-			if (b == 0 || !verify_agbno(mp, agno, b)) {
++			if (!libxfs_verify_agbno(mp, agno, b)) {
+ 				do_warn(
+ 	_("invalid start block %u in record %u of %s btree block %u/%u\n"),
+ 					b, i, name, agno, bno);
+ 				continue;
+ 			}
+ 			if (len == 0 || end <= b ||
+-			    !verify_agbno(mp, agno, end - 1)) {
++			    !libxfs_verify_agbno(mp, agno, end - 1)) {
+ 				do_warn(
+ 	_("invalid length %u in record %u of %s btree block %u/%u\n"),
+ 					len, i, name, agno, bno);
+@@ -914,6 +914,16 @@ rmap_in_order(
+ 	return offset > lastoffset;
+ }
+ 
++static inline bool
++verify_rmap_agbno(
++	struct xfs_mount	*mp,
++	xfs_agnumber_t		agno,
++	xfs_agblock_t		agbno)
++{
++	return agbno < libxfs_ag_block_count(mp, agno);
++}
++
++
+ static void
+ scan_rmapbt(
+ 	struct xfs_btree_block	*block,
+@@ -1031,14 +1041,14 @@ _("%s rmap btree block claimed (state %d
+ 			end = key.rm_startblock + key.rm_blockcount;
+ 
+ 			/* Make sure agbno & len make sense. */
+-			if (!verify_agbno(mp, agno, b)) {
++			if (!verify_rmap_agbno(mp, agno, b)) {
+ 				do_warn(
+ 	_("invalid start block %u in record %u of %s btree block %u/%u\n"),
+ 					b, i, name, agno, bno);
+ 				continue;
+ 			}
+ 			if (len == 0 || end <= b ||
+-			    !verify_agbno(mp, agno, end - 1)) {
++			    !verify_rmap_agbno(mp, agno, end - 1)) {
+ 				do_warn(
+ 	_("invalid length %u in record %u of %s btree block %u/%u\n"),
+ 					len, i, name, agno, bno);
+@@ -1325,14 +1335,14 @@ _("leftover CoW extent has invalid start
+ 			}
+ 			end = agb + len;
+ 
+-			if (!verify_agbno(mp, agno, agb)) {
++			if (!libxfs_verify_agbno(mp, agno, agb)) {
+ 				do_warn(
+ 	_("invalid start block %u in record %u of %s btree block %u/%u\n"),
+ 					b, i, name, agno, bno);
+ 				continue;
+ 			}
+ 			if (len == 0 || end <= agb ||
+-			    !verify_agbno(mp, agno, end - 1)) {
++			    !libxfs_verify_agbno(mp, agno, end - 1)) {
+ 				do_warn(
+ 	_("invalid length %u in record %u of %s btree block %u/%u\n"),
+ 					len, i, name, agno, bno);
+@@ -2145,7 +2155,7 @@ scan_agfl(
+ {
+ 	struct agfl_state	*as = priv;
+ 
+-	if (verify_agbno(mp, as->agno, bno))
++	if (libxfs_verify_agbno(mp, as->agno, bno))
+ 		set_bmap(as->agno, bno, XR_E_FREE);
+ 	else
+ 		do_warn(_("bad agbno %u in agfl, agno %d\n"),
+@@ -2217,7 +2227,7 @@ validate_agf(
+ 	uint32_t		magic;
+ 
+ 	bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_BNO]);
+-	if (bno != 0 && verify_agbno(mp, agno, bno)) {
++	if (libxfs_verify_agbno(mp, agno, bno)) {
+ 		magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_ABTB_CRC_MAGIC
+ 							 : XFS_ABTB_MAGIC;
+ 		scan_sbtree(bno, be32_to_cpu(agf->agf_levels[XFS_BTNUM_BNO]),
+@@ -2229,7 +2239,7 @@ validate_agf(
+ 	}
+ 
+ 	bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_CNT]);
+-	if (bno != 0 && verify_agbno(mp, agno, bno)) {
++	if (libxfs_verify_agbno(mp, agno, bno)) {
+ 		magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_ABTC_CRC_MAGIC
+ 							 : XFS_ABTC_MAGIC;
+ 		scan_sbtree(bno, be32_to_cpu(agf->agf_levels[XFS_BTNUM_CNT]),
+@@ -2249,7 +2259,7 @@ validate_agf(
+ 		priv.last_rec.rm_owner = XFS_RMAP_OWN_UNKNOWN;
+ 		priv.nr_blocks = 0;
+ 		bno = be32_to_cpu(agf->agf_roots[XFS_BTNUM_RMAP]);
+-		if (bno != 0 && verify_agbno(mp, agno, bno)) {
++		if (libxfs_verify_agbno(mp, agno, bno)) {
+ 			scan_sbtree(bno,
+ 				    be32_to_cpu(agf->agf_levels[XFS_BTNUM_RMAP]),
+ 				    agno, 0, scan_rmapbt, 1, XFS_RMAP_CRC_MAGIC,
+@@ -2267,7 +2277,7 @@ validate_agf(
+ 
+ 	if (xfs_sb_version_hasreflink(&mp->m_sb)) {
+ 		bno = be32_to_cpu(agf->agf_refcount_root);
+-		if (bno != 0 && verify_agbno(mp, agno, bno)) {
++		if (libxfs_verify_agbno(mp, agno, bno)) {
+ 			struct refc_priv	priv;
+ 
+ 			memset(&priv, 0, sizeof(priv));
+@@ -2315,7 +2325,7 @@ validate_agi(
+ 	uint32_t		magic;
+ 
+ 	bno = be32_to_cpu(agi->agi_root);
+-	if (bno != 0 && verify_agbno(mp, agno, bno)) {
++	if (libxfs_verify_agbno(mp, agno, bno)) {
+ 		magic = xfs_sb_version_hascrc(&mp->m_sb) ? XFS_IBT_CRC_MAGIC
+ 							 : XFS_IBT_MAGIC;
+ 		scan_sbtree(bno, be32_to_cpu(agi->agi_level),
+@@ -2328,7 +2338,7 @@ validate_agi(
+ 
+ 	if (xfs_sb_version_hasfinobt(&mp->m_sb)) {
+ 		bno = be32_to_cpu(agi->agi_free_root);
+-		if (bno != 0 && verify_agbno(mp, agno, bno)) {
++		if (libxfs_verify_agbno(mp, agno, bno)) {
+ 			magic = xfs_sb_version_hascrc(&mp->m_sb) ?
+ 					XFS_FIBT_CRC_MAGIC : XFS_FIBT_MAGIC;
+ 			scan_sbtree(bno, be32_to_cpu(agi->agi_free_level),
diff --git a/SOURCES/xfsprogs-5.7.0-xfs_repair-fix-rebuilding-btree-block-less-than-minr.patch b/SOURCES/xfsprogs-5.7.0-xfs_repair-fix-rebuilding-btree-block-less-than-minr.patch
new file mode 100644
index 0000000..9192518
--- /dev/null
+++ b/SOURCES/xfsprogs-5.7.0-xfs_repair-fix-rebuilding-btree-block-less-than-minr.patch
@@ -0,0 +1,290 @@
+From 6df28d12d7760701c9d11e659e374665c5ffd0b9 Mon Sep 17 00:00:00 2001
+From: Gao Xiang <hsiangkao@redhat.com>
+Date: Fri, 10 Jul 2020 15:32:36 -0400
+Subject: [PATCH] xfs_repair: fix rebuilding btree block less than minrecs
+
+In production, we found that sometimes xfs_repair phase 5
+rebuilds freespace node block with pointers less than minrecs
+and if we trigger xfs_repair again it would report such
+the following message:
+
+bad btree nrecs (39, min=40, max=80) in btbno block 0/7882
+
+The background is that xfs_repair starts to rebuild AGFL
+after the freespace btree is settled in phase 5 so we may
+need to leave necessary room in advance for each btree
+leaves in order to avoid freespace btree split and then
+result in AGFL rebuild fails. The old mathematics uses
+ceil(num_extents / maxrecs) to decide the number of node
+blocks. That would be fine without leaving extra space
+since minrecs = maxrecs / 2 but if some slack was decreased
+from maxrecs, the result would be larger than what is
+expected and cause num_recs_pb less than minrecs, i.e:
+
+num_extents = 79, adj_maxrecs = 80 - 2 (slack) = 78
+
+so we'd get
+
+num_blocks = ceil(79 / 78) = 2,
+num_recs_pb = 79 / 2 = 39, which is less than
+minrecs = 80 / 2 = 40
+
+OTOH, btree bulk loading code behaves in a different way.
+As in xfs_btree_bload_level_geometry it wrote
+
+num_blocks = floor(num_extents / maxrecs)
+
+which will never go below minrecs. And when it goes above
+maxrecs, just increment num_blocks and recalculate so we
+can get the reasonable results.
+
+Later, btree bulk loader will replace the current repair code.
+But we may still want to look for a backportable solution
+for stable versions. Hence, keep the same logic to avoid
+the freespace as well as rmap btree minrecs underflow for now.
+
+Cc: "Darrick J. Wong" <darrick.wong@oracle.com>
+Cc: Dave Chinner <dchinner@redhat.com>
+Cc: Eric Sandeen <sandeen@sandeen.net>
+Fixes: 9851fd79bfb1 ("repair: AGFL rebuild fails if btree split required")
+Signed-off-by: Gao Xiang <hsiangkao@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
+---
+ repair/phase5.c | 152 ++++++++++++++++++++----------------------------
+ 1 file changed, 63 insertions(+), 89 deletions(-)
+
+Index: xfsprogs-5.0.0/repair/phase5.c
+===================================================================
+--- xfsprogs-5.0.0.orig/repair/phase5.c
++++ xfsprogs-5.0.0/repair/phase5.c
+@@ -346,11 +346,32 @@ finish_cursor(bt_status_t *curs)
+  * failure at runtime. Hence leave a couple of records slack space in
+  * each block to allow immediate modification of the tree without
+  * requiring splits to be done.
+- *
+- * XXX(hch): any reason we don't just look at mp->m_alloc_mxr?
+  */
+-#define XR_ALLOC_BLOCK_MAXRECS(mp, level) \
+-	(libxfs_allocbt_maxrecs((mp), (mp)->m_sb.sb_blocksize, (level) == 0) - 2)
++static void
++compute_level_geometry(
++	struct xfs_mount	*mp,
++	struct bt_stat_level	*lptr,
++	uint64_t		nr_this_level,
++	int			slack,
++	bool			leaf)
++{
++	unsigned int		maxrecs = mp->m_alloc_mxr[!leaf];
++	unsigned int		desired_npb;
++
++	desired_npb = max(mp->m_alloc_mnr[!leaf], maxrecs - slack);
++	lptr->num_recs_tot = nr_this_level;
++	lptr->num_blocks = max(1ULL, nr_this_level / desired_npb);
++
++	lptr->num_recs_pb = nr_this_level / lptr->num_blocks;
++	lptr->modulo = nr_this_level % lptr->num_blocks;
++	if (lptr->num_recs_pb > maxrecs ||
++	    (lptr->num_recs_pb == maxrecs && lptr->modulo)) {
++		lptr->num_blocks++;
++
++		lptr->num_recs_pb = nr_this_level / lptr->num_blocks;
++		lptr->modulo = nr_this_level % lptr->num_blocks;
++	}
++}
+ 
+ /*
+  * this calculates a freespace cursor for an ag.
+@@ -368,6 +389,7 @@ calculate_freespace_cursor(xfs_mount_t *
+ 	int			i;
+ 	int			extents_used;
+ 	int			extra_blocks;
++	uint64_t		old_blocks;
+ 	bt_stat_level_t		*lptr;
+ 	bt_stat_level_t		*p_lptr;
+ 	extent_tree_node_t	*ext_ptr;
+@@ -386,10 +408,7 @@ calculate_freespace_cursor(xfs_mount_t *
+ 	 * of the tree and set up the cursor for the leaf level
+ 	 * (note that the same code is duplicated further down)
+ 	 */
+-	lptr->num_blocks = howmany(num_extents, XR_ALLOC_BLOCK_MAXRECS(mp, 0));
+-	lptr->num_recs_pb = num_extents / lptr->num_blocks;
+-	lptr->modulo = num_extents % lptr->num_blocks;
+-	lptr->num_recs_tot = num_extents;
++	compute_level_geometry(mp, lptr, num_extents, 2, true);
+ 	level = 1;
+ 
+ #ifdef XR_BLD_FREE_TRACE
+@@ -403,30 +422,23 @@ calculate_freespace_cursor(xfs_mount_t *
+ 	 * if we need more levels, set them up.  # of records
+ 	 * per level is the # of blocks in the level below it
+ 	 */
+-	if (lptr->num_blocks > 1)  {
+-		for (; btree_curs->level[level - 1].num_blocks > 1
+-				&& level < XFS_BTREE_MAXLEVELS;
+-				level++)  {
+-			lptr = &btree_curs->level[level];
+-			p_lptr = &btree_curs->level[level - 1];
+-			lptr->num_blocks = howmany(p_lptr->num_blocks,
+-					XR_ALLOC_BLOCK_MAXRECS(mp, level));
+-			lptr->modulo = p_lptr->num_blocks
+-					% lptr->num_blocks;
+-			lptr->num_recs_pb = p_lptr->num_blocks
+-					/ lptr->num_blocks;
+-			lptr->num_recs_tot = p_lptr->num_blocks;
++	while (lptr->num_blocks > 1) {
++		p_lptr = lptr;
++		lptr = &btree_curs->level[level];
++
++		compute_level_geometry(mp, lptr,
++				p_lptr->num_blocks, 0, false);
+ #ifdef XR_BLD_FREE_TRACE
+-			fprintf(stderr, "%s %d %d %d %d %d\n", __func__,
+-					level,
+-					lptr->num_blocks,
+-					lptr->num_recs_pb,
+-					lptr->modulo,
+-					lptr->num_recs_tot);
++		fprintf(stderr, "%s %d %d %d %d %d\n", __func__,
++				level,
++				lptr->num_blocks,
++				lptr->num_recs_pb,
++				lptr->modulo,
++				lptr->num_recs_tot);
+ #endif
+-		}
++		level++;
+ 	}
+-
++	ASSERT(level < XFS_BTREE_MAXLEVELS);
+ 	ASSERT(lptr->num_blocks == 1);
+ 	btree_curs->num_levels = level;
+ 
+@@ -494,8 +506,11 @@ calculate_freespace_cursor(xfs_mount_t *
+ 	 * see if the number of leaf blocks will change as a result
+ 	 * of the number of extents changing
+ 	 */
+-	if (howmany(num_extents, XR_ALLOC_BLOCK_MAXRECS(mp, 0))
+-			!= btree_curs->level[0].num_blocks)  {
++	old_blocks = btree_curs->level[0].num_blocks;
++	compute_level_geometry(mp, &btree_curs->level[0], num_extents, 2, true);
++	extra_blocks = 0;
++
++	if (old_blocks != btree_curs->level[0].num_blocks)  {
+ 		/*
+ 		 * yes -- recalculate the cursor.  If the number of
+ 		 * excess (overallocated) blocks is < xfs_agfl_size/2, we're ok.
+@@ -551,31 +566,19 @@ calculate_freespace_cursor(xfs_mount_t *
+ 		}
+ 
+ 		lptr = &btree_curs->level[0];
+-		lptr->num_blocks = howmany(num_extents,
+-					XR_ALLOC_BLOCK_MAXRECS(mp, 0));
+-		lptr->num_recs_pb = num_extents / lptr->num_blocks;
+-		lptr->modulo = num_extents % lptr->num_blocks;
+-		lptr->num_recs_tot = num_extents;
+ 		level = 1;
+ 
+ 		/*
+ 		 * if we need more levels, set them up
+ 		 */
+-		if (lptr->num_blocks > 1)  {
+-			for (level = 1; btree_curs->level[level-1].num_blocks
+-					> 1 && level < XFS_BTREE_MAXLEVELS;
+-					level++)  {
+-				lptr = &btree_curs->level[level];
+-				p_lptr = &btree_curs->level[level-1];
+-				lptr->num_blocks = howmany(p_lptr->num_blocks,
+-					XR_ALLOC_BLOCK_MAXRECS(mp, level));
+-				lptr->modulo = p_lptr->num_blocks
+-						% lptr->num_blocks;
+-				lptr->num_recs_pb = p_lptr->num_blocks
+-						/ lptr->num_blocks;
+-				lptr->num_recs_tot = p_lptr->num_blocks;
+-			}
++		while (lptr->num_blocks > 1) {
++			p_lptr = lptr;
++			lptr = &btree_curs->level[level++];
++
++			compute_level_geometry(mp, lptr,
++					p_lptr->num_blocks, 0, false);
+ 		}
++		ASSERT(level < XFS_BTREE_MAXLEVELS);
+ 		ASSERT(lptr->num_blocks == 1);
+ 		btree_curs->num_levels = level;
+ 
+@@ -589,22 +592,6 @@ calculate_freespace_cursor(xfs_mount_t *
+ 
+ 		ASSERT(blocks_allocated_total >= blocks_needed);
+ 		extra_blocks = blocks_allocated_total - blocks_needed;
+-	} else  {
+-		if (extents_used > 0) {
+-			/*
+-			 * reset the leaf level geometry to account
+-			 * for consumed extents.  we can leave the
+-			 * rest of the cursor alone since the number
+-			 * of leaf blocks hasn't changed.
+-			 */
+-			lptr = &btree_curs->level[0];
+-
+-			lptr->num_recs_pb = num_extents / lptr->num_blocks;
+-			lptr->modulo = num_extents % lptr->num_blocks;
+-			lptr->num_recs_tot = num_extents;
+-		}
+-
+-		extra_blocks = 0;
+ 	}
+ 
+ 	btree_curs->num_tot_blocks = blocks_allocated_pt;
+@@ -1335,7 +1322,6 @@ init_rmapbt_cursor(
+ 	struct bt_stat_level	*lptr;
+ 	struct bt_stat_level	*p_lptr;
+ 	xfs_extlen_t		blocks_allocated;
+-	int			maxrecs;
+ 
+ 	if (!xfs_sb_version_hasrmapbt(&mp->m_sb)) {
+ 		memset(btree_curs, 0, sizeof(struct bt_status));
+@@ -1371,32 +1357,20 @@ init_rmapbt_cursor(
+ 	 * Leave enough slack in the rmapbt that we can insert the
+ 	 * metadata AG entries without too many splits.
+ 	 */
+-	maxrecs = mp->m_rmap_mxr[0];
+-	if (num_recs > maxrecs)
+-		maxrecs -= 10;
+-	blocks_allocated = lptr->num_blocks = howmany(num_recs, maxrecs);
+-
+-	lptr->modulo = num_recs % lptr->num_blocks;
+-	lptr->num_recs_pb = num_recs / lptr->num_blocks;
+-	lptr->num_recs_tot = num_recs;
++	compute_level_geometry(mp, lptr, num_recs,
++			num_recs > mp->m_rmap_mxr[0] ? 10 : 0, true);
++	blocks_allocated = lptr->num_blocks;
+ 	level = 1;
+ 
+-	if (lptr->num_blocks > 1)  {
+-		for (; btree_curs->level[level-1].num_blocks > 1
+-				&& level < XFS_BTREE_MAXLEVELS;
+-				level++)  {
+-			lptr = &btree_curs->level[level];
+-			p_lptr = &btree_curs->level[level - 1];
+-			lptr->num_blocks = howmany(p_lptr->num_blocks,
+-				mp->m_rmap_mxr[1]);
+-			lptr->modulo = p_lptr->num_blocks % lptr->num_blocks;
+-			lptr->num_recs_pb = p_lptr->num_blocks
+-					/ lptr->num_blocks;
+-			lptr->num_recs_tot = p_lptr->num_blocks;
+-
+-			blocks_allocated += lptr->num_blocks;
+-		}
++	while (lptr->num_blocks > 1) {
++		p_lptr = lptr;
++		lptr = &btree_curs->level[level++];
++
++		compute_level_geometry(mp, lptr,
++				p_lptr->num_blocks, 0, false);
++		blocks_allocated += lptr->num_blocks;
+ 	}
++	ASSERT(level < XFS_BTREE_MAXLEVELS);
+ 	ASSERT(lptr->num_blocks == 1);
+ 	btree_curs->num_levels = level;
+ 
diff --git a/SOURCES/xfsprogs-5.7.0-xfs_repair-tag-inobt-vs-finobt-errors-properly.patch b/SOURCES/xfsprogs-5.7.0-xfs_repair-tag-inobt-vs-finobt-errors-properly.patch
new file mode 100644
index 0000000..82a1e3b
--- /dev/null
+++ b/SOURCES/xfsprogs-5.7.0-xfs_repair-tag-inobt-vs-finobt-errors-properly.patch
@@ -0,0 +1,88 @@
+From 08280b4b6efd317c673c6718a27d77e702d0480d Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <darrick.wong@oracle.com>
+Date: Fri, 10 Jul 2020 15:35:45 -0400
+Subject: [PATCH] xfs_repair: tag inobt vs finobt errors properly
+
+Amend the generic inode btree block scanner function to tag correctly
+which tree it's complaining about.  Previously, dubious finobt headers
+would be attributed to the "inode btree", which is at best ambiguous
+and misleading at worst.
+
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
+---
+ repair/scan.c | 36 ++++++++++++++++++++++++++----------
+ 1 file changed, 26 insertions(+), 10 deletions(-)
+
+Index: xfsprogs-5.0.0/repair/scan.c
+===================================================================
+--- xfsprogs-5.0.0.orig/repair/scan.c
++++ xfsprogs-5.0.0/repair/scan.c
+@@ -1934,6 +1934,7 @@ scan_inobt(
+ 	const struct xfs_buf_ops *ops)
+ {
+ 	struct aghdr_cnts	*agcnts = priv;
++	char			*name;
+ 	int			i;
+ 	int			numrecs;
+ 	int			state;
+@@ -1944,17 +1945,32 @@ scan_inobt(
+ 
+ 	hdr_errors = 0;
+ 
++	switch (magic) {
++	case XFS_FIBT_MAGIC:
++	case XFS_FIBT_CRC_MAGIC:
++		name = "fino";
++		break;
++	case XFS_IBT_MAGIC:
++	case XFS_IBT_CRC_MAGIC:
++		name = "ino";
++		break;
++	default:
++		name = "(unknown)";
++		assert(0);
++		break;
++	}
++
+ 	if (be32_to_cpu(block->bb_magic) != magic) {
+-		do_warn(_("bad magic # %#x in inobt block %d/%d\n"),
+-			be32_to_cpu(block->bb_magic), agno, bno);
++		do_warn(_("bad magic # %#x in %sbt block %d/%d\n"),
++			be32_to_cpu(block->bb_magic), name, agno, bno);
+ 		hdr_errors++;
+ 		bad_ino_btree = 1;
+ 		if (suspect)
+ 			return;
+ 	}
+ 	if (be16_to_cpu(block->bb_level) != level) {
+-		do_warn(_("expected level %d got %d in inobt block %d/%d\n"),
+-			level, be16_to_cpu(block->bb_level), agno, bno);
++		do_warn(_("expected level %d got %d in %sbt block %d/%d\n"),
++			level, be16_to_cpu(block->bb_level), name, agno, bno);
+ 		hdr_errors++;
+ 		bad_ino_btree = 1;
+ 		if (suspect)
+@@ -1976,8 +1992,8 @@ scan_inobt(
+ 	default:
+ 		set_bmap(agno, bno, XR_E_MULT);
+ 		do_warn(
+-_("inode btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
+-			state, agno, bno, suspect);
++_("%sbt btree block claimed (state %d), agno %d, bno %d, suspect %d\n"),
++			name, state, agno, bno, suspect);
+ 	}
+ 
+ 	numrecs = be16_to_cpu(block->bb_numrecs);
+@@ -1999,8 +2015,8 @@ _("inode btree block claimed (state %d),
+ 
+ 		if (hdr_errors)  {
+ 			bad_ino_btree = 1;
+-			do_warn(_("dubious inode btree block header %d/%d\n"),
+-				agno, bno);
++			do_warn(_("dubious %sbt btree block header %d/%d\n"),
++				name, agno, bno);
+ 			suspect++;
+ 		}
+ 
diff --git a/SOURCES/xfsprogs-5.8.0-xfs_db-short-circuit-type_f-if-type-is-unchanged.patch b/SOURCES/xfsprogs-5.8.0-xfs_db-short-circuit-type_f-if-type-is-unchanged.patch
new file mode 100644
index 0000000..784ad1e
--- /dev/null
+++ b/SOURCES/xfsprogs-5.8.0-xfs_db-short-circuit-type_f-if-type-is-unchanged.patch
@@ -0,0 +1,31 @@
+From 7b4a7b3f6bce91be45b54fc68e169cb756dc8c74 Mon Sep 17 00:00:00 2001
+From: Eric Sandeen <sandeen@redhat.com>
+Date: Mon, 24 Aug 2020 12:47:47 -0400
+Subject: [PATCH] xfs_db: short circuit type_f if type is unchanged
+
+There's no reason to go through the type change code if the
+type has not been changed.
+
+Signed-off-by: Eric Sandeen <sandeen@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
+---
+ db/type.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/db/type.c b/db/type.c
+index 3cb1e868..572ac6d6 100644
+--- a/db/type.c
++++ b/db/type.c
+@@ -216,6 +216,8 @@ type_f(
+ 		tt = findtyp(argv[1]);
+ 		if (tt == NULL) {
+ 			dbprintf(_("no such type %s\n"), argv[1]);
++		} else if (iocur_top->typ == tt) {
++			return 0;
+ 		} else {
+ 			if (iocur_top->typ == NULL)
+ 				dbprintf(_("no current object\n"));
+-- 
+2.29.2
+
diff --git a/SOURCES/xfsprogs-5.9.0-mkfs.xfs-fix-ASSERT-on-too-small-device-with-stripe.patch b/SOURCES/xfsprogs-5.9.0-mkfs.xfs-fix-ASSERT-on-too-small-device-with-stripe.patch
new file mode 100644
index 0000000..86323d0
--- /dev/null
+++ b/SOURCES/xfsprogs-5.9.0-mkfs.xfs-fix-ASSERT-on-too-small-device-with-stripe.patch
@@ -0,0 +1,76 @@
+From 97a4059660b27a9b0e3d8cdde5dbef8712685865 Mon Sep 17 00:00:00 2001
+From: Pavel Reichl <preichl@redhat.com>
+Date: Mon, 28 Sep 2020 17:31:18 -0400
+Subject: [PATCH] mkfs.xfs: fix ASSERT on too-small device with stripe geometry
+
+When a too-small device is created with stripe geometry, we hit an
+assert in align_ag_geometry():
+
+mkfs.xfs: xfs_mkfs.c:2834: align_ag_geometry: Assertion `cfg->agcount != 0' failed.
+
+This is because align_ag_geometry() finds that the size of the last
+(only) AG is too small, and attempts to trim it off.  Obviously 0
+AGs is invalid, and we hit the ASSERT.
+
+Reported-by: Zdenek Kabelac <zkabelac@redhat.com>
+Suggested-by: Dave Chinner <dchinner@redhat.com>
+Signed-off-by: Pavel Reichl <preichl@redhat.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
+Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
+---
+ include/xfs_multidisk.h | 14 +++++++-------
+ mkfs/xfs_mkfs.c         |  6 +++---
+ 2 files changed, 10 insertions(+), 10 deletions(-)
+
+Index: xfsprogs-5.0.0/include/xfs_multidisk.h
+===================================================================
+--- xfsprogs-5.0.0.orig/include/xfs_multidisk.h
++++ xfsprogs-5.0.0/include/xfs_multidisk.h
+@@ -14,7 +14,6 @@
+ #define	XFS_DFL_BLOCKSIZE_LOG	12		/* 4096 byte blocks */
+ #define	XFS_DINODE_DFL_LOG	8		/* 256 byte inodes */
+ #define	XFS_DINODE_DFL_CRC_LOG	9		/* 512 byte inodes for CRCs */
+-#define	XFS_MIN_DATA_BLOCKS	100
+ #define	XFS_MIN_INODE_PERBLOCK	2		/* min inodes per block */
+ #define	XFS_DFL_IMAXIMUM_PCT	25		/* max % of space for inodes */
+ #define	XFS_MIN_REC_DIRSIZE	12		/* 4096 byte dirblocks (V2) */
+@@ -25,13 +24,14 @@
+ 						 * accept w/o warnings
+ 						 */
+ 
+-#define XFS_AG_BYTES(bblog)	((long long)BBSIZE << (bblog))
+-#define	XFS_AG_MIN_BYTES	((XFS_AG_BYTES(15)))	/* 16 MB */
+-#define	XFS_AG_MAX_BYTES	((XFS_AG_BYTES(31)))	/* 1 TB */
+-#define XFS_AG_MIN_BLOCKS(blog)	(XFS_AG_MIN_BYTES >> (blog))
+-#define XFS_AG_MAX_BLOCKS(blog)	((XFS_AG_MAX_BYTES - 1) >> (blog))
++#define XFS_AG_BYTES(bblog)		((long long)BBSIZE << (bblog))
++#define	XFS_MIN_DATA_BLOCKS(cfg)	(XFS_AG_MIN_BLOCKS((cfg)->blocklog))
++#define	XFS_AG_MIN_BYTES		((XFS_AG_BYTES(15)))	/* 16 MB */
++#define	XFS_AG_MAX_BYTES		((XFS_AG_BYTES(31)))	/* 1 TB */
++#define XFS_AG_MIN_BLOCKS(blog)		(XFS_AG_MIN_BYTES >> (blog))
++#define XFS_AG_MAX_BLOCKS(blog)		((XFS_AG_MAX_BYTES - 1) >> (blog))
+ 
+-#define XFS_MAX_AGNUMBER	((xfs_agnumber_t)(NULLAGNUMBER - 1))
++#define XFS_MAX_AGNUMBER		((xfs_agnumber_t)(NULLAGNUMBER - 1))
+ 
+ /*
+  * These values define what we consider a "multi-disk" filesystem. That is, a
+Index: xfsprogs-5.0.0/mkfs/xfs_mkfs.c
+===================================================================
+--- xfsprogs-5.0.0.orig/mkfs/xfs_mkfs.c
++++ xfsprogs-5.0.0/mkfs/xfs_mkfs.c
+@@ -2581,10 +2581,10 @@ _("size %s specified for data subvolume
+ 		cfg->dblocks = DTOBT(xi->dsize, cfg->blocklog);
+ 	}
+ 
+-	if (cfg->dblocks < XFS_MIN_DATA_BLOCKS) {
++	if (cfg->dblocks < XFS_MIN_DATA_BLOCKS(cfg)) {
+ 		fprintf(stderr,
+-_("size %lld of data subvolume is too small, minimum %d blocks\n"),
+-			(long long)cfg->dblocks, XFS_MIN_DATA_BLOCKS);
++_("size %lld of data subvolume is too small, minimum %lld blocks\n"),
++			(long long)cfg->dblocks, XFS_MIN_DATA_BLOCKS(cfg));
+ 		usage();
+ 	}
+ 
diff --git a/SPECS/xfsprogs.spec b/SPECS/xfsprogs.spec
index 1af6b15..b07b2c6 100644
--- a/SPECS/xfsprogs.spec
+++ b/SPECS/xfsprogs.spec
@@ -1,7 +1,7 @@
 Summary:	Utilities for managing the XFS filesystem
 Name:		xfsprogs
 Version:	5.0.0
-Release:	4%{?dist}
+Release:	8%{?dist}
 License:	GPL+ and LGPLv2+
 Group:		System Environment/Base
 URL:		https://xfs.wiki.kernel.org
@@ -25,6 +25,18 @@ Patch4:		xfsprogs-5.3.0-xfs_growfs-allow-mounted-device-node-as-argument.patch
 Patch5:		xfsprogs-5.5.0-libxfs-use-FALLOC_FL_ZERO_RANGE-in-libxfs_device_zer.patch
 Patch6:		xfsprogs-5.4.0-mkfs-Break-block-discard-into-chunks-of-2-GB.patch
 Patch7:		xfsprogs-5.4.0-mkfs-tidy-up-discard-notifications.patch
+Patch8:		xfsprogs-5.7.0-xfs_quota-refactor-code-to-generate-id-from-name.patch
+Patch9:		xfsprogs-5.7.0-xfs_quota-allow-individual-timer-extension.patch
+Patch10:	xfsprogs-5.7.0-xfs_quota-fix-unsigned-int-id-comparisons.patch
+Patch11:	xfsprogs-5.7.0-xfs_repair-check-for-AG-btree-records-that-would-wra.patch
+Patch12:	xfsprogs-5.7.0-xfs_repair-tag-inobt-vs-finobt-errors-properly.patch
+Patch13:	xfsprogs-5.7.0-xfs_repair-complain-about-bad-interior-btree-pointer.patch
+Patch14:	xfsprogs-5.7.0-xfs_repair-convert-to-libxfs_verify_agbno.patch
+Patch15:	xfsprogs-5.9.0-mkfs.xfs-fix-ASSERT-on-too-small-device-with-stripe.patch
+Patch16:	xfsprogs-5.7.0-xfs_repair-fix-rebuilding-btree-block-less-than-minr.patch
+Patch17:	xfsprogs-5.10.0-xfs_quota-document-how-the-default-quota-is-stored.patch
+Patch18:	xfsprogs-5.8.0-xfs_db-short-circuit-type_f-if-type-is-unchanged.patch
+Patch19:	xfsprogs-5.10.0-xfs_repair-Use-proper-min-max-values-in-compute_level_geometry.patch
 
 %description
 A set of commands to use the XFS filesystem, including mkfs.xfs.
@@ -63,6 +75,18 @@ also want to install xfsprogs.
 %patch5 -p1
 %patch6 -p1
 %patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
+%patch19 -p1
 
 %build
 export tagname=CC
@@ -122,6 +146,21 @@ rm -rf $RPM_BUILD_ROOT/%{_mandir}/man8/xfs_scrub*
 %{_libdir}/*.so
 
 %changelog
+* Thu Jan 07 2021 Bill O'Donnell <billodo@redhat.com> 5.0.0-8
+- xfs_repair: Use proper min/max values in compute_level_geometry (#1910384)
+
+* Mon Dec 14 2020 Bill O'Donnell <billodo@redhat.com> 5.0.0-7
+- xfs_quota: document how the default quota is stored (#1850188)
+- xfs_db: skip type change if type_f unchanged (#1867474)
+
+* Wed Dec 09 2020 Bill O'Donnell <billodo@redhat.com> 5.0.0-6
+- xfs_repair: improve AG btree ptr validation (libxfs_verify_agbno) (#1887288)
+- mkfs.xfs: fix ASSERT on too-small device with stripe geometry (#1887401)
+- xfs_repair: fix rebuilding btree block less than minrecs (#1759452)
+
+* Wed Dec 02 2020 Bill O'Donnell <billodo@redhat.com> 5.0.0-5
+- xfs_quota: allow individual timer extension (#1899204)
+
 * Wed Jun 03 2020 Eric Sandeen <sandeen@redhat.com> 5.0.0-4
 - mkfs.xfs: inform user about discard, and make interruptable (#1836414)