Skip to contentSkip to conversation

xfs: allow inode allocations in post-growfs disk space

PATCH In review Eric Sandeen 3 participants 6 messages Jul 3, 2014 – Jul 7, 2014 XFS filesystem

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 xfs: allow inode allocations in post-growfs disk space

Today, if we perform an xfs_growfs which adds allocation groups, mp->m_maxagi is not properly updated when the growfs is complete.

Therefore inodes will continue to be allocated only in the AGs which existed prior to the growfs, and the new space won't be utilized.

This is because of this path in xfs_growfs_data_private():

xfs_growfs_data_private

	xfs_initialize_perag(mp, nagcount, &nagimax);
	 	if (mp->m_flags & XFS_MOUNT_32BITINODES)
			index = xfs_set_inode32(mp);
 		else
			index = xfs_set_inode64(mp);

	 	if (maxagi)

*maxagi = index;

where xfs_set_inode* iterates over the (old) agcount in mp->m_sb.sb_agblocks, which has not yet been updated in the growfs path. So "index" will be returned based on the old agcount, not the new one, and new AGs are not available for inode allocation.

Fix this by explicitly passing the proper AG count (which xfs_initialize_perag() already has) down another level, so that xfs_set_inode* can make the proper decision about acceptable AGs for inode allocation in the potentially newly-added AGs.

This has been broken since 3.7, when these two xfs_set_inode* functions were added in commit 2d2194f. Prior to that, we looped over "agcount" not sb_agblocks in these calculations.

---

tested for regression with the -g growfs group, but this shows that we need another testcase for growfs.

fs/xfs/xfs_mount.c +2 -2
index 993cb19..b291ada 100644
@@ -250,9 +250,9 @@ xfs_initialize_perag(
 		mp->m_flags &= ~XFS_MOUNT_32BITINODES;
 
 	if (mp->m_flags & XFS_MOUNT_32BITINODES)
-		index = xfs_set_inode32(mp);
+		index = xfs_set_inode32(mp, agcount);
 	else
-		index = xfs_set_inode64(mp);
+		index = xfs_set_inode64(mp, agcount);
 
 	if (maxagi)
 		*maxagi = index;
fs/xfs/xfs_super.c +13 -7
index 87e8b01..ccc564d 100644
@@ -597,8 +597,13 @@ xfs_max_file_offset(
 	return (((__uint64_t)pagefactor) << bitshift) - 1;
 }
 
+/*
+ * xfs_set_inode32() and xfs_set_inode64() are passed an agcount
+ * because in the growfs case, mp->m_sb.sb_agcount is not updated
+ * yet to the potentially higher ag count.
+ */
 xfs_agnumber_t
-xfs_set_inode32(struct xfs_mount *mp)
+xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount)
 {
 	xfs_agnumber_t	index = 0;
 	xfs_agnumber_t	maxagi = 0;
@@ -620,10 +625,10 @@ xfs_set_inode32(struct xfs_mount *mp)
 		do_div(icount, sbp->sb_agblocks);
 		max_metadata = icount;
 	} else {
-		max_metadata = sbp->sb_agcount;
+		max_metadata = agcount;
 	}
 
-	for (index = 0; index < sbp->sb_agcount; index++) {
+	for (index = 0; index < agcount; index++) {
 		ino = XFS_AGINO_TO_INO(mp, index, agino);
 
 		if (ino > XFS_MAXINUMBER_32) {
@@ -648,11 +653,11 @@ xfs_set_inode32(struct xfs_mount *mp)
 }
 
 xfs_agnumber_t
-xfs_set_inode64(struct xfs_mount *mp)
+xfs_set_inode64(struct xfs_mount *mp, xfs_agnumber_t agcount)
 {
 	xfs_agnumber_t index = 0;
 
-	for (index = 0; index < mp->m_sb.sb_agcount; index++) {
+	for (index = 0; index < agcount; index++) {
 		struct xfs_perag	*pag;
 
 		pag = xfs_perag_get(mp, index);
@@ -1193,6 +1198,7 @@ xfs_fs_remount(
 	char			*options)
 {
 	struct xfs_mount	*mp = XFS_M(sb);
+	xfs_sb_t		*sbp = &mp->m_sb;
 	substring_t		args[MAX_OPT_ARGS];
 	char			*p;
 	int			error;
@@ -1212,10 +1218,10 @@ xfs_fs_remount(
 			mp->m_flags &= ~XFS_MOUNT_BARRIER;
 			break;
 		case Opt_inode64:
-			mp->m_maxagi = xfs_set_inode64(mp);
+			mp->m_maxagi = xfs_set_inode64(mp, sbp->sb_agcount);
 			break;
 		case Opt_inode32:
-			mp->m_maxagi = xfs_set_inode32(mp);
+			mp->m_maxagi = xfs_set_inode32(mp, sbp->sb_agcount);
 			break;
 		default:
 			/*
fs/xfs/xfs_super.h +2 -2
index bbe3d15..b4cfe21 100644
@@ -76,8 +76,8 @@ extern __uint64_t xfs_max_file_offset(unsigned int);
 
 extern void xfs_flush_inodes(struct xfs_mount *mp);
 extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
-extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *);
-extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *);
+extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *, xfs_agnumber_t agcount);
+extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *, xfs_agnumber_t agcount);
 
 extern const struct export_operations xfs_export_operations;
 extern const struct xattr_handler *xfs_xattr_handlers[];

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

#1 lore raw

PATCH 2/2 xfs: tidy up xfs_set_inode32

xfs_set_inode32() caught my eye because it had weird spacing around the "-1's". In cleaning that up, I realized that the assignment in the declaration of "ino" is never used; it's rewritten before it gets read.

Drop the ino initializer from its declaration since it's not used, and move the agino initialization into the body of the function, mostly so that we can have pretty whitespace and not exceed 80 columns. :)

---

fs/xfs/xfs_super.c +4 -2
index e71c0f8..39c9315 100644
@@ -609,8 +609,8 @@ xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount)
 	xfs_agnumber_t	maxagi = 0;
 	xfs_sb_t	*sbp = &mp->m_sb;
 	xfs_agnumber_t	max_metadata;
-	xfs_agino_t	agino =	XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks -1, 0);
-	xfs_ino_t	ino = XFS_AGINO_TO_INO(mp, sbp->sb_agcount -1, agino);
+	xfs_agino_t	agino;
+	xfs_ino_t	ino;
 	xfs_perag_t	*pag;
 
 	/* Calculate how much should be reserved for inodes to meet
@@ -628,6 +628,8 @@ xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount)
 		max_metadata = agcount;
 	}
 
+	agino =	XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);
+
 	for (index = 0; index < agcount; index++) {
 		ino = XFS_AGINO_TO_INO(mp, index, agino);
 

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

#3 lore raw
In reply to Eric Sandeen
Quoted 79 lines · Eric Sandeen

Today, if we perform an xfs_growfs which adds allocation groups, mp->m_maxagi is not properly updated when the growfs is complete.

Therefore inodes will continue to be allocated only in the AGs which existed prior to the growfs, and the new space won't be utilized.

This is because of this path in xfs_growfs_data_private():

xfs_growfs_data_private

	xfs_initialize_perag(mp, nagcount, &nagimax);
	 	if (mp->m_flags & XFS_MOUNT_32BITINODES)
			index = xfs_set_inode32(mp);
 		else
			index = xfs_set_inode64(mp);

	 	if (maxagi)

*maxagi = index;

where xfs_set_inode* iterates over the (old) agcount in mp->m_sb.sb_agblocks, which has not yet been updated in the growfs path. So "index" will be returned based on the old agcount, not the new one, and new AGs are not available for inode allocation.

Fix this by explicitly passing the proper AG count (which xfs_initialize_perag() already has) down another level, so that xfs_set_inode* can make the proper decision about acceptable AGs for inode allocation in the potentially newly-added AGs.

This has been broken since 3.7, when these two xfs_set_inode* functions were added in commit 2d2194f. Prior to that, we looped over "agcount" not sb_agblocks in these calculations.

---

tested for regression with the -g growfs group, but this shows that we need another testcase for growfs.

fs/xfs/xfs_mount.c +2 -2
index 993cb19..b291ada 100644
@@ -250,9 +250,9 @@ xfs_initialize_perag(
 		mp->m_flags &= ~XFS_MOUNT_32BITINODES;
 
 	if (mp->m_flags & XFS_MOUNT_32BITINODES)
-		index = xfs_set_inode32(mp);
+		index = xfs_set_inode32(mp, agcount);
 	else
-		index = xfs_set_inode64(mp);
+		index = xfs_set_inode64(mp, agcount);
 
 	if (maxagi)
 		*maxagi = index;
fs/xfs/xfs_super.c +6 -1
index 87e8b01..ccc564d 100644
@@ -597,8 +597,13 @@ xfs_max_file_offset(
 	return (((__uint64_t)pagefactor) << bitshift) - 1;
 }
 
+/*
+ * xfs_set_inode32() and xfs_set_inode64() are passed an agcount
+ * because in the growfs case, mp->m_sb.sb_agcount is not updated
+ * yet to the potentially higher ag count.
+ */
 xfs_agnumber_t
-xfs_set_inode32(struct xfs_mount *mp)
+xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount)
 {
 	xfs_agnumber_t	index = 0;
 	xfs_agnumber_t	maxagi = 0;

fs/xfs/xfs_super.c xfs_set_inode32(struct xfs_mount *mp) · line 628

Quoted 5 lines
fs/xfs/xfs_super.c +1 -1
@@ -620,10 +625,10 @@ xfs_set_inode32(struct xfs_mount *mp)
 		do_div(icount, sbp->sb_agblocks);
 		max_metadata = icount;
 	} else {
-		max_metadata = sbp->sb_agcount;
+		max_metadata = agcount;

The fix looks pretty good to me, but what about the 'if' branch of this logic here? We calculate max_metadata based on sb_dblocks, which also isn't updated until the growfs tp commit. That appears to be a similar bug in that we wouldn't set pagf_metadata on the new AGs where appropriate, which I think means data allocation could steal the new inode space sooner than anticipated.

I wonder if this is better moved after the superblock is updated?

Brian

Quoted 59 lines
fs/xfs/xfs_super.c +6 -5
 	}
 
-	for (index = 0; index < sbp->sb_agcount; index++) {
+	for (index = 0; index < agcount; index++) {
 		ino = XFS_AGINO_TO_INO(mp, index, agino);
 
 		if (ino > XFS_MAXINUMBER_32) {
@@ -648,11 +653,11 @@ xfs_set_inode32(struct xfs_mount *mp)
 }
 
 xfs_agnumber_t
-xfs_set_inode64(struct xfs_mount *mp)
+xfs_set_inode64(struct xfs_mount *mp, xfs_agnumber_t agcount)
 {
 	xfs_agnumber_t index = 0;
 
-	for (index = 0; index < mp->m_sb.sb_agcount; index++) {
+	for (index = 0; index < agcount; index++) {
 		struct xfs_perag	*pag;
 
 		pag = xfs_perag_get(mp, index);
@@ -1193,6 +1198,7 @@ xfs_fs_remount(
 	char			*options)
 {
 	struct xfs_mount	*mp = XFS_M(sb);
+	xfs_sb_t		*sbp = &mp->m_sb;
 	substring_t		args[MAX_OPT_ARGS];
 	char			*p;
 	int			error;
@@ -1212,10 +1218,10 @@ xfs_fs_remount(
 			mp->m_flags &= ~XFS_MOUNT_BARRIER;
 			break;
 		case Opt_inode64:
-			mp->m_maxagi = xfs_set_inode64(mp);
+			mp->m_maxagi = xfs_set_inode64(mp, sbp->sb_agcount);
 			break;
 		case Opt_inode32:
-			mp->m_maxagi = xfs_set_inode32(mp);
+			mp->m_maxagi = xfs_set_inode32(mp, sbp->sb_agcount);
 			break;
 		default:
 			/*
fs/xfs/xfs_super.h +2 -2
index bbe3d15..b4cfe21 100644
@@ -76,8 +76,8 @@ extern __uint64_t xfs_max_file_offset(unsigned int);
 
 extern void xfs_flush_inodes(struct xfs_mount *mp);
 extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
-extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *);
-extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *);
+extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *, xfs_agnumber_t agcount);
+extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *, xfs_agnumber_t agcount);
 
 extern const struct export_operations xfs_export_operations;
 extern const struct xattr_handler *xfs_xattr_handlers[];
Quoted 4 lines

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

Reviewed-by on v1 2/2
#2 lore raw

Re: [PATCH 2/2] xfs: tidy up xfs_set_inode32

In reply to Eric Sandeen
Quoted 6 lines · Eric Sandeen

xfs_set_inode32() caught my eye because it had weird spacing around the "-1's". In cleaning that up, I realized that the assignment in the declaration of "ino" is never used; it's rewritten before it gets read.

Quoted 7 lines

Drop the ino initializer from its declaration since it's not used, and move the agino initialization into the body of the function, mostly so that we can have pretty whitespace and not exceed 80 columns. :)

---

Quoted 26 lines
fs/xfs/xfs_super.c +4 -2
index e71c0f8..39c9315 100644
@@ -609,8 +609,8 @@ xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount)
 	xfs_agnumber_t	maxagi = 0;
 	xfs_sb_t	*sbp = &mp->m_sb;
 	xfs_agnumber_t	max_metadata;
-	xfs_agino_t	agino =	XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks -1, 0);
-	xfs_ino_t	ino = XFS_AGINO_TO_INO(mp, sbp->sb_agcount -1, agino);
+	xfs_agino_t	agino;
+	xfs_ino_t	ino;
 	xfs_perag_t	*pag;
 
 	/* Calculate how much should be reserved for inodes to meet
@@ -628,6 +628,8 @@ xfs_set_inode32(struct xfs_mount *mp, xfs_agnumber_t agcount)
 		max_metadata = agcount;
 	}
 
+	agino =	XFS_OFFBNO_TO_AGINO(mp, sbp->sb_agblocks - 1, 0);
+
 	for (index = 0; index < agcount; index++) {
 		ino = XFS_AGINO_TO_INO(mp, index, agino);
 
Quoted 4 lines

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

#4 lore raw
In reply to Brian Foster
Quoted 1 line · Brian Foster

On Wed, Jul 02, 2014 at 11:54:06PM -0500, Eric Sandeen wrote:

<context added>:

        /* Calculate how much should be reserved for inodes to meet
         * the max inode percentage.
         */
        if (mp->m_maxicount) {
                __uint64_t      icount;

                icount = sbp->sb_dblocks * sbp->sb_imax_pct;
                do_div(icount, 100);
                icount += sbp->sb_agblocks - 1;
Quoted 5 lines
Quoted 5 lines
fs/xfs/xfs_super.c +0 -1
@@ -620,10 +625,10 @@ xfs_set_inode32(struct xfs_mount *mp)
 		do_div(icount, sbp->sb_agblocks);
 		max_metadata = icount;
 	} else {
-		max_metadata = sbp->sb_agcount;
Quoted 8 lines

fs/xfs/xfs_super.c xfs_set_inode32(struct xfs_mount *mp) · line 628

Quoted 1 line
fs/xfs/xfs_super.c +1 -0
+		max_metadata = agcount;

The fix looks pretty good to me, but what about the 'if' branch of this logic here? We calculate max_metadata based on sb_dblocks, which also isn't updated until the growfs tp commit. That appears to be a similar bug in that we wouldn't set pagf_metadata on the new AGs where appropriate, which I think means data allocation could steal the new inode space sooner than anticipated.

Yeah, good catch...

Hm, well - not that this is an answer, but this code has been this way since 2005. So I'd like to fix the *regression* w/ my patch as-is, and then worry about this.

So, on to worrying about this ... ;)

"max_metadata" seems a little misnamed; inodes can be allocated in higher AGs, but "max_metadata" and lower are the 'preferred' AGs for inode allocation.

We only carve out enough via pag->pagf_metadata to reserve m_maxicount, which (here) is based on the (old) sb_dblocks & sb_imax_pct.

So yeah, it seems that in the growfs case, we don't mark any *new* AGs as "preferred" for inodes, even though with a fixed sb_imax_pct and a larger sb_dblocks, we'd need more space to accommodate the imaxpct.

But reserving higher AGs would be a half-measure at best; they weren't preferred before the growfs, so are very likely not wholly available after the growfs.

To really nail this down we'd probably need to see how many inode clusters could be created in each AG above the old threshold, and keep advancing AGs until we've "preferred" enough. Bleah. I hate inode32...

-Eric

Quoted 63 lines

I wonder if this is better moved after the superblock is updated?

Brian

Quoted 59 lines
fs/xfs/xfs_super.c +6 -5
 	}
 
-	for (index = 0; index < sbp->sb_agcount; index++) {
+	for (index = 0; index < agcount; index++) {
 		ino = XFS_AGINO_TO_INO(mp, index, agino);
 
 		if (ino > XFS_MAXINUMBER_32) {
@@ -648,11 +653,11 @@ xfs_set_inode32(struct xfs_mount *mp)
 }
 
 xfs_agnumber_t
-xfs_set_inode64(struct xfs_mount *mp)
+xfs_set_inode64(struct xfs_mount *mp, xfs_agnumber_t agcount)
 {
 	xfs_agnumber_t index = 0;
 
-	for (index = 0; index < mp->m_sb.sb_agcount; index++) {
+	for (index = 0; index < agcount; index++) {
 		struct xfs_perag	*pag;
 
 		pag = xfs_perag_get(mp, index);
@@ -1193,6 +1198,7 @@ xfs_fs_remount(
 	char			*options)
 {
 	struct xfs_mount	*mp = XFS_M(sb);
+	xfs_sb_t		*sbp = &mp->m_sb;
 	substring_t		args[MAX_OPT_ARGS];
 	char			*p;
 	int			error;
@@ -1212,10 +1218,10 @@ xfs_fs_remount(
 			mp->m_flags &= ~XFS_MOUNT_BARRIER;
 			break;
 		case Opt_inode64:
-			mp->m_maxagi = xfs_set_inode64(mp);
+			mp->m_maxagi = xfs_set_inode64(mp, sbp->sb_agcount);
 			break;
 		case Opt_inode32:
-			mp->m_maxagi = xfs_set_inode32(mp);
+			mp->m_maxagi = xfs_set_inode32(mp, sbp->sb_agcount);
 			break;
 		default:
 			/*
fs/xfs/xfs_super.h +2 -2
index bbe3d15..b4cfe21 100644
@@ -76,8 +76,8 @@ extern __uint64_t xfs_max_file_offset(unsigned int);
 
 extern void xfs_flush_inodes(struct xfs_mount *mp);
 extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
-extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *);
-extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *);
+extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *, xfs_agnumber_t agcount);
+extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *, xfs_agnumber_t agcount);
 
 extern const struct export_operations xfs_export_operations;
 extern const struct xattr_handler *xfs_xattr_handlers[];
Quoted 10 lines
Quoted 4 lines

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

Reviewed-by
#5 lore raw
Quoted 29 lines · Eric Sandeen
Quoted 1 line · Brian Foster

On Wed, Jul 02, 2014 at 11:54:06PM -0500, Eric Sandeen wrote:

<context added>:

        /* Calculate how much should be reserved for inodes to meet
         * the max inode percentage.
         */
        if (mp->m_maxicount) {
                __uint64_t      icount;

                icount = sbp->sb_dblocks * sbp->sb_imax_pct;
                do_div(icount, 100);
                icount += sbp->sb_agblocks - 1;
Quoted 5 lines
Quoted 5 lines
fs/xfs/xfs_super.c +0 -1
@@ -620,10 +625,10 @@ xfs_set_inode32(struct xfs_mount *mp)
 		do_div(icount, sbp->sb_agblocks);
 		max_metadata = icount;
 	} else {
-		max_metadata = sbp->sb_agcount;
Quoted 8 lines

fs/xfs/xfs_super.c xfs_set_inode32(struct xfs_mount *mp) · line 628

Quoted 1 line
fs/xfs/xfs_super.c +1 -0
+		max_metadata = agcount;

The fix looks pretty good to me, but what about the 'if' branch of this logic here? We calculate max_metadata based on sb_dblocks, which also isn't updated until the growfs tp commit. That appears to be a similar bug in that we wouldn't set pagf_metadata on the new AGs where appropriate, which I think means data allocation could steal the new inode space sooner than anticipated.

Quoted 6 lines

Yeah, good catch...

Hm, well - not that this is an answer, but this code has been this way since 2005. So I'd like to fix the *regression* w/ my patch as-is, and then worry about this.

That's fine by me... for this patch:

Quoted 6 lines

So, on to worrying about this ... ;)

"max_metadata" seems a little misnamed; inodes can be allocated in higher AGs, but "max_metadata" and lower are the 'preferred' AGs for inode allocation.

My impression is that it's named after its very specific/local use: the max ag to set the metadata flag. I don't really like the name either. ;)

Quoted 7 lines

We only carve out enough via pag->pagf_metadata to reserve m_maxicount, which (here) is based on the (old) sb_dblocks & sb_imax_pct.

So yeah, it seems that in the growfs case, we don't mark any *new* AGs as "preferred" for inodes, even though with a fixed sb_imax_pct and a larger sb_dblocks, we'd need more space to accommodate the imaxpct.

Quoted 8 lines

But reserving higher AGs would be a half-measure at best; they weren't preferred before the growfs, so are very likely not wholly available after the growfs.

To really nail this down we'd probably need to see how many inode clusters could be created in each AG above the old threshold, and keep advancing AGs until we've "preferred" enough. Bleah. I hate inode32...

That's true, but then you have to worry about if that space is freed up and all that...

I was just looking at it from the perspective of using old metadata to update some of our heuristics while thinking it might be easier to move this hunk of code and fix both problems at once. I doubt this is something that reproduces a tangible problem out in the wild much, if ever, given the circumstances.

My sense is that this heuristic is not really a guarantee. E.g., setting imaxpct doesn't guarantee one that much space. Somebody could tune that after the fact even after all "preferred" space has been consumed just the same, so it's probably not worth doing any kind of fancy inode allocation tracking to try and make this retroactive or dynamic unless it proves to be a problem. I suspect this primarily exists for the case of larger inode32 fs' where we don't want data allocations to eat up limited inode space right off the bat.

Brian

Quoted 78 lines

-Eric

Quoted 73 lines

I wonder if this is better moved after the superblock is updated?

Brian

Quoted 59 lines
fs/xfs/xfs_super.c +6 -5
 	}
 
-	for (index = 0; index < sbp->sb_agcount; index++) {
+	for (index = 0; index < agcount; index++) {
 		ino = XFS_AGINO_TO_INO(mp, index, agino);
 
 		if (ino > XFS_MAXINUMBER_32) {
@@ -648,11 +653,11 @@ xfs_set_inode32(struct xfs_mount *mp)
 }
 
 xfs_agnumber_t
-xfs_set_inode64(struct xfs_mount *mp)
+xfs_set_inode64(struct xfs_mount *mp, xfs_agnumber_t agcount)
 {
 	xfs_agnumber_t index = 0;
 
-	for (index = 0; index < mp->m_sb.sb_agcount; index++) {
+	for (index = 0; index < agcount; index++) {
 		struct xfs_perag	*pag;
 
 		pag = xfs_perag_get(mp, index);
@@ -1193,6 +1198,7 @@ xfs_fs_remount(
 	char			*options)
 {
 	struct xfs_mount	*mp = XFS_M(sb);
+	xfs_sb_t		*sbp = &mp->m_sb;
 	substring_t		args[MAX_OPT_ARGS];
 	char			*p;
 	int			error;
@@ -1212,10 +1218,10 @@ xfs_fs_remount(
 			mp->m_flags &= ~XFS_MOUNT_BARRIER;
 			break;
 		case Opt_inode64:
-			mp->m_maxagi = xfs_set_inode64(mp);
+			mp->m_maxagi = xfs_set_inode64(mp, sbp->sb_agcount);
 			break;
 		case Opt_inode32:
-			mp->m_maxagi = xfs_set_inode32(mp);
+			mp->m_maxagi = xfs_set_inode32(mp, sbp->sb_agcount);
 			break;
 		default:
 			/*
fs/xfs/xfs_super.h +2 -2
index bbe3d15..b4cfe21 100644
@@ -76,8 +76,8 @@ extern __uint64_t xfs_max_file_offset(unsigned int);
 
 extern void xfs_flush_inodes(struct xfs_mount *mp);
 extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
-extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *);
-extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *);
+extern xfs_agnumber_t xfs_set_inode32(struct xfs_mount *, xfs_agnumber_t agcount);
+extern xfs_agnumber_t xfs_set_inode64(struct xfs_mount *, xfs_agnumber_t agcount);
 
 extern const struct export_operations xfs_export_operations;
 extern const struct xattr_handler *xfs_xattr_handlers[];
Quoted 4 lines

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs

_______________________________________________
xfs mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/xfs