mirror of
https://github.com/torvalds/linux.git
synced 2025-12-07 20:06:24 +00:00
ext4: add mext_check_validity() to do basic check
Currently, the basic validation checks during the move extent operation are scattered across __ext4_ioctl() and ext4_move_extents(), which makes the code somewhat disorganized. Introduce a new helper, mext_check_validity(), to handle these checks. This change involves only code relocation without any logical modifications. Signed-off-by: Zhang Yi <yi.zhang@huawei.com> Reviewed-by: Jan Kara <jack@suse.cz> Message-ID: <20251013015128.499308-7-yi.zhang@huaweicloud.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
@@ -1641,16 +1641,6 @@ group_extend_out:
|
||||
if (!(fd_file(donor)->f_mode & FMODE_WRITE))
|
||||
return -EBADF;
|
||||
|
||||
if (ext4_has_feature_bigalloc(sb)) {
|
||||
ext4_msg(sb, KERN_ERR,
|
||||
"Online defrag not supported with bigalloc");
|
||||
return -EOPNOTSUPP;
|
||||
} else if (IS_DAX(inode)) {
|
||||
ext4_msg(sb, KERN_ERR,
|
||||
"Online defrag not supported with DAX");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
err = mnt_want_write_file(filp);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
@@ -442,6 +442,68 @@ repair_branches:
|
||||
goto unlock_folios;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the validity of the basic filesystem environment and the
|
||||
* inodes' support status.
|
||||
*/
|
||||
static int mext_check_validity(struct inode *orig_inode,
|
||||
struct inode *donor_inode)
|
||||
{
|
||||
struct super_block *sb = orig_inode->i_sb;
|
||||
|
||||
/* origin and donor should be different inodes */
|
||||
if (orig_inode == donor_inode) {
|
||||
ext4_debug("ext4 move extent: The argument files should not be same inode [ino:orig %lu, donor %lu]\n",
|
||||
orig_inode->i_ino, donor_inode->i_ino);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* origin and donor should belone to the same filesystem */
|
||||
if (orig_inode->i_sb != donor_inode->i_sb) {
|
||||
ext4_debug("ext4 move extent: The argument files should be in same FS [ino:orig %lu, donor %lu]\n",
|
||||
orig_inode->i_ino, donor_inode->i_ino);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Regular file check */
|
||||
if (!S_ISREG(orig_inode->i_mode) || !S_ISREG(donor_inode->i_mode)) {
|
||||
ext4_debug("ext4 move extent: The argument files should be regular file [ino:orig %lu, donor %lu]\n",
|
||||
orig_inode->i_ino, donor_inode->i_ino);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ext4_has_feature_bigalloc(sb)) {
|
||||
ext4_msg(sb, KERN_ERR,
|
||||
"Online defrag not supported with bigalloc");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (IS_DAX(orig_inode)) {
|
||||
ext4_msg(sb, KERN_ERR,
|
||||
"Online defrag not supported with DAX");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: it's not obvious how to swap blocks for inodes with full
|
||||
* journaling enabled.
|
||||
*/
|
||||
if (ext4_should_journal_data(orig_inode) ||
|
||||
ext4_should_journal_data(donor_inode)) {
|
||||
ext4_msg(sb, KERN_ERR,
|
||||
"Online defrag not supported with data journaling");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (IS_ENCRYPTED(orig_inode) || IS_ENCRYPTED(donor_inode)) {
|
||||
ext4_msg(sb, KERN_ERR,
|
||||
"Online defrag not supported for encrypted files");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mext_check_arguments - Check whether move extent can be done
|
||||
*
|
||||
@@ -567,43 +629,9 @@ ext4_move_extents(struct file *o_filp, struct file *d_filp, __u64 orig_blk,
|
||||
ext4_lblk_t d_start = donor_blk;
|
||||
int ret;
|
||||
|
||||
if (orig_inode->i_sb != donor_inode->i_sb) {
|
||||
ext4_debug("ext4 move extent: The argument files "
|
||||
"should be in same FS [ino:orig %lu, donor %lu]\n",
|
||||
orig_inode->i_ino, donor_inode->i_ino);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* orig and donor should be different inodes */
|
||||
if (orig_inode == donor_inode) {
|
||||
ext4_debug("ext4 move extent: The argument files should not "
|
||||
"be same inode [ino:orig %lu, donor %lu]\n",
|
||||
orig_inode->i_ino, donor_inode->i_ino);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Regular file check */
|
||||
if (!S_ISREG(orig_inode->i_mode) || !S_ISREG(donor_inode->i_mode)) {
|
||||
ext4_debug("ext4 move extent: The argument files should be "
|
||||
"regular file [ino:orig %lu, donor %lu]\n",
|
||||
orig_inode->i_ino, donor_inode->i_ino);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* TODO: it's not obvious how to swap blocks for inodes with full
|
||||
journaling enabled */
|
||||
if (ext4_should_journal_data(orig_inode) ||
|
||||
ext4_should_journal_data(donor_inode)) {
|
||||
ext4_msg(orig_inode->i_sb, KERN_ERR,
|
||||
"Online defrag not supported with data journaling");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (IS_ENCRYPTED(orig_inode) || IS_ENCRYPTED(donor_inode)) {
|
||||
ext4_msg(orig_inode->i_sb, KERN_ERR,
|
||||
"Online defrag not supported for encrypted files");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
ret = mext_check_validity(orig_inode, donor_inode);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Protect orig and donor inodes against a truncate */
|
||||
lock_two_nondirectories(orig_inode, donor_inode);
|
||||
|
||||
Reference in New Issue
Block a user