Skip to content

Commit ae91dfe

Browse files
fs/ntfs3: implement NTFS3_IOC_SHUTDOWN ioctl
Add support for the NTFS3_IOC_SHUTDOWN ioctl, allowing userspace to request a filesystem shutdown. The ioctl number is shared with other filesystems such as ext4, exfat, and f2fs. Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
1 parent 2109b08 commit ae91dfe

1 file changed

Lines changed: 43 additions & 1 deletion

File tree

fs/ntfs3/file.c

Lines changed: 43 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@
1919
#include "ntfs.h"
2020
#include "ntfs_fs.h"
2121

22+
/*
23+
* cifx, btrfs, exfat, ext4, f2fs use this constant.
24+
* Hope this value will become common to all fs.
25+
*/
26+
#define NTFS3_IOC_SHUTDOWN _IOR('X', 125, __u32)
27+
2228
static int ntfs_ioctl_fitrim(struct ntfs_sb_info *sbi, unsigned long arg)
2329
{
2430
struct fstrim_range __user *user_range;
@@ -73,13 +79,47 @@ static int ntfs_ioctl_set_volume_label(struct ntfs_sb_info *sbi, u8 __user *buf)
7379
return ntfs_set_label(sbi, user, len);
7480
}
7581

82+
/*
83+
* ntfs_force_shutdown - helper function. Called from ioctl
84+
*/
85+
static int ntfs_force_shutdown(struct super_block *sb, u32 flags)
86+
{
87+
int err;
88+
struct ntfs_sb_info *sbi = sb->s_fs_info;
89+
90+
if (unlikely(ntfs3_forced_shutdown(sb)))
91+
return 0;
92+
93+
/* No additional options yet (flags). */
94+
err = bdev_freeze(sb->s_bdev);
95+
if (err)
96+
return err;
97+
set_bit(NTFS_FLAGS_SHUTDOWN_BIT, &sbi->flags);
98+
bdev_thaw(sb->s_bdev);
99+
return 0;
100+
}
101+
102+
static int ntfs_ioctl_shutdown(struct super_block *sb, unsigned long arg)
103+
{
104+
u32 flags;
105+
106+
if (!capable(CAP_SYS_ADMIN))
107+
return -EPERM;
108+
109+
if (get_user(flags, (__u32 __user *)arg))
110+
return -EFAULT;
111+
112+
return ntfs_force_shutdown(sb, flags);
113+
}
114+
76115
/*
77116
* ntfs_ioctl - file_operations::unlocked_ioctl
78117
*/
79118
long ntfs_ioctl(struct file *filp, u32 cmd, unsigned long arg)
80119
{
81120
struct inode *inode = file_inode(filp);
82-
struct ntfs_sb_info *sbi = inode->i_sb->s_fs_info;
121+
struct super_block *sb = inode->i_sb;
122+
struct ntfs_sb_info *sbi = sb->s_fs_info;
83123

84124
/* Avoid any operation if inode is bad. */
85125
if (unlikely(is_bad_ni(ntfs_i(inode))))
@@ -92,6 +132,8 @@ long ntfs_ioctl(struct file *filp, u32 cmd, unsigned long arg)
92132
return ntfs_ioctl_get_volume_label(sbi, (u8 __user *)arg);
93133
case FS_IOC_SETFSLABEL:
94134
return ntfs_ioctl_set_volume_label(sbi, (u8 __user *)arg);
135+
case NTFS3_IOC_SHUTDOWN:
136+
return ntfs_ioctl_shutdown(sb, arg);
95137
}
96138
return -ENOTTY; /* Inappropriate ioctl for device. */
97139
}

0 commit comments

Comments
 (0)