vfs-6.9-rc6.fixes
-----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCZiulnAAKCRCRxhvAZXjc ogO+AP9z3+WAvgGmJkWOjT1aOrcQWVe+ZEdEUdK26ufkHhM5vAD/RXmdUBVHcYWk 3oE1hG8bONOASUc6dUIATPHBDjvqFg8= =LtmL -----END PGP SIGNATURE----- Merge tag 'vfs-6.9-rc6.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs Pull vfs fixes from Christian Brauner: "This contains a few small fixes for this merge window and the attempt to handle the ntfs removal regression that was reported a little while ago: - After the removal of the legacy ntfs driver we received reports about regressions for some people that do mount "ntfs" explicitly and expect the driver to be available. Since ntfs3 is a drop-in for legacy ntfs we alias legacy ntfs to ntfs3 just like ext3 is aliased to ext4. We also enforce legacy ntfs is always mounted read-only and give it custom file operations to ensure that ioctl()'s can't be abused to perform write operations. - Fix an unbalanced module_get() in bdev_open(). - Two smaller fixes for the netfs work done earlier in this cycle. - Fix the errno returned from the new FS_IOC_GETUUID and FS_IOC_GETFSSYSFSPATH ioctls. Both commands just pull information out of the superblock so there's no need to call into the actual ioctl handlers. So instead of returning ENOIOCTLCMD to indicate to fallback we just return ENOTTY directly avoiding that indirection" * tag 'vfs-6.9-rc6.fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: netfs: Fix the pre-flush when appending to a file in writethrough mode netfs: Fix writethrough-mode error handling ntfs3: add legacy ntfs file operations ntfs3: enforce read-only when used as legacy ntfs driver ntfs3: serve as alias for the legacy ntfs driver block: fix module reference leakage from bdev_open_by_dev error path fs: Return ENOTTY directly if FS_IOC_GETUUID or FS_IOC_GETFSSYSFSPATH fail
This commit is contained in:
commit
52034cae02
|
@ -882,7 +882,7 @@ int bdev_open(struct block_device *bdev, blk_mode_t mode, void *holder,
|
|||
goto abort_claiming;
|
||||
ret = -EBUSY;
|
||||
if (!bdev_may_open(bdev, mode))
|
||||
goto abort_claiming;
|
||||
goto put_module;
|
||||
if (bdev_is_partition(bdev))
|
||||
ret = blkdev_get_part(bdev, mode);
|
||||
else
|
||||
|
|
|
@ -769,7 +769,7 @@ static int ioctl_getfsuuid(struct file *file, void __user *argp)
|
|||
struct fsuuid2 u = { .len = sb->s_uuid_len, };
|
||||
|
||||
if (!sb->s_uuid_len)
|
||||
return -ENOIOCTLCMD;
|
||||
return -ENOTTY;
|
||||
|
||||
memcpy(&u.uuid[0], &sb->s_uuid, sb->s_uuid_len);
|
||||
|
||||
|
@ -781,7 +781,7 @@ static int ioctl_get_fs_sysfs_path(struct file *file, void __user *argp)
|
|||
struct super_block *sb = file_inode(file)->i_sb;
|
||||
|
||||
if (!strlen(sb->s_sysfs_name))
|
||||
return -ENOIOCTLCMD;
|
||||
return -ENOTTY;
|
||||
|
||||
struct fs_sysfs_path u = {};
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
|
|||
enum netfs_how_to_modify howto;
|
||||
enum netfs_folio_trace trace;
|
||||
unsigned int bdp_flags = (iocb->ki_flags & IOCB_SYNC) ? 0: BDP_ASYNC;
|
||||
ssize_t written = 0, ret;
|
||||
ssize_t written = 0, ret, ret2;
|
||||
loff_t i_size, pos = iocb->ki_pos, from, to;
|
||||
size_t max_chunk = PAGE_SIZE << MAX_PAGECACHE_ORDER;
|
||||
bool maybe_trouble = false;
|
||||
|
@ -172,15 +172,14 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
|
|||
if (unlikely(test_bit(NETFS_ICTX_WRITETHROUGH, &ctx->flags) ||
|
||||
iocb->ki_flags & (IOCB_DSYNC | IOCB_SYNC))
|
||||
) {
|
||||
if (pos < i_size_read(inode)) {
|
||||
ret = filemap_write_and_wait_range(mapping, pos, pos + iter->count);
|
||||
if (ret < 0) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
wbc_attach_fdatawrite_inode(&wbc, mapping->host);
|
||||
|
||||
ret = filemap_write_and_wait_range(mapping, pos, pos + iter->count);
|
||||
if (ret < 0) {
|
||||
wbc_detach_inode(&wbc);
|
||||
goto out;
|
||||
}
|
||||
|
||||
wreq = netfs_begin_writethrough(iocb, iter->count);
|
||||
if (IS_ERR(wreq)) {
|
||||
wbc_detach_inode(&wbc);
|
||||
|
@ -395,10 +394,12 @@ ssize_t netfs_perform_write(struct kiocb *iocb, struct iov_iter *iter,
|
|||
|
||||
out:
|
||||
if (unlikely(wreq)) {
|
||||
ret = netfs_end_writethrough(wreq, iocb);
|
||||
ret2 = netfs_end_writethrough(wreq, iocb);
|
||||
wbc_detach_inode(&wbc);
|
||||
if (ret == -EIOCBQUEUED)
|
||||
return ret;
|
||||
if (ret2 == -EIOCBQUEUED)
|
||||
return ret2;
|
||||
if (ret == 0)
|
||||
ret = ret2;
|
||||
}
|
||||
|
||||
iocb->ki_pos += written;
|
||||
|
|
|
@ -46,3 +46,12 @@ config NTFS3_FS_POSIX_ACL
|
|||
NOTE: this is linux only feature. Windows will ignore these ACLs.
|
||||
|
||||
If you don't know what Access Control Lists are, say N.
|
||||
|
||||
config NTFS_FS
|
||||
tristate "NTFS file system support"
|
||||
select NTFS3_FS
|
||||
select BUFFER_HEAD
|
||||
select NLS
|
||||
help
|
||||
This config option is here only for backward compatibility. NTFS
|
||||
filesystem is now handled by the NTFS3 driver.
|
||||
|
|
|
@ -616,4 +616,11 @@ const struct file_operations ntfs_dir_operations = {
|
|||
.compat_ioctl = ntfs_compat_ioctl,
|
||||
#endif
|
||||
};
|
||||
|
||||
const struct file_operations ntfs_legacy_dir_operations = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = generic_read_dir,
|
||||
.iterate_shared = ntfs_readdir,
|
||||
.open = ntfs_file_open,
|
||||
};
|
||||
// clang-format on
|
||||
|
|
|
@ -1236,4 +1236,12 @@ const struct file_operations ntfs_file_operations = {
|
|||
.fallocate = ntfs_fallocate,
|
||||
.release = ntfs_file_release,
|
||||
};
|
||||
|
||||
const struct file_operations ntfs_legacy_file_operations = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read_iter = ntfs_file_read_iter,
|
||||
.splice_read = ntfs_file_splice_read,
|
||||
.open = ntfs_file_open,
|
||||
.release = ntfs_file_release,
|
||||
};
|
||||
// clang-format on
|
||||
|
|
|
@ -440,7 +440,10 @@ end_enum:
|
|||
* Usually a hard links to directories are disabled.
|
||||
*/
|
||||
inode->i_op = &ntfs_dir_inode_operations;
|
||||
inode->i_fop = &ntfs_dir_operations;
|
||||
if (is_legacy_ntfs(inode->i_sb))
|
||||
inode->i_fop = &ntfs_legacy_dir_operations;
|
||||
else
|
||||
inode->i_fop = &ntfs_dir_operations;
|
||||
ni->i_valid = 0;
|
||||
} else if (S_ISLNK(mode)) {
|
||||
ni->std_fa &= ~FILE_ATTRIBUTE_DIRECTORY;
|
||||
|
@ -450,7 +453,10 @@ end_enum:
|
|||
} else if (S_ISREG(mode)) {
|
||||
ni->std_fa &= ~FILE_ATTRIBUTE_DIRECTORY;
|
||||
inode->i_op = &ntfs_file_inode_operations;
|
||||
inode->i_fop = &ntfs_file_operations;
|
||||
if (is_legacy_ntfs(inode->i_sb))
|
||||
inode->i_fop = &ntfs_legacy_file_operations;
|
||||
else
|
||||
inode->i_fop = &ntfs_file_operations;
|
||||
inode->i_mapping->a_ops = is_compressed(ni) ? &ntfs_aops_cmpr :
|
||||
&ntfs_aops;
|
||||
if (ino != MFT_REC_MFT)
|
||||
|
@ -1614,7 +1620,10 @@ struct inode *ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir,
|
|||
|
||||
if (S_ISDIR(mode)) {
|
||||
inode->i_op = &ntfs_dir_inode_operations;
|
||||
inode->i_fop = &ntfs_dir_operations;
|
||||
if (is_legacy_ntfs(inode->i_sb))
|
||||
inode->i_fop = &ntfs_legacy_dir_operations;
|
||||
else
|
||||
inode->i_fop = &ntfs_dir_operations;
|
||||
} else if (S_ISLNK(mode)) {
|
||||
inode->i_op = &ntfs_link_inode_operations;
|
||||
inode->i_fop = NULL;
|
||||
|
@ -1623,7 +1632,10 @@ struct inode *ntfs_create_inode(struct mnt_idmap *idmap, struct inode *dir,
|
|||
inode_nohighmem(inode);
|
||||
} else if (S_ISREG(mode)) {
|
||||
inode->i_op = &ntfs_file_inode_operations;
|
||||
inode->i_fop = &ntfs_file_operations;
|
||||
if (is_legacy_ntfs(inode->i_sb))
|
||||
inode->i_fop = &ntfs_legacy_file_operations;
|
||||
else
|
||||
inode->i_fop = &ntfs_file_operations;
|
||||
inode->i_mapping->a_ops = is_compressed(ni) ? &ntfs_aops_cmpr :
|
||||
&ntfs_aops;
|
||||
init_rwsem(&ni->file.run_lock);
|
||||
|
|
|
@ -493,6 +493,7 @@ struct inode *dir_search_u(struct inode *dir, const struct cpu_str *uni,
|
|||
struct ntfs_fnd *fnd);
|
||||
bool dir_is_empty(struct inode *dir);
|
||||
extern const struct file_operations ntfs_dir_operations;
|
||||
extern const struct file_operations ntfs_legacy_dir_operations;
|
||||
|
||||
/* Globals from file.c */
|
||||
int ntfs_getattr(struct mnt_idmap *idmap, const struct path *path,
|
||||
|
@ -507,6 +508,7 @@ long ntfs_compat_ioctl(struct file *filp, u32 cmd, unsigned long arg);
|
|||
extern const struct inode_operations ntfs_special_inode_operations;
|
||||
extern const struct inode_operations ntfs_file_inode_operations;
|
||||
extern const struct file_operations ntfs_file_operations;
|
||||
extern const struct file_operations ntfs_legacy_file_operations;
|
||||
|
||||
/* Globals from frecord.c */
|
||||
void ni_remove_mi(struct ntfs_inode *ni, struct mft_inode *mi);
|
||||
|
@ -1154,4 +1156,6 @@ static inline void le64_sub_cpu(__le64 *var, u64 val)
|
|||
*var = cpu_to_le64(le64_to_cpu(*var) - val);
|
||||
}
|
||||
|
||||
bool is_legacy_ntfs(struct super_block *sb);
|
||||
|
||||
#endif /* _LINUX_NTFS3_NTFS_FS_H */
|
||||
|
|
|
@ -408,6 +408,12 @@ static int ntfs_fs_reconfigure(struct fs_context *fc)
|
|||
struct ntfs_mount_options *new_opts = fc->fs_private;
|
||||
int ro_rw;
|
||||
|
||||
/* If ntfs3 is used as legacy ntfs enforce read-only mode. */
|
||||
if (is_legacy_ntfs(sb)) {
|
||||
fc->sb_flags |= SB_RDONLY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ro_rw = sb_rdonly(sb) && !(fc->sb_flags & SB_RDONLY);
|
||||
if (ro_rw && (sbi->flags & NTFS_FLAGS_NEED_REPLAY)) {
|
||||
errorf(fc,
|
||||
|
@ -427,8 +433,6 @@ static int ntfs_fs_reconfigure(struct fs_context *fc)
|
|||
fc,
|
||||
"ntfs3: Cannot use different iocharset when remounting!");
|
||||
|
||||
sync_filesystem(sb);
|
||||
|
||||
if (ro_rw && (sbi->volume.flags & VOLUME_FLAG_DIRTY) &&
|
||||
!new_opts->force) {
|
||||
errorf(fc,
|
||||
|
@ -436,6 +440,8 @@ static int ntfs_fs_reconfigure(struct fs_context *fc)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
out:
|
||||
sync_filesystem(sb);
|
||||
swap(sbi->options, fc->fs_private);
|
||||
|
||||
return 0;
|
||||
|
@ -1613,6 +1619,8 @@ load_root:
|
|||
}
|
||||
#endif
|
||||
|
||||
if (is_legacy_ntfs(sb))
|
||||
sb->s_flags |= SB_RDONLY;
|
||||
return 0;
|
||||
|
||||
put_inode_out:
|
||||
|
@ -1730,7 +1738,7 @@ static const struct fs_context_operations ntfs_context_ops = {
|
|||
* This will called when mount/remount. We will first initialize
|
||||
* options so that if remount we can use just that.
|
||||
*/
|
||||
static int ntfs_init_fs_context(struct fs_context *fc)
|
||||
static int __ntfs_init_fs_context(struct fs_context *fc)
|
||||
{
|
||||
struct ntfs_mount_options *opts;
|
||||
struct ntfs_sb_info *sbi;
|
||||
|
@ -1778,6 +1786,11 @@ free_opts:
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static int ntfs_init_fs_context(struct fs_context *fc)
|
||||
{
|
||||
return __ntfs_init_fs_context(fc);
|
||||
}
|
||||
|
||||
static void ntfs3_kill_sb(struct super_block *sb)
|
||||
{
|
||||
struct ntfs_sb_info *sbi = sb->s_fs_info;
|
||||
|
@ -1798,6 +1811,50 @@ static struct file_system_type ntfs_fs_type = {
|
|||
.kill_sb = ntfs3_kill_sb,
|
||||
.fs_flags = FS_REQUIRES_DEV | FS_ALLOW_IDMAP,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_NTFS_FS)
|
||||
static int ntfs_legacy_init_fs_context(struct fs_context *fc)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = __ntfs_init_fs_context(fc);
|
||||
/* If ntfs3 is used as legacy ntfs enforce read-only mode. */
|
||||
fc->sb_flags |= SB_RDONLY;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct file_system_type ntfs_legacy_fs_type = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "ntfs",
|
||||
.init_fs_context = ntfs_legacy_init_fs_context,
|
||||
.parameters = ntfs_fs_parameters,
|
||||
.kill_sb = ntfs3_kill_sb,
|
||||
.fs_flags = FS_REQUIRES_DEV | FS_ALLOW_IDMAP,
|
||||
};
|
||||
MODULE_ALIAS_FS("ntfs");
|
||||
|
||||
static inline void register_as_ntfs_legacy(void)
|
||||
{
|
||||
int err = register_filesystem(&ntfs_legacy_fs_type);
|
||||
if (err)
|
||||
pr_warn("ntfs3: Failed to register legacy ntfs filesystem driver: %d\n", err);
|
||||
}
|
||||
|
||||
static inline void unregister_as_ntfs_legacy(void)
|
||||
{
|
||||
unregister_filesystem(&ntfs_legacy_fs_type);
|
||||
}
|
||||
bool is_legacy_ntfs(struct super_block *sb)
|
||||
{
|
||||
return sb->s_type == &ntfs_legacy_fs_type;
|
||||
}
|
||||
#else
|
||||
static inline void register_as_ntfs_legacy(void) {}
|
||||
static inline void unregister_as_ntfs_legacy(void) {}
|
||||
bool is_legacy_ntfs(struct super_block *sb) { return false; }
|
||||
#endif
|
||||
|
||||
|
||||
// clang-format on
|
||||
|
||||
static int __init init_ntfs_fs(void)
|
||||
|
@ -1832,6 +1889,7 @@ static int __init init_ntfs_fs(void)
|
|||
goto out1;
|
||||
}
|
||||
|
||||
register_as_ntfs_legacy();
|
||||
err = register_filesystem(&ntfs_fs_type);
|
||||
if (err)
|
||||
goto out;
|
||||
|
@ -1849,6 +1907,7 @@ static void __exit exit_ntfs_fs(void)
|
|||
rcu_barrier();
|
||||
kmem_cache_destroy(ntfs_inode_cachep);
|
||||
unregister_filesystem(&ntfs_fs_type);
|
||||
unregister_as_ntfs_legacy();
|
||||
ntfs3_exit_bitmap();
|
||||
|
||||
#ifdef CONFIG_PROC_FS
|
||||
|
|
Loading…
Reference in New Issue