Commit 1cf12c71 authored by Bo Liu (OpenAnolis)'s avatar Bo Liu (OpenAnolis) Committed by Gao Xiang
Browse files

erofs: Add support for FS_IOC_GETFSLABEL



Add support for reading to the erofs volume label from the
FS_IOC_GETFSLABEL ioctls.

Signed-off-by: default avatarBo Liu (OpenAnolis) <liubo03@inspur.com>
Reviewed-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
Reviewed-by: default avatarChao Yu <chao@kernel.org>
Reviewed-by: default avatarHongbo Li <lihongbo22@huawei.com>
Signed-off-by: default avatarGao Xiang <hsiangkao@linux.alibaba.com>
parent 334c0e49
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -475,6 +475,10 @@ static loff_t erofs_file_llseek(struct file *file, loff_t offset, int whence)
const struct file_operations erofs_file_fops = {
	.llseek		= erofs_file_llseek,
	.read_iter	= erofs_file_read_iter,
	.unlocked_ioctl = erofs_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl   = erofs_compat_ioctl,
#endif
	.mmap_prepare	= erofs_file_mmap_prepare,
	.get_unmapped_area = thp_get_unmapped_area,
	.splice_read	= filemap_splice_read,
+4 −0
Original line number Diff line number Diff line
@@ -123,4 +123,8 @@ const struct file_operations erofs_dir_fops = {
	.llseek		= generic_file_llseek,
	.read		= generic_read_dir,
	.iterate_shared	= erofs_readdir,
	.unlocked_ioctl = erofs_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl   = erofs_compat_ioctl,
#endif
};
+36 −4
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
 * Copyright (C) 2021, Alibaba Cloud
 */
#include "xattr.h"
#include <linux/compat.h>
#include <trace/events/erofs.h>

static int erofs_fill_symlink(struct inode *inode, void *kaddr,
@@ -213,9 +214,6 @@ static int erofs_fill_inode(struct inode *inode)
	switch (inode->i_mode & S_IFMT) {
	case S_IFREG:
		inode->i_op = &erofs_generic_iops;
		if (erofs_inode_is_data_compressed(vi->datalayout))
			inode->i_fop = &generic_ro_fops;
		else
		inode->i_fop = &erofs_file_fops;
		break;
	case S_IFDIR:
@@ -341,6 +339,40 @@ int erofs_getattr(struct mnt_idmap *idmap, const struct path *path,
	return 0;
}

static int erofs_ioctl_get_volume_label(struct inode *inode, void __user *arg)
{
	struct erofs_sb_info *sbi = EROFS_I_SB(inode);
	int ret;

	if (!sbi->volume_name)
		ret = clear_user(arg, 1);
	else
		ret = copy_to_user(arg, sbi->volume_name,
				   strlen(sbi->volume_name));
	return ret ? -EFAULT : 0;
}

long erofs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	struct inode *inode = file_inode(filp);
	void __user *argp = (void __user *)arg;

	switch (cmd) {
	case FS_IOC_GETFSLABEL:
		return erofs_ioctl_get_volume_label(inode, argp);
	default:
		return -ENOTTY;
	}
}

#ifdef CONFIG_COMPAT
long erofs_compat_ioctl(struct file *filp, unsigned int cmd,
			unsigned long arg)
{
	return erofs_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
}
#endif

const struct inode_operations erofs_generic_iops = {
	.getattr = erofs_getattr,
	.listxattr = erofs_listxattr,
+5 −0
Original line number Diff line number Diff line
@@ -153,6 +153,7 @@ struct erofs_sb_info {
	/* used for statfs, f_files - f_favail */
	u64 inos;

	char *volume_name;
	u32 feature_compat;
	u32 feature_incompat;

@@ -536,6 +537,10 @@ static inline struct bio *erofs_fscache_bio_alloc(struct erofs_map_dev *mdev) {
static inline void erofs_fscache_submit_bio(struct bio *bio) {}
#endif

long erofs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
long erofs_compat_ioctl(struct file *filp, unsigned int cmd,
			unsigned long arg);

#define EFSCORRUPTED    EUCLEAN         /* Filesystem is corrupted */

#endif	/* __EROFS_INTERNAL_H */
+8 −0
Original line number Diff line number Diff line
@@ -343,6 +343,13 @@ static int erofs_read_superblock(struct super_block *sb)
	sbi->fixed_nsec = le32_to_cpu(dsb->fixed_nsec);
	super_set_uuid(sb, (void *)dsb->uuid, sizeof(dsb->uuid));

	if (dsb->volume_name[0]) {
		sbi->volume_name = kstrndup(dsb->volume_name,
					    sizeof(dsb->volume_name), GFP_KERNEL);
		if (!sbi->volume_name)
			return -ENOMEM;
	}

	/* parse on-disk compression configurations */
	ret = z_erofs_parse_cfgs(sb, dsb);
	if (ret < 0)
@@ -822,6 +829,7 @@ static void erofs_sb_free(struct erofs_sb_info *sbi)
	kfree(sbi->domain_id);
	if (sbi->dif0.file)
		fput(sbi->dif0.file);
	kfree(sbi->volume_name);
	kfree(sbi);
}