All of lore.kernel.org
 help / color / mirror / Atom feed
From: Eric Sandeen <sandeen@redhat.com>
To: linux-xfs <linux-xfs@vger.kernel.org>
Subject: [PATCH RFC] xfs: log message when allocation fails due to alignment constraints
Date: Thu, 23 Apr 2020 14:34:50 -0500	[thread overview]
Message-ID: <37a73948-ff5a-5375-c2e7-54174ae75462@redhat.com> (raw)

This scenario is the source of much confusion for admins and
support folks alike:

# touch mnt/newfile
touch: cannot touch ‘mnt/newfile’: No space left on device
# df -h mnt
Filesystem      Size  Used Avail Use% Mounted on
/dev/loop0      196M  137M   59M  71% /tmp/mnt
# df -i mnt/
Filesystem     Inodes IUsed IFree IUse% Mounted on
/dev/loop0     102400 64256 38144   63% /tmp/mnt

because it appears that there is plenty of space available, yet ENOSPC
is returned.

Track this case in the allocation args structure, and when an allocation
fails due to alignment constraints, leave a clue in the kernel logs:

 XFS (loop0): Failed metadata allocation due to 4-block alignment constraint

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---

Right now this depends on my "printk_once" patch but you can change
xfs_warn_once to xfs_warn or xfs_warn_ratelimited for testing.

Perhaps a 2nd patch to log a similar message if alignment failed due to
/contiguous/ free space constraints would be good as well?

diff --git a/fs/xfs/libxfs/xfs_alloc.c b/fs/xfs/libxfs/xfs_alloc.c
index 203e74fa64aa..10f32797e5ca 100644
--- a/fs/xfs/libxfs/xfs_alloc.c
+++ b/fs/xfs/libxfs/xfs_alloc.c
@@ -2303,8 +2303,12 @@ xfs_alloc_space_available(
 	/* do we have enough contiguous free space for the allocation? */
 	alloc_len = args->minlen + (args->alignment - 1) + args->minalignslop;
 	longest = xfs_alloc_longest_free_extent(pag, min_free, reservation);
-	if (longest < alloc_len)
+	if (longest < alloc_len) {
+		/* Did we fail only due to alignment? */
+		if (longest >= args->minlen)
+			args->alignfail = 1;
 		return false;
+	}
 
 	/*
 	 * Do we have enough free space remaining for the allocation? Don't
@@ -3067,8 +3071,10 @@ xfs_alloc_vextent(
 	agsize = mp->m_sb.sb_agblocks;
 	if (args->maxlen > agsize)
 		args->maxlen = agsize;
-	if (args->alignment == 0)
+	if (args->alignment == 0) {
 		args->alignment = 1;
+		args->alignfail = 0;
+	}
 	ASSERT(XFS_FSB_TO_AGNO(mp, args->fsbno) < mp->m_sb.sb_agcount);
 	ASSERT(XFS_FSB_TO_AGBNO(mp, args->fsbno) < agsize);
 	ASSERT(args->minlen <= args->maxlen);
@@ -3227,6 +3233,13 @@ xfs_alloc_vextent(
 
 	}
 	xfs_perag_put(args->pag);
+	if (!args->agbp && args->alignment > 1 && args->alignfail) {
+		xfs_warn_once(args->mp,
+"Failed %s allocation due to %u-block alignment constraint",
+			XFS_RMAP_NON_INODE_OWNER(args->oinfo.oi_owner) ?
+			  "metadata" : "data",
+			args->alignment);
+	}
 	return 0;
 error0:
 	xfs_perag_put(args->pag);
diff --git a/fs/xfs/libxfs/xfs_alloc.h b/fs/xfs/libxfs/xfs_alloc.h
index a851bf77f17b..29d13cd5c9ac 100644
--- a/fs/xfs/libxfs/xfs_alloc.h
+++ b/fs/xfs/libxfs/xfs_alloc.h
@@ -73,6 +73,7 @@ typedef struct xfs_alloc_arg {
 	int		datatype;	/* mask defining data type treatment */
 	char		wasdel;		/* set if allocation was prev delayed */
 	char		wasfromfl;	/* set if allocation is from freelist */
+	char		alignfail;	/* set if alloc failed due to alignmt */
 	struct xfs_owner_info	oinfo;	/* owner of blocks being allocated */
 	enum xfs_ag_resv_type	resv;	/* block reservation to use */
 } xfs_alloc_arg_t;
diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c
index fda13cd7add0..808060649cad 100644
--- a/fs/xfs/libxfs/xfs_bmap.c
+++ b/fs/xfs/libxfs/xfs_bmap.c
@@ -3563,6 +3563,7 @@ xfs_bmap_btalloc(
 	args.mp = mp;
 	args.fsbno = ap->blkno;
 	args.oinfo = XFS_RMAP_OINFO_SKIP_UPDATE;
+	args.alignfail = 0;
 
 	/* Trim the allocation back to the maximum an AG can fit. */
 	args.maxlen = min(ap->length, mp->m_ag_max_usable);
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
index 7fcf62b324b0..e98dcb8e65eb 100644
--- a/fs/xfs/libxfs/xfs_ialloc.c
+++ b/fs/xfs/libxfs/xfs_ialloc.c
@@ -685,6 +685,7 @@ xfs_ialloc_ag_alloc(
 		 * but not to use them in the actual exact allocation.
 		 */
 		args.alignment = 1;
+		args.alignfail = 0;
 		args.minalignslop = igeo->cluster_align - 1;
 
 		/* Allow space for the inode btree to split. */


             reply	other threads:[~2020-04-23 19:34 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-23 19:34 Eric Sandeen [this message]
2020-04-23 19:52 ` [PATCH RFC] xfs: log message when allocation fails due to alignment constraints Eric Sandeen
2020-04-24 12:40   ` Brian Foster
2020-04-24 13:41     ` Eric Sandeen
2020-04-24 14:00       ` 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=37a73948-ff5a-5375-c2e7-54174ae75462@redhat.com \
    --to=sandeen@redhat.com \
    --cc=linux-xfs@vger.kernel.org \
    /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.