fs/ext4/ext4fs.c, fs/fs.c fs/fat/fat_write.c: Adjust 64bit math methods
Subsystems (3)
PATCH v2 1/1 fs/ext4/ext4fs.c, fs/fs.c fs/fat/fat_write.c: Adjust 64bit math methods
The changes to introduce loff_t into filesize means that we need to do 64bit math on 32bit platforms. Make sure we use the right wrappers for these operations.
--- fs/ext4/ext4fs.c | 11 ++++++----- fs/fat/fat_write.c | 10 ++++++---- fs/fs.c | 6 ++++-- 3 files changed, 16 insertions(+), 11 deletions(-)
fs/ext4/ext4fs.c +6 -5
@@ -25,6 +25,7 @@#include <ext_common.h> #include <ext4fs.h> #include "ext4_common.h" +#include <div64.h> int ext4fs_symlinknest;struct ext_filesystem ext_fs;
@@ -67,11 +68,11 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos,if (len > filesize) len = filesize; - blockcnt = ((len + pos) + blocksize -1 ) / blocksize; + blockcnt =lldiv (((len + pos) + blocksize -1 ), blocksize); -for (i = pos / blocksize; i < blockcnt; i++) { +for (i =lldiv (pos, blocksize); i < blockcnt; i++) {lbaint_t blknr; -int blockoff = pos % blocksize; +int blockoff = pos - (blocksize * i);int blockend = blocksize;int skipfirst =0 ; blknr =read_allocated_block (&(node->inode), i);
@@ -82,7 +83,7 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos,/* Last block. */ if (i == blockcnt -1 ) { - blockend = (len + pos) % blocksize; + blockend = (len + pos) - (blocksize * i);/* The last portion is exactly blocksize. */ if (!blockend)
@@ -90,7 +91,7 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos, }/* First block. */ -if (i == pos / blocksize) { +if (i ==lldiv (pos, blocksize)) { skipfirst = blockoff; blockend -= skipfirst; }
fs/fat/fat_write.c +6 -4
@@ -13,6 +13,8 @@#include <asm/byteorder.h> #include <part.h> #include <linux/ctype.h> +#include <div64.h> +#include <linux/math64.h> #include "fat.c" static void uppercase (char *str,int len)
@@ -770,7 +772,7 @@ static void fill_dentry(fsdata *mydata, dir_entry *dentptr,*/ static int check_overflow (fsdata *mydata,__u32 clustnum,loff_t size) { -__u32 startsect, sect_num; +__u32 startsect, sect_num, offset;if (clustnum >0 ) { startsect = mydata->data_begin +
@@ -779,13 +781,13 @@ static int check_overflow(fsdata *mydata, __u32 clustnum, loff_t size) startsect = mydata->rootdir_sect; } - sect_num = size / mydata->sect_size; -if (size % mydata->sect_size) + sect_num =div_u64_rem (size, mydata->sect_size, &offset); + +if (offset !=0 ) sect_num++;if (startsect + sect_num > cur_part_info.start + total_sector)return -1 ; -return 0 ; }
fs/fs.c +4 -2
@@ -23,6 +23,8 @@#include <fs.h> #include <sandboxfs.h> #include <asm/io.h> +#include <div64.h> +#include <linux/math64.h> DECLARE_GLOBAL_DATA_PTR ;
@@ -399,7 +401,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],printf ("%llu bytes read in %lu ms" , len_read, time);if (time >0 ) {puts (" (" ); -print_size (len_read / time *1000 ,"/s" ); +print_size (div_u64 (len_read, time *1000 ),"/s" );puts (")" ); }puts ("\n" );
@@ -469,7 +471,7 @@ int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],printf ("%llu bytes written in %lu ms" , len, time);if (time >0 ) {puts (" (" ); -print_size (len / time *1000 ,"/s" ); +print_size (div_u64 (len, time *1000 ),"/s" );puts (")" ); }puts ("\n" );
Signature · 1 line
1.7.9.5
PATCH v2 1/1 fs/ext4/ext4fs.c, fs/fs.c fs/fat/fat_write.c: Adjust 64bit math methods
Hi Tom,
Quoted 8 lines · Tom Rini
The changes to introduce
loff_tinto filesize means that we need to do 64bit math on 32bit platforms. Make sure we use the right wrappers for these operations.Cc Daniel Schwierzeck <[email protected]>Cc Suriyan Ramasami <[email protected]>Cc Simon Glass <[email protected]>Signed-off-by Tom Rini <[email protected]>
This fixes things for me, thanks! But please see below.
Quoted 34 lines
--- fs/ext4/ext4fs.c | 11 ++++++----- fs/fat/fat_write.c | 10 ++++++---- fs/fs.c | 6 ++++-- 3 files changed, 16 insertions(+), 11 deletions(-)fs/ext4/ext4fs.c +4
-3@@ -25,6 +25,7 @@#include <ext_common.h> #include <ext4fs.h> #include "ext4_common.h" +#include <div64.h> int ext4fs_symlinknest;struct ext_filesystem ext_fs;@@ -67,11 +68,11 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos,if (len > filesize) len = filesize; - blockcnt = ((len + pos) + blocksize -1 ) / blocksize; + blockcnt =lldiv (((len + pos) + blocksize -1 ), blocksize); -for (i = pos / blocksize; i < blockcnt; i++) { +for (i =lldiv (pos, blocksize); i < blockcnt; i++) {lbaint_t blknr; -int blockoff = pos % blocksize; +int blockoff = pos - (blocksize * i);int blockend = blocksize;int skipfirst =0 ; blknr =read_allocated_block (&(node->inode), i);
fs/ext4/ext4fs.c int ext4fs_read_file(struct ext2fs_node *node, loff_t pos, · line 86
Quoted 5 lines
fs/ext4/ext4fs.c +1
-1@@ -82,7 +83,7 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos,/* Last block. */ if (i == blockcnt -1 ) { - blockend = (len + pos) % blocksize; + blockend = (len + pos) - (blocksize * i);
Actually do you think it would be clearer to use div_u64_rem() here?
Quoted 65 lines
fs/ext4/ext4fs.c +1
-1/* The last portion is exactly blocksize. */ if (!blockend)@@ -90,7 +91,7 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos, }/* First block. */ -if (i == pos / blocksize) { +if (i ==lldiv (pos, blocksize)) { skipfirst = blockoff; blockend -= skipfirst; }fs/fat/fat_write.c +6
-4@@ -13,6 +13,8 @@#include <asm/byteorder.h> #include <part.h> #include <linux/ctype.h> +#include <div64.h> +#include <linux/math64.h> #include "fat.c" static void uppercase (char *str,int len)@@ -770,7 +772,7 @@ static void fill_dentry(fsdata *mydata, dir_entry *dentptr,*/ static int check_overflow (fsdata *mydata,__u32 clustnum,loff_t size) { -__u32 startsect, sect_num; +__u32 startsect, sect_num, offset;if (clustnum >0 ) { startsect = mydata->data_begin +@@ -779,13 +781,13 @@ static int check_overflow(fsdata *mydata, __u32 clustnum, loff_t size) startsect = mydata->rootdir_sect; } - sect_num = size / mydata->sect_size; -if (size % mydata->sect_size) + sect_num =div_u64_rem (size, mydata->sect_size, &offset); + +if (offset !=0 ) sect_num++;if (startsect + sect_num > cur_part_info.start + total_sector)return -1 ; -return 0 ; }fs/fs.c +2
-0@@ -23,6 +23,8 @@#include <fs.h> #include <sandboxfs.h> #include <asm/io.h> +#include <div64.h> +#include <linux/math64.h> DECLARE_GLOBAL_DATA_PTR ;
fs/fs.c int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], · line 404
Quoted 5 lines
fs/fs.c +1
-1@@ -399,7 +401,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],printf ("%llu bytes read in %lu ms" , len_read, time);if (time >0 ) {puts (" (" ); -print_size (len_read / time *1000 ,"/s" ); +print_size (div_u64 (len_read, time *1000 ),"/s" );
The old code multiplies by 1000 but the new code divides. I think it should be:
print_size(div_u64(len_read, time) * 1000, "/s");
fs/fs.c int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], · line 474
Quoted 9 lines
fs/fs.c +1
-1puts (")" ); }puts ("\n" );@@ -469,7 +471,7 @@ int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],printf ("%llu bytes written in %lu ms" , len, time);if (time >0 ) {puts (" (" ); -print_size (len / time *1000 ,"/s" ); +print_size (div_u64 (len, time *1000 ),"/s" );
and here.
Quoted 6 lines
fs/fs.c +0
-1puts (")" ); }puts ("\n" ); --1.7.9.5
Regards,
Simon
PATCH v2 1/1 fs/ext4/ext4fs.c, fs/fs.c fs/fat/fat_write.c: Adjust 64bit math methods
Quoted 49 lines · Simon Glass
Hi Tom,
Quoted 8 lines · Tom Rini
The changes to introduce
loff_tinto filesize means that we need to do 64bit math on 32bit platforms. Make sure we use the right wrappers for these operations.Cc Daniel Schwierzeck <[email protected]>Cc Suriyan Ramasami <[email protected]>Cc Simon Glass <[email protected]>Signed-off-by Tom Rini <[email protected]>This fixes things for me, thanks! But please see below.
Quoted 35 lines
--- fs/ext4/ext4fs.c | 11 ++++++----- fs/fat/fat_write.c | 10 ++++++---- fs/fs.c | 6 ++++-- 3 files changed, 16 insertions(+), 11 deletions(-)fs/ext4/ext4fs.c +4
-3@@ -25,6 +25,7 @@#include <ext_common.h> #include <ext4fs.h> #include "ext4_common.h" +#include <div64.h> int ext4fs_symlinknest;struct ext_filesystem ext_fs;@@ -67,11 +68,11 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos,if (len > filesize) len = filesize; - blockcnt = ((len + pos) + blocksize -1 ) / blocksize; + blockcnt =lldiv (((len + pos) + blocksize -1 ), blocksize); -for (i = pos / blocksize; i < blockcnt; i++) { +for (i =lldiv (pos, blocksize); i < blockcnt; i++) {lbaint_t blknr; -int blockoff = pos % blocksize; +int blockoff = pos - (blocksize * i);int blockend = blocksize;int skipfirst =0 ; blknr =read_allocated_block (&(node->inode), i);@@ -82,7 +83,7 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos,
Quoted 6 lines
fs/ext4/ext4fs.c int ext4fs_read_file(struct ext2fs_node *node, loff_t pos, · line 86
Quoted 4 lines
fs/ext4/ext4fs.c +1
-1/* Last block. */ if (i == blockcnt -1 ) { - blockend = (len + pos) % blocksize; + blockend = (len + pos) - (blocksize * i);Actually do you think it would be clearer to use
div_u64_rem()here?
I don't think so only since we don't care about the quotient only the remainder. In the FAT case we needed both (and that's what got me seeing the <linux/math64.h> functions.
Quoted 76 lines
Quoted 66 lines
fs/ext4/ext4fs.c +1
-1/* The last portion is exactly blocksize. */ if (!blockend)@@ -90,7 +91,7 @@ int ext4fs_read_file(struct ext2fs_node *node, loff_t pos, }/* First block. */ -if (i == pos / blocksize) { +if (i ==lldiv (pos, blocksize)) { skipfirst = blockoff; blockend -= skipfirst; }fs/fat/fat_write.c +6
-4@@ -13,6 +13,8 @@#include <asm/byteorder.h> #include <part.h> #include <linux/ctype.h> +#include <div64.h> +#include <linux/math64.h> #include "fat.c" static void uppercase (char *str,int len)@@ -770,7 +772,7 @@ static void fill_dentry(fsdata *mydata, dir_entry *dentptr,*/ static int check_overflow (fsdata *mydata,__u32 clustnum,loff_t size) { -__u32 startsect, sect_num; +__u32 startsect, sect_num, offset;if (clustnum >0 ) { startsect = mydata->data_begin +@@ -779,13 +781,13 @@ static int check_overflow(fsdata *mydata, __u32 clustnum, loff_t size) startsect = mydata->rootdir_sect; } - sect_num = size / mydata->sect_size; -if (size % mydata->sect_size) + sect_num =div_u64_rem (size, mydata->sect_size, &offset); + +if (offset !=0 ) sect_num++;if (startsect + sect_num > cur_part_info.start + total_sector)return -1 ; -return 0 ; }fs/fs.c +2
-0@@ -23,6 +23,8 @@#include <fs.h> #include <sandboxfs.h> #include <asm/io.h> +#include <div64.h> +#include <linux/math64.h> DECLARE_GLOBAL_DATA_PTR ;fs/fs.c int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], · line 404
Quoted 5 lines
fs/fs.c +1
-1@@ -399,7 +401,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],printf ("%llu bytes read in %lu ms" , len_read, time);if (time >0 ) {puts (" (" ); -print_size (len_read / time *1000 ,"/s" ); +print_size (div_u64 (len_read, time *1000 ),"/s" );The old code multiplies by 1000 but the new code divides. I think it should be:
print_size(div_u64(len_read, time) * 1000, "/s");
Quoted 11 lines
fs/fs.c int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], · line 474
Quoted 9 lines
fs/fs.c +1
-1puts (")" ); }puts ("\n" );@@ -469,7 +471,7 @@ int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],printf ("%llu bytes written in %lu ms" , len, time);if (time >0 ) {puts (" (" ); -print_size (len / time *1000 ,"/s" ); +print_size (div_u64 (len, time *1000 ),"/s" );and here.
Whoops, those are bugs, fixed.
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20141126/f826bfad/attachment.pgp>