[Skiboot] [PATCH v2] libflash/file: Only use 64bit MTD erase ioctl() when needed

Michael Neuling mikey at neuling.org
Thu Apr 20 15:57:28 AEST 2017


This has been merged into skiboot upstream as 86d4bcbdcb.



On Thu, 2017-04-20 at 15:39 +1000, Cyril Bur wrote:
> We recently made MTD 64 bit safe in e5720d3fe94 which now requires the
> 64 bit MTD erase ioctl. Unfortunately this ioctl is not present in
> older kernels used by some BMC vendors that use pflash.
> 
> This patch addresses this by only using the 64bit version of the erase
> ioctl() if the parameters exceed 32bit in size.
> 
> If an erase requires the 64bit ioctl() on a kernel which does not
> support it, the code will still attempt it. There is no way of knowing
> beforehand if the kernel supports it. The ioctl() will fail and an error
> will be returned from from the function.
> 
> Signed-off-by: Cyril Bur <cyril.bur at au1.ibm.com>
> ---
> V2: Reword this commit message
>     Dropped the test, on reflection it isn't a great test. In that it
>     doesn't really test much.
> 
>  libflash/file.c | 44 ++++++++++++++++++++++++++++++++++++++------
>  1 file changed, 38 insertions(+), 6 deletions(-)
> 
> diff --git a/libflash/file.c b/libflash/file.c
> index 5f074cf2..8d1ed02a 100644
> --- a/libflash/file.c
> +++ b/libflash/file.c
> @@ -15,6 +15,7 @@
>   */
>  #define _GNU_SOURCE
>  #include <errno.h>
> +#include <inttypes.h>
>  #include <stdio.h>
>  #include <stdlib.h>
>  #include <string.h>
> @@ -130,13 +131,44 @@ static int file_erase(struct blocklevel_device *bl,
> uint64_t dst, uint64_t len)
>  static int mtd_erase(struct blocklevel_device *bl, uint64_t dst, uint64_t
> len)
>  {
>  	struct file_data *file_data = container_of(bl, struct file_data, bl);
> -	struct erase_info_user64 erase_info = {
> -		.start = dst,
> -		.length = len
> -	};
> +	int err;
>  
> -	if (ioctl(file_data->fd, MEMERASE64, &erase_info) == -1)
> -		return FLASH_ERR_PARM_ERROR;
> +	FL_DBG("%s: dst: 0x%" PRIx64 ", len: 0x%" PRIx64 "\n", __func__, dst,
> len);
> +
> +	/*
> +	 * Some kernels that pflash supports do not know about the 64bit
> +	 * version of the ioctl() therefore we'll just use the 32bit (which
> +	 * should always be supported...) unless we MUST use the 64bit and
> +	 * then lets just hope the kernel knows how to deal with it. If it
> +	 * is unsupported the ioctl() will fail and we'll report that -
> +	 * there is no other option.
> +	 */
> +	if (dst > UINT_MAX || len > UINT_MAX) {
> +		struct erase_info_user64 erase_info = {
> +			.start = dst,
> +			.length = len
> +		};
> +
> +		if (ioctl(file_data->fd, MEMERASE64, &erase_info) == -1) {
> +			err = errno;
> +			if (err == 25) /* Kernel doesn't do 64bit MTD erase
> ioctl() */
> +				FL_DBG("Attempted a 64bit erase on a kernel
> which doesn't support it\n");
> +			FL_ERR("%s: IOCTL to kernel failed! %s\n", __func__,
> strerror(err));
> +			errno = err;
> +			return FLASH_ERR_PARM_ERROR;
> +		}
> +	} else {
> +		struct erase_info_user erase_info = {
> +			.start = dst,
> +			.length = len
> +		};
> +		if (ioctl(file_data->fd, MEMERASE, &erase_info) == -1) {
> +			err = errno;
> +			FL_ERR("%s: IOCTL to kernel failed! %s\n", __func__,
> strerror(err));
> +			errno = err;
> +			return FLASH_ERR_PARM_ERROR;
> +		}
> +	}
>  
>  	return 0;
>  }


More information about the Skiboot mailing list