summaryrefslogtreecommitdiff
path: root/lib
AgeCommit message (Collapse)Author
2018-08-23axmap: return early of an overlap results in 0 settable bitsJens Axboe
Reported-by: Bart Van Assche <bart.vanassche@wdc.com> Fixes: 15a4f49 ("lib/axmap: Simplify axmap_set_fn()") Signed-off-by: Jens Axboe <axboe@kernel.dk>
2018-08-22lib/axmap: Optimize __axmap_set()Bart Van Assche
Since it is guaranteed that nr_bits <= BLOCKS_PER_UNIT and since axmap_set_fn() needs to be called only once to set that number of bits, remove the loop from __axmap_set(). Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
2018-08-22lib/axmap: Simplify axmap_set_fn()Bart Van Assche
Instead of handling ffz(~overlap) == bit as a special case, handle this case in the same way as ffz(~overlap) != bit. This patch does not change any functionality but removes one if-instruction from the hot path. Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
2018-08-22lib/axmap: Make axmap_new() more robustBart Van Assche
Return NULL instead of triggering a segmentation fault if calloc() fails. Note: calling free(NULL) is safe so it is not necessary to check the free() argument before calling free(). Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
2018-08-22lib/axmap: Inline ulog64()Bart Van Assche
Since the function ulog64() only has one caller and since it can be replaced by a single closed-form expression, inline that function. Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
2018-08-22lib/axmap: Add more documentationBart Van Assche
Make the axmap code easier to follow by documenting the semantics of the structures and functions in the lib/axmap.c source file. Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
2018-08-17Remove unused code in lib/axmap.cMichael Kelley
With the new axmap_next_free() implementation, the "first_free" cache is no longer used. Remove all references to it. Also axmap_clear() is never referenced, so remove it and related code.
2018-08-17Reimplement axmap_next_free() to prevent distribution skewMichael Kelley
New algorithm starts the search at the specified bit, and only looks forward (higher index) for a free bit, wrapping around the end of the map if necessary. This avoids a distribution skew in the current algorithm where the low order 5 or 6 bits of the replacement address tend toward zero. The first_free cached value is not updated or used. But performance of the new algorithm is marginally faster than the old algorithm when measured on a 200 million entry map that is half full, averaged across searches starting with each of the 200 million entries. A separate commit adds new tests to t/axmap.c to confirm the correct behavior in a variety of situations and edge cases.
2018-07-12axmap: optimize ulog64 usage in axmap_handler()Jens Axboe
We can do this incrementally, no need to compute from scratch for every iteration. Signed-off-by: Jens Axboe <axboe@kernel.dk>
2018-07-11axmap: fix continued sequential bit settingJens Axboe
We need to remember to clear ->set_bits if we don't set new bits, or the caller will think we re-set the previously set bits. Signed-off-by: Jens Axboe <axboe@kernel.dk>
2018-07-11axmap: a few more cleanupsJens Axboe
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2018-07-11axmap: remove unused 'data' argument to topdown handlerJens Axboe
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2018-07-11axmap: code cleanupsJens Axboe
- Move the const bit masks to the start of the file - Get rid of a useless variable in axmap_handler_topdown() Signed-off-by: Jens Axboe <axboe@kernel.dk>
2018-07-11axmap: clean up 'no bits to set' caseJens Axboe
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2018-07-10axmap: ensure that overlaps are handled strictly sequentialJens Axboe
We must terminate at the first overlapping bit, we can't just mask off non-sequential ranges. Signed-off-by: Jens Axboe <axboe@kernel.dk>
2018-06-12rand: make randX_upto() do the end value incrementJens Axboe
We should not do it in the caller, the functions that need fixing are really rand32/64_upto() instead. Also move a (now) misplaced comment. Fixes: c6fc6d2ab2c2 ("rand: ensure that rand_between() can reach max value") Signed-off-by: Jens Axboe <axboe@kernel.dk>
2018-06-12rand: ensure that rand_between() can reach max valueJens Axboe
We need to add 1, otherwise the maximum generated value will be end -1. The API is both inclusive. Signed-off-by: Jens Axboe <axboe@kernel.dk>
2018-06-12rand: cleanup rand_between() and helpersJens Axboe
Make the 32/64-bit helper just return a random number up to a certain value, and let the generic helper handle the range part. Signed-off-by: Jens Axboe <axboe@kernel.dk>
2018-06-12rand: add rand64_between()Jens Axboe
For some reason we only had the 32-bit variant, and there's a use case for the 64-bit version. Add that, and add a 32/64 agnostic helper that can be called. Signed-off-by: Jens Axboe <axboe@kernel.dk>
2018-06-05Make nowarn_snprintf() call va_end()Bart Van Assche
This patch suppresses the following Coverity complaint: CID 175867: API usage errors (VARARGS) va_end was not called for "args". Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
2018-06-05Move nowarn_snprintf.h to lib/Jens Axboe
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2018-04-18Simplify num2str()Bart Van Assche
Instead of translating the N2S_* constants into an array index inside num2str(), make the N2S_* constants identical to the array index used inside num2str(). This patch does not change the behavior of num2str(). Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
2018-04-18Introduce enum n2s_unitBart Van Assche
This patch does not change any functionality but makes num2str() slightly easier to read. Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
2018-04-08axmap: use calloc() for level allocJens Axboe
We rely on it being set to NULL for error handling. Signed-off-by: Jens Axboe <axboe@kernel.dk>
2018-03-21Add include-what-you-use pragmasSitsofe Wheeler
Add IWYU pragmas to improve its analysis. Signed-off-by: Sitsofe Wheeler <sitsofe@yahoo.com>
2018-03-21Refactor #includes and headersSitsofe Wheeler
- Try and remove unneeded #include lines - Try and add #include lines that would allow the files to be built in a more standalone manner Signed-off-by: Sitsofe Wheeler <sitsofe@yahoo.com>
2018-03-12Rename struct rb_node into struct fio_rb_nodeBart Van Assche
This patch avoids that building fio fails as follows on NetBSD systems: CC crc/test.o In file included from crc/../iolog.h:4, from crc/../stat.h:4, from crc/../thread_options.h:7, from crc/../fio.h:18, from crc/test.c:5: crc/../lib/rbtree.h:101: error: redefinition of 'struct rb_node' Makefile:336: recipe for target 'crc/test.o' failed gmake: *** [crc/test.o] Error 1 Signed-off-by: Bart Van Assche <bart.vanassche@wdc.com>
2017-12-01memcpy: add hybridJens Axboe
Use builtin memcpy for < 64 bytes, use simple variant for larger ones. libc doesn't seem to like to use SSE, the hand rolled simple variant uses that for larger copies. Signed-off-by: Jens Axboe <axboe@kernel.dk>
2017-12-01memcpy: free buffer in case of failureJens Axboe
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2017-12-01memcpy: use mallocJens Axboe
We don't have posix_memalign() everywhere, let's just use malloc. Also free memory when done. Signed-off-by: Jens Axboe <axboe@kernel.dk>
2017-12-01Add basic memcpy testJens Axboe
Research is ongoing in how to improve (and make deterministic) the memcpy speed, since it's especially applicable to the persistent memory engines. Not documented yet. Signed-off-by: Jens Axboe <axboe@kernel.dk>
2017-10-29fio: update FSF addressSitsofe Wheeler
Signed-off-by: Sitsofe Wheeler <sitsofe@yahoo.com>
2017-10-03Merge branch 'master' of https://github.com/dyniusz/fioJens Axboe
2017-09-18lib/memalign: don't malloc size twiceTomohiro Kusumi
The footer offset (diff between malloc'd address and aligned address) is (alignment-1) at most, and footer appears `size' bytes after the aligned address, thus required size is (alignment-1 + size + sizeof(*f)). The existing code seems to allocate extra unused `size' bytes. Signed-off-by: Tomohiro Kusumi <tkusumi@tuxera.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
2017-08-30lib/axmap: a few fixes/cleanupsJens Axboe
- If we clear a bit and it's lower than the first free cache, update the cache. - Mark bit_masks[] as const. - Clean up logic in axmap_first_free() Signed-off-by: Jens Axboe <axboe@kernel.dk>
2017-06-27lib/ffz: remove dead storeDaniel Verkamp
word' is written in the last 'if' block but never read again. This is harmless, but scan-build (clang-analyzer) flags it as a warning. Signed-off-by: Daniel Verkamp <daniel.verkamp@intel.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
2017-06-21lib/seqlock: #include "types.h" for bool typeVincent Fu
2017-06-08Add strndup() function, if we don't have itJens Axboe
Signed-off-by: Jens Axboe <axboe@kernel.dk>
2017-06-08pattern: Add support for files in buffer_pattern argument.Stephen Bates
It is useful to be able to initialize the buffer contents using an input file (e.g. when testing certain pathological patterns for compression). Add support to the buffer_pattern input argument for reading data from a file via enclosing the filename in ``''``. Reviewed-by: Sagi Grimberg <sagi@grimberg.me> Reviewed-by: Logan Gunthorpe <logang@deltatee.com> Reviewed-By: Muli Ben-Yehuda <muli@lightbitslabs.com> Signed-off-by: Stephen Bates <sbates@raithlin.com> Signed-off-by: Jens Axboe <axboe@fb.com>
2017-05-24lib/output_buffer: harden buf_output_free() and kill buf_output_clear()Jens Axboe
The clear is superfluous. Kill the caller and the function. Ensure that we leave the output buffer in a sane state, once buf_output_free() has been called on it. Signed-off-by: Jens Axboe <axboe@fb.com>
2017-05-23Drop circular dependency in log.c and lib/output_buffer.cTomohiro Kusumi
Two files log.c and lib/output_buffer.c have dependency on each other, i.e. log.c is using buf_output_add() in lib/output_buffer.c, while lib/output_buffer.c is using log_info_buf() in log.c. This commit removes this dependency from lib/output_buffer.c by dropping log_info_buf() call from a library function buf_output_flush(), and then as a result rename buf_output_flush() to buf_output_clear() since it's no longer flusing anything. log_info_buf() is now called independently by __show_run_stats() which was the only caller of buf_output_flush(). log_info_buf() returning 0 on !len is necessary to keep this commit without making functional difference. dprint()/log_info() basically never pass NULL or "" to log_info_buf(), but __show_run_stats() would pass NULL with length 0 for unused output modes which then needs to be avoided as a special case. Signed-off-by: Tomohiro Kusumi <tkusumi@tuxera.com> Signed-off-by: Jens Axboe <axboe@fb.com>
2017-05-04Adjustments to support C++ enginesdyniusz
2017-04-26seqlock: add simple user space code for sequence locksJens Axboe
Signed-off-by: Jens Axboe <axboe@fb.com>
2017-04-26Make lib/mountcheck.c a stand-alone libraryTomohiro Kusumi
It needs to include mountcheck.h from local directory where mountcheck.c is also located, to be able to use this as a stand-alone library, which is useful for debugging purpose. In fact, most of the files under lib/ directory do things this way. -- # cat ./test11.c #include <stdio.h> #include "lib/mountcheck.h" int main(int argc, char **argv) { printf("%d\n", device_is_mounted(argv[1])); return 0; } -- # uname Linux # gcc -Wall -g -DCONFIG_GETMNTENT ./test11.c ./lib/mountcheck.c # ./a.out /dev/sda1 1 -- # uname DragonFly # gcc -Wall -g -DCONFIG_GETMNTINFO ./test11.c ./lib/mountcheck.c # ./a.out /dev/da0s1a 1 -- # uname NetBSD # gcc -Wall -g -DCONFIG_GETMNTINFO_STATVFS ./test11.c ./lib/mountcheck.c # ./a.out /dev/sd0a 1 Signed-off-by: Tomohiro Kusumi <tkusumi@tuxera.com> Signed-off-by: Jens Axboe <axboe@fb.com>
2017-04-26Make lib/zipf.c a stand-alone libraryTomohiro Kusumi
lib/zipf.c not having dependency on fio header (log.h) enables it to be a stand-alone library, which is useful for debugging purpose. In fact, most of the files under lib/ directory do things this way. lib/zipf.c doesn't use log.h (log(3) is apparently from -lm). This requires the previous commit. -- # cat ./test8.c #include <stdio.h> #include "lib/zipf.h" int main(void) { /* just to see if it compiles */ zipf_init(NULL, 0, 0, 0); return 0; } # gcc -Wall -g -lm -DBITS_PER_LONG=64 ./test8.c ./lib/zipf.c ./lib/rand.c ./lib/pattern.c ./lib/strntol.c Signed-off-by: Tomohiro Kusumi <tkusumi@tuxera.com> Signed-off-by: Jens Axboe <axboe@fb.com>
2017-04-26Make lib/rand.c a stand-alone libraryTomohiro Kusumi
It needs to include pattern.h from local directory where rand.c is also located, to be able to use this as a stand-alone library, which is useful for debugging purpose. In fact, most of the files under lib/ directory do things this way. -- # cat ./test7.c #include <stdio.h> #include "lib/rand.h" int main(void) { /* just to see if it compiles */ init_rand(NULL, 0); return 0; } # gcc -Wall -g -DBITS_PER_LONG=64 ./test7.c ./lib/rand.c ./lib/pattern.c ./lib/strntol.c Signed-off-by: Tomohiro Kusumi <tkusumi@tuxera.com> Signed-off-by: Jens Axboe <axboe@fb.com>
2017-04-26Make lib/pattern.c a stand-alone libraryTomohiro Kusumi
lib/pattern.c not having dependency on fio.h enables it to be a stand-alone library, which is useful for debugging purpose. In fact, most of the files under lib/ directory do things this way. This requires the previous commit. -- # cat ./test6.c #include <stdio.h> #include "lib/pattern.h" int main(void) { /* just to see if it compiles */ paste_format_inplace(NULL, 0, NULL, 0, NULL); return 0; } # gcc -Wall -g ./test6.c ./lib/pattern.c ./lib/strntol.c Signed-off-by: Tomohiro Kusumi <tkusumi@tuxera.com> Signed-off-by: Jens Axboe <axboe@fb.com>
2017-04-26Make lib/strntol.c a stand-alone libraryTomohiro Kusumi
It needs to include strntol.h from local directory where strntol.c is also located, to be able to use this as a stand-alone library, which is useful for debugging purpose. In fact, most of the files under lib/ directory do things this way. -- # cat ./test5.c #include <stdio.h> #include "lib/strntol.h" int main(void) { /* just to see if it compiles */ strntol(NULL, 0, NULL, 0); return 0; } # gcc -Wall -g ./test5.c ./lib/strntol.c Signed-off-by: Tomohiro Kusumi <tkusumi@tuxera.com> Signed-off-by: Jens Axboe <axboe@fb.com>
2017-04-26Fix num2str() output when modulo != -1UTomohiro Kusumi
I'm not sure what 05463816 actually fixed (as it only says "fix"), but this isn't properly working at least for some input numbers unless ".%s" part of sprintf() is meant to be something other than decimal part of the input number. This commit might be breaking something that 05463816 had fixed, which then needs to be rejected, but it at least prints decimal number as expected. For example, when 12345 is 12.0556640625 KiB, and 23456 is 22.90625 KiB, # python -c "print(12345.0 / 1024)" 12.0556640625 # python -c "print(23456.0 / 1024)" 22.90625 running this code as well as fio result in # cat ./test1.c #include <stdio.h> #include "lib/num2str.h" int main(void) { printf("%s-%s\n", num2str(12345, 4, 1, 1, N2S_BYTE), num2str(23456, 4, 1, 1, N2S_BYTE)); return 0; } # gcc -Wall -g -DCONFIG_STATIC_ASSERT ./test1.c ./lib/num2str.c below with the current implementation # ./a.out 12.6KiB-22.1KiB # ./fio --name=xxxxx --ioengine=sync --rw=read --size=1m --unlink=1 --bsrange=12345:23456 | grep "rw=read" xxxxx: (g=0): rw=read, bs=(R) 12.6KiB-22.1KiB, (W) 12.6KiB-22.1KiB, (T) 12.6KiB-22.1KiB, ioengine=sync, iodepth=1 whereas below with this commit. # ./a.out 12.1KiB-22.9KiB # ./fio --name=xxxxx --ioengine=sync --rw=read --size=1m --unlink=1 --bsrange=12345:23456 | grep "rw=read" xxxxx: (g=0): rw=read, bs=(R) 12.1KiB-22.9KiB, (W) 12.1KiB-22.9KiB, (T) 12.1KiB-22.9KiB, ioengine=sync, iodepth=1 -- Also see below http://www.spinics.net/lists/fio/msg05720.html > > + sprintf(fmt, "%%.%df", (int)(maxlen - strlen(tmp) - 1)); > > + sprintf(tmp, fmt, (double)modulo / (double)thousand[!!pow2]); > > I suspect one of the goals of that function was to restrict itself > to integer math and avoid invoking the floating point unit (which > might not even exist on some CPUs). -- These are some more verification with various parameters # cat ./testx.c #include <stdio.h> #include "lib/num2str.h" static void f(uint64_t n, int maxlen, int base, int pow2, int units) { printf("%10jd %s\n", n, num2str(n, maxlen, base, pow2, units)); } int main(void) { /* 1 */ f(1, 1, 1, 1, N2S_BYTE); f(1, 1, 1, 0, N2S_BYTE); printf("====================\n"); /* 10 */ f(10, 2, 1, 1, N2S_BYTE); f(10, 2, 1, 0, N2S_BYTE); printf("====================\n"); /* 1000 */ f(1000, 5, 1, 1, N2S_BYTE); f(1000, 5, 1, 0, N2S_BYTE); f(1000, 4, 1, 1, N2S_BYTE); f(1000, 4, 1, 0, N2S_BYTE); f(1000, 3, 1, 1, N2S_BYTE); f(1000, 3, 1, 0, N2S_BYTE); f(1000, 2, 1, 1, N2S_BYTE); f(1000, 2, 1, 0, N2S_BYTE); f(1000, 1, 1, 1, N2S_BYTE); f(1000, 1, 1, 0, N2S_BYTE); printf("====================\n"); /* 1024 */ f(1024, 5, 1, 1, N2S_BYTE); f(1024, 5, 1, 0, N2S_BYTE); f(1024, 4, 1, 1, N2S_BYTE); f(1024, 4, 1, 0, N2S_BYTE); f(1024, 3, 1, 1, N2S_BYTE); f(1024, 3, 1, 0, N2S_BYTE); f(1024, 2, 1, 1, N2S_BYTE); f(1024, 2, 1, 0, N2S_BYTE); f(1024, 1, 1, 1, N2S_BYTE); f(1024, 1, 1, 0, N2S_BYTE); printf("====================\n"); /* 12345 */ f(12345, 6, 1, 1, N2S_BYTE); f(12345, 6, 1, 0, N2S_BYTE); f(12345, 5, 1, 1, N2S_BYTE); f(12345, 5, 1, 0, N2S_BYTE); f(12345, 4, 1, 1, N2S_BYTE); f(12345, 4, 1, 0, N2S_BYTE); f(12345, 3, 1, 1, N2S_BYTE); f(12345, 3, 1, 0, N2S_BYTE); f(12345, 2, 1, 1, N2S_BYTE); f(12345, 2, 1, 0, N2S_BYTE); f(12345, 1, 1, 1, N2S_BYTE); f(12345, 1, 1, 0, N2S_BYTE); printf("====================\n"); /* 1234567 */ f(1234567, 8, 1, 1, N2S_BYTE); f(1234567, 8, 1, 0, N2S_BYTE); f(1234567, 7, 1, 1, N2S_BYTE); f(1234567, 7, 1, 0, N2S_BYTE); f(1234567, 6, 1, 1, N2S_BYTE); f(1234567, 6, 1, 0, N2S_BYTE); f(1234567, 5, 1, 1, N2S_BYTE); f(1234567, 5, 1, 0, N2S_BYTE); f(1234567, 4, 1, 1, N2S_BYTE); f(1234567, 4, 1, 0, N2S_BYTE); f(1234567, 3, 1, 1, N2S_BYTE); f(1234567, 3, 1, 0, N2S_BYTE); f(1234567, 2, 1, 1, N2S_BYTE); f(1234567, 2, 1, 0, N2S_BYTE); f(1234567, 1, 1, 1, N2S_BYTE); f(1234567, 1, 1, 0, N2S_BYTE); printf("====================\n"); /* 1234567 with base 1024 */ f(1234567, 8, 1024, 1, N2S_BYTE); f(1234567, 8, 1024, 0, N2S_BYTE); f(1234567, 7, 1024, 1, N2S_BYTE); f(1234567, 7, 1024, 0, N2S_BYTE); f(1234567, 6, 1024, 1, N2S_BYTE); f(1234567, 6, 1024, 0, N2S_BYTE); f(1234567, 5, 1024, 1, N2S_BYTE); f(1234567, 5, 1024, 0, N2S_BYTE); f(1234567, 4, 1024, 1, N2S_BYTE); f(1234567, 4, 1024, 0, N2S_BYTE); f(1234567, 3, 1024, 1, N2S_BYTE); f(1234567, 3, 1024, 0, N2S_BYTE); f(1234567, 2, 1024, 1, N2S_BYTE); f(1234567, 2, 1024, 0, N2S_BYTE); f(1234567, 1, 1024, 1, N2S_BYTE); f(1234567, 1, 1024, 0, N2S_BYTE); printf("====================\n"); /* 1234567 with base 1024 with N2S_BIT */ f(1234567, 9, 1024, 1, N2S_BIT); f(1234567, 9, 1024, 0, N2S_BIT); f(1234567, 8, 1024, 1, N2S_BIT); f(1234567, 8, 1024, 0, N2S_BIT); f(1234567, 7, 1024, 1, N2S_BIT); f(1234567, 7, 1024, 0, N2S_BIT); f(1234567, 6, 1024, 1, N2S_BIT); f(1234567, 6, 1024, 0, N2S_BIT); f(1234567, 5, 1024, 1, N2S_BIT); f(1234567, 5, 1024, 0, N2S_BIT); f(1234567, 4, 1024, 1, N2S_BIT); f(1234567, 4, 1024, 0, N2S_BIT); f(1234567, 3, 1024, 1, N2S_BIT); f(1234567, 3, 1024, 0, N2S_BIT); f(1234567, 2, 1024, 1, N2S_BIT); f(1234567, 2, 1024, 0, N2S_BIT); f(1234567, 1, 1024, 1, N2S_BIT); f(1234567, 1, 1024, 0, N2S_BIT); printf("====================\n"); return 0; } # gcc -Wall -g -DCONFIG_STATIC_ASSERT ./testx.c ./lib/num2str.c # ./a.out 1 1B 1 1B ==================== 10 10B 10 10B ==================== 1000 1000B 1000 1000B 1000 1000B 1000 1000B 1000 0.0KiB 1000 1.0kB 1000 1KiB 1000 1kB 1000 1KiB 1000 1kB ==================== 1024 1024B 1024 1024B 1024 1024B 1024 1024B 1024 1.0KiB 1024 1.0kB 1024 1KiB 1024 1kB 1024 1KiB 1024 1kB ==================== 12345 12345B 12345 12345B 12345 12345B 12345 12345B 12345 12.1KiB 12345 12.3kB 12345 12KiB 12345 12kB 12345 12KiB 12345 12kB 12345 0MiB 12345 0MB ==================== 1234567 1234567B 1234567 1234567B 1234567 1234567B 1234567 1234567B 1234567 1205.6KiB 1234567 1234.6kB 1234567 1206KiB 1234567 1235kB 1234567 1206KiB 1234567 1235kB 1234567 1.2MiB 1234567 1.2MB 1234567 1MiB 1234567 1MB 1234567 1MiB 1234567 1MB ==================== 1234567 1234567KiB 1234567 1234567kB 1234567 1234567KiB 1234567 1234567kB 1234567 1205.6MiB 1234567 1234.6MB 1234567 1206MiB 1234567 1235MB 1234567 1206MiB 1234567 1235MB 1234567 1.2GiB 1234567 1.2GB 1234567 1GiB 1234567 1GB 1234567 1GiB 1234567 1GB ==================== 1234567 9876536Kibit 1234567 9876536kbit 1234567 9876536Kibit 1234567 9876536kbit 1234567 9876536Kibit 1234567 9876536kbit 1234567 9645.1Mibit 1234567 9876.5Mbit 1234567 9645Mibit 1234567 9877Mbit 1234567 9645Mibit 1234567 9877Mbit 1234567 9.4Gibit 1234567 9.9Gbit 1234567 9Gibit 1234567 10Gbit 1234567 9Gibit 1234567 10Gbit ==================== Signed-off-by: Tomohiro Kusumi <tkusumi@tuxera.com> Signed-off-by: Jens Axboe <axboe@fb.com>
2017-04-08Fix num2str() output when maxlen <= strlen(tmp)Tomohiro Kusumi
Since a local variable decimals is unsigned int, this conditional if (decimals <= 1) needs cast as shown below. if ((int)decimals <= 1) Otherwise it results in showing some garbage in case of maxlen == 0, # cat ./test0.c #include <stdio.h> #include "lib/num2str.h" int main(void) { printf("%s\n", num2str(123, 3, 1, 1, N2S_BYTE)); printf("%s\n", num2str(123, 2, 1, 1, N2S_BYTE)); printf("%s\n", num2str(123, 1, 1, 1, N2S_BYTE)); printf("%s\n", num2str(123, 0, 1, 1, N2S_BYTE)); return 0; } # gcc -Wall -g -DCONFIG_STATIC_ASSERT ./test0.c ./lib/num2str.c # ./a.out 123B 0KiB 0KiB 0.0?$-JB # ./a.out 123B 0KiB 0KiB 0.0#;bB # ./a.out 123B 0KiB 0KiB 0.0|B whereas with this commit it prints "0B". # gcc -Wall -g -DCONFIG_STATIC_ASSERT ./test0.c ./lib/num2str.c # ./a.out 123B 0KiB 0KiB 0B Signed-off-by: Tomohiro Kusumi <tkusumi@tuxera.com> Signed-off-by: Jens Axboe <axboe@fb.com>