From: rajan.shanmugavelu@oracle.com
Date: Mon 27 Nov 2023 09:02:28 AM PST
Subject: [PATCH] Oracleasm: fix SLE-15-SP5 issues
Patch-mainline: never (Oracle KMP specific)
References: bsc#1215781

Various fixes to get oracleasm KMP driver working correctly for
SLE-15-SP5:Update.

Signed-off-by: Lee Duncan <lduncan@suse.com>
---
*** a/drivers/block/oracleasm/driver.c
--- b/drivers/block/oracleasm/driver.c
***************
*** 72,77 ****
--- 72,78 ----
  #include <linux/compat.h>
  #include <linux/log2.h>
  #include <linux/bug.h>
+ #include <linux/bio.h>
  
  #include <asm/uaccess.h>
  #include <linux/spinlock.h>
***************
*** 149,156 ****
  {
  	bio_release_pages(bio, bio_data_dir(bio) == READ);
  	bio_put(bio);
! 	bio_put(bio);
  	trace_bio(bio, "released");
  }
  
  /*
--- 150,158 ----
  {
  	bio_release_pages(bio, bio_data_dir(bio) == READ);
  	bio_put(bio);
! 	bio_cnt_set(bio, 0);
  	trace_bio(bio, "released");
+ 	kfree(bio);
  }
  
  /*
***************
*** 1138,1145 ****
  
  
  static struct bio *asm_bio_map_user_iov(struct request_queue *q,
!                 struct iov_iter *iter, gfp_t gfp_mask)
  {
          struct bio *bio;
          int ret;
          int j;
--- 1140,1148 ----
  
  
  static struct bio *asm_bio_map_user_iov(struct request_queue *q,
!                 struct iov_iter *iter, gfp_t gfp_mask, int rw)
  {
+ 	unsigned int nr_vecs = iov_iter_npages(iter, BIO_MAX_VECS);
          struct bio *bio;
          int ret;
          int j;
***************
*** 1147,1155 ****
          if (!iov_iter_count(iter))
                  return ERR_PTR(-EINVAL);
  
!         bio = bio_kmalloc(gfp_mask, iov_iter_npages(iter, BIO_MAX_VECS));
!         if (!bio)
                  return ERR_PTR(-ENOMEM);
  
          while (iov_iter_count(iter)) {
                  struct page **pages;
--- 1150,1161 ----
          if (!iov_iter_count(iter))
                  return ERR_PTR(-EINVAL);
  
!         bio = bio_kmalloc(nr_vecs, gfp_mask);
!         if (!bio) {
! 		pr_err("%s: bio_kmalloc failed!\n", __func__);
                  return ERR_PTR(-ENOMEM);
+ 	}
+ 	bio_init(bio, NULL, bio->bi_inline_vecs, nr_vecs, rw);
  
          while (iov_iter_count(iter)) {
                  struct page **pages;
***************
*** 1172,1179 ****
                          for (j = 0; j < npages; j++) {
                                  struct page *page = pages[j];
                                  unsigned int n = PAGE_SIZE - offs;
!                                 /* unsigned short prev_bi_vcnt = bio->bi_vcnt;*/
!                                 unsigned short prev_bi_vcnt = bio->bi_vcnt;
  
                                  if (n > bytes)
                                          n = bytes;
--- 1178,1184 ----
                          for (j = 0; j < npages; j++) {
                                  struct page *page = pages[j];
                                  unsigned int n = PAGE_SIZE - offs;
!                                 unsigned short prev_bi_vcnt = bio->bi_vcnt; 
  
                                  if (n > bytes)
                                          n = bytes;
***************
*** 1217,1223 ****
  
  out_unmap:
          bio_release_pages(bio, false);
!         bio_put(bio);
          return ERR_PTR(ret);
  }
  
--- 1222,1231 ----
  
  out_unmap:
          bio_release_pages(bio, false);
! 	bio_uninit(bio);
! 	bio_put(bio);
! 	bio_cnt_set(bio, 0);
!         kfree(bio);
          return ERR_PTR(ret);
  }
  
***************
*** 1344,1352 ****
  	iov.iov_base = (void __user *)ioc->buffer_asm_ioc;
  	iov.iov_len = r->r_count;
  	iov_iter_init(&iter, rw, &iov, 1, r->r_count);
! 	r->r_bio = asm_bio_map_user_iov(bdev_get_queue(bdev), &iter, GFP_KERNEL);
  
  	if (IS_ERR(r->r_bio)) {
  		ret = PTR_ERR(r->r_bio);
  		r->r_bio = NULL;
  		ret = -ENOMEM;
--- 1352,1361 ----
  	iov.iov_base = (void __user *)ioc->buffer_asm_ioc;
  	iov.iov_len = r->r_count;
  	iov_iter_init(&iter, rw, &iov, 1, r->r_count);
! 	r->r_bio = asm_bio_map_user_iov(bdev_get_queue(bdev), &iter, GFP_KERNEL, rw);
  
  	if (IS_ERR(r->r_bio)) {
+ 		pr_err("%s: r_bio errored!\n", __func__);
  		ret = PTR_ERR(r->r_bio);
  		r->r_bio = NULL;
  		ret = -ENOMEM;

