Commit 94426e42 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: opts.casefold_disabled



Add an option for completely disabling casefolding on a filesystem, as a
workaround for overlayfs.

This should only be needed as a temporary workaround, until the
overlayfs fix arrives.

Signed-off-by: default avatarKent Overstreet <kent.overstreet@linux.dev>
parent c6e8d51b
Loading
Loading
Loading
Loading
+9 −2
Original line number Diff line number Diff line
@@ -863,9 +863,7 @@ struct bch_fs {
	DARRAY(enum bcachefs_metadata_version)
				incompat_versions_requested;

#ifdef CONFIG_UNICODE
	struct unicode_map	*cf_encoding;
#endif

	struct bch_sb_handle	disk_sb;

@@ -1285,4 +1283,13 @@ static inline bool bch2_discard_opt_enabled(struct bch_fs *c, struct bch_dev *ca
		: ca->mi.discard;
}

static inline bool bch2_fs_casefold_enabled(struct bch_fs *c)
{
#ifdef CONFIG_UNICODE
	return !c->opts.casefold_disabled;
#else
	return false;
#endif
}

#endif /* _BCACHEFS_H */
+9 −10
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@ int bch2_casefold(struct btree_trans *trans, const struct bch_hash_info *info,
{
	*out_cf = (struct qstr) QSTR_INIT(NULL, 0);

#ifdef CONFIG_UNICODE
	if (!bch2_fs_casefold_enabled(trans->c))
		return -EOPNOTSUPP;

	unsigned char *buf = bch2_trans_kmalloc(trans, BCH_NAME_MAX + 1);
	int ret = PTR_ERR_OR_ZERO(buf);
	if (ret)
@@ -30,9 +32,6 @@ int bch2_casefold(struct btree_trans *trans, const struct bch_hash_info *info,

	*out_cf = (struct qstr) QSTR_INIT(buf, ret);
	return 0;
#else
	return -EOPNOTSUPP;
#endif
}

static unsigned bch2_dirent_name_bytes(struct bkey_s_c_dirent d)
@@ -231,7 +230,8 @@ void bch2_dirent_to_text(struct printbuf *out, struct bch_fs *c, struct bkey_s_c
	prt_printf(out, " type %s", bch2_d_type_str(d.v->d_type));
}

int bch2_dirent_init_name(struct bkey_i_dirent *dirent,
int bch2_dirent_init_name(struct bch_fs *c,
			  struct bkey_i_dirent *dirent,
			  const struct bch_hash_info *hash_info,
			  const struct qstr *name,
			  const struct qstr *cf_name)
@@ -251,7 +251,9 @@ int bch2_dirent_init_name(struct bkey_i_dirent *dirent,
		       offsetof(struct bch_dirent, d_name) -
		       name->len);
	} else {
#ifdef CONFIG_UNICODE
		if (!bch2_fs_casefold_enabled(c))
			return -EOPNOTSUPP;

		memcpy(&dirent->v.d_cf_name_block.d_names[0], name->name, name->len);

		char *cf_out = &dirent->v.d_cf_name_block.d_names[name->len];
@@ -277,9 +279,6 @@ int bch2_dirent_init_name(struct bkey_i_dirent *dirent,
		dirent->v.d_cf_name_block.d_cf_name_len = cpu_to_le16(cf_len);

		EBUG_ON(bch2_dirent_get_casefold_name(dirent_i_to_s_c(dirent)).len != cf_len);
#else
	return -EOPNOTSUPP;
#endif
	}

	unsigned u64s = dirent_val_u64s(name->len, cf_len);
@@ -313,7 +312,7 @@ struct bkey_i_dirent *bch2_dirent_create_key(struct btree_trans *trans,
	dirent->v.d_type = type;
	dirent->v.d_unused = 0;

	int ret = bch2_dirent_init_name(dirent, hash_info, name, cf_name);
	int ret = bch2_dirent_init_name(trans->c, dirent, hash_info, name, cf_name);
	if (ret)
		return ERR_PTR(ret);

+2 −1
Original line number Diff line number Diff line
@@ -59,7 +59,8 @@ static inline void dirent_copy_target(struct bkey_i_dirent *dst,
	dst->v.d_type = src.v->d_type;
}

int bch2_dirent_init_name(struct bkey_i_dirent *,
int bch2_dirent_init_name(struct bch_fs *,
			  struct bkey_i_dirent *,
			  const struct bch_hash_info *,
			  const struct qstr *,
			  const struct qstr *);
+3 −4
Original line number Diff line number Diff line
@@ -722,7 +722,6 @@ static struct dentry *bch2_lookup(struct inode *vdir, struct dentry *dentry,
	if (IS_ERR(inode))
		inode = NULL;

#ifdef CONFIG_UNICODE
	if (!inode && IS_CASEFOLDED(vdir)) {
		/*
		 * Do not cache a negative dentry in casefolded directories
@@ -737,7 +736,6 @@ static struct dentry *bch2_lookup(struct inode *vdir, struct dentry *dentry,
		 */
		return NULL;
	}
#endif

	return d_splice_alias(&inode->v, dentry);
}
@@ -2566,9 +2564,10 @@ static int bch2_fs_get_tree(struct fs_context *fc)
	sb->s_shrink->seeks = 0;

#ifdef CONFIG_UNICODE
	if (bch2_fs_casefold_enabled(c))
		sb->s_encoding = c->cf_encoding;
#endif
	generic_set_sb_d_ops(sb);
#endif

	vinode = bch2_vfs_inode_get(c, BCACHEFS_ROOT_SUBVOL_INUM);
	ret = PTR_ERR_OR_ZERO(vinode);
+0 −2
Original line number Diff line number Diff line
@@ -2302,9 +2302,7 @@ static int check_dirent(struct btree_trans *trans, struct btree_iter *iter,
		*hash_info = bch2_hash_info_init(c, &i->inode);
	dir->first_this_inode = false;

#ifdef CONFIG_UNICODE
	hash_info->cf_encoding = bch2_inode_casefold(c, &i->inode) ? c->cf_encoding : NULL;
#endif

	ret = bch2_str_hash_check_key(trans, s, &bch2_dirent_hash_desc, hash_info,
				      iter, k, need_second_pass);
Loading