summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorHongbo Li <lihongbo22@huawei.com>2024-06-03 21:26:20 +0800
committerKent Overstreet <kent.overstreet@linux.dev>2024-07-14 19:00:15 -0400
commit7a254053a59008913247606d0ce4a0a8b61fe6ee (patch)
treeb60e6f06dd19f9b8394e274d8ddd33f80b8f3965 /fs
parent81bce3cf2b2b4adcba4eda58fb3ebc4082b13fb3 (diff)
bcachefs: support FS_IOC_SETFSLABEL
Implement support for FS_IOC_SETFSLABEL ioctl to set filesystem label. Signed-off-by: Hongbo Li <lihongbo22@huawei.com> Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs')
-rw-r--r--fs/bcachefs/fs-ioctl.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/fs/bcachefs/fs-ioctl.c b/fs/bcachefs/fs-ioctl.c
index c82c25e7f45a..aea8132d2c40 100644
--- a/fs/bcachefs/fs-ioctl.c
+++ b/fs/bcachefs/fs-ioctl.c
@@ -301,6 +301,41 @@ static int bch2_ioc_getlabel(struct bch_fs *c, char __user *user_label)
return ret ? -EFAULT : 0;
}
+static int bch2_ioc_setlabel(struct bch_fs *c,
+ struct file *file,
+ struct bch_inode_info *inode,
+ const char __user *user_label)
+{
+ int ret;
+ char label[BCH_SB_LABEL_SIZE];
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ if (copy_from_user(label, user_label, sizeof(label)))
+ return -EFAULT;
+
+ if (strnlen(label, BCH_SB_LABEL_SIZE) == BCH_SB_LABEL_SIZE) {
+ bch_err(c,
+ "unable to set label with more than %d bytes",
+ BCH_SB_LABEL_SIZE - 1);
+ return -EINVAL;
+ }
+
+ ret = mnt_want_write_file(file);
+ if (ret)
+ return ret;
+
+ mutex_lock(&c->sb_lock);
+ strscpy(c->disk_sb.sb->label, label, BCH_SB_LABEL_SIZE);
+ mutex_unlock(&c->sb_lock);
+
+ ret = bch2_write_super(c);
+
+ mnt_drop_write_file(file);
+ return ret;
+}
+
static int bch2_ioc_goingdown(struct bch_fs *c, u32 __user *arg)
{
u32 flags;
@@ -539,6 +574,10 @@ long bch2_fs_file_ioctl(struct file *file, unsigned cmd, unsigned long arg)
ret = bch2_ioc_getlabel(c, (void __user *) arg);
break;
+ case FS_IOC_SETFSLABEL:
+ ret = bch2_ioc_setlabel(c, file, inode, (const void __user *) arg);
+ break;
+
case FS_IOC_GOINGDOWN:
ret = bch2_ioc_goingdown(c, (u32 __user *) arg);
break;
@@ -584,6 +623,7 @@ long bch2_compat_fs_ioctl(struct file *file, unsigned cmd, unsigned long arg)
cmd = FS_IOC_GETVERSION;
break;
case FS_IOC_GETFSLABEL:
+ case FS_IOC_SETFSLABEL:
break;
default:
return -ENOIOCTLCMD;