ext4: switch to fscrypt ->symlink() helper functions

Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
This commit is contained in:
Eric Biggers 2018-01-11 22:10:40 -05:00 committed by Theodore Ts'o
parent 3b0d8837a7
commit 78e1060c94
1 changed files with 15 additions and 43 deletions

View File

@ -3056,39 +3056,19 @@ static int ext4_symlink(struct inode *dir,
struct inode *inode;
int err, len = strlen(symname);
int credits;
bool encryption_required;
struct fscrypt_str disk_link;
struct fscrypt_symlink_data *sd = NULL;
if (unlikely(ext4_forced_shutdown(EXT4_SB(dir->i_sb))))
return -EIO;
disk_link.len = len + 1;
disk_link.name = (char *) symname;
encryption_required = (ext4_encrypted_inode(dir) ||
DUMMY_ENCRYPTION_ENABLED(EXT4_SB(dir->i_sb)));
if (encryption_required) {
err = fscrypt_get_encryption_info(dir);
if (err)
return err;
if (!fscrypt_has_encryption_key(dir))
return -ENOKEY;
disk_link.len = (fscrypt_fname_encrypted_size(dir, len) +
sizeof(struct fscrypt_symlink_data));
sd = kzalloc(disk_link.len, GFP_KERNEL);
if (!sd)
return -ENOMEM;
}
if (disk_link.len > dir->i_sb->s_blocksize) {
err = -ENAMETOOLONG;
goto err_free_sd;
}
err = fscrypt_prepare_symlink(dir, symname, len, dir->i_sb->s_blocksize,
&disk_link);
if (err)
return err;
err = dquot_initialize(dir);
if (err)
goto err_free_sd;
return err;
if ((disk_link.len > EXT4_N_BLOCKS * 4)) {
/*
@ -3117,27 +3097,18 @@ static int ext4_symlink(struct inode *dir,
if (IS_ERR(inode)) {
if (handle)
ext4_journal_stop(handle);
err = PTR_ERR(inode);
goto err_free_sd;
return PTR_ERR(inode);
}
if (encryption_required) {
struct qstr istr;
struct fscrypt_str ostr =
FSTR_INIT(sd->encrypted_path, disk_link.len);
istr.name = (const unsigned char *) symname;
istr.len = len;
err = fscrypt_fname_usr_to_disk(inode, &istr, &ostr);
if (IS_ENCRYPTED(inode)) {
err = fscrypt_encrypt_symlink(inode, symname, len, &disk_link);
if (err)
goto err_drop_inode;
sd->len = cpu_to_le16(ostr.len);
disk_link.name = (char *) sd;
inode->i_op = &ext4_encrypted_symlink_inode_operations;
}
if ((disk_link.len > EXT4_N_BLOCKS * 4)) {
if (!encryption_required)
if (!IS_ENCRYPTED(inode))
inode->i_op = &ext4_symlink_inode_operations;
inode_nohighmem(inode);
ext4_set_aops(inode);
@ -3179,7 +3150,7 @@ static int ext4_symlink(struct inode *dir,
} else {
/* clear the extent format for fast symlink */
ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS);
if (!encryption_required) {
if (!IS_ENCRYPTED(inode)) {
inode->i_op = &ext4_fast_symlink_inode_operations;
inode->i_link = (char *)&EXT4_I(inode)->i_data;
}
@ -3194,16 +3165,17 @@ static int ext4_symlink(struct inode *dir,
if (handle)
ext4_journal_stop(handle);
kfree(sd);
return err;
goto out_free_encrypted_link;
err_drop_inode:
if (handle)
ext4_journal_stop(handle);
clear_nlink(inode);
unlock_new_inode(inode);
iput(inode);
err_free_sd:
kfree(sd);
out_free_encrypted_link:
if (disk_link.name != (unsigned char *)symname)
kfree(disk_link.name);
return err;
}