Skip to content
  1. Feb 15, 2019
  2. Feb 11, 2019
  3. Feb 10, 2019
  4. Feb 09, 2019
    • Coly Li's avatar
      bcache: use (REQ_META|REQ_PRIO) to indicate bio for metadata · dc7292a5
      Coly Li authored
      In 'commit 752f66a7
      
       ("bcache: use REQ_PRIO to indicate bio for
      metadata")' REQ_META is replaced by REQ_PRIO to indicate metadata bio.
      This assumption is not always correct, e.g. XFS uses REQ_META to mark
      metadata bio other than REQ_PRIO. This is why Nix noticed that bcache
      does not cache metadata for XFS after the above commit.
      
      Thanks to Dave Chinner, he explains the difference between REQ_META and
      REQ_PRIO from view of file system developer. Here I quote part of his
      explanation from mailing list,
         REQ_META is used for metadata. REQ_PRIO is used to communicate to
         the lower layers that the submitter considers this IO to be more
         important that non REQ_PRIO IO and so dispatch should be expedited.
      
         IOWs, if the filesystem considers metadata IO to be more important
         that user data IO, then it will use REQ_PRIO | REQ_META rather than
         just REQ_META.
      
      Then it seems bios with REQ_META or REQ_PRIO should both be cached for
      performance optimation, because they are all probably low I/O latency
      demand by upper layer (e.g. file system).
      
      So in this patch, when we want to decide whether to bypass the cache,
      REQ_META and REQ_PRIO are both checked. Then both metadata and
      high priority I/O requests will be handled properly.
      
      Reported-by: default avatarNix <nix@esperi.org.uk>
      Signed-off-by: default avatarColy Li <colyli@suse.de>
      Reviewed-by: default avatarAndre Noll <maan@tuebingen.mpg.de>
      Tested-by: default avatarNix <nix@esperi.org.uk>
      Cc: stable@vger.kernel.org
      Cc: Dave Chinner <david@fromorbit.com>
      Cc: Christoph Hellwig <hch@lst.de>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      dc7292a5
    • Coly Li's avatar
      bcache: fix input overflow to cache set sysfs file io_error_halflife · a91fbda4
      Coly Li authored
      
      
      Cache set sysfs entry io_error_halflife is used to set c->error_decay.
      c->error_decay is in type unsigned int, and it is converted by
      strtoul_or_return(), therefore overflow to c->error_decay is possible
      for a large input value.
      
      This patch fixes the overflow by using strtoul_safe_clamp() to convert
      input string to an unsigned long value in range [0, UINT_MAX], then
      divides by 88 and set it to c->error_decay.
      
      Signed-off-by: default avatarColy Li <colyli@suse.de>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      a91fbda4
    • Coly Li's avatar
      bcache: fix input overflow to cache set io_error_limit · b1500840
      Coly Li authored
      
      
      c->error_limit is in type unsigned int, it is set via cache set sysfs
      file io_error_limit. Inside the bcache code, input string is converted
      by strtoul_or_return() and set the converted value to c->error_limit.
      
      Because the converted value is unsigned long, and c->error_limit is
      unsigned int, if the input is large enought, overflow will happen to
      c->error_limit.
      
      This patch uses sysfs_strtoul_clamp() to convert input string, and set
      the range in [0, UINT_MAX] to avoid the potential overflow.
      
      Signed-off-by: default avatarColy Li <colyli@suse.de>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      b1500840
    • Coly Li's avatar
      bcache: fix input overflow to journal_delay_ms · 453745fb
      Coly Li authored
      
      
      c->journal_delay_ms is in type unsigned short, it is set via sysfs
      interface and converted by sysfs_strtoul() from input string to
      unsigned short value. Therefore overflow to unsigned short might be
      happen when the converted value exceed USHRT_MAX. e.g. writing
      65536 into sysfs file journal_delay_ms, c->journal_delay_ms is set to
      0.
      
      This patch uses sysfs_strtoul_clamp() to convert the input string and
      limit value range in [0, USHRT_MAX], to avoid the input overflow.
      
      Signed-off-by: default avatarColy Li <colyli@suse.de>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      453745fb
    • Coly Li's avatar
      bcache: fix input overflow to writeback_rate_minimum · dab71b2d
      Coly Li authored
      
      
      dc->writeback_rate_minimum is type unsigned integer variable, it is set
      via sysfs interface, and converte from input string to unsigned integer
      by d_strtoul_nonzero(). When the converted input value is larger than
      UINT_MAX, overflow to unsigned integer happens.
      
      This patch fixes the overflow by using sysfs_strotoul_clamp() to
      convert input string and limit the value in range [1, UINT_MAX], then
      the overflow can be avoided.
      
      Signed-off-by: default avatarColy Li <colyli@suse.de>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      dab71b2d
    • Coly Li's avatar
      bcache: fix potential div-zero error of writeback_rate_p_term_inverse · 5b5fd3c9
      Coly Li authored
      
      
      Current code already uses d_strtoul_nonzero() to convert input string
      to an unsigned integer, to make sure writeback_rate_p_term_inverse
      won't be zero value. But overflow may happen when converting input
      string to an unsigned integer value by d_strtoul_nonzero(), then
      dc->writeback_rate_p_term_inverse can still be set to 0 even if the
      sysfs file input value is not zero, e.g. 4294967296 (a.k.a UINT_MAX+1).
      
      If dc->writeback_rate_p_term_inverse is set to 0, it might cause a
      dev-zero error in following code from __update_writeback_rate(),
      	int64_t proportional_scaled =
      		div_s64(error, dc->writeback_rate_p_term_inverse);
      
      This patch replaces d_strtoul_nonzero() by sysfs_strtoul_clamp() and
      limit the value range in [1, UINT_MAX]. Then the unsigned integer
      overflow and dev-zero error can be avoided.
      
      Signed-off-by: default avatarColy Li <colyli@suse.de>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      5b5fd3c9
    • Coly Li's avatar
      bcache: fix potential div-zero error of writeback_rate_i_term_inverse · c3b75a21
      Coly Li authored
      
      
      dc->writeback_rate_i_term_inverse can be set via sysfs interface. It is
      in type unsigned int, and convert from input string by d_strtoul(). The
      problem is d_strtoul() does not check valid range of the input, if
      4294967296 is written into sysfs file writeback_rate_i_term_inverse,
      an overflow of unsigned integer will happen and value 0 is set to
      dc->writeback_rate_i_term_inverse.
      
      In writeback.c:__update_writeback_rate(), there are following lines of
      code,
            integral_scaled = div_s64(dc->writeback_rate_integral,
                            dc->writeback_rate_i_term_inverse);
      If dc->writeback_rate_i_term_inverse is set to 0 via sysfs interface,
      a div-zero error might be triggered in the above code.
      
      Therefore we need to add a range limitation in the sysfs interface,
      this is what this patch does, use sysfs_stroul_clamp() to replace
      d_strtoul() and restrict the input range in [1, UINT_MAX].
      
      Signed-off-by: default avatarColy Li <colyli@suse.de>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      c3b75a21
    • Coly Li's avatar
      bcache: fix input overflow to writeback_delay · 369d21a7
      Coly Li authored
      
      
      Sysfs file writeback_delay is used to configure dc->writeback_delay
      which is type unsigned int. But bcache code uses sysfs_strtoul() to
      convert the input string, therefore it might be overflowed if the input
      value is too large. E.g. input value is 4294967296 but indeed 0 is
      set to dc->writeback_delay.
      
      This patch uses sysfs_strtoul_clamp() to convert the input string and
      set the result value range in [0, UINT_MAX] to avoid such unsigned
      integer overflow.
      
      Signed-off-by: default avatarColy Li <colyli@suse.de>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      369d21a7
    • Coly Li's avatar
      bcache: use sysfs_strtoul_bool() to set bit-field variables · f5c0b95d
      Coly Li authored
      
      
      When setting bcache parameters via sysfs, there are some variables are
      defined as bit-field value. Current bcache code in sysfs.c uses either
      d_strtoul() or sysfs_strtoul() to convert the input string to unsigned
      integer value and set it to the corresponded bit-field value.
      
      The problem is, the bit-field value only takes the lowest bit of the
      converted value. If input is 2, the expected value (like bool value)
      of the bit-field value should be 1, but indeed it is 0.
      
      The following sysfs files for bit-field variables have such problem,
      	bypass_torture_test,	for dc->bypass_torture_test
      	writeback_metadata,	for dc->writeback_metadata
      	writeback_running,	for dc->writeback_running
      	verify,			for c->verify
      	key_merging_disabled,	for c->key_merging_disabled
      	gc_always_rewrite,	for c->gc_always_rewrite
      	btree_shrinker_disabled,for c->shrinker_disabled
      	copy_gc_enabled,	for c->copy_gc_enabled
      
      This patch uses sysfs_strtoul_bool() to set such bit-field variables,
      then if the converted value is non-zero, the bit-field variables will
      be set to 1, like setting a bool value like expensive_debug_checks.
      
      Signed-off-by: default avatarColy Li <colyli@suse.de>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      f5c0b95d
    • Coly Li's avatar
      bcache: add sysfs_strtoul_bool() for setting bit-field variables · e4db37fb
      Coly Li authored
      
      
      When setting bool values via sysfs interface, e.g. writeback_metadata,
      if writing 1 into writeback_metadata file, dc->writeback_metadata is
      set to 1, but if writing 2 into the file, dc->writeback_metadata is
      0. This is misleading, a better result should be 1 for all non-zero
      input value.
      
      It is because dc->writeback_metadata is a bit-field variable, and
      current code simply use d_strtoul() to convert a string into integer
      and takes the lowest bit value. To fix such error, we need a routine
      to convert the input string into unsigned integer, and set target
      variable to 1 if the converted integer is non-zero.
      
      This patch introduces a new macro called sysfs_strtoul_bool(), it can
      be used to convert input string into bool value, we can use it to set
      bool value for bit-field vairables.
      
      Signed-off-by: default avatarColy Li <colyli@suse.de>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      e4db37fb
    • Coly Li's avatar
      bcache: fix input overflow to sequential_cutoff · 8c27a395
      Coly Li authored
      
      
      People may set sequential_cutoff of a cached device via sysfs file,
      but current code does not check input value overflow. E.g. if value
      4294967295 (UINT_MAX) is written to file sequential_cutoff, its value
      is 4GB, but if 4294967296 (UINT_MAX + 1) is written into, its value
      will be 0. This is an unexpected behavior.
      
      This patch replaces d_strtoi_h() by sysfs_strtoul_clamp() to convert
      input string to unsigned integer value, and limit its range in
      [0, UINT_MAX]. Then the input overflow can be fixed.
      
      Signed-off-by: default avatarColy Li <colyli@suse.de>
      Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
      8c27a395