UBI: Use the bit operation with min_io_size
Subsystems (2)
PATCH 1/1 UBI: Use the bit operation with min_io_size
It already checks the min io size is the power of 2 at io_init.
/* Make sure minimal I/O unit is power of 2 */
if (!is_power_of_2(ubi->min_io_size)) {
ubi_err("min. I/O unit (%d) is not power of 2",
ubi->min_io_size);
return -EINVAL;
}---
drivers/mtd/ubi/build.c +1 -1
@@ -581,7 +581,7 @@ static int io_init(struct ubi_device *ubi)if (ubi->vid_hdr_offset <UBI_EC_HDR_SIZE || ubi->leb_start < ubi->vid_hdr_offset +UBI_VID_HDR_SIZE || ubi->leb_start > ubi->peb_size -UBI_VID_HDR_SIZE || - ubi->leb_start % ubi->min_io_size) { + ubi->leb_start & (ubi->min_io_size -1 )) {ubi_err ("bad VID header (%d) or data offsets (%d)" , ubi->vid_hdr_offset, ubi->leb_start);return -EINVAL ;
drivers/mtd/ubi/cdev.c +3 -3
@@ -290,7 +290,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, off =do_div (tmp, vol->usable_leb_size); lnum = tmp; -if (off % ubi->min_io_size) { +if (off & (ubi->min_io_size -1 )) {dbg_err ("unaligned position" );return -EINVAL ; }
@@ -299,7 +299,7 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, count_save = count = vol->used_bytes - *offp;/* We can write only in fractions of the minimum I/O unit */ -if (count % ubi->min_io_size) { +if (count & (ubi->min_io_size -1 )) {dbg_err ("unaligned write length" );return -EINVAL ; }
@@ -559,7 +559,7 @@ static int verify_mkvol_req(const struct ubi_device *ubi,if (req->alignment > ubi->leb_size) goto bad; - n = req->alignment % ubi->min_io_size; + n = req->alignment & (ubi->min_io_size -1 );if (req->alignment !=1 && n) goto bad;
drivers/mtd/ubi/eba.c +1 -1
@@ -752,7 +752,7 @@ int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol,/* If this is the last LEB @len may be unaligned */ len =ALIGN (data_size, ubi->min_io_size); else - ubi_assert(len % ubi->min_io_size == 0); + ubi_assert(len & (ubi->min_io_size - 1) == 0); vid_hdr =ubi_zalloc_vid_hdr (ubi,GFP_NOFS );if (!vid_hdr)
drivers/mtd/ubi/kapi.c +3 -3
@@ -397,8 +397,8 @@ int ubi_leb_write(struct ubi_volume_desc *desc, int lnum, const void *buf,return -EROFS ;if (lnum <0 || lnum >= vol->reserved_pebs || offset <0 || len <0 || - offset + len > vol->usable_leb_size || offset % ubi->min_io_size || - len % ubi->min_io_size) + offset + len > vol->usable_leb_size || + offset & (ubi->min_io_size -1 ) || len & (ubi->min_io_size -1 ))return -EINVAL ; if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM &&
@@ -447,7 +447,7 @@ int ubi_leb_change(struct ubi_volume_desc *desc, int lnum, const void *buf,return -EROFS ;if (lnum <0 || lnum >= vol->reserved_pebs || len <0 || - len > vol->usable_leb_size || len % ubi->min_io_size) + len > vol->usable_leb_size || len & (ubi->min_io_size -1 ))return -EINVAL ; if (dtype != UBI_LONGTERM && dtype != UBI_SHORTTERM &&
drivers/mtd/ubi/misc.c +1 -1
@@ -37,7 +37,7 @@ int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf, {int i; -ubi_assert (length % ubi->min_io_size ==0 ); +ubi_assert (length & (ubi->min_io_size -1 ) ==0 );for (i = length -1 ; i >=0 ; i--)if (((const uint8_t *)buf)[i] !=0xFF )
drivers/mtd/ubi/vmt.c +1 -1
@@ -727,7 +727,7 @@ static void paranoid_check_volume(struct ubi_device *ubi, int vol_id) goto fail; } - n = vol->alignment % ubi->min_io_size; + n = vol->alignment & (ubi->min_io_size -1 );if (vol->alignment !=1 && n) {ubi_err ("alignment is not multiple of min I/O unit" ); goto fail;
drivers/mtd/ubi/vtbl.c +2 -3
@@ -170,7 +170,7 @@ static int vtbl_check(const struct ubi_device *ubi, goto bad; } - n = alignment % ubi->min_io_size; + n = alignment & (ubi->min_io_size -1 );if (alignment !=1 && n) {dbg_err ("alignment is not multiple of min I/O unit" ); goto bad;
@@ -672,14 +672,13 @@ static int check_scanning_info(const struct ubi_device *ubi,return -EINVAL ; } -if (si->highest_vol_id >= ubi->vtbl_slots +UBI_INT_VOL_COUNT && +if (si->highest_vol_id >= ubi->vtbl_slots +UBI_INT_VOL_COUNT && si->highest_vol_id <UBI_INTERNAL_VOL_START ) {ubi_err ("too large volume ID %d found by scanning" , si->highest_vol_id);return -EINVAL ; } -for (i =0 ; i < ubi->vtbl_slots +UBI_INT_VOL_COUNT ; i++) {cond_resched ();
drivers/mtd/ubi/wl.c +1 -2
@@ -1368,7 +1368,7 @@ int ubi_thread(void *u)int err;if (kthread_should_stop ()) - goto out; +break ;if (try_to_freeze ())continue ;
@@ -1403,7 +1403,6 @@ int ubi_thread(void *u)cond_resched (); } -out:dbg_wl ("background thread \"%s\" is killed" , ubi->bgt_name);return 0 ; }
Hi Kyungmin,
you patch looks OK to me and I'll apply it, but with few changes (see below).
Quoted 3 lines · Kyungmin Park
It already checks the min io size is the power of 2 at
io_init./* Make sure minimal I/O unit is power of 2 */
I will add a comment here that we do not have any fundamental reason to require this. It is just an optimization which makes it possible to avoid costly division operations.
drivers/mtd/ubi/cdev.c static int verify_mkvol_req(const struct ubi_device *ubi, · line 562
Quoted 1 line
drivers/mtd/ubi/cdev.c +1
-0+ n = req->alignment & (ubi->min_io_size -1 );
Probably we could introduce an ubi->min_io_mask variable even. But this is anyway a subject of a separate change.
drivers/mtd/ubi/eba.c int ubi_eba_write_leb_st(struct ubi_device *ubi, struct ubi_volume *vol, · line 755
Quoted 2 lines
drivers/mtd/ubi/eba.c +1
-1-ubi_assert (len % ubi->min_io_size ==0 ); +ubi_assert (len & (ubi->min_io_size -1 ) ==0 );
Bitwise & has smaller priority than ==, so I think this should be
ubi_assert((len & (ubi->min_io_size - 1)) == 0); or better ubi_assert(!(len & (ubi->min_io_size - 1)));
drivers/mtd/ubi/misc.c int ubi_calc_data_len(const struct ubi_device *ubi, const void *buf, · line 40
Quoted 2 lines
drivers/mtd/ubi/misc.c +1
-1-ubi_assert (length % ubi->min_io_size ==0 ); +ubi_assert (length & (ubi->min_io_size -1 ) ==0 );
Similar.
Thank you!
Signature · 2 lines
Best regards, Artem Bityutskiy (Битюцкий Артём)