From: Brian Foster <bfoster@redhat.com>
To: Eric Sandeen <sandeen@redhat.com>
Cc: xfs-oss <xfs@oss.sgi.com>
Subject: Re: [PATCH 1/2] xfs: allow inode allocations in post-growfs disk space
Date: Mon, 7 Jul 2014 14:21:08 -0400 [thread overview]
Message-ID: <20140707182108.GD4123@laptop.bfoster> (raw)
In-Reply-To: <53B4E1EE.40702@redhat.com>
On Wed, Jul 02, 2014 at 11:54:06PM -0500, Eric Sandeen wrote:
> 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.
>
> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
> ---
>
> tested for regression with the -g growfs group, but this
> shows that we need another testcase for growfs.
>
>
> diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
> index 993cb19..b291ada 100644
> --- a/fs/xfs/xfs_mount.c
> +++ b/fs/xfs/xfs_mount.c
> @@ -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;
> diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c
> index 87e8b01..ccc564d 100644
> --- a/fs/xfs/xfs_super.c
> +++ b/fs/xfs/xfs_super.c
> @@ -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;
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
> }
>
> - 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:
> /*
> diff --git a/fs/xfs/xfs_super.h b/fs/xfs/xfs_super.h
> index bbe3d15..b4cfe21 100644
> --- a/fs/xfs/xfs_super.h
> +++ b/fs/xfs/xfs_super.h
> @@ -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
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2014-07-07 18:21 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-07-03 4:54 [PATCH 1/2] xfs: allow inode allocations in post-growfs disk space Eric Sandeen
2014-07-03 4:57 ` [PATCH 2/2] xfs: tidy up xfs_set_inode32 Eric Sandeen
2014-07-07 18:21 ` Brian Foster
2014-07-07 18:21 ` Brian Foster [this message]
2014-07-07 19:01 ` [PATCH 1/2] xfs: allow inode allocations in post-growfs disk space Eric Sandeen
2014-07-07 19:38 ` Brian Foster
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=20140707182108.GD4123@laptop.bfoster \
--to=bfoster@redhat.com \
--cc=sandeen@redhat.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.