diff --git a/fs/dcache.c b/fs/dcache.c index 20370a0997bf..1897833a4668 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2712,6 +2712,20 @@ static void copy_name(struct dentry *dentry, struct dentry *target) call_rcu(&old_name->u.head, __d_free_external_name); } +/* + * When d_splice_alias() moves a directory's encrypted alias to its decrypted + * alias as a result of the encryption key being added, DCACHE_ENCRYPTED_NAME + * must be cleared. Note that we don't have to support arbitrary moves of this + * flag because fscrypt doesn't allow encrypted aliases to be the source or + * target of a rename(). + */ +static inline void fscrypt_handle_d_move(struct dentry *dentry) +{ +#if IS_ENABLED(CONFIG_FS_ENCRYPTION) + dentry->d_flags &= ~DCACHE_ENCRYPTED_NAME; +#endif +} + /* * __d_move - move a dentry * @dentry: entry to move @@ -2787,6 +2801,7 @@ static void __d_move(struct dentry *dentry, struct dentry *target, list_move(&dentry->d_child, &dentry->d_parent->d_subdirs); __d_rehash(dentry); fsnotify_update_flags(dentry); + fscrypt_handle_d_move(dentry); write_seqcount_end(&target->d_seq); write_seqcount_end(&dentry->d_seq);