Implement support for FS_IOC_GETFSLABEL ioctl to read filesystem
label.

Signed-off-by: Hongbo Li <[email protected]>
---
 fs/bcachefs/fs-ioctl.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/fs/bcachefs/fs-ioctl.c b/fs/bcachefs/fs-ioctl.c
index 19ab28767208..dace11ae1931 100644
--- a/fs/bcachefs/fs-ioctl.c
+++ b/fs/bcachefs/fs-ioctl.c
@@ -277,6 +277,30 @@ static int bch2_ioc_getversion(struct bch_inode_info 
*inode, u32 __user *arg)
        return put_user(inode->v.i_generation, arg);
 }
 
+static int bch2_ioc_getlabel(struct bch_fs *c, char __user *user_label)
+{
+       int ret;
+       size_t len;
+       char label[BCH_SB_LABEL_SIZE];
+
+       BUILD_BUG_ON(BCH_SB_LABEL_SIZE >= FSLABEL_MAX);
+
+       mutex_lock(&c->sb_lock);
+       memcpy(label, c->disk_sb.sb->label, BCH_SB_LABEL_SIZE);
+       mutex_unlock(&c->sb_lock);
+
+       len = strnlen(label, BCH_SB_LABEL_SIZE);
+       if (len == BCH_SB_LABEL_SIZE) {
+               bch_warn(c,
+                       "label is too long, return the first %zu bytes",
+                       --len);
+       }
+
+       ret = copy_to_user(user_label, label, len);
+
+       return ret ? -EFAULT : 0;
+}
+
 static int bch2_ioc_goingdown(struct bch_fs *c, u32 __user *arg)
 {
        u32 flags;
@@ -518,6 +542,10 @@ long bch2_fs_file_ioctl(struct file *file, unsigned cmd, 
unsigned long arg)
                ret = -ENOTTY;
                break;
 
+       case FS_IOC_GETFSLABEL:
+               ret = bch2_ioc_getlabel(c, (void __user *) arg);
+               break;
+
        case FS_IOC_GOINGDOWN:
                ret = bch2_ioc_goingdown(c, (u32 __user *) arg);
                break;
@@ -562,6 +590,8 @@ long bch2_compat_fs_ioctl(struct file *file, unsigned cmd, 
unsigned long arg)
        case FS_IOC32_GETVERSION:
                cmd = FS_IOC_GETVERSION;
                break;
+       case FS_IOC_GETFSLABEL:
+               break;
        default:
                return -ENOIOCTLCMD;
        }
-- 
2.34.1


Reply via email to