Commit b9e1f873 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

bcachefs: Casefold is now a regular opts.h option

parent 7a4a8661
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -867,6 +867,7 @@ LE64_BITMASK(BCH_SB_VERSION_INCOMPAT_ALLOWED,
LE64_BITMASK(BCH_SB_SHARD_INUMS_NBITS,	struct bch_sb, flags[6],  0,  4);
LE64_BITMASK(BCH_SB_WRITE_ERROR_TIMEOUT,struct bch_sb, flags[6],  4, 14);
LE64_BITMASK(BCH_SB_CSUM_ERR_RETRY_NR,	struct bch_sb, flags[6], 14, 20);
LE64_BITMASK(BCH_SB_CASEFOLD,		struct bch_sb, flags[6], 22, 23);

static inline __u64 BCH_SB_COMPRESSION_TYPE(const struct bch_sb *sb)
{
+22 −11
Original line number Diff line number Diff line
@@ -53,16 +53,19 @@ static void bch2_vfs_inode_init(struct btree_trans *, subvol_inum,
				struct bch_subvolume *);

/* Set VFS inode flags from bcachefs inode: */
static inline void bch2_inode_flags_to_vfs(struct bch_inode_info *inode)
static inline void bch2_inode_flags_to_vfs(struct bch_fs *c, struct bch_inode_info *inode)
{
	static const __maybe_unused unsigned bch_flags_to_vfs[] = {
		[__BCH_INODE_sync]		= S_SYNC,
		[__BCH_INODE_immutable]		= S_IMMUTABLE,
		[__BCH_INODE_append]		= S_APPEND,
		[__BCH_INODE_noatime]		= S_NOATIME,
		[__BCH_INODE_casefolded]	= S_CASEFOLD,
	};

	set_flags(bch_flags_to_vfs, inode->ei_inode.bi_flags, inode->v.i_flags);

	if (bch2_inode_casefold(c, &inode->ei_inode))
		inode->v.i_flags |= S_CASEFOLD;
}

void bch2_inode_update_after_write(struct btree_trans *trans,
@@ -93,7 +96,7 @@ void bch2_inode_update_after_write(struct btree_trans *trans,

	inode->ei_inode		= *bi;

	bch2_inode_flags_to_vfs(inode);
	bch2_inode_flags_to_vfs(c, inode);
}

int __must_check bch2_write_inode(struct bch_fs *c,
@@ -1470,7 +1473,6 @@ static const __maybe_unused unsigned bch_flags_to_uflags[] = {
	[__BCH_INODE_append]		= FS_APPEND_FL,
	[__BCH_INODE_nodump]		= FS_NODUMP_FL,
	[__BCH_INODE_noatime]		= FS_NOATIME_FL,
	[__BCH_INODE_casefolded]	= FS_CASEFOLD_FL,
};

/* bcachefs inode flags -> FS_IOC_FSGETXATTR: */
@@ -1486,13 +1488,14 @@ static int bch2_fileattr_get(struct dentry *dentry,
			     struct fileattr *fa)
{
	struct bch_inode_info *inode = to_bch_ei(d_inode(dentry));
	struct bch_fs *c = inode->v.i_sb->s_fs_info;

	fileattr_fill_xflags(fa, map_flags(bch_flags_to_xflags, inode->ei_inode.bi_flags));

	if (inode->ei_inode.bi_fields_set & (1 << Inode_opt_project))
		fa->fsx_xflags |= FS_XFLAG_PROJINHERIT;

	if (inode->ei_inode.bi_flags & BCH_INODE_casefolded)
	if (bch2_inode_casefold(c, &inode->ei_inode))
		fa->flags |= FS_CASEFOLD_FL;

	fa->fsx_projid = inode->ei_qid.q[QTYP_PRJ];
@@ -1504,6 +1507,8 @@ struct flags_set {
	unsigned		flags;
	unsigned		projid;
	bool			set_project;
	bool			set_casefold;
	bool			casefold;
};

static int fssetxattr_inode_update_fn(struct btree_trans *trans,
@@ -1518,15 +1523,12 @@ static int fssetxattr_inode_update_fn(struct btree_trans *trans,
	 * We're relying on btree locking here for exclusion with other ioctl
	 * calls - use the flags in the btree (@bi), not inode->i_flags:
	 */
	unsigned newflags = s->flags;
	unsigned oldflags = bi->bi_flags & s->mask;

	if (!S_ISREG(bi->bi_mode) &&
	    !S_ISDIR(bi->bi_mode) &&
	    (newflags & (BCH_INODE_nodump|BCH_INODE_noatime)) != newflags)
	    (s->flags & (BCH_INODE_nodump|BCH_INODE_noatime)) != s->flags)
		return -EINVAL;

	if ((newflags ^ oldflags) & BCH_INODE_casefolded) {
	if (s->casefold != bch2_inode_casefold(c, bi)) {
#ifdef CONFIG_UNICODE
		int ret = 0;
		/* Not supported on individual files. */
@@ -1546,6 +1548,10 @@ static int fssetxattr_inode_update_fn(struct btree_trans *trans,
			return ret;

		bch2_check_set_feature(c, BCH_FEATURE_casefolding);

		bi->bi_casefold = s->casefold + 1;
		bi->bi_fields_set |= BIT(Inode_opt_casefold);

#else
		printk(KERN_ERR "Cannot use casefolding on a kernel without CONFIG_UNICODE\n");
		return -EOPNOTSUPP;
@@ -1558,7 +1564,7 @@ static int fssetxattr_inode_update_fn(struct btree_trans *trans,
	}

	bi->bi_flags &= ~s->mask;
	bi->bi_flags |= newflags;
	bi->bi_flags |= s->flags;

	bi->bi_ctime = timespec_to_bch2_time(c, current_time(&inode->v));
	return 0;
@@ -1598,6 +1604,11 @@ static int bch2_fileattr_set(struct mnt_idmap *idmap,

	if (fa->flags_valid) {
		s.mask = map_defined(bch_flags_to_uflags);

		s.set_casefold = true;
		s.casefold = (fa->flags & FS_CASEFOLD_FL) != 0;
		fa->flags &= ~FS_CASEFOLD_FL;

		s.flags |= map_flags_rev(bch_flags_to_uflags, fa->flags);
		if (fa->flags)
			return -EOPNOTSUPP;
+8 −0
Original line number Diff line number Diff line
@@ -243,6 +243,14 @@ static inline unsigned bkey_inode_mode(struct bkey_s_c k)
	}
}

static inline bool bch2_inode_casefold(struct bch_fs *c, const struct bch_inode_unpacked *bi)
{
	/* inode apts are stored with a +1 bias: 0 means "unset, use fs opt" */
	return bi->bi_casefold
		? bi->bi_casefold - 1
		: c->opts.casefold;
}

/* i_nlink: */

static inline unsigned nlink_bias(umode_t mode)
+5 −4
Original line number Diff line number Diff line
@@ -103,7 +103,8 @@ struct bch_inode_generation {
	x(bi_parent_subvol,		32)	\
	x(bi_nocow,			8)	\
	x(bi_depth,			32)	\
	x(bi_inodes_32bit,		8)
	x(bi_inodes_32bit,		8)	\
	x(bi_casefold,			8)

/* subset of BCH_INODE_FIELDS */
#define BCH_INODE_OPTS()			\
@@ -117,7 +118,8 @@ struct bch_inode_generation {
	x(background_target,		16)	\
	x(erasure_code,			16)	\
	x(nocow,			8)	\
	x(inodes_32bit,			8)
	x(inodes_32bit,			8)	\
	x(casefold,			8)

enum inode_opt_id {
#define x(name, ...)				\
@@ -137,8 +139,7 @@ enum inode_opt_id {
	x(i_sectors_dirty,		6)	\
	x(unlinked,			7)	\
	x(backptr_untrusted,		8)	\
	x(has_child_snapshot,		9)	\
	x(casefolded,			10)
	x(has_child_snapshot,		9)

/* bits 20+ reserved for packed fields below: */

+0 −4
Original line number Diff line number Diff line
@@ -47,10 +47,6 @@ int bch2_create_trans(struct btree_trans *trans,
	if (ret)
		goto err;

	/* Inherit casefold state from parent. */
	if (S_ISDIR(mode))
		new_inode->bi_flags |= dir_u->bi_flags & BCH_INODE_casefolded;

	if (!(flags & BCH_CREATE_SNAPSHOT)) {
		/* Normal create path - allocate a new inode: */
		bch2_inode_init_late(new_inode, now, uid, gid, mode, rdev, dir_u);
Loading