bch: add BIOC_DISCARD ioctl that discards cached sector

This forces the bch layer to read the sector from the physical device
instead of using the cached values. It is necessary to call when the
device is updated from the different source than bch, for example
erased by the MTD ioctl command.

It also has to invalidate readahead buffer from FTL if option
CONFIG_DRVR_READAHEAD is set.

Signed-off-by: Michal Lenc <michallenc@seznam.cz>
This commit is contained in:
Michal Lenc 2025-01-22 11:35:52 +01:00 committed by Xiang Xiao
parent 4050c79505
commit d9270f9ea8
5 changed files with 52 additions and 1 deletions

View file

@ -435,6 +435,14 @@ static int bch_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
break;
#endif
case BIOC_DISCARD:
{
/* Invalidate the sector so next read is from the device- */
bch->sector = (size_t)-1;
goto ioctl_default;
}
case BIOC_FLUSH:
{
/* Flush any dirty pages remaining in the cache */
@ -450,6 +458,7 @@ static int bch_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
/* Pass the IOCTL command on to the contained block driver. */
ioctl_default:
default:
{
FAR struct inode *bchinode = bch->inode;
@ -462,7 +471,8 @@ static int bch_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
/* Drivers may not support command BIOC_FLUSH */
if (ret == -ENOTTY && cmd == BIOC_FLUSH)
if (ret == -ENOTTY && (cmd == BIOC_FLUSH ||
cmd == BIOC_DISCARD))
{
ret = 0;
}

View file

@ -1279,4 +1279,30 @@ int rwb_flush(FAR struct rwbuffer_s *rwb)
}
#endif
/****************************************************************************
* Name: rwb_flush
*
* Description:
* Flush the write buffer
*
****************************************************************************/
#ifdef CONFIG_DRVR_READAHEAD
int rwb_discard(FAR struct rwbuffer_s *rwb)
{
int ret;
ret = rwb_lock(&rwb->rhlock);
if (ret < 0)
{
return ret;
}
rwb_resetrhbuffer(rwb);
rwb_unlock(&rwb->rhlock);
return ret;
}
#endif
#endif /* CONFIG_DRVR_WRITEBUFFER || CONFIG_DRVR_READAHEAD */

View file

@ -716,6 +716,13 @@ static int ftl_ioctl(FAR struct inode *inode, int cmd, unsigned long arg)
dev = inode->i_private;
if (cmd == BIOC_DISCARD)
{
#ifdef CONFIG_FTL_READAHEAD
rwb_discard(&dev->rwb);
#endif
}
if (cmd == BIOC_FLUSH)
{
#ifdef CONFIG_FTL_WRITEBUFFER

View file

@ -198,6 +198,10 @@ int rwb_invalidate(FAR struct rwbuffer_s *rwb,
int rwb_flush(FAR struct rwbuffer_s *rwb);
#endif
#ifdef CONFIG_DRVR_READAHEAD
int rwb_discard(FAR struct rwbuffer_s *rwb);
#endif
#undef EXTERN
#if defined(__cplusplus)
}

View file

@ -348,6 +348,10 @@
* to return sector numbers.
* OUT: Data return in user-provided
* buffer. */
#define BIOC_DISCARD _BIOC(0x0011) /* Discards the block device read buffer
* IN: None
* OUT: None (ioctl return value provides
* success/failure indication). */
/* NuttX MTD driver ioctl definitions ***************************************/