Merge tag 'for-6.13/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm

Pull device mapper fixes from Mikulas Patocka:

- dm-array fixes

- dm-verity forward error correction fixes

- remove the flag DM_TARGET_PASSES_INTEGRITY from dm-ebs

- dm-thin RCU list fix

* tag 'for-6.13/dm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/device-mapper/linux-dm:
dm thin: make get_first_thin use rcu-safe list first function
dm-ebs: don't set the flag DM_TARGET_PASSES_INTEGRITY
dm-verity FEC: Avoid copying RS parity bytes twice.
dm-verity FEC: Fix RS FEC repair for roots unaligned to block size (take 2)
dm array: fix cursor index when skipping across block boundaries
dm array: fix unreleased btree blocks on closing a faulty array cursor
dm array: fix releasing a faulty array block twice in dm_array_cursor_end

Changed files
+45 -40
drivers
+1 -1
drivers/md/dm-ebs-target.c
··· 442 442 static struct target_type ebs_target = { 443 443 .name = "ebs", 444 444 .version = {1, 0, 1}, 445 - .features = DM_TARGET_PASSES_INTEGRITY, 445 + .features = 0, 446 446 .module = THIS_MODULE, 447 447 .ctr = ebs_ctr, 448 448 .dtr = ebs_dtr,
+2 -3
drivers/md/dm-thin.c
··· 2332 2332 struct thin_c *tc = NULL; 2333 2333 2334 2334 rcu_read_lock(); 2335 - if (!list_empty(&pool->active_thins)) { 2336 - tc = list_entry_rcu(pool->active_thins.next, struct thin_c, list); 2335 + tc = list_first_or_null_rcu(&pool->active_thins, struct thin_c, list); 2336 + if (tc) 2337 2337 thin_get(tc); 2338 - } 2339 2338 rcu_read_unlock(); 2340 2339 2341 2340 return tc;
+30 -29
drivers/md/dm-verity-fec.c
··· 40 40 } 41 41 42 42 /* 43 - * Decode an RS block using Reed-Solomon. 44 - */ 45 - static int fec_decode_rs8(struct dm_verity *v, struct dm_verity_fec_io *fio, 46 - u8 *data, u8 *fec, int neras) 47 - { 48 - int i; 49 - uint16_t par[DM_VERITY_FEC_RSM - DM_VERITY_FEC_MIN_RSN]; 50 - 51 - for (i = 0; i < v->fec->roots; i++) 52 - par[i] = fec[i]; 53 - 54 - return decode_rs8(fio->rs, data, par, v->fec->rsn, NULL, neras, 55 - fio->erasures, 0, NULL); 56 - } 57 - 58 - /* 59 43 * Read error-correcting codes for the requested RS block. Returns a pointer 60 44 * to the data block. Caller is responsible for releasing buf. 61 45 */ 62 46 static u8 *fec_read_parity(struct dm_verity *v, u64 rsb, int index, 63 - unsigned int *offset, struct dm_buffer **buf, 64 - unsigned short ioprio) 47 + unsigned int *offset, unsigned int par_buf_offset, 48 + struct dm_buffer **buf, unsigned short ioprio) 65 49 { 66 50 u64 position, block, rem; 67 51 u8 *res; 68 52 53 + /* We have already part of parity bytes read, skip to the next block */ 54 + if (par_buf_offset) 55 + index++; 56 + 69 57 position = (index + rsb) * v->fec->roots; 70 58 block = div64_u64_rem(position, v->fec->io_size, &rem); 71 - *offset = (unsigned int)rem; 59 + *offset = par_buf_offset ? 0 : (unsigned int)rem; 72 60 73 61 res = dm_bufio_read_with_ioprio(v->fec->bufio, block, buf, ioprio); 74 62 if (IS_ERR(res)) { ··· 116 128 { 117 129 int r, corrected = 0, res; 118 130 struct dm_buffer *buf; 119 - unsigned int n, i, offset; 131 + unsigned int n, i, j, offset, par_buf_offset = 0; 132 + uint16_t par_buf[DM_VERITY_FEC_RSM - DM_VERITY_FEC_MIN_RSN]; 120 133 u8 *par, *block; 121 134 struct bio *bio = dm_bio_from_per_bio_data(io, v->ti->per_io_data_size); 122 135 123 - par = fec_read_parity(v, rsb, block_offset, &offset, &buf, bio_prio(bio)); 136 + par = fec_read_parity(v, rsb, block_offset, &offset, 137 + par_buf_offset, &buf, bio_prio(bio)); 124 138 if (IS_ERR(par)) 125 139 return PTR_ERR(par); 126 140 ··· 132 142 */ 133 143 fec_for_each_buffer_rs_block(fio, n, i) { 134 144 block = fec_buffer_rs_block(v, fio, n, i); 135 - res = fec_decode_rs8(v, fio, block, &par[offset], neras); 145 + for (j = 0; j < v->fec->roots - par_buf_offset; j++) 146 + par_buf[par_buf_offset + j] = par[offset + j]; 147 + /* Decode an RS block using Reed-Solomon */ 148 + res = decode_rs8(fio->rs, block, par_buf, v->fec->rsn, 149 + NULL, neras, fio->erasures, 0, NULL); 136 150 if (res < 0) { 137 151 r = res; 138 152 goto error; ··· 149 155 if (block_offset >= 1 << v->data_dev_block_bits) 150 156 goto done; 151 157 152 - /* read the next block when we run out of parity bytes */ 153 - offset += v->fec->roots; 158 + /* Read the next block when we run out of parity bytes */ 159 + offset += (v->fec->roots - par_buf_offset); 160 + /* Check if parity bytes are split between blocks */ 161 + if (offset < v->fec->io_size && (offset + v->fec->roots) > v->fec->io_size) { 162 + par_buf_offset = v->fec->io_size - offset; 163 + for (j = 0; j < par_buf_offset; j++) 164 + par_buf[j] = par[offset + j]; 165 + offset += par_buf_offset; 166 + } else 167 + par_buf_offset = 0; 168 + 154 169 if (offset >= v->fec->io_size) { 155 170 dm_bufio_release(buf); 156 171 157 - par = fec_read_parity(v, rsb, block_offset, &offset, &buf, bio_prio(bio)); 172 + par = fec_read_parity(v, rsb, block_offset, &offset, 173 + par_buf_offset, &buf, bio_prio(bio)); 158 174 if (IS_ERR(par)) 159 175 return PTR_ERR(par); 160 176 } ··· 728 724 return -E2BIG; 729 725 } 730 726 731 - if ((f->roots << SECTOR_SHIFT) & ((1 << v->data_dev_block_bits) - 1)) 732 - f->io_size = 1 << v->data_dev_block_bits; 733 - else 734 - f->io_size = v->fec->roots << SECTOR_SHIFT; 727 + f->io_size = 1 << v->data_dev_block_bits; 735 728 736 729 f->bufio = dm_bufio_client_create(f->dev->bdev, 737 730 f->io_size,
+12 -7
drivers/md/persistent-data/dm-array.c
··· 917 917 if (c->block) 918 918 unlock_ablock(c->info, c->block); 919 919 920 - c->block = NULL; 921 - c->ab = NULL; 922 920 c->index = 0; 923 921 924 922 r = dm_btree_cursor_get_value(&c->cursor, &key, &value_le); 925 923 if (r) { 926 924 DMERR("dm_btree_cursor_get_value failed"); 927 - dm_btree_cursor_end(&c->cursor); 925 + goto out; 928 926 929 927 } else { 930 928 r = get_ablock(c->info, le64_to_cpu(value_le), &c->block, &c->ab); 931 929 if (r) { 932 930 DMERR("get_ablock failed"); 933 - dm_btree_cursor_end(&c->cursor); 931 + goto out; 934 932 } 935 933 } 936 934 935 + return 0; 936 + 937 + out: 938 + dm_btree_cursor_end(&c->cursor); 939 + c->block = NULL; 940 + c->ab = NULL; 937 941 return r; 938 942 } 939 943 ··· 960 956 961 957 void dm_array_cursor_end(struct dm_array_cursor *c) 962 958 { 963 - if (c->block) { 959 + if (c->block) 964 960 unlock_ablock(c->info, c->block); 965 - dm_btree_cursor_end(&c->cursor); 966 - } 961 + 962 + dm_btree_cursor_end(&c->cursor); 967 963 } 968 964 EXPORT_SYMBOL_GPL(dm_array_cursor_end); 969 965 ··· 1003 999 } 1004 1000 1005 1001 count -= remaining; 1002 + c->index += (remaining - 1); 1006 1003 r = dm_array_cursor_next(c); 1007 1004 1008 1005 } while (!r);