]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
erofs: Add support for FS_IOC_GETFSLABEL
authorBo Liu (OpenAnolis) <liubo03@inspur.com>
Tue, 23 Sep 2025 07:01:12 +0000 (15:01 +0800)
committerGao Xiang <hsiangkao@linux.alibaba.com>
Thu, 25 Sep 2025 03:26:20 +0000 (11:26 +0800)
Add support for reading to the erofs volume label from the
FS_IOC_GETFSLABEL ioctls.

Signed-off-by: Bo Liu (OpenAnolis) <liubo03@inspur.com>
Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Reviewed-by: Hongbo Li <lihongbo22@huawei.com>
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
fs/erofs/data.c
fs/erofs/dir.c
fs/erofs/inode.c
fs/erofs/internal.h
fs/erofs/super.c

index 3b1ba571c7286b6b01b66e04f4ba16681ac79db2..8ca29962a3ddefedb51d81afb8dbcdd1fb4414db 100644 (file)
@@ -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,
index debf469ad6bd56e92af9f7fd0c0874ca5f4fa05c..32b4f5aa60c986dc2acf209960ff6df4077c7aa1 100644 (file)
@@ -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
 };
index 9a2f59721522570d2bc46b474ec423a573dfb4fd..cb780c095d282a653211582fd992bb6aa8eb7e20 100644 (file)
@@ -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,10 +214,7 @@ 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;
+               inode->i_fop = &erofs_file_fops;
                break;
        case S_IFDIR:
                inode->i_op = &erofs_dir_iops;
@@ -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,
index 9319c66e86c3c32bb9acd4cf9bf9c223f6a71bb7..f7f622836198daeda18b5da81a643312282c44e1 100644 (file)
@@ -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 */
index db13b40a78e07d1d491487977bed986ef1b6e64b..f3f8d8c066e4e68c797f02d1974c953a7170a06a 100644 (file)
@@ -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);
 }