summaryrefslogtreecommitdiffstats
path: root/fs/crypto
diff options
context:
space:
mode:
Diffstat (limited to 'fs/crypto')
-rw-r--r--fs/crypto/crypto.c31
1 files changed, 27 insertions, 4 deletions
diff --git a/fs/crypto/crypto.c b/fs/crypto/crypto.c
index ff43a13c3abf..f82c45ac285a 100644
--- a/fs/crypto/crypto.c
+++ b/fs/crypto/crypto.c
@@ -285,8 +285,7 @@ EXPORT_SYMBOL(fscrypt_encrypt_block_inplace);
/**
* fscrypt_decrypt_page() - Decrypts a page in-place
* @inode: The corresponding inode for the page to decrypt.
- * @page: The page to decrypt. Must be locked in case
- * it is a writeback page (FS_CFLG_OWN_PAGES unset).
+ * @page: The page to decrypt. Must be locked.
* @len: Number of bytes in @page to be decrypted.
* @offs: Start of data in @page.
* @lblk_num: Logical block number.
@@ -300,8 +299,7 @@ EXPORT_SYMBOL(fscrypt_encrypt_block_inplace);
int fscrypt_decrypt_page(const struct inode *inode, struct page *page,
unsigned int len, unsigned int offs, u64 lblk_num)
{
- if (WARN_ON_ONCE(!PageLocked(page) &&
- !(inode->i_sb->s_cop->flags & FS_CFLG_OWN_PAGES)))
+ if (WARN_ON_ONCE(!PageLocked(page)))
return -EINVAL;
return fscrypt_crypt_block(inode, FS_DECRYPT, lblk_num, page, page,
@@ -309,6 +307,31 @@ int fscrypt_decrypt_page(const struct inode *inode, struct page *page,
}
EXPORT_SYMBOL(fscrypt_decrypt_page);
+/**
+ * fscrypt_decrypt_block_inplace() - Decrypt a filesystem block in-place
+ * @inode: The inode to which this block belongs
+ * @page: The page containing the block to decrypt
+ * @len: Size of block to decrypt. Doesn't need to be a multiple of the
+ * fs block size, but must be a multiple of FS_CRYPTO_BLOCK_SIZE.
+ * @offs: Byte offset within @page at which the block to decrypt begins
+ * @lblk_num: Filesystem logical block number of the block, i.e. the 0-based
+ * number of the block within the file
+ *
+ * Decrypt a possibly-compressed filesystem block that is located in an
+ * arbitrary page, not necessarily in the original pagecache page. The @inode
+ * and @lblk_num must be specified, as they can't be determined from @page.
+ *
+ * Return: 0 on success; -errno on failure
+ */
+int fscrypt_decrypt_block_inplace(const struct inode *inode, struct page *page,
+ unsigned int len, unsigned int offs,
+ u64 lblk_num)
+{
+ return fscrypt_crypt_block(inode, FS_DECRYPT, lblk_num, page, page,
+ len, offs, GFP_NOFS);
+}
+EXPORT_SYMBOL(fscrypt_decrypt_block_inplace);
+
/*
* Validate dentries in encrypted directories to make sure we aren't potentially
* caching stale dentries after a key has been added.