From: Richard Wareing <rwareing@fb.com>
To: linux-xfs@vger.kernel.org
Cc: david@fromorbit.com, darrick.wong@oracle.com, hch@infradead.org
Subject: [PATCH v4 3/3] xfs: Add realtime fallback if data device full
Date: Mon, 18 Sep 2017 20:52:38 -0700 [thread overview]
Message-ID: <20170919035238.3976871-4-rwareing@fb.com> (raw)
In-Reply-To: <20170919035238.3976871-1-rwareing@fb.com>
- Adds tunable option to fallback to realtime device if configured
when data device is full.
- Useful for realtime device users to help prevent ENOSPC errors when
selectively storing some files (e.g. small files) on data device, while
others are stored on realtime block device.
- Set via the "rt_fallback_pct" sysfs value which is available if
the kernel is compiled with CONFIG_XFS_RT.
Signed-off-by: Richard Wareing <rwareing@fb.com>
---
Changes since v3:
* None, new patch to patch set
fs/xfs/xfs_bmap_util.c | 4 +++-
fs/xfs/xfs_fsops.c | 4 ++++
fs/xfs/xfs_iomap.c | 8 ++++++--
fs/xfs/xfs_mount.c | 27 ++++++++++++++++++++++++++-
fs/xfs/xfs_mount.h | 7 ++++++-
fs/xfs/xfs_rtalloc.c | 14 ++++++++++++++
fs/xfs/xfs_rtalloc.h | 3 ++-
fs/xfs/xfs_sysfs.c | 39 +++++++++++++++++++++++++++++++++++++++
8 files changed, 100 insertions(+), 6 deletions(-)
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 2d253fb..9797c69 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -1026,8 +1026,10 @@ xfs_alloc_file_space(
if (len <= 0)
return -EINVAL;
- if (XFS_IS_REALTIME_MOUNT(mp))
+ if (XFS_IS_REALTIME_MOUNT(mp)) {
xfs_rt_alloc_min(ip, len);
+ xfs_rt_fallback(ip, mp);
+ }
rt = XFS_IS_REALTIME_INODE(ip);
extsz = xfs_get_extsz_hint(ip);
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index 6ccaae9..c15e906 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -610,6 +610,10 @@ xfs_growfs_data_private(
xfs_set_low_space_thresholds(mp);
mp->m_alloc_set_aside = xfs_alloc_set_aside(mp);
+ if (XFS_IS_REALTIME_MOUNT(mp)) {
+ xfs_set_rt_min_fdblocks(mp);
+ }
+
/*
* If we expanded the last AG, free the per-AG reservation
* so we can reinitialize it with the new size.
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index 11f1c95..707ba97 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -176,8 +176,10 @@ xfs_iomap_write_direct(
uint tflags = 0;
- if (XFS_IS_REALTIME_MOUNT(mp))
+ if (XFS_IS_REALTIME_MOUNT(mp)) {
xfs_rt_alloc_min(ip, count);
+ xfs_rt_fallback(ip, mp);
+ }
rt = XFS_IS_REALTIME_INODE(ip);
extsz = xfs_get_extsz_hint(ip);
@@ -986,8 +988,10 @@ xfs_file_iomap_begin(
if (XFS_FORCED_SHUTDOWN(mp))
return -EIO;
- if (XFS_IS_REALTIME_MOUNT(mp))
+ if (XFS_IS_REALTIME_MOUNT(mp)) {
xfs_rt_alloc_min(ip, length);
+ xfs_rt_fallback(ip, mp);
+ }
if (((flags & (IOMAP_WRITE | IOMAP_DIRECT)) == IOMAP_WRITE) &&
!IS_DAX(inode) && !xfs_get_extsz_hint(ip)) {
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c
index 2eaf818..543e80d 100644
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -509,7 +509,6 @@ xfs_set_low_space_thresholds(
}
}
-
/*
* Set whether we're using inode alignment.
*/
@@ -1396,3 +1395,29 @@ xfs_dev_is_read_only(
}
return 0;
}
+
+/*
+ * precalculate minimum of data blocks required, if we fall
+ * below this value, we will fallback to the real-time device.
+ *
+ * m_rt_fallback_pct can only be non-zero if a real-time device
+ * is configured.
+ */
+void
+xfs_set_rt_min_fdblocks(
+ struct xfs_mount *mp)
+{
+ if (mp->m_rt_fallback_pct) {
+ xfs_sb_t *sbp = &mp->m_sb;
+ xfs_extlen_t lsize;
+ __uint64_t min_blocks;
+
+ lsize = sbp->sb_logstart ? sbp->sb_logblocks : 0;
+ min_blocks = (mp->m_sb.sb_dblocks - lsize) * mp->m_rt_fallback_pct;
+ do_div(min_blocks, 100);
+ /* Pre-compute minimum data blocks required before
+ * falling back to RT device for allocations
+ */
+ mp->m_rt_min_fdblocks = min_blocks;
+ }
+}
diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h
index 067be3b..36676c4 100644
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -197,7 +197,11 @@ typedef struct xfs_mount {
__uint32_t m_generation;
bool m_fail_unmount;
- uint m_rt_alloc_min; /* Min RT allocation */
+ uint m_rt_alloc_min; /* Min RT allocation */
+ __uint8_t m_rt_fallback_pct; /* Fall back to realtime device if
+ * data dev above rt_fallback_pct
+ */
+ __uint64_t m_rt_min_fdblocks; /* Realtime min fdblock threshold */
#ifdef DEBUG
/*
* DEBUG mode instrumentation to test and/or trigger delayed allocation
@@ -463,4 +467,5 @@ int xfs_zero_extent(struct xfs_inode *ip, xfs_fsblock_t start_fsb,
struct xfs_error_cfg * xfs_error_get_cfg(struct xfs_mount *mp,
int error_class, int error);
+void xfs_set_rt_min_fdblocks(struct xfs_mount *mp);
#endif /* __XFS_MOUNT_H__ */
diff --git a/fs/xfs/xfs_rtalloc.c b/fs/xfs/xfs_rtalloc.c
index e51cb25..f0d25a0 100644
--- a/fs/xfs/xfs_rtalloc.c
+++ b/fs/xfs/xfs_rtalloc.c
@@ -1310,3 +1310,17 @@ void xfs_rt_alloc_min(
}
}
}
+
+void xfs_rt_fallback(
+ struct xfs_inode *ip,
+ struct xfs_mount *mp)
+{
+ if (!XFS_IS_REALTIME_INODE(ip)) {
+ __uint64_t free;
+ free = percpu_counter_sum(&mp->m_fdblocks) -
+ mp->m_alloc_set_aside;
+ if (free < mp->m_rt_min_fdblocks) {
+ ip->i_d.di_flags |= XFS_DIFLAG_REALTIME;
+ }
+ }
+}
diff --git a/fs/xfs/xfs_rtalloc.h b/fs/xfs/xfs_rtalloc.h
index 12939d9..28f3e42 100644
--- a/fs/xfs/xfs_rtalloc.h
+++ b/fs/xfs/xfs_rtalloc.h
@@ -137,7 +137,7 @@ int xfs_rtalloc_query_all(struct xfs_trans *tp,
xfs_rtalloc_query_range_fn fn,
void *priv);
void xfs_rt_alloc_min(struct xfs_inode *ip, xfs_off_t len);
-
+void xfs_rt_fallback(struct xfs_inode *ip, struct xfs_mount *mp);
#else
# define xfs_rtallocate_extent(t,b,min,max,l,f,p,rb) (ENOSYS)
@@ -159,6 +159,7 @@ xfs_rtmount_init(
# define xfs_rtmount_inodes(m) (((mp)->m_sb.sb_rblocks == 0)? 0 : (ENOSYS))
# define xfs_rtunmount_inodes(m)
# define xfs_rt_alloc_min(i,l) (ENOSYS)
+# define xfs_rt_fallback(i,m) (ENOSYS)
#endif /* CONFIG_XFS_RT */
#endif /* __XFS_RTALLOC_H__ */
diff --git a/fs/xfs/xfs_sysfs.c b/fs/xfs/xfs_sysfs.c
index 3c8dedb..c22da05 100644
--- a/fs/xfs/xfs_sysfs.c
+++ b/fs/xfs/xfs_sysfs.c
@@ -165,6 +165,44 @@ rt_alloc_min_show(
return snprintf(buf, PAGE_SIZE, "%d\n", mp->m_rt_alloc_min);
}
XFS_SYSFS_ATTR_RW(rt_alloc_min);
+
+STATIC ssize_t
+rt_fallback_pct_store(
+ struct kobject *kobject,
+ const char *buf,
+ size_t count)
+{
+ struct xfs_mount *mp = to_mp(kobject);
+ int ret;
+ int val;
+
+ ret = kstrtoint(buf, 0, &val);
+ if (ret)
+ return ret;
+
+ /* Only valid if using a real-time device */
+ if (XFS_IS_REALTIME_MOUNT(mp) && ((val > 0) && (val <=100))) {
+ mp->m_rt_fallback_pct = val;
+ xfs_set_rt_min_fdblocks(mp);
+ } else if (val <= 0) {
+ mp->m_rt_fallback_pct = 0;
+ mp->m_rt_min_fdblocks = 0;
+ } else
+ return -EINVAL;
+
+ return count;
+}
+
+STATIC ssize_t
+rt_fallback_pct_show(
+ struct kobject *kobject,
+ char *buf)
+{
+ struct xfs_mount *mp = to_mp(kobject);
+
+ return snprintf(buf, PAGE_SIZE, "%d\n", mp->m_rt_fallback_pct);
+}
+XFS_SYSFS_ATTR_RW(rt_fallback_pct);
#endif /* CONFIG_XFS_RT */
static struct attribute *xfs_mp_attrs[] = {
@@ -173,6 +211,7 @@ static struct attribute *xfs_mp_attrs[] = {
#endif
#ifdef CONFIG_XFS_RT
ATTR_LIST(rt_alloc_min),
+ ATTR_LIST(rt_fallback_pct),
#endif
NULL,
};
--
2.9.5
next prev parent reply other threads:[~2017-09-19 3:52 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-19 3:52 [PATCH v4 0/3] XFS realtime device tweaks Richard Wareing
2017-09-19 3:52 ` [PATCH v4 1/3] xfs: Show realtime device stats on statfs calls if inherit flag set Richard Wareing
2017-09-22 5:35 ` Dave Chinner
2017-09-22 18:26 ` Richard Wareing
2017-09-19 3:52 ` [PATCH v4 2/3] xfs: Set realtime flag based on initial allocation size Richard Wareing
2017-09-22 5:54 ` Dave Chinner
2017-09-22 19:06 ` Richard Wareing
2017-09-19 3:52 ` Richard Wareing [this message]
2017-09-22 7:04 ` [PATCH v4 3/3] xfs: Add realtime fallback if data device full Dave Chinner
2017-09-25 18:37 ` Richard Wareing
2017-09-25 23:16 ` Dave Chinner
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=20170919035238.3976871-4-rwareing@fb.com \
--to=rwareing@fb.com \
--cc=darrick.wong@oracle.com \
--cc=david@fromorbit.com \
--cc=hch@infradead.org \
--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.