Commit 4495cbed authored by Kent Overstreet's avatar Kent Overstreet Committed by Kent Overstreet

bcachefs: Improve FS_IOC_GOINGDOWN ioctl

We weren't interpreting the flags argument at all.
Signed-off-by: default avatarKent Overstreet <kent.overstreet@gmail.com>
parent 731bdd2e
......@@ -13,6 +13,9 @@
#include <linux/mount.h>
#define FS_IOC_GOINGDOWN _IOR('X', 125, __u32)
#define FSOP_GOING_FLAGS_DEFAULT 0x0 /* going down */
#define FSOP_GOING_FLAGS_LOGFLUSH 0x1 /* flush log but not data */
#define FSOP_GOING_FLAGS_NOLOGFLUSH 0x2 /* don't flush log nor data */
struct flags_set {
unsigned mask;
......@@ -247,11 +250,54 @@ static int bch2_ioc_reinherit_attrs(struct bch_fs *c,
return ret;
}
static int bch2_ioc_goingdown(struct bch_fs *c, u32 __user *arg)
{
u32 flags;
int ret = 0;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
if (get_user(flags, arg))
return -EFAULT;
bch_notice(c, "shutdown by ioctl type %u", flags);
down_write(&c->vfs_sb->s_umount);
switch (flags) {
case FSOP_GOING_FLAGS_DEFAULT:
ret = freeze_bdev(c->vfs_sb->s_bdev);
if (ret)
goto err;
bch2_journal_flush(&c->journal);
c->vfs_sb->s_flags |= SB_RDONLY;
bch2_fs_emergency_read_only(c);
thaw_bdev(c->vfs_sb->s_bdev);
break;
case FSOP_GOING_FLAGS_LOGFLUSH:
bch2_journal_flush(&c->journal);
fallthrough;
case FSOP_GOING_FLAGS_NOLOGFLUSH:
c->vfs_sb->s_flags |= SB_RDONLY;
bch2_fs_emergency_read_only(c);
break;
default:
ret = -EINVAL;
break;
}
err:
up_write(&c->vfs_sb->s_umount);
return ret;
}
long bch2_fs_file_ioctl(struct file *file, unsigned cmd, unsigned long arg)
{
struct bch_inode_info *inode = file_bch_inode(file);
struct super_block *sb = inode->v.i_sb;
struct bch_fs *c = sb->s_fs_info;
struct bch_fs *c = inode->v.i_sb->s_fs_info;
switch (cmd) {
case FS_IOC_GETFLAGS:
......@@ -276,15 +322,7 @@ long bch2_fs_file_ioctl(struct file *file, unsigned cmd, unsigned long arg)
return -ENOTTY;
case FS_IOC_GOINGDOWN:
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
down_write(&sb->s_umount);
sb->s_flags |= SB_RDONLY;
if (bch2_fs_emergency_read_only(c))
bch_err(c, "emergency read only due to ioctl");
up_write(&sb->s_umount);
return 0;
return bch2_ioc_goingdown(c, (u32 __user *) arg);
default:
return bch2_fs_ioctl(c, cmd, (void __user *) arg);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment