Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'block-7.0-20260227' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux

Pull block fixes from Jens Axboe:
"Two sets of fixes, one for drbd, and one for the zoned loop driver"

* tag 'block-7.0-20260227' of git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux:
zloop: check for spurious options passed to remove
zloop: advertise a volatile write cache
drbd: fix null-pointer dereference on local read error
drbd: Replace deprecated strcpy with strscpy
drbd: fix "LOGIC BUG" in drbd_al_begin_io_nonblock()

+64 -46
+23 -30
drivers/block/drbd/drbd_actlog.c
··· 483 483 484 484 int drbd_al_begin_io_nonblock(struct drbd_device *device, struct drbd_interval *i) 485 485 { 486 - struct lru_cache *al = device->act_log; 487 486 /* for bios crossing activity log extent boundaries, 488 487 * we may need to activate two extents in one go */ 489 488 unsigned first = i->sector >> (AL_EXTENT_SHIFT-9); 490 489 unsigned last = i->size == 0 ? first : (i->sector + (i->size >> 9) - 1) >> (AL_EXTENT_SHIFT-9); 491 - unsigned nr_al_extents; 492 - unsigned available_update_slots; 493 490 unsigned enr; 494 491 495 - D_ASSERT(device, first <= last); 496 - 497 - nr_al_extents = 1 + last - first; /* worst case: all touched extends are cold. */ 498 - available_update_slots = min(al->nr_elements - al->used, 499 - al->max_pending_changes - al->pending_changes); 500 - 501 - /* We want all necessary updates for a given request within the same transaction 502 - * We could first check how many updates are *actually* needed, 503 - * and use that instead of the worst-case nr_al_extents */ 504 - if (available_update_slots < nr_al_extents) { 505 - /* Too many activity log extents are currently "hot". 506 - * 507 - * If we have accumulated pending changes already, 508 - * we made progress. 509 - * 510 - * If we cannot get even a single pending change through, 511 - * stop the fast path until we made some progress, 512 - * or requests to "cold" extents could be starved. */ 513 - if (!al->pending_changes) 514 - __set_bit(__LC_STARVING, &device->act_log->flags); 515 - return -ENOBUFS; 492 + if (i->partially_in_al_next_enr) { 493 + D_ASSERT(device, first < i->partially_in_al_next_enr); 494 + D_ASSERT(device, last >= i->partially_in_al_next_enr); 495 + first = i->partially_in_al_next_enr; 516 496 } 497 + 498 + D_ASSERT(device, first <= last); 517 499 518 500 /* Is resync active in this area? */ 519 501 for (enr = first; enr <= last; enr++) { ··· 511 529 } 512 530 } 513 531 514 - /* Checkout the refcounts. 515 - * Given that we checked for available elements and update slots above, 516 - * this has to be successful. */ 532 + /* Try to checkout the refcounts. */ 517 533 for (enr = first; enr <= last; enr++) { 518 534 struct lc_element *al_ext; 519 535 al_ext = lc_get_cumulative(device->act_log, enr); 520 - if (!al_ext) 521 - drbd_info(device, "LOGIC BUG for enr=%u\n", enr); 536 + 537 + if (!al_ext) { 538 + /* Did not work. We may have exhausted the possible 539 + * changes per transaction. Or raced with someone 540 + * "locking" it against changes. 541 + * Remember where to continue from. 542 + */ 543 + if (enr > first) 544 + i->partially_in_al_next_enr = enr; 545 + return -ENOBUFS; 546 + } 522 547 } 523 548 return 0; 524 549 } ··· 545 556 546 557 for (enr = first; enr <= last; enr++) { 547 558 extent = lc_find(device->act_log, enr); 548 - if (!extent) { 559 + /* Yes, this masks a bug elsewhere. However, during normal 560 + * operation this is harmless, so no need to crash the kernel 561 + * by the BUG_ON(refcount == 0) in lc_put(). 562 + */ 563 + if (!extent || extent->refcnt == 0) { 549 564 drbd_err(device, "al_complete_io() called on inactive extent %u\n", enr); 550 565 continue; 551 566 }
+4 -1
drivers/block/drbd/drbd_interval.h
··· 8 8 struct drbd_interval { 9 9 struct rb_node rb; 10 10 sector_t sector; /* start sector of the interval */ 11 - unsigned int size; /* size in bytes */ 12 11 sector_t end; /* highest interval end in subtree */ 12 + unsigned int size; /* size in bytes */ 13 13 unsigned int local:1 /* local or remote request? */; 14 14 unsigned int waiting:1; /* someone is waiting for completion */ 15 15 unsigned int completed:1; /* this has been completed already; 16 16 * ignore for conflict detection */ 17 + 18 + /* to resume a partially successful drbd_al_begin_io_nonblock(); */ 19 + unsigned int partially_in_al_next_enr; 17 20 }; 18 21 19 22 static inline void drbd_clear_interval(struct drbd_interval *i)
+9 -5
drivers/block/drbd/drbd_main.c
··· 32 32 #include <linux/memcontrol.h> 33 33 #include <linux/mm_inline.h> 34 34 #include <linux/slab.h> 35 + #include <linux/string.h> 35 36 #include <linux/random.h> 36 37 #include <linux/reboot.h> 37 38 #include <linux/notifier.h> ··· 733 732 } 734 733 735 734 if (apv >= 88) 736 - strcpy(p->verify_alg, nc->verify_alg); 735 + strscpy(p->verify_alg, nc->verify_alg); 737 736 if (apv >= 89) 738 - strcpy(p->csums_alg, nc->csums_alg); 737 + strscpy(p->csums_alg, nc->csums_alg); 739 738 rcu_read_unlock(); 740 739 741 740 return drbd_send_command(peer_device, sock, cmd, size, NULL, 0); ··· 746 745 struct drbd_socket *sock; 747 746 struct p_protocol *p; 748 747 struct net_conf *nc; 748 + size_t integrity_alg_len; 749 749 int size, cf; 750 750 751 751 sock = &connection->data; ··· 764 762 } 765 763 766 764 size = sizeof(*p); 767 - if (connection->agreed_pro_version >= 87) 768 - size += strlen(nc->integrity_alg) + 1; 765 + if (connection->agreed_pro_version >= 87) { 766 + integrity_alg_len = strlen(nc->integrity_alg) + 1; 767 + size += integrity_alg_len; 768 + } 769 769 770 770 p->protocol = cpu_to_be32(nc->wire_protocol); 771 771 p->after_sb_0p = cpu_to_be32(nc->after_sb_0p); ··· 782 778 p->conn_flags = cpu_to_be32(cf); 783 779 784 780 if (connection->agreed_pro_version >= 87) 785 - strcpy(p->integrity_alg, nc->integrity_alg); 781 + strscpy(p->integrity_alg, nc->integrity_alg, integrity_alg_len); 786 782 rcu_read_unlock(); 787 783 788 784 return __conn_send_command(connection, sock, cmd, size, NULL, 0);
+2 -2
drivers/block/drbd/drbd_receiver.c
··· 3801 3801 *new_net_conf = *old_net_conf; 3802 3802 3803 3803 if (verify_tfm) { 3804 - strcpy(new_net_conf->verify_alg, p->verify_alg); 3804 + strscpy(new_net_conf->verify_alg, p->verify_alg); 3805 3805 new_net_conf->verify_alg_len = strlen(p->verify_alg) + 1; 3806 3806 crypto_free_shash(peer_device->connection->verify_tfm); 3807 3807 peer_device->connection->verify_tfm = verify_tfm; 3808 3808 drbd_info(device, "using verify-alg: \"%s\"\n", p->verify_alg); 3809 3809 } 3810 3810 if (csums_tfm) { 3811 - strcpy(new_net_conf->csums_alg, p->csums_alg); 3811 + strscpy(new_net_conf->csums_alg, p->csums_alg); 3812 3812 new_net_conf->csums_alg_len = strlen(p->csums_alg) + 1; 3813 3813 crypto_free_shash(peer_device->connection->csums_tfm); 3814 3814 peer_device->connection->csums_tfm = csums_tfm;
+2 -1
drivers/block/drbd/drbd_req.c
··· 621 621 break; 622 622 623 623 case READ_COMPLETED_WITH_ERROR: 624 - drbd_set_out_of_sync(peer_device, req->i.sector, req->i.size); 624 + drbd_set_out_of_sync(first_peer_device(device), 625 + req->i.sector, req->i.size); 625 626 drbd_report_io_error(device, req); 626 627 __drbd_chk_io_error(device, DRBD_READ_ERROR); 627 628 fallthrough;
+24 -7
drivers/block/zloop.c
··· 542 542 zloop_put_cmd(cmd); 543 543 } 544 544 545 + /* 546 + * Sync the entire FS containing the zone files instead of walking all files. 547 + */ 548 + static int zloop_flush(struct zloop_device *zlo) 549 + { 550 + struct super_block *sb = file_inode(zlo->data_dir)->i_sb; 551 + int ret; 552 + 553 + down_read(&sb->s_umount); 554 + ret = sync_filesystem(sb); 555 + up_read(&sb->s_umount); 556 + 557 + return ret; 558 + } 559 + 545 560 static void zloop_handle_cmd(struct zloop_cmd *cmd) 546 561 { 547 562 struct request *rq = blk_mq_rq_from_pdu(cmd); ··· 577 562 zloop_rw(cmd); 578 563 return; 579 564 case REQ_OP_FLUSH: 580 - /* 581 - * Sync the entire FS containing the zone files instead of 582 - * walking all files 583 - */ 584 - cmd->ret = sync_filesystem(file_inode(zlo->data_dir)->i_sb); 565 + cmd->ret = zloop_flush(zlo); 585 566 break; 586 567 case REQ_OP_ZONE_RESET: 587 568 cmd->ret = zloop_reset_zone(zlo, rq_zone_no(rq)); ··· 992 981 struct queue_limits lim = { 993 982 .max_hw_sectors = SZ_1M >> SECTOR_SHIFT, 994 983 .chunk_sectors = opts->zone_size, 995 - .features = BLK_FEAT_ZONED, 984 + .features = BLK_FEAT_ZONED | BLK_FEAT_WRITE_CACHE, 985 + 996 986 }; 997 987 unsigned int nr_zones, i, j; 998 988 struct zloop_device *zlo; ··· 1174 1162 int ret; 1175 1163 1176 1164 if (!(opts->mask & ZLOOP_OPT_ID)) { 1177 - pr_err("No ID specified\n"); 1165 + pr_err("No ID specified for remove\n"); 1166 + return -EINVAL; 1167 + } 1168 + 1169 + if (opts->mask & ~ZLOOP_OPT_ID) { 1170 + pr_err("Invalid option specified for remove\n"); 1178 1171 return -EINVAL; 1179 1172 } 1180 1173