From: Dave Chinner <david@fromorbit.com>
To: linux-xfs@vger.kernel.org
Subject: [PATCH 13/14] xfs: add suport for "thin space" filesystems
Date: Thu, 26 Oct 2017 19:33:21 +1100 [thread overview]
Message-ID: <20171026083322.20428-14-david@fromorbit.com> (raw)
In-Reply-To: <20171026083322.20428-1-david@fromorbit.com>
From: Dave Chinner <dchinner@redhat.com>
With separation of the device size from the usuable space, and the
metadata reservation space hidden from the user, we can now add
direct manipulation of the usable space. This involves modifying the
on-disk superblock to store the maximum usable space and allowing
growfs to change the usable space rather than the device size.
This patch adds the feature bit and superblock support for
storing the maximum usable space, growfs will be done separately.
Signed-Off-By: Dave Chinner <dchinner@redhat.com>
---
fs/xfs/libxfs/xfs_format.h | 22 ++++++++++++----
fs/xfs/libxfs/xfs_fs.h | 4 ++-
fs/xfs/libxfs/xfs_sb.c | 62 ++++++++++++++++++++++++++++++++++++----------
fs/xfs/xfs_fsops.c | 7 +++++-
fs/xfs/xfs_ondisk.h | 2 +-
5 files changed, 76 insertions(+), 21 deletions(-)
diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
index 3fb6d2a96d36..38972cd7b9e2 100644
--- a/fs/xfs/libxfs/xfs_format.h
+++ b/fs/xfs/libxfs/xfs_format.h
@@ -105,7 +105,7 @@ struct xfs_ifork;
typedef struct xfs_sb {
uint32_t sb_magicnum; /* magic number == XFS_SB_MAGIC */
uint32_t sb_blocksize; /* logical block size, bytes */
- xfs_rfsblock_t sb_dblocks; /* number of data blocks */
+ xfs_rfsblock_t sb_dblocks; /* number of data blocks in device LBA */
xfs_rfsblock_t sb_rblocks; /* number of realtime blocks */
xfs_rtblock_t sb_rextents; /* number of realtime extents */
uuid_t sb_uuid; /* user-visible file system unique id */
@@ -184,6 +184,8 @@ typedef struct xfs_sb {
xfs_lsn_t sb_lsn; /* last write sequence */
uuid_t sb_meta_uuid; /* metadata file system unique id */
+ uint64_t sb_usable_dblocks; /* usable space limit */
+
/* must be padded to 64 bit alignment */
} xfs_sb_t;
@@ -196,7 +198,7 @@ typedef struct xfs_sb {
typedef struct xfs_dsb {
__be32 sb_magicnum; /* magic number == XFS_SB_MAGIC */
__be32 sb_blocksize; /* logical block size, bytes */
- __be64 sb_dblocks; /* number of data blocks */
+ __be64 sb_dblocks; /* number of data blocks in device LBA */
__be64 sb_rblocks; /* number of realtime blocks */
__be64 sb_rextents; /* number of realtime extents */
uuid_t sb_uuid; /* user-visible file system unique id */
@@ -271,6 +273,8 @@ typedef struct xfs_dsb {
__be64 sb_lsn; /* last write sequence */
uuid_t sb_meta_uuid; /* metadata file system unique id */
+ uint64_t sb_usable_dblocks; /* usable space limit */
+
/* must be padded to 64 bit alignment */
} xfs_dsb_t;
@@ -478,10 +482,12 @@ xfs_sb_has_ro_compat_feature(
#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
#define XFS_SB_FEAT_INCOMPAT_SPINODES (1 << 1) /* sparse inode chunks */
#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
+#define XFS_SB_FEAT_INCOMPAT_THINSPACE (1 << 3) /* usable space limited */
#define XFS_SB_FEAT_INCOMPAT_ALL \
- (XFS_SB_FEAT_INCOMPAT_FTYPE| \
- XFS_SB_FEAT_INCOMPAT_SPINODES| \
- XFS_SB_FEAT_INCOMPAT_META_UUID)
+ (XFS_SB_FEAT_INCOMPAT_FTYPE | \
+ XFS_SB_FEAT_INCOMPAT_SPINODES | \
+ XFS_SB_FEAT_INCOMPAT_META_UUID | \
+ XFS_SB_FEAT_INCOMPAT_THINSPACE)
#define XFS_SB_FEAT_INCOMPAT_UNKNOWN ~XFS_SB_FEAT_INCOMPAT_ALL
static inline bool
@@ -559,6 +565,12 @@ static inline bool xfs_sb_version_hasreflink(struct xfs_sb *sbp)
(sbp->sb_features_ro_compat & XFS_SB_FEAT_RO_COMPAT_REFLINK);
}
+static inline bool xfs_sb_version_hasthinspace(struct xfs_sb *sbp)
+{
+ return XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5 &&
+ (sbp->sb_features_ro_compat & XFS_SB_FEAT_INCOMPAT_THINSPACE);
+}
+
/*
* end of superblock version macros
*/
diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
index 223ec2695678..9fad678cae48 100644
--- a/fs/xfs/libxfs/xfs_fs.h
+++ b/fs/xfs/libxfs/xfs_fs.h
@@ -211,7 +211,8 @@ struct xfs_fsop_geom {
__u32 rtsectsize; /* realtime sector size, bytes */
__u32 dirblocksize; /* directory block size, bytes */
__u32 logsunit; /* log stripe unit, bytes */
- __u64 pad[16]; /* expansion space */
+ __u64 usable_dblocks; /* usable space limit, fsblocks */
+ __u64 pad[15]; /* expansion space */
};
/* Output for XFS_FS_COUNTS */
@@ -252,6 +253,7 @@ typedef struct xfs_fsop_resblks {
#define XFS_FSOP_GEOM_FLAGS_SPINODES (1 << 18) /* sparse inode chunks */
#define XFS_FSOP_GEOM_FLAGS_RMAPBT (1 << 19) /* reverse mapping btree */
#define XFS_FSOP_GEOM_FLAGS_REFLINK (1 << 20) /* files can share blocks */
+#define XFS_FSOP_GEOM_FLAGS_THINSPACE (1 << 21) /* space limited fs */
/*
* Minimum and maximum sizes need for growth checks.
diff --git a/fs/xfs/libxfs/xfs_sb.c b/fs/xfs/libxfs/xfs_sb.c
index 87b57abeace2..9a4593970e0a 100644
--- a/fs/xfs/libxfs/xfs_sb.c
+++ b/fs/xfs/libxfs/xfs_sb.c
@@ -268,6 +268,14 @@ xfs_mount_validate_sb(
return -EFSCORRUPTED;
}
+ if (xfs_sb_version_hasthinspace(sbp) &&
+ (sbp->sb_usable_dblocks > sbp->sb_dblocks ||
+ sbp->sb_usable_dblocks < sbp->sb_fdblocks ||
+ sbp->sb_usable_dblocks < XFS_MIN_DBLOCKS(sbp))) {
+ xfs_notice(mp, "Thinspace SB sanity check failed");
+ return -EFSCORRUPTED;
+ }
+
/*
* Until this is fixed only page-sized or smaller data blocks work.
*/
@@ -417,11 +425,13 @@ __xfs_sb_from_disk(
to->sb_features_incompat = be32_to_cpu(from->sb_features_incompat);
to->sb_features_log_incompat =
be32_to_cpu(from->sb_features_log_incompat);
+
/* crc is only used on disk, not in memory; just init to 0 here. */
to->sb_crc = 0;
to->sb_spino_align = be32_to_cpu(from->sb_spino_align);
to->sb_pquotino = be64_to_cpu(from->sb_pquotino);
to->sb_lsn = be64_to_cpu(from->sb_lsn);
+
/*
* sb_meta_uuid is only on disk if it differs from sb_uuid and the
* feature flag is set; if not set we keep it only in memory.
@@ -430,9 +440,20 @@ __xfs_sb_from_disk(
uuid_copy(&to->sb_meta_uuid, &from->sb_meta_uuid);
else
uuid_copy(&to->sb_meta_uuid, &from->sb_uuid);
+
/* Convert on-disk flags to in-memory flags? */
if (convert_xquota)
xfs_sb_quota_from_disk(to);
+
+ /*
+ * Everything in memory relies on sb_usable_dblocks having a correct
+ * value. For non-thin filesystems, this is not set on disk but is
+ * simply the size of the device, so use it instead.
+ */
+ if (xfs_sb_version_hasthinspace(to))
+ to->sb_usable_dblocks = be64_to_cpu(from->sb_usable_dblocks);
+ else
+ to->sb_usable_dblocks = to->sb_dblocks;
}
void
@@ -561,19 +582,24 @@ xfs_sb_to_disk(
to->sb_features2 = cpu_to_be32(from->sb_features2);
to->sb_bad_features2 = cpu_to_be32(from->sb_bad_features2);
- if (xfs_sb_version_hascrc(from)) {
- to->sb_features_compat = cpu_to_be32(from->sb_features_compat);
- to->sb_features_ro_compat =
- cpu_to_be32(from->sb_features_ro_compat);
- to->sb_features_incompat =
- cpu_to_be32(from->sb_features_incompat);
- to->sb_features_log_incompat =
+ if (!xfs_sb_version_hascrc(from))
+ return;
+
+ /*
+ * V5+ fields only after this point.
+ */
+ to->sb_features_compat = cpu_to_be32(from->sb_features_compat);
+ to->sb_features_ro_compat = cpu_to_be32(from->sb_features_ro_compat);
+ to->sb_features_incompat = cpu_to_be32(from->sb_features_incompat);
+ to->sb_features_log_incompat =
cpu_to_be32(from->sb_features_log_incompat);
- to->sb_spino_align = cpu_to_be32(from->sb_spino_align);
- to->sb_lsn = cpu_to_be64(from->sb_lsn);
- if (xfs_sb_version_hasmetauuid(from))
- uuid_copy(&to->sb_meta_uuid, &from->sb_meta_uuid);
- }
+ to->sb_spino_align = cpu_to_be32(from->sb_spino_align);
+ to->sb_lsn = cpu_to_be64(from->sb_lsn);
+
+ if (xfs_sb_version_hasmetauuid(from))
+ uuid_copy(&to->sb_meta_uuid, &from->sb_meta_uuid);
+ if (xfs_sb_version_hasthinspace(from))
+ to->sb_usable_dblocks = cpu_to_be64(from->sb_usable_dblocks);
}
static int
@@ -732,7 +758,7 @@ xfs_sb_mount_common(
* Set up the filesystem size and addressing limits
*/
mp->m_LBA_size = sbp->sb_dblocks;
- mp->m_usable_blocks = sbp->sb_dblocks;
+ mp->m_usable_blocks = sbp->sb_usable_dblocks;
mp->m_alloc_mxr[0] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 1);
mp->m_alloc_mxr[1] = xfs_allocbt_maxrecs(mp, sbp->sb_blocksize, 0);
@@ -824,6 +850,16 @@ xfs_initialize_perag_data(
sbp->sb_ifree = ifree;
sbp->sb_icount = ialloc;
sbp->sb_fdblocks = bfree + bfreelst + btree;
+
+ /*
+ * The aggregate free space from the AGs does not take into account the
+ * difference between the address space size and the maximum usable
+ * space we have configured for thinspace filesystems. Take that into
+ * account now.
+ */
+ if (xfs_sb_version_hasthinspace(sbp))
+ sbp->sb_fdblocks -= sbp->sb_dblocks - sbp->sb_usable_dblocks;
+
spin_unlock(&mp->m_sb_lock);
xfs_reinit_percpu_counters(mp);
diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c
index b1659e535f7a..e0565eb01c0b 100644
--- a/fs/xfs/xfs_fsops.c
+++ b/fs/xfs/xfs_fsops.c
@@ -124,8 +124,13 @@ xfs_fs_geometry(
geo->logsunit = mp->m_sb.sb_logsunit;
}
- if (new_version >= 5)
+ if (new_version >= 5) {
geo->version = XFS_FSOP_GEOM_VERSION_V5;
+ geo->flags |=
+ (xfs_sb_version_hasthinspace(&mp->m_sb) ?
+ XFS_FSOP_GEOM_FLAGS_THINSPACE : 0);
+ geo->usable_dblocks = mp->m_sb.sb_usable_dblocks;
+ }
return 0;
}
diff --git a/fs/xfs/xfs_ondisk.h b/fs/xfs/xfs_ondisk.h
index 0492436a053f..5ae5dac38e6f 100644
--- a/fs/xfs/xfs_ondisk.h
+++ b/fs/xfs/xfs_ondisk.h
@@ -45,7 +45,7 @@ xfs_check_ondisk_structs(void)
XFS_CHECK_STRUCT_SIZE(struct xfs_dinode, 176);
XFS_CHECK_STRUCT_SIZE(struct xfs_disk_dquot, 104);
XFS_CHECK_STRUCT_SIZE(struct xfs_dqblk, 136);
- XFS_CHECK_STRUCT_SIZE(struct xfs_dsb, 264);
+ XFS_CHECK_STRUCT_SIZE(struct xfs_dsb, 272);
XFS_CHECK_STRUCT_SIZE(struct xfs_dsymlink_hdr, 56);
XFS_CHECK_STRUCT_SIZE(struct xfs_inobt_key, 4);
XFS_CHECK_STRUCT_SIZE(struct xfs_inobt_rec, 16);
--
2.15.0.rc0
next prev parent reply other threads:[~2017-10-26 8:33 UTC|newest]
Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-26 8:33 [RFC PATCH 0/14] xfs: Towards thin provisioning aware filesystems Dave Chinner
2017-10-26 8:33 ` [PATCH 01/14] xfs: factor out AG header initialisation from growfs core Dave Chinner
2017-10-26 8:33 ` [PATCH 02/14] xfs: convert growfs AG header init to use buffer lists Dave Chinner
2017-10-26 8:33 ` [PATCH 03/14] xfs: factor ag btree reoot block initialisation Dave Chinner
2017-10-26 8:33 ` [PATCH 04/14] xfs: turn ag header initialisation into a table driven operation Dave Chinner
2017-10-26 8:33 ` [PATCH 05/14] xfs: make imaxpct changes in growfs separate Dave Chinner
2017-10-26 8:33 ` [PATCH 06/14] xfs: separate secondary sb update in growfs Dave Chinner
2017-10-26 8:33 ` [PATCH 07/14] xfs: rework secondary superblock updates " Dave Chinner
2017-10-26 8:33 ` [PATCH 08/14] xfs: move various type verifiers to common file Dave Chinner
2017-10-26 8:33 ` [PATCH 09/14] xfs: split usable space from block device size Dave Chinner
2017-10-26 8:33 ` [PATCH 10/14] xfs: hide reserved metadata space from users Dave Chinner
2017-10-26 8:33 ` [PATCH 11/14] xfs: bump XFS_IOC_FSGEOMETRY to v5 structures Dave Chinner
2017-10-26 8:33 ` [PATCH 12/14] xfs: convert remaingin xfs_sb_version_... checks to bool Dave Chinner
2017-10-26 16:03 ` Darrick J. Wong
2017-10-26 8:33 ` Dave Chinner [this message]
2017-10-26 8:33 ` [PATCH 14/14] xfs: add growfs support for changing usable blocks Dave Chinner
2017-10-26 11:30 ` Amir Goldstein
2017-10-26 12:48 ` Dave Chinner
2017-10-26 13:32 ` Amir Goldstein
2017-10-27 10:26 ` Amir Goldstein
2017-10-26 11:09 ` [RFC PATCH 0/14] xfs: Towards thin provisioning aware filesystems Amir Goldstein
2017-10-26 12:35 ` Dave Chinner
2017-11-01 22:31 ` Darrick J. Wong
2017-10-30 13:31 ` Brian Foster
2017-10-30 21:09 ` Dave Chinner
2017-10-31 4:49 ` Amir Goldstein
2017-10-31 22:40 ` Dave Chinner
2017-10-31 11:24 ` Brian Foster
2017-11-01 0:45 ` Dave Chinner
2017-11-01 14:17 ` Brian Foster
2017-11-01 23:53 ` Dave Chinner
2017-11-02 11:25 ` Brian Foster
2017-11-02 23:30 ` Dave Chinner
2017-11-03 2:47 ` Darrick J. Wong
2017-11-03 11:36 ` Brian Foster
2017-11-05 22:50 ` Dave Chinner
2017-11-06 13:01 ` Brian Foster
2017-11-06 21:20 ` Dave Chinner
2017-11-07 11:28 ` Brian Foster
2017-11-03 11:26 ` Brian Foster
2017-11-03 12:19 ` Amir Goldstein
2017-11-06 1:16 ` Dave Chinner
2017-11-06 9:48 ` Amir Goldstein
2017-11-06 21:46 ` Dave Chinner
2017-11-07 5:30 ` Amir Goldstein
2017-11-05 23:51 ` Dave Chinner
2017-11-06 13:07 ` 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=20171026083322.20428-14-david@fromorbit.com \
--to=david@fromorbit.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).