Skip to content

Commit d301f16

Browse files
Zheng Qixingaxboe
authored andcommitted
badblocks: use sector_t instead of int to avoid truncation of badblocks length
There is a truncation of badblocks length issue when set badblocks as follow: echo "2055 4294967299" > bad_blocks cat bad_blocks 2055 3 Change 'sectors' argument type from 'int' to 'sector_t'. This change avoids truncation of badblocks length for large sectors by replacing 'int' with 'sector_t' (u64), enabling proper handling of larger disk sizes and ensuring compatibility with 64-bit sector addressing. Fixes: 9e0e252 ("badblocks: Add core badblock management code") Signed-off-by: Zheng Qixing <[email protected]> Reviewed-by: Yu Kuai <[email protected]> Acked-by: Coly Li <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent 7e5102d commit d301f16

File tree

10 files changed

+29
-33
lines changed

10 files changed

+29
-33
lines changed

block/badblocks.c

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -836,7 +836,7 @@ static bool try_adjacent_combine(struct badblocks *bb, int prev)
836836
}
837837

838838
/* Do exact work to set bad block range into the bad block table */
839-
static bool _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
839+
static bool _badblocks_set(struct badblocks *bb, sector_t s, sector_t sectors,
840840
int acknowledged)
841841
{
842842
int len = 0, added = 0;
@@ -956,8 +956,6 @@ static bool _badblocks_set(struct badblocks *bb, sector_t s, int sectors,
956956
if (sectors > 0)
957957
goto re_insert;
958958

959-
WARN_ON(sectors < 0);
960-
961959
/*
962960
* Check whether the following already set range can be
963961
* merged. (prev < 0) condition is not handled here,
@@ -1048,7 +1046,7 @@ static int front_splitting_clear(struct badblocks *bb, int prev,
10481046
}
10491047

10501048
/* Do the exact work to clear bad block range from the bad block table */
1051-
static bool _badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
1049+
static bool _badblocks_clear(struct badblocks *bb, sector_t s, sector_t sectors)
10521050
{
10531051
struct badblocks_context bad;
10541052
int prev = -1, hint = -1;
@@ -1171,8 +1169,6 @@ static bool _badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
11711169
if (sectors > 0)
11721170
goto re_clear;
11731171

1174-
WARN_ON(sectors < 0);
1175-
11761172
if (cleared) {
11771173
badblocks_update_acked(bb);
11781174
set_changed(bb);
@@ -1187,8 +1183,8 @@ static bool _badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
11871183
}
11881184

11891185
/* Do the exact work to check bad blocks range from the bad block table */
1190-
static int _badblocks_check(struct badblocks *bb, sector_t s, int sectors,
1191-
sector_t *first_bad, int *bad_sectors)
1186+
static int _badblocks_check(struct badblocks *bb, sector_t s, sector_t sectors,
1187+
sector_t *first_bad, sector_t *bad_sectors)
11921188
{
11931189
int prev = -1, hint = -1, set = 0;
11941190
struct badblocks_context bad;
@@ -1298,8 +1294,8 @@ static int _badblocks_check(struct badblocks *bb, sector_t s, int sectors,
12981294
* -1: there are bad blocks which have not yet been acknowledged in metadata.
12991295
* plus the start/length of the first bad section we overlap.
13001296
*/
1301-
int badblocks_check(struct badblocks *bb, sector_t s, int sectors,
1302-
sector_t *first_bad, int *bad_sectors)
1297+
int badblocks_check(struct badblocks *bb, sector_t s, sector_t sectors,
1298+
sector_t *first_bad, sector_t *bad_sectors)
13031299
{
13041300
unsigned int seq;
13051301
int rv;
@@ -1341,7 +1337,7 @@ EXPORT_SYMBOL_GPL(badblocks_check);
13411337
* false: failed to set badblocks (out of space). Parital setting will be
13421338
* treated as failure.
13431339
*/
1344-
bool badblocks_set(struct badblocks *bb, sector_t s, int sectors,
1340+
bool badblocks_set(struct badblocks *bb, sector_t s, sector_t sectors,
13451341
int acknowledged)
13461342
{
13471343
return _badblocks_set(bb, s, sectors, acknowledged);
@@ -1362,7 +1358,7 @@ EXPORT_SYMBOL_GPL(badblocks_set);
13621358
* true: success
13631359
* false: failed to clear badblocks
13641360
*/
1365-
bool badblocks_clear(struct badblocks *bb, sector_t s, int sectors)
1361+
bool badblocks_clear(struct badblocks *bb, sector_t s, sector_t sectors)
13661362
{
13671363
return _badblocks_clear(bb, s, sectors);
13681364
}

drivers/block/null_blk/main.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1339,8 +1339,7 @@ blk_status_t null_handle_badblocks(struct nullb_cmd *cmd, sector_t sector,
13391339
struct badblocks *bb = &cmd->nq->dev->badblocks;
13401340
struct nullb_device *dev = cmd->nq->dev;
13411341
unsigned int block_sectors = dev->blocksize >> SECTOR_SHIFT;
1342-
sector_t first_bad;
1343-
int bad_sectors;
1342+
sector_t first_bad, bad_sectors;
13441343
unsigned int partial_io_sectors = 0;
13451344

13461345
if (!badblocks_check(bb, sector, *nr_sectors, &first_bad, &bad_sectors))

drivers/md/md.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -266,8 +266,8 @@ enum flag_bits {
266266
Nonrot, /* non-rotational device (SSD) */
267267
};
268268

269-
static inline int is_badblock(struct md_rdev *rdev, sector_t s, int sectors,
270-
sector_t *first_bad, int *bad_sectors)
269+
static inline int is_badblock(struct md_rdev *rdev, sector_t s, sector_t sectors,
270+
sector_t *first_bad, sector_t *bad_sectors)
271271
{
272272
if (unlikely(rdev->badblocks.count)) {
273273
int rv = badblocks_check(&rdev->badblocks, rdev->data_offset + s,
@@ -284,7 +284,7 @@ static inline int rdev_has_badblock(struct md_rdev *rdev, sector_t s,
284284
int sectors)
285285
{
286286
sector_t first_bad;
287-
int bad_sectors;
287+
sector_t bad_sectors;
288288

289289
return is_badblock(rdev, s, sectors, &first_bad, &bad_sectors);
290290
}

drivers/md/raid1-10.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ static inline int raid1_check_read_range(struct md_rdev *rdev,
247247
sector_t this_sector, int *len)
248248
{
249249
sector_t first_bad;
250-
int bad_sectors;
250+
sector_t bad_sectors;
251251

252252
/* no bad block overlap */
253253
if (!is_badblock(rdev, this_sector, *len, &first_bad, &bad_sectors))

drivers/md/raid1.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,7 +1537,7 @@ static void raid1_write_request(struct mddev *mddev, struct bio *bio,
15371537
atomic_inc(&rdev->nr_pending);
15381538
if (test_bit(WriteErrorSeen, &rdev->flags)) {
15391539
sector_t first_bad;
1540-
int bad_sectors;
1540+
sector_t bad_sectors;
15411541
int is_bad;
15421542

15431543
is_bad = is_badblock(rdev, r1_bio->sector, max_sectors,
@@ -2886,7 +2886,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
28862886
} else {
28872887
/* may need to read from here */
28882888
sector_t first_bad = MaxSector;
2889-
int bad_sectors;
2889+
sector_t bad_sectors;
28902890

28912891
if (is_badblock(rdev, sector_nr, good_sectors,
28922892
&first_bad, &bad_sectors)) {

drivers/md/raid10.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -747,7 +747,7 @@ static struct md_rdev *read_balance(struct r10conf *conf,
747747

748748
for (slot = 0; slot < conf->copies ; slot++) {
749749
sector_t first_bad;
750-
int bad_sectors;
750+
sector_t bad_sectors;
751751
sector_t dev_sector;
752752
unsigned int pending;
753753
bool nonrot;
@@ -1438,7 +1438,7 @@ static void raid10_write_request(struct mddev *mddev, struct bio *bio,
14381438
if (rdev && test_bit(WriteErrorSeen, &rdev->flags)) {
14391439
sector_t first_bad;
14401440
sector_t dev_sector = r10_bio->devs[i].addr;
1441-
int bad_sectors;
1441+
sector_t bad_sectors;
14421442
int is_bad;
14431443

14441444
is_bad = is_badblock(rdev, dev_sector, max_sectors,
@@ -3413,7 +3413,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
34133413
sector_t from_addr, to_addr;
34143414
struct md_rdev *rdev = conf->mirrors[d].rdev;
34153415
sector_t sector, first_bad;
3416-
int bad_sectors;
3416+
sector_t bad_sectors;
34173417
if (!rdev ||
34183418
!test_bit(In_sync, &rdev->flags))
34193419
continue;
@@ -3609,7 +3609,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,
36093609
for (i = 0; i < conf->copies; i++) {
36103610
int d = r10_bio->devs[i].devnum;
36113611
sector_t first_bad, sector;
3612-
int bad_sectors;
3612+
sector_t bad_sectors;
36133613
struct md_rdev *rdev;
36143614

36153615
if (r10_bio->devs[i].repl_bio)

drivers/nvdimm/nd.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ static inline bool is_bad_pmem(struct badblocks *bb, sector_t sector,
673673
{
674674
if (bb->count) {
675675
sector_t first_bad;
676-
int num_bad;
676+
sector_t num_bad;
677677

678678
return !!badblocks_check(bb, sector, len / 512, &first_bad,
679679
&num_bad);

drivers/nvdimm/pfn_devs.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -367,9 +367,10 @@ static int nd_pfn_clear_memmap_errors(struct nd_pfn *nd_pfn)
367367
struct nd_namespace_common *ndns = nd_pfn->ndns;
368368
void *zero_page = page_address(ZERO_PAGE(0));
369369
struct nd_pfn_sb *pfn_sb = nd_pfn->pfn_sb;
370-
int num_bad, meta_num, rc, bb_present;
370+
int meta_num, rc, bb_present;
371371
sector_t first_bad, meta_start;
372372
struct nd_namespace_io *nsio;
373+
sector_t num_bad;
373374

374375
if (nd_pfn->mode != PFN_MODE_PMEM)
375376
return 0;
@@ -394,7 +395,7 @@ static int nd_pfn_clear_memmap_errors(struct nd_pfn *nd_pfn)
394395
bb_present = badblocks_check(&nd_region->bb, meta_start,
395396
meta_num, &first_bad, &num_bad);
396397
if (bb_present) {
397-
dev_dbg(&nd_pfn->dev, "meta: %x badblocks at %llx\n",
398+
dev_dbg(&nd_pfn->dev, "meta: %llx badblocks at %llx\n",
398399
num_bad, first_bad);
399400
nsoff = ALIGN_DOWN((nd_region->ndr_start
400401
+ (first_bad << 9)) - nsio->res.start,
@@ -413,7 +414,7 @@ static int nd_pfn_clear_memmap_errors(struct nd_pfn *nd_pfn)
413414
}
414415
if (rc) {
415416
dev_err(&nd_pfn->dev,
416-
"error clearing %x badblocks at %llx\n",
417+
"error clearing %llx badblocks at %llx\n",
417418
num_bad, first_bad);
418419
return rc;
419420
}

drivers/nvdimm/pmem.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,7 +249,7 @@ __weak long __pmem_direct_access(struct pmem_device *pmem, pgoff_t pgoff,
249249
unsigned int num = PFN_PHYS(nr_pages) >> SECTOR_SHIFT;
250250
struct badblocks *bb = &pmem->bb;
251251
sector_t first_bad;
252-
int num_bad;
252+
sector_t num_bad;
253253

254254
if (kaddr)
255255
*kaddr = pmem->virt_addr + offset;

include/linux/badblocks.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ struct badblocks_context {
4848
int ack;
4949
};
5050

51-
int badblocks_check(struct badblocks *bb, sector_t s, int sectors,
52-
sector_t *first_bad, int *bad_sectors);
53-
bool badblocks_set(struct badblocks *bb, sector_t s, int sectors,
51+
int badblocks_check(struct badblocks *bb, sector_t s, sector_t sectors,
52+
sector_t *first_bad, sector_t *bad_sectors);
53+
bool badblocks_set(struct badblocks *bb, sector_t s, sector_t sectors,
5454
int acknowledged);
55-
bool badblocks_clear(struct badblocks *bb, sector_t s, int sectors);
55+
bool badblocks_clear(struct badblocks *bb, sector_t s, sector_t sectors);
5656
void ack_all_badblocks(struct badblocks *bb);
5757
ssize_t badblocks_show(struct badblocks *bb, char *page, int unack);
5858
ssize_t badblocks_store(struct badblocks *bb, const char *page, size_t len,

0 commit comments

Comments
 (0)