@@ -875,6 +875,16 @@ static void evict_dentries_for_decrypted_inodes(struct fscrypt_master_key *mk)
list_for_each_entry(ci, &mk->mk_decrypted_inodes, ci_master_key_link) {
inode = ci->ci_inode;
+ if (!inode) {
+ if (!ci->ci_sb->s_cop->forget_extent_info)
+ continue;
+
+ spin_unlock(&mk->mk_decrypted_inodes_lock);
+ ci->ci_sb->s_cop->forget_extent_info(ci->ci_info_ptr);
+ spin_lock(&mk->mk_decrypted_inodes_lock);
+ continue;
+ }
+
spin_lock(&inode->i_lock);
if (inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW)) {
spin_unlock(&inode->i_lock);
@@ -887,7 +897,6 @@ static void evict_dentries_for_decrypted_inodes(struct fscrypt_master_key *mk)
shrink_dcache_inode(inode);
iput(toput_inode);
toput_inode = inode;
-
spin_lock(&mk->mk_decrypted_inodes_lock);
}
@@ -129,6 +129,15 @@ struct fscrypt_operations {
*/
bool (*empty_dir)(struct inode *inode);
+ /*
+ * Inform the filesystem that a particular extent must forget its
+ * fscrypt_info (for instance, for a key removal).
+ *
+ * @info_ptr: a pointer to the location storing the fscrypt_info pointer
+ * within the opaque extent whose info is to be freed
+ */
+ void (*forget_extent_info)(struct fscrypt_info **info_ptr);
+
/*
* Check whether the filesystem's inode numbers and UUID are stable,
* meaning that they will never be changed even by offline operations
When fscrypt_infos can be owned by an extent, we need some way to attempt to evict the extent infos in the same way we evict inodes. This change adds a function pointer to allow a filesystem to optionally provide a way to evict extents; locking if needed must be handled by the filesystem. Signed-off-by: Sweet Tea Dorminy <sweettea-kernel@dorminy.me> --- fs/crypto/keyring.c | 11 ++++++++++- include/linux/fscrypt.h | 9 +++++++++ 2 files changed, 19 insertions(+), 1 deletion(-)