summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmds-check.c14
-rw-r--r--ctree.h4
-rw-r--r--mkfs.c2
3 files changed, 17 insertions, 3 deletions
diff --git a/cmds-check.c b/cmds-check.c
index c658879c..1569d6f4 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -51,6 +51,7 @@ static int found_old_backref = 0;
static LIST_HEAD(duplicate_extents);
static LIST_HEAD(delete_items);
static int repair = 0;
+static int no_holes = 0;
struct extent_backref {
struct list_head list;
@@ -456,8 +457,9 @@ static void maybe_free_inode_rec(struct cache_tree *inode_cache,
rec->errors |= I_ERR_FILE_NBYTES_WRONG;
if (rec->extent_start == (u64)-1 || rec->extent_start > 0)
rec->first_extent_gap = 0;
- if (rec->nlink > 0 && (rec->extent_end < rec->isize ||
- rec->first_extent_gap < rec->isize))
+ if (rec->nlink > 0 && !no_holes &&
+ (rec->extent_end < rec->isize ||
+ rec->first_extent_gap < rec->isize))
rec->errors |= I_ERR_FILE_EXTENT_DISCOUNT;
}
@@ -6500,6 +6502,14 @@ int cmd_check(int argc, char **argv)
if (ret)
goto out;
+ /*
+ * We used to have to have these hole extents in between our real
+ * extents so if we don't have this flag set we need to make sure there
+ * are no gaps in the file extents for inodes, otherwise we can just
+ * ignore it when this happens.
+ */
+ no_holes = btrfs_fs_incompat(root->fs_info,
+ BTRFS_FEATURE_INCOMPAT_NO_HOLES);
fprintf(stderr, "checking fs roots\n");
ret = check_fs_roots(root, &root_cache);
if (ret)
diff --git a/ctree.h b/ctree.h
index 22a5c6ae..3cc3477b 100644
--- a/ctree.h
+++ b/ctree.h
@@ -470,6 +470,7 @@ struct btrfs_super_block {
#define BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF (1ULL << 6)
#define BTRFS_FEATURE_INCOMPAT_RAID56 (1ULL << 7)
#define BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA (1ULL << 8)
+#define BTRFS_FEATURE_INCOMPAT_NO_HOLES (1ULL << 9)
#define BTRFS_FEATURE_COMPAT_SUPP 0ULL
@@ -482,7 +483,8 @@ struct btrfs_super_block {
BTRFS_FEATURE_INCOMPAT_EXTENDED_IREF | \
BTRFS_FEATURE_INCOMPAT_RAID56 | \
BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS | \
- BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA)
+ BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA | \
+ BTRFS_FEATURE_INCOMPAT_NO_HOLES)
/*
* A leaf is full of items. offset and size tell us where to find
diff --git a/mkfs.c b/mkfs.c
index aaea3682..d238b5c3 100644
--- a/mkfs.c
+++ b/mkfs.c
@@ -1147,6 +1147,8 @@ static const struct btrfs_fs_feature {
"raid56 extended format" },
{ "skinny-metadata", BTRFS_FEATURE_INCOMPAT_SKINNY_METADATA,
"reduced-size metadata extent refs" },
+ { "no-holes", BTRFS_FEATURE_INCOMPAT_NO_HOLES,
+ "no explicit hole extents for files" },
/* Keep this one last */
{ "list-all", BTRFS_FEATURE_LIST_ALL, NULL }
};