diff options
author | Eric Biggers <ebiggers@google.com> | 2018-01-11 22:10:40 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2018-01-11 22:10:40 -0500 |
commit | 78e1060c9474da8760ac91fa2deea70bd41d2821 (patch) | |
tree | 88132fe0c6c2b5f33b1f1990f4b50ad7fdcfc818 | |
parent | 3b0d8837a79ba7b7cc324d1f2b206c074e9c6182 (diff) |
ext4: switch to fscrypt ->symlink() helper functions
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r-- | fs/ext4/namei.c | 58 |
1 files changed, 15 insertions, 43 deletions
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index e750d68fbcb5..727675794a45 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -3056,39 +3056,19 @@ static int ext4_symlink(struct inode *dir, | |||
3056 | struct inode *inode; | 3056 | struct inode *inode; |
3057 | int err, len = strlen(symname); | 3057 | int err, len = strlen(symname); |
3058 | int credits; | 3058 | int credits; |
3059 | bool encryption_required; | ||
3060 | struct fscrypt_str disk_link; | 3059 | struct fscrypt_str disk_link; |
3061 | struct fscrypt_symlink_data *sd = NULL; | ||
3062 | 3060 | ||
3063 | if (unlikely(ext4_forced_shutdown(EXT4_SB(dir->i_sb)))) | 3061 | if (unlikely(ext4_forced_shutdown(EXT4_SB(dir->i_sb)))) |
3064 | return -EIO; | 3062 | return -EIO; |
3065 | 3063 | ||
3066 | disk_link.len = len + 1; | 3064 | err = fscrypt_prepare_symlink(dir, symname, len, dir->i_sb->s_blocksize, |
3067 | disk_link.name = (char *) symname; | 3065 | &disk_link); |
3068 | 3066 | if (err) | |
3069 | encryption_required = (ext4_encrypted_inode(dir) || | 3067 | return err; |
3070 | DUMMY_ENCRYPTION_ENABLED(EXT4_SB(dir->i_sb))); | ||
3071 | if (encryption_required) { | ||
3072 | err = fscrypt_get_encryption_info(dir); | ||
3073 | if (err) | ||
3074 | return err; | ||
3075 | if (!fscrypt_has_encryption_key(dir)) | ||
3076 | return -ENOKEY; | ||
3077 | disk_link.len = (fscrypt_fname_encrypted_size(dir, len) + | ||
3078 | sizeof(struct fscrypt_symlink_data)); | ||
3079 | sd = kzalloc(disk_link.len, GFP_KERNEL); | ||
3080 | if (!sd) | ||
3081 | return -ENOMEM; | ||
3082 | } | ||
3083 | |||
3084 | if (disk_link.len > dir->i_sb->s_blocksize) { | ||
3085 | err = -ENAMETOOLONG; | ||
3086 | goto err_free_sd; | ||
3087 | } | ||
3088 | 3068 | ||
3089 | err = dquot_initialize(dir); | 3069 | err = dquot_initialize(dir); |
3090 | if (err) | 3070 | if (err) |
3091 | goto err_free_sd; | 3071 | return err; |
3092 | 3072 | ||
3093 | if ((disk_link.len > EXT4_N_BLOCKS * 4)) { | 3073 | if ((disk_link.len > EXT4_N_BLOCKS * 4)) { |
3094 | /* | 3074 | /* |
@@ -3117,27 +3097,18 @@ static int ext4_symlink(struct inode *dir, | |||
3117 | if (IS_ERR(inode)) { | 3097 | if (IS_ERR(inode)) { |
3118 | if (handle) | 3098 | if (handle) |
3119 | ext4_journal_stop(handle); | 3099 | ext4_journal_stop(handle); |
3120 | err = PTR_ERR(inode); | 3100 | return PTR_ERR(inode); |
3121 | goto err_free_sd; | ||
3122 | } | 3101 | } |
3123 | 3102 | ||
3124 | if (encryption_required) { | 3103 | if (IS_ENCRYPTED(inode)) { |
3125 | struct qstr istr; | 3104 | err = fscrypt_encrypt_symlink(inode, symname, len, &disk_link); |
3126 | struct fscrypt_str ostr = | ||
3127 | FSTR_INIT(sd->encrypted_path, disk_link.len); | ||
3128 | |||
3129 | istr.name = (const unsigned char *) symname; | ||
3130 | istr.len = len; | ||
3131 | err = fscrypt_fname_usr_to_disk(inode, &istr, &ostr); | ||
3132 | if (err) | 3105 | if (err) |
3133 | goto err_drop_inode; | 3106 | goto err_drop_inode; |
3134 | sd->len = cpu_to_le16(ostr.len); | ||
3135 | disk_link.name = (char *) sd; | ||
3136 | inode->i_op = &ext4_encrypted_symlink_inode_operations; | 3107 | inode->i_op = &ext4_encrypted_symlink_inode_operations; |
3137 | } | 3108 | } |
3138 | 3109 | ||
3139 | if ((disk_link.len > EXT4_N_BLOCKS * 4)) { | 3110 | if ((disk_link.len > EXT4_N_BLOCKS * 4)) { |
3140 | if (!encryption_required) | 3111 | if (!IS_ENCRYPTED(inode)) |
3141 | inode->i_op = &ext4_symlink_inode_operations; | 3112 | inode->i_op = &ext4_symlink_inode_operations; |
3142 | inode_nohighmem(inode); | 3113 | inode_nohighmem(inode); |
3143 | ext4_set_aops(inode); | 3114 | ext4_set_aops(inode); |
@@ -3179,7 +3150,7 @@ static int ext4_symlink(struct inode *dir, | |||
3179 | } else { | 3150 | } else { |
3180 | /* clear the extent format for fast symlink */ | 3151 | /* clear the extent format for fast symlink */ |
3181 | ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS); | 3152 | ext4_clear_inode_flag(inode, EXT4_INODE_EXTENTS); |
3182 | if (!encryption_required) { | 3153 | if (!IS_ENCRYPTED(inode)) { |
3183 | inode->i_op = &ext4_fast_symlink_inode_operations; | 3154 | inode->i_op = &ext4_fast_symlink_inode_operations; |
3184 | inode->i_link = (char *)&EXT4_I(inode)->i_data; | 3155 | inode->i_link = (char *)&EXT4_I(inode)->i_data; |
3185 | } | 3156 | } |
@@ -3194,16 +3165,17 @@ static int ext4_symlink(struct inode *dir, | |||
3194 | 3165 | ||
3195 | if (handle) | 3166 | if (handle) |
3196 | ext4_journal_stop(handle); | 3167 | ext4_journal_stop(handle); |
3197 | kfree(sd); | 3168 | goto out_free_encrypted_link; |
3198 | return err; | 3169 | |
3199 | err_drop_inode: | 3170 | err_drop_inode: |
3200 | if (handle) | 3171 | if (handle) |
3201 | ext4_journal_stop(handle); | 3172 | ext4_journal_stop(handle); |
3202 | clear_nlink(inode); | 3173 | clear_nlink(inode); |
3203 | unlock_new_inode(inode); | 3174 | unlock_new_inode(inode); |
3204 | iput(inode); | 3175 | iput(inode); |
3205 | err_free_sd: | 3176 | out_free_encrypted_link: |
3206 | kfree(sd); | 3177 | if (disk_link.name != (unsigned char *)symname) |
3178 | kfree(disk_link.name); | ||
3207 | return err; | 3179 | return err; |
3208 | } | 3180 | } |
3209 | 3181 | ||