[PATCH v2] mtd: Fix mtdblock for >4GB MTD devices
Change to use loff_t instead of unsigned long in some functions to make sure mtdblock can handle offset bigger than 4G in 32 bits mode. Signed-off-by: Lepton Wu <ytht@gmail.com> --- Changes in v2: - Make the commit message more clearer and fix some format issues. drivers/mtd/mtdblock.c| 35 ++- drivers/mtd/mtdblock_ro.c | 4 ++-- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c index bb4c14f83c75..373c0edca803 100644 --- a/drivers/mtd/mtdblock.c +++ b/drivers/mtd/mtdblock.c @@ -61,8 +61,8 @@ static void erase_callback(struct erase_info *done) wake_up(wait_q); } -static int erase_write (struct mtd_info *mtd, unsigned long pos, - int len, const char *buf) +static int erase_write(struct mtd_info *mtd, loff_t pos, int len, + const char *buf) { struct erase_info erase; DECLARE_WAITQUEUE(wait, current); @@ -88,8 +88,7 @@ static int erase_write (struct mtd_info *mtd, unsigned long pos, if (ret) { set_current_state(TASK_RUNNING); remove_wait_queue(_q, ); - printk (KERN_WARNING "mtdblock: erase of region [0x%lx, 0x%x] " -"on \"%s\" failed\n", + pr_warn("mtdblock: erase of region [0x%llx, 0x%x] on \"%s\" failed\n", pos, len, mtd->name); return ret; } @@ -139,23 +138,24 @@ static int write_cached_data (struct mtdblk_dev *mtdblk) } -static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, - int len, const char *buf) +static int do_cached_write(struct mtdblk_dev *mtdblk, loff_t pos, + int len, const char *buf) { struct mtd_info *mtd = mtdblk->mbd.mtd; unsigned int sect_size = mtdblk->cache_size; size_t retlen; int ret; - pr_debug("mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n", + pr_debug("mtdblock: write on \"%s\" at 0x%llx, size 0x%x\n", mtd->name, pos, len); if (!sect_size) return mtd_write(mtd, pos, len, , buf); while (len > 0) { - unsigned long sect_start = (pos/sect_size)*sect_size; - unsigned int offset = pos - sect_start; + unsigned int offset; + loff_t sect_start = + div_u64_rem(pos, sect_size, ) * sect_size; unsigned int size = sect_size - offset; if( size > len ) size = len; @@ -209,23 +209,24 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, } -static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, - int len, char *buf) +static int do_cached_read(struct mtdblk_dev *mtdblk, loff_t pos, + int len, char *buf) { struct mtd_info *mtd = mtdblk->mbd.mtd; unsigned int sect_size = mtdblk->cache_size; size_t retlen; int ret; - pr_debug("mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n", - mtd->name, pos, len); + pr_debug("mtdblock: read on \"%s\" at 0x%llx, size 0x%x\n", +mtd->name, pos, len); if (!sect_size) return mtd_read(mtd, pos, len, , buf); while (len > 0) { - unsigned long sect_start = (pos/sect_size)*sect_size; - unsigned int offset = pos - sect_start; + unsigned int offset; + loff_t sect_start = + div_u64_rem(pos, sect_size, ) * sect_size; unsigned int size = sect_size - offset; if (size > len) size = len; @@ -259,7 +260,7 @@ static int mtdblock_readsect(struct mtd_blktrans_dev *dev, unsigned long block, char *buf) { struct mtdblk_dev *mtdblk = container_of(dev, struct mtdblk_dev, mbd); - return do_cached_read(mtdblk, block<<9, 512, buf); + return do_cached_read(mtdblk, (loff_t)block << 9, 512, buf); } static int mtdblock_writesect(struct mtd_blktrans_dev *dev, @@ -275,7 +276,7 @@ static int mtdblock_writesect(struct mtd_blktrans_dev *dev, * return -EAGAIN sometimes, but why bother? */ } - return do_cached_write(mtdblk, block<<9, 512, buf); + return do_cached_write(mtdblk, (loff_t)block << 9, 512, buf); } static int mtdblock_open(struct mtd_blktrans_dev *mbd) diff --git a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c index fb5dc89369de..92829e3fb3b7 100644 --- a/drivers/mtd/mtdblock_ro.c +++ b/drivers/mtd/mtdblock_ro
[PATCH v2] mtd: Fix mtdblock for >4GB MTD devices
Change to use loff_t instead of unsigned long in some functions to make sure mtdblock can handle offset bigger than 4G in 32 bits mode. Signed-off-by: Lepton Wu --- Changes in v2: - Make the commit message more clearer and fix some format issues. drivers/mtd/mtdblock.c| 35 ++- drivers/mtd/mtdblock_ro.c | 4 ++-- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c index bb4c14f83c75..373c0edca803 100644 --- a/drivers/mtd/mtdblock.c +++ b/drivers/mtd/mtdblock.c @@ -61,8 +61,8 @@ static void erase_callback(struct erase_info *done) wake_up(wait_q); } -static int erase_write (struct mtd_info *mtd, unsigned long pos, - int len, const char *buf) +static int erase_write(struct mtd_info *mtd, loff_t pos, int len, + const char *buf) { struct erase_info erase; DECLARE_WAITQUEUE(wait, current); @@ -88,8 +88,7 @@ static int erase_write (struct mtd_info *mtd, unsigned long pos, if (ret) { set_current_state(TASK_RUNNING); remove_wait_queue(_q, ); - printk (KERN_WARNING "mtdblock: erase of region [0x%lx, 0x%x] " -"on \"%s\" failed\n", + pr_warn("mtdblock: erase of region [0x%llx, 0x%x] on \"%s\" failed\n", pos, len, mtd->name); return ret; } @@ -139,23 +138,24 @@ static int write_cached_data (struct mtdblk_dev *mtdblk) } -static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, - int len, const char *buf) +static int do_cached_write(struct mtdblk_dev *mtdblk, loff_t pos, + int len, const char *buf) { struct mtd_info *mtd = mtdblk->mbd.mtd; unsigned int sect_size = mtdblk->cache_size; size_t retlen; int ret; - pr_debug("mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n", + pr_debug("mtdblock: write on \"%s\" at 0x%llx, size 0x%x\n", mtd->name, pos, len); if (!sect_size) return mtd_write(mtd, pos, len, , buf); while (len > 0) { - unsigned long sect_start = (pos/sect_size)*sect_size; - unsigned int offset = pos - sect_start; + unsigned int offset; + loff_t sect_start = + div_u64_rem(pos, sect_size, ) * sect_size; unsigned int size = sect_size - offset; if( size > len ) size = len; @@ -209,23 +209,24 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, } -static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, - int len, char *buf) +static int do_cached_read(struct mtdblk_dev *mtdblk, loff_t pos, + int len, char *buf) { struct mtd_info *mtd = mtdblk->mbd.mtd; unsigned int sect_size = mtdblk->cache_size; size_t retlen; int ret; - pr_debug("mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n", - mtd->name, pos, len); + pr_debug("mtdblock: read on \"%s\" at 0x%llx, size 0x%x\n", +mtd->name, pos, len); if (!sect_size) return mtd_read(mtd, pos, len, , buf); while (len > 0) { - unsigned long sect_start = (pos/sect_size)*sect_size; - unsigned int offset = pos - sect_start; + unsigned int offset; + loff_t sect_start = + div_u64_rem(pos, sect_size, ) * sect_size; unsigned int size = sect_size - offset; if (size > len) size = len; @@ -259,7 +260,7 @@ static int mtdblock_readsect(struct mtd_blktrans_dev *dev, unsigned long block, char *buf) { struct mtdblk_dev *mtdblk = container_of(dev, struct mtdblk_dev, mbd); - return do_cached_read(mtdblk, block<<9, 512, buf); + return do_cached_read(mtdblk, (loff_t)block << 9, 512, buf); } static int mtdblock_writesect(struct mtd_blktrans_dev *dev, @@ -275,7 +276,7 @@ static int mtdblock_writesect(struct mtd_blktrans_dev *dev, * return -EAGAIN sometimes, but why bother? */ } - return do_cached_write(mtdblk, block<<9, 512, buf); + return do_cached_write(mtdblk, (loff_t)block << 9, 512, buf); } static int mtdblock_open(struct mtd_blktrans_dev *mbd) diff --git a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c index fb5dc89369de..92829e3fb3b7 100644 --- a/drivers/mtd/mtdblock_ro.c +++ b/drivers/mtd/mtdblock_ro.c @@ -31,7 +31,7 @@ stati
[PATCH] Make mtdblock can handle partition bigger than 4G.
Signed-off-by: Lepton Wu <ytht@gmail.com> --- drivers/mtd/mtdblock.c| 33 + drivers/mtd/mtdblock_ro.c | 4 ++-- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c index bb4c14f83c75..3d2da76287a7 100644 --- a/drivers/mtd/mtdblock.c +++ b/drivers/mtd/mtdblock.c @@ -61,8 +61,8 @@ static void erase_callback(struct erase_info *done) wake_up(wait_q); } -static int erase_write (struct mtd_info *mtd, unsigned long pos, - int len, const char *buf) +static int erase_write(struct mtd_info *mtd, loff_t pos, int len, + const char *buf) { struct erase_info erase; DECLARE_WAITQUEUE(wait, current); @@ -88,8 +88,7 @@ static int erase_write (struct mtd_info *mtd, unsigned long pos, if (ret) { set_current_state(TASK_RUNNING); remove_wait_queue(_q, ); - printk (KERN_WARNING "mtdblock: erase of region [0x%lx, 0x%x] " -"on \"%s\" failed\n", + pr_warn("mtdblock: erase of region [0x%llx, 0x%x] on \"%s\" failed\n", pos, len, mtd->name); return ret; } @@ -139,23 +138,24 @@ static int write_cached_data (struct mtdblk_dev *mtdblk) } -static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, - int len, const char *buf) +static int do_cached_write(struct mtdblk_dev *mtdblk, loff_t pos, + int len, const char *buf) { struct mtd_info *mtd = mtdblk->mbd.mtd; unsigned int sect_size = mtdblk->cache_size; size_t retlen; int ret; - pr_debug("mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n", + pr_debug("mtdblock: write on \"%s\" at 0x%llx, size 0x%x\n", mtd->name, pos, len); if (!sect_size) return mtd_write(mtd, pos, len, , buf); while (len > 0) { - unsigned long sect_start = (pos/sect_size)*sect_size; - unsigned int offset = pos - sect_start; + unsigned int offset; + loff_t sect_start = + div_u64_rem(pos, sect_size, ) * sect_size; unsigned int size = sect_size - offset; if( size > len ) size = len; @@ -209,23 +209,24 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, } -static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, - int len, char *buf) +static int do_cached_read(struct mtdblk_dev *mtdblk, loff_t pos, + int len, char *buf) { struct mtd_info *mtd = mtdblk->mbd.mtd; unsigned int sect_size = mtdblk->cache_size; size_t retlen; int ret; - pr_debug("mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n", + pr_debug("mtdblock: read on \"%s\" at 0x%llx, size 0x%x\n", mtd->name, pos, len); if (!sect_size) return mtd_read(mtd, pos, len, , buf); while (len > 0) { - unsigned long sect_start = (pos/sect_size)*sect_size; - unsigned int offset = pos - sect_start; + unsigned int offset; + loff_t sect_start = + div_u64_rem(pos, sect_size, ) * sect_size; unsigned int size = sect_size - offset; if (size > len) size = len; @@ -259,7 +260,7 @@ static int mtdblock_readsect(struct mtd_blktrans_dev *dev, unsigned long block, char *buf) { struct mtdblk_dev *mtdblk = container_of(dev, struct mtdblk_dev, mbd); - return do_cached_read(mtdblk, block<<9, 512, buf); + return do_cached_read(mtdblk, (loff_t)block<<9, 512, buf); } static int mtdblock_writesect(struct mtd_blktrans_dev *dev, @@ -275,7 +276,7 @@ static int mtdblock_writesect(struct mtd_blktrans_dev *dev, * return -EAGAIN sometimes, but why bother? */ } - return do_cached_write(mtdblk, block<<9, 512, buf); + return do_cached_write(mtdblk, (loff_t)block<<9, 512, buf); } static int mtdblock_open(struct mtd_blktrans_dev *mbd) diff --git a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c index fb5dc89369de..92829e3fb3b7 100644 --- a/drivers/mtd/mtdblock_ro.c +++ b/drivers/mtd/mtdblock_ro.c @@ -31,7 +31,7 @@ static int mtdblock_readsect(struct mtd_blktrans_dev *dev, { size_t retlen; - if (mtd_read(dev->mtd, (block * 512), 512, , buf)) + if (mtd_read(dev->mtd, (loff_t)block << 9, 512, , buf)) return 1;
[PATCH] Make mtdblock can handle partition bigger than 4G.
Signed-off-by: Lepton Wu --- drivers/mtd/mtdblock.c| 33 + drivers/mtd/mtdblock_ro.c | 4 ++-- 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/drivers/mtd/mtdblock.c b/drivers/mtd/mtdblock.c index bb4c14f83c75..3d2da76287a7 100644 --- a/drivers/mtd/mtdblock.c +++ b/drivers/mtd/mtdblock.c @@ -61,8 +61,8 @@ static void erase_callback(struct erase_info *done) wake_up(wait_q); } -static int erase_write (struct mtd_info *mtd, unsigned long pos, - int len, const char *buf) +static int erase_write(struct mtd_info *mtd, loff_t pos, int len, + const char *buf) { struct erase_info erase; DECLARE_WAITQUEUE(wait, current); @@ -88,8 +88,7 @@ static int erase_write (struct mtd_info *mtd, unsigned long pos, if (ret) { set_current_state(TASK_RUNNING); remove_wait_queue(_q, ); - printk (KERN_WARNING "mtdblock: erase of region [0x%lx, 0x%x] " -"on \"%s\" failed\n", + pr_warn("mtdblock: erase of region [0x%llx, 0x%x] on \"%s\" failed\n", pos, len, mtd->name); return ret; } @@ -139,23 +138,24 @@ static int write_cached_data (struct mtdblk_dev *mtdblk) } -static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, - int len, const char *buf) +static int do_cached_write(struct mtdblk_dev *mtdblk, loff_t pos, + int len, const char *buf) { struct mtd_info *mtd = mtdblk->mbd.mtd; unsigned int sect_size = mtdblk->cache_size; size_t retlen; int ret; - pr_debug("mtdblock: write on \"%s\" at 0x%lx, size 0x%x\n", + pr_debug("mtdblock: write on \"%s\" at 0x%llx, size 0x%x\n", mtd->name, pos, len); if (!sect_size) return mtd_write(mtd, pos, len, , buf); while (len > 0) { - unsigned long sect_start = (pos/sect_size)*sect_size; - unsigned int offset = pos - sect_start; + unsigned int offset; + loff_t sect_start = + div_u64_rem(pos, sect_size, ) * sect_size; unsigned int size = sect_size - offset; if( size > len ) size = len; @@ -209,23 +209,24 @@ static int do_cached_write (struct mtdblk_dev *mtdblk, unsigned long pos, } -static int do_cached_read (struct mtdblk_dev *mtdblk, unsigned long pos, - int len, char *buf) +static int do_cached_read(struct mtdblk_dev *mtdblk, loff_t pos, + int len, char *buf) { struct mtd_info *mtd = mtdblk->mbd.mtd; unsigned int sect_size = mtdblk->cache_size; size_t retlen; int ret; - pr_debug("mtdblock: read on \"%s\" at 0x%lx, size 0x%x\n", + pr_debug("mtdblock: read on \"%s\" at 0x%llx, size 0x%x\n", mtd->name, pos, len); if (!sect_size) return mtd_read(mtd, pos, len, , buf); while (len > 0) { - unsigned long sect_start = (pos/sect_size)*sect_size; - unsigned int offset = pos - sect_start; + unsigned int offset; + loff_t sect_start = + div_u64_rem(pos, sect_size, ) * sect_size; unsigned int size = sect_size - offset; if (size > len) size = len; @@ -259,7 +260,7 @@ static int mtdblock_readsect(struct mtd_blktrans_dev *dev, unsigned long block, char *buf) { struct mtdblk_dev *mtdblk = container_of(dev, struct mtdblk_dev, mbd); - return do_cached_read(mtdblk, block<<9, 512, buf); + return do_cached_read(mtdblk, (loff_t)block<<9, 512, buf); } static int mtdblock_writesect(struct mtd_blktrans_dev *dev, @@ -275,7 +276,7 @@ static int mtdblock_writesect(struct mtd_blktrans_dev *dev, * return -EAGAIN sometimes, but why bother? */ } - return do_cached_write(mtdblk, block<<9, 512, buf); + return do_cached_write(mtdblk, (loff_t)block<<9, 512, buf); } static int mtdblock_open(struct mtd_blktrans_dev *mbd) diff --git a/drivers/mtd/mtdblock_ro.c b/drivers/mtd/mtdblock_ro.c index fb5dc89369de..92829e3fb3b7 100644 --- a/drivers/mtd/mtdblock_ro.c +++ b/drivers/mtd/mtdblock_ro.c @@ -31,7 +31,7 @@ static int mtdblock_readsect(struct mtd_blktrans_dev *dev, { size_t retlen; - if (mtd_read(dev->mtd, (block * 512), 512, , buf)) + if (mtd_read(dev->mtd, (loff_t)block << 9, 512, , buf)) return 1; return 0; } @@ -41