ext4: switch to fscrypt ->symlink() helper functions
authorEric Biggers <ebiggers@google.com>
Fri, 12 Jan 2018 03:10:40 +0000 (22:10 -0500)
committerJaegeuk Kim <jaegeuk@kernel.org>
Sun, 8 Apr 2018 09:51:54 +0000 (02:51 -0700)
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/namei.c

index bd48a8d83961bcc560525fd6b88933f8aa6ce532..e360df71d5ea1b4b07e8e93060278e8606e13626 100644 (file)
@@ -3062,39 +3062,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)) {
                /*
@@ -3123,27 +3103,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);
@@ -3185,7 +3156,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;
                }
@@ -3200,16 +3171,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;
 }