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