#include <linux/namei.h>
 #include "fscrypt_private.h"
 
-/*
- * Call fscrypt_decrypt_page on every single page, reusing the encryption
- * context.
- */
-static void completion_pages(struct work_struct *work)
+static void __fscrypt_decrypt_bio(struct bio *bio, bool done)
 {
-       struct fscrypt_ctx *ctx =
-               container_of(work, struct fscrypt_ctx, r.work);
-       struct bio *bio = ctx->r.bio;
        struct bio_vec *bv;
        int i;
 
                if (ret) {
                        WARN_ON_ONCE(1);
                        SetPageError(page);
-               } else {
+               } else if (done) {
                        SetPageUptodate(page);
                }
-               unlock_page(page);
+               if (done)
+                       unlock_page(page);
        }
+}
+
+void fscrypt_decrypt_bio(struct bio *bio)
+{
+       __fscrypt_decrypt_bio(bio, false);
+}
+EXPORT_SYMBOL(fscrypt_decrypt_bio);
+
+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;
+
+       __fscrypt_decrypt_bio(bio, true);
        fscrypt_release_ctx(ctx);
        bio_put(bio);
 }
 
-void fscrypt_decrypt_bio_pages(struct fscrypt_ctx *ctx, struct bio *bio)
+void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx, struct bio *bio)
 {
        INIT_WORK(&ctx->r.work, completion_pages);
        ctx->r.bio = bio;
-       queue_work(fscrypt_read_workqueue, &ctx->r.work);
+       fscrypt_enqueue_decrypt_work(&ctx->r.work);
 }
-EXPORT_SYMBOL(fscrypt_decrypt_bio_pages);
+EXPORT_SYMBOL(fscrypt_enqueue_decrypt_bio);
 
 void fscrypt_pullback_bio_page(struct page **page, bool restore)
 {
 
 static LIST_HEAD(fscrypt_free_ctxs);
 static DEFINE_SPINLOCK(fscrypt_ctx_lock);
 
-struct workqueue_struct *fscrypt_read_workqueue;
+static struct workqueue_struct *fscrypt_read_workqueue;
 static DEFINE_MUTEX(fscrypt_init_mutex);
 
 static struct kmem_cache *fscrypt_ctx_cachep;
 struct kmem_cache *fscrypt_info_cachep;
 
+void fscrypt_enqueue_decrypt_work(struct work_struct *work)
+{
+       queue_work(fscrypt_read_workqueue, work);
+}
+EXPORT_SYMBOL(fscrypt_enqueue_decrypt_work);
+
 /**
  * fscrypt_release_ctx() - Releases an encryption context
  * @ctx: The encryption context to release.
 
 /* crypto.c */
 extern struct kmem_cache *fscrypt_info_cachep;
 extern int fscrypt_initialize(unsigned int cop_flags);
-extern struct workqueue_struct *fscrypt_read_workqueue;
 extern int fscrypt_do_page_crypto(const struct inode *inode,
                                  fscrypt_direction_t rw, u64 lblk_num,
                                  struct page *src_page,
 
                if (bio->bi_status) {
                        fscrypt_release_ctx(bio->bi_private);
                } else {
-                       fscrypt_decrypt_bio_pages(bio->bi_private, bio);
+                       fscrypt_enqueue_decrypt_bio(bio->bi_private, bio);
                        return;
                }
        }
 
                if (bio->bi_status) {
                        fscrypt_release_ctx(bio->bi_private);
                } else {
-                       fscrypt_decrypt_bio_pages(bio->bi_private, bio);
+                       fscrypt_enqueue_decrypt_bio(bio->bi_private, bio);
                        return;
                }
        }
 
 }
 
 /* crypto.c */
+static inline void fscrypt_enqueue_decrypt_work(struct work_struct *work)
+{
+}
+
 static inline struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *inode,
                                                  gfp_t gfp_flags)
 {
 }
 
 /* bio.c */
-static inline void fscrypt_decrypt_bio_pages(struct fscrypt_ctx *ctx,
-                                            struct bio *bio)
+static inline void fscrypt_decrypt_bio(struct bio *bio)
+{
+}
+
+static inline void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx,
+                                              struct bio *bio)
 {
-       return;
 }
 
 static inline void fscrypt_pullback_bio_page(struct page **page, bool restore)
 
 }
 
 /* crypto.c */
+extern void fscrypt_enqueue_decrypt_work(struct work_struct *);
 extern struct fscrypt_ctx *fscrypt_get_ctx(const struct inode *, gfp_t);
 extern void fscrypt_release_ctx(struct fscrypt_ctx *);
 extern struct page *fscrypt_encrypt_page(const struct inode *, struct page *,
 }
 
 /* bio.c */
-extern void fscrypt_decrypt_bio_pages(struct fscrypt_ctx *, struct bio *);
+extern void fscrypt_decrypt_bio(struct bio *);
+extern void fscrypt_enqueue_decrypt_bio(struct fscrypt_ctx *ctx,
+                                       struct bio *bio);
 extern void fscrypt_pullback_bio_page(struct page **, bool);
 extern int fscrypt_zeroout_range(const struct inode *, pgoff_t, sector_t,
                                 unsigned int);