}
}
+/*
+ * stripe_alloc covers raid56 *data* block groups only. A filesystem whose
+ * metadata is also raid56 keeps the write hole there. The data guarantee is
+ * easy to read as a filesystem-wide one, so say once, when the policy turns
+ * on, what is not covered. That is btrfs_enable_stripe_alloc(): at mount the
+ * property applies after the block groups are read, so a report from
+ * btrfs_read_block_groups() would find the flag still clear. (Mixed block
+ * groups cannot get here: the property refuses them.)
+ */
+static void warn_stripe_alloc_uncovered(struct btrfs_fs_info *info)
+{
+ if (!btrfs_test_opt(info, STRIPE_ALLOC))
+ return;
+
+ /*
+ * raid56 metadata is covered now that the policy follows the chunk
+ * profile. System chunks are not: btrfs_is_stripe_meta_bg() tests
+ * the METADATA flag, and a system chunk does not carry it, so a
+ * raid56 system chunk keeps the legacy read-modify-write and its
+ * write hole. They are small and rewritten rarely, but say so
+ * rather than let the earlier "covered" message imply otherwise.
+ */
+ if (info->avail_system_alloc_bits & BTRFS_BLOCK_GROUP_RAID56_MASK)
+ btrfs_warn(info,
+"stripe_alloc does not cover raid56 system chunks: the write hole remains for them, consider converting to raid1c3/raid1c4");
+}
+
/*
* Turn on stripe-exclusive allocation, from the "stripe_alloc" filesystem
* property on the top-level subvolume's root directory. Runs during mount
if (live)
set_bit(BTRFS_FS_STRIPE_ALLOC_ENABLING, &fs_info->flags);
btrfs_set_opt(fs_info->mount_opt, STRIPE_ALLOC);
+ warn_stripe_alloc_uncovered(fs_info);
/*
* Arm stripe_unusable accounting for raid56 data groups whose caches
* loaded before the policy was enabled: block groups are read before
return ret;
}
-/*
- * stripe_alloc covers raid56 *data* block groups only. A filesystem whose
- * metadata is also raid56 keeps the write hole there. The data guarantee is
- * easy to read as a filesystem-wide one, so say once at mount what is not
- * covered. (Mixed block groups cannot get here: the mount is refused, see
- * btrfs_check_mountopts().)
- */
-static void warn_stripe_alloc_uncovered(struct btrfs_fs_info *info)
-{
- if (!btrfs_test_opt(info, STRIPE_ALLOC))
- return;
-
- /*
- * raid56 metadata is covered now that the policy follows the chunk
- * profile. System chunks are not: btrfs_is_stripe_meta_bg() tests
- * the METADATA flag, and a system chunk does not carry it, so a
- * raid56 system chunk keeps the legacy read-modify-write and its
- * write hole. They are small and rewritten rarely, but say so
- * rather than let the earlier "covered" message imply otherwise.
- */
- if (info->avail_system_alloc_bits & BTRFS_BLOCK_GROUP_RAID56_MASK)
- btrfs_warn(info,
-"stripe_alloc does not cover raid56 system chunks: the write hole remains for them, consider converting to raid1c3/raid1c4");
-}
-
int btrfs_read_block_groups(struct btrfs_fs_info *info)
{
struct btrfs_root *root = btrfs_block_group_root(info);
inc_block_group_ro(cache, 1);
}
- warn_stripe_alloc_uncovered(info);
/*
* The mount options rule out space_cache=v1, but the cache format can
* only be changed at mount, so a filesystem can arrive here with cache
u32 commit_interval;
u32 metadata_ratio;
u32 thread_pool_size;
- u32 stripe_rmw_opt;
unsigned long long mount_opt;
unsigned long compress_type:4;
int compress_level;
Opt_rescan_uuid_tree,
Opt_skip_balance,
Opt_space_cache,
- Opt_stripe_alloc,
- Opt_stripe_alloc_allow_rmw,
Opt_space_cache_version,
Opt_ssd,
Opt_ssd_spread,
fsparam_flag("skip_balance", Opt_skip_balance),
fsparam_flag_no("space_cache", Opt_space_cache),
fsparam_enum("space_cache", Opt_space_cache_version, btrfs_parameter_space_cache),
- fsparam_flag_no("stripe_alloc", Opt_stripe_alloc),
- fsparam_string("stripe_alloc_allow_rmw",
- Opt_stripe_alloc_allow_rmw),
fsparam_flag_no("ssd", Opt_ssd),
fsparam_flag_no("ssd_spread", Opt_ssd_spread),
fsparam_string("subvol", Opt_subvol),
else
btrfs_set_opt(ctx->mount_opt, FLUSHONCOMMIT);
break;
- case Opt_stripe_alloc:
- if (result.negated)
- btrfs_clear_opt(ctx->mount_opt, STRIPE_ALLOC);
- else
- btrfs_set_opt(ctx->mount_opt, STRIPE_ALLOC);
- break;
- case Opt_stripe_alloc_allow_rmw:
- if (btrfs_parse_stripe_rmw(param->string,
- strlen(param->string),
- &ctx->stripe_rmw_opt)) {
- btrfs_err(NULL,
- "invalid stripe_alloc_allow_rmw value %s",
- param->string);
- return -EINVAL;
- }
- break;
case Opt_ratio:
ctx->metadata_ratio = result.uint_32;
break;
ret = false;
}
- if (btrfs_raw_test_opt(*mount_opt, STRIPE_ALLOC)) {
- /*
- * Only v1 is a problem: its cache inode is nodatacow and
- * preallocated, so the cache is overwritten in place during
- * commit -- a sub-stripe write into a data block group, into
- * whatever committed stripes the cache occupies, and nodatasum
- * so nothing would show the damage afterwards. The free space
- * tree and no cache at all are both fine; nothing here needs
- * either one.
- */
- if (btrfs_raw_test_opt(*mount_opt, SPACE_CACHE)) {
- btrfs_err(info,
- "stripe_alloc is not supported with space_cache=v1");
- ret = false;
- }
- if (btrfs_is_zoned(info)) {
- btrfs_err(info,
- "stripe_alloc is not supported on zoned filesystems");
- ret = false;
- }
- if (btrfs_fs_incompat(info, MIXED_GROUPS)) {
- btrfs_err(info,
- "stripe_alloc is not supported on mixed block groups");
- ret = false;
- }
- }
-
if (btrfs_check_mountopts_zoned(info, mount_opt))
ret = false;
}
/*
- * State whether stripe-exclusive allocation is on, and which of the two things
- * that can turn it on did.
+ * State whether stripe-exclusive allocation is on.
*
- * Neither path said so before. The mount option sets the flag while
- * btrfs_emit_options() has no entry to print for it, and the
- * btrfs.stripe_alloc property applies later still, when the root directory's
- * inode is read. So nothing in the log distinguished a filesystem running the
- * policy from one that was not: silence meant "off" and "on via the mount
- * option" equally well, and the only way to answer the question was
- * /proc/mounts on a live system -- no use at all when reading a log after a
- * crash. Say it once, whatever turned it on.
+ * Nothing said so before. The btrfs.stripe_alloc property applies while the
+ * root directory's inode is read, and no line went to the log, so silence
+ * meant "off" and "on" equally well and the only way to answer the question
+ * was to look at a live filesystem -- no use at all when reading a log after a
+ * crash. Say it once at mount.
*/
-static void btrfs_emit_stripe_alloc_state(struct btrfs_fs_info *info,
- bool from_option)
+static void btrfs_emit_stripe_alloc_state(struct btrfs_fs_info *info)
{
if (!btrfs_test_opt(info, STRIPE_ALLOC))
return;
- btrfs_info(info, "using stripe-exclusive allocation for raid56 data (%s)",
- from_option ? "mount option" : "filesystem property");
+ btrfs_info(info,
+ "using stripe-exclusive allocation for raid56 data (filesystem property)");
}
static int btrfs_fill_super(struct super_block *sb,
{
struct btrfs_inode *inode;
struct btrfs_fs_info *fs_info = btrfs_sb(sb);
- bool stripe_alloc_from_option;
int ret;
sb->s_maxbytes = MAX_LFS_FILESIZE;
return ret;
}
- /*
- * Sample what the mount option asked for before open_ctree(): the mount
- * context has already been copied into fs_info by now, and open_ctree()
- * goes far enough into the mount to read the root directory's inode and
- * apply btrfs.stripe_alloc from it. Sampling afterwards would report
- * every property-enabled filesystem as an option-enabled one.
- */
- stripe_alloc_from_option = btrfs_test_opt(fs_info, STRIPE_ALLOC);
-
ret = open_ctree(sb, fs_devices);
if (ret) {
btrfs_err(fs_info, "open_ctree failed: %d", ret);
goto fail_close;
}
- btrfs_emit_stripe_alloc_state(fs_info, stripe_alloc_from_option);
+ btrfs_emit_stripe_alloc_state(fs_info);
sb->s_root = d_make_root(&inode->vfs_inode);
if (!sb->s_root) {
print_rescue_option(seq, "ignoresuperflags", &printed);
if (btrfs_test_opt(info, FLUSHONCOMMIT))
seq_puts(seq, ",flushoncommit");
- if (btrfs_test_opt(info, STRIPE_ALLOC))
- seq_puts(seq, ",stripe_alloc");
- if (info->stripe_rmw_opt) {
- seq_puts(seq, ",stripe_alloc_allow_rmw=");
- btrfs_show_stripe_rmw(seq, info->stripe_rmw_opt);
- }
if (btrfs_test_opt(info, DISCARD_SYNC))
seq_puts(seq, ",discard");
if (btrfs_test_opt(info, DISCARD_ASYNC))
fs_info->max_inline = ctx->max_inline;
fs_info->commit_interval = ctx->commit_interval;
fs_info->metadata_ratio = ctx->metadata_ratio;
- fs_info->stripe_rmw_opt = ctx->stripe_rmw_opt;
fs_info->thread_pool_size = ctx->thread_pool_size;
fs_info->mount_opt = ctx->mount_opt;
fs_info->compress_type = ctx->compress_type;
fc->sb_flags_mask |= SB_POSIXACL;
btrfs_emit_options(fs_info, &old_ctx);
- /*
- * A remount can only change this through the option; the property path
- * reports itself. Say so only when it actually changed.
- */
- if (!btrfs_raw_test_opt(old_ctx.mount_opt, STRIPE_ALLOC) !=
- !btrfs_test_opt(fs_info, STRIPE_ALLOC)) {
- if (btrfs_test_opt(fs_info, STRIPE_ALLOC))
- btrfs_emit_stripe_alloc_state(fs_info, true);
- else
- btrfs_info(fs_info,
- "stripe-exclusive allocation for raid56 data is off");
- }
wake_up_process(fs_info->transaction_kthread);
btrfs_remount_cleanup(fs_info, old_ctx.mount_opt);
btrfs_clear_oneshot_options(fs_info);