fscrypt: work on block_devices instead of request_queues
[platform/kernel/linux-starfive.git] / fs / crypto / inline_crypt.c
index 7d1e2ec..c40bd55 100644 (file)
 
 #include "fscrypt_private.h"
 
-static int fscrypt_get_num_devices(struct super_block *sb)
+static struct block_device **fscrypt_get_devices(struct super_block *sb,
+                                                unsigned int *num_devs)
 {
-       if (sb->s_cop->get_num_devices)
-               return sb->s_cop->get_num_devices(sb);
-       return 1;
-}
+       struct block_device **devs;
 
-static void fscrypt_get_devices(struct super_block *sb, int num_devs,
-                               struct request_queue **devs)
-{
-       if (num_devs == 1)
-               devs[0] = bdev_get_queue(sb->s_bdev);
-       else
-               sb->s_cop->get_devices(sb, devs);
+       if (sb->s_cop->get_devices) {
+               devs = sb->s_cop->get_devices(sb, num_devs);
+               if (devs)
+                       return devs;
+       }
+       devs = kmalloc(sizeof(*devs), GFP_KERNEL);
+       if (!devs)
+               return ERR_PTR(-ENOMEM);
+       devs[0] = sb->s_bdev;
+       *num_devs = 1;
+       return devs;
 }
 
 static unsigned int fscrypt_get_dun_bytes(const struct fscrypt_info *ci)
@@ -68,15 +70,17 @@ static unsigned int fscrypt_get_dun_bytes(const struct fscrypt_info *ci)
  * helpful for debugging problems where the "wrong" implementation is used.
  */
 static void fscrypt_log_blk_crypto_impl(struct fscrypt_mode *mode,
-                                       struct request_queue **devs,
-                                       int num_devs,
+                                       struct block_device **devs,
+                                       unsigned int num_devs,
                                        const struct blk_crypto_config *cfg)
 {
-       int i;
+       unsigned int i;
 
        for (i = 0; i < num_devs; i++) {
+               struct request_queue *q = bdev_get_queue(devs[i]);
+
                if (!IS_ENABLED(CONFIG_BLK_INLINE_ENCRYPTION_FALLBACK) ||
-                   __blk_crypto_cfg_supported(devs[i]->crypto_profile, cfg)) {
+                   __blk_crypto_cfg_supported(q->crypto_profile, cfg)) {
                        if (!xchg(&mode->logged_blk_crypto_native, 1))
                                pr_info("fscrypt: %s using blk-crypto (native)\n",
                                        mode->friendly_name);
@@ -93,9 +97,9 @@ int fscrypt_select_encryption_impl(struct fscrypt_info *ci)
        const struct inode *inode = ci->ci_inode;
        struct super_block *sb = inode->i_sb;
        struct blk_crypto_config crypto_cfg;
-       int num_devs;
-       struct request_queue **devs;
-       int i;
+       struct block_device **devs;
+       unsigned int num_devs;
+       unsigned int i;
 
        /* The file must need contents encryption, not filenames encryption */
        if (!S_ISREG(inode->i_mode))
@@ -123,20 +127,20 @@ int fscrypt_select_encryption_impl(struct fscrypt_info *ci)
                return 0;
 
        /*
-        * On all the filesystem's devices, blk-crypto must support the crypto
-        * configuration that the file would use.
+        * On all the filesystem's block devices, blk-crypto must support the
+        * crypto configuration that the file would use.
         */
        crypto_cfg.crypto_mode = ci->ci_mode->blk_crypto_mode;
        crypto_cfg.data_unit_size = sb->s_blocksize;
        crypto_cfg.dun_bytes = fscrypt_get_dun_bytes(ci);
-       num_devs = fscrypt_get_num_devices(sb);
-       devs = kmalloc_array(num_devs, sizeof(*devs), GFP_KERNEL);
-       if (!devs)
-               return -ENOMEM;
-       fscrypt_get_devices(sb, num_devs, devs);
+
+       devs = fscrypt_get_devices(sb, &num_devs);
+       if (IS_ERR(devs))
+               return PTR_ERR(devs);
 
        for (i = 0; i < num_devs; i++) {
-               if (!blk_crypto_config_supported(devs[i], &crypto_cfg))
+               if (!blk_crypto_config_supported(bdev_get_queue(devs[i]),
+                                                &crypto_cfg))
                        goto out_free_devs;
        }
 
@@ -157,7 +161,7 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key,
        struct super_block *sb = inode->i_sb;
        enum blk_crypto_mode_num crypto_mode = ci->ci_mode->blk_crypto_mode;
        struct blk_crypto_key *blk_key;
-       struct request_queue **devs;
+       struct block_device **devs;
        unsigned int num_devs;
        unsigned int i;
        int err;
@@ -174,15 +178,14 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key,
        }
 
        /* Start using blk-crypto on all the filesystem's block devices. */
-       num_devs = fscrypt_get_num_devices(sb);
-       devs = kmalloc_array(num_devs, sizeof(*devs), GFP_KERNEL);
-       if (!devs) {
-               err = -ENOMEM;
+       devs = fscrypt_get_devices(sb, &num_devs);
+       if (IS_ERR(devs)) {
+               err = PTR_ERR(devs);
                goto fail;
        }
-       fscrypt_get_devices(sb, num_devs, devs);
        for (i = 0; i < num_devs; i++) {
-               err = blk_crypto_start_using_key(blk_key, devs[i]);
+               err = blk_crypto_start_using_key(blk_key,
+                                                bdev_get_queue(devs[i]));
                if (err)
                        break;
        }
@@ -210,7 +213,7 @@ void fscrypt_destroy_inline_crypt_key(struct super_block *sb,
                                      struct fscrypt_prepared_key *prep_key)
 {
        struct blk_crypto_key *blk_key = prep_key->blk_key;
-       struct request_queue **devs;
+       struct block_device **devs;
        unsigned int num_devs;
        unsigned int i;
 
@@ -218,12 +221,10 @@ void fscrypt_destroy_inline_crypt_key(struct super_block *sb,
                return;
 
        /* Evict the key from all the filesystem's block devices. */
-       num_devs = fscrypt_get_num_devices(sb);
-       devs = kmalloc_array(num_devs, sizeof(*devs), GFP_KERNEL);
-       if (devs) {
-               fscrypt_get_devices(sb, num_devs, devs);
+       devs = fscrypt_get_devices(sb, &num_devs);
+       if (!IS_ERR(devs)) {
                for (i = 0; i < num_devs; i++)
-                       blk_crypto_evict_key(devs[i], blk_key);
+                       blk_crypto_evict_key(bdev_get_queue(devs[i]), blk_key);
                kfree(devs);
        }
        kfree_sensitive(blk_key);