static void __fscrypt_decrypt_bio(struct bio *bio, bool done) { struct bio_vec *bv; int i; bio_for_each_segment_all(bv, bio, i) { struct page *page = bv->bv_page; int ret = fscrypt_decrypt_page(page->mapping->host, page, PAGE_SIZE, 0, page->index); if (ret) { WARN_ON_ONCE(1); SetPageError(page); } else if (done) { SetPageUptodate(page); } if (done) unlock_page(page); } }
/* * Call fscrypt_decrypt_page on every single page, reusing the encryption * context. */ static void completion_pages(struct work_struct *work) { struct fscrypt_ctx *ctx = container_of(work, struct fscrypt_ctx, r.work); struct bio *bio = ctx->r.bio; struct bio_vec *bv; int i; bio_for_each_segment_all(bv, bio, i) { struct page *page = bv->bv_page; int ret = fscrypt_decrypt_page(page); if (ret) { WARN_ON_ONCE(1); SetPageError(page); } else { SetPageUptodate(page); } unlock_page(page); } fscrypt_release_ctx(ctx); bio_put(bio); }
int ubifs_decrypt(const struct inode *inode, struct ubifs_data_node *dn, unsigned int *out_len, int block) { struct ubifs_info *c = inode->i_sb->s_fs_info; int err; unsigned int clen = le16_to_cpu(dn->compr_size); unsigned int dlen = *out_len; if (clen <= 0 || clen > UBIFS_BLOCK_SIZE || clen > dlen) { ubifs_err(c, "bad compr_size: %i", clen); return -EINVAL; } ubifs_assert(dlen <= UBIFS_BLOCK_SIZE); err = fscrypt_decrypt_page(inode, virt_to_page(&dn->data), dlen, offset_in_page(&dn->data), block); if (err) { ubifs_err(c, "fscrypt_decrypt_page failed: %i", err); return err; } *out_len = clen; return 0; }