diff options
Diffstat (limited to 'cpukit/libblock')
-rw-r--r-- | cpukit/libblock/include/rtems/bdbuf.h | 18 | ||||
-rw-r--r-- | cpukit/libblock/src/bdbuf.c | 13 | ||||
-rw-r--r-- | cpukit/libblock/src/blkdev-ioctl.c | 2 | ||||
-rw-r--r-- | cpukit/libblock/src/diskdevs-init.c | 4 |
4 files changed, 28 insertions, 9 deletions
diff --git a/cpukit/libblock/include/rtems/bdbuf.h b/cpukit/libblock/include/rtems/bdbuf.h index 05e324c342..8a4631b9db 100644 --- a/cpukit/libblock/include/rtems/bdbuf.h +++ b/cpukit/libblock/include/rtems/bdbuf.h @@ -644,21 +644,31 @@ rtems_bdbuf_purge_dev (rtems_disk_device *dd); /** * @brief Sets the block size of a disk device. * - * This will set the block size derived fields of the disk device. The - * read-ahead state of this device is reset. + * This will set the block size derived fields of the disk device. If + * requested the disk device is synchronized before the block size change + * occurs. Since the cache is unlocked during the synchronization operation + * some tasks may access the disk device in the meantime. This may result in + * loss of data. After the synchronization the disk device is purged to ensure + * a consistent cache state and the block size change occurs. This also resets + * the read-ahead state of this disk device. Due to the purge operation this + * may result in loss of data. * * Before you can use this function, the rtems_bdbuf_init() routine must be * called at least once to initialize the cache, otherwise a fatal error will * occur. * * @param dd [in, out] The disk device. - * @param dd [in] The new block size. + * @param block_size [in] The new block size. + * @param sync [in] If @c true, then synchronize the disk device before the + * block size change. * * @retval RTEMS_SUCCESSFUL Successful operation. * @retval RTEMS_INVALID_NUMBER Invalid block size. */ rtems_status_code -rtems_bdbuf_set_block_size (rtems_disk_device *dd, uint32_t block_size); +rtems_bdbuf_set_block_size (rtems_disk_device *dd, + uint32_t block_size, + bool sync); /** * @brief Returns the block device statistics. diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c index 3f4915be43..c4336cd8cd 100644 --- a/cpukit/libblock/src/bdbuf.c +++ b/cpukit/libblock/src/bdbuf.c @@ -2948,10 +2948,19 @@ rtems_bdbuf_purge_dev (rtems_disk_device *dd) } rtems_status_code -rtems_bdbuf_set_block_size (rtems_disk_device *dd, uint32_t block_size) +rtems_bdbuf_set_block_size (rtems_disk_device *dd, + uint32_t block_size, + bool sync) { rtems_status_code sc = RTEMS_SUCCESSFUL; + /* + * We do not care about the synchronization status since we will purge the + * device later. + */ + if (sync) + rtems_bdbuf_syncdev (dd); + rtems_bdbuf_lock_cache (); if (block_size > 0) @@ -2978,7 +2987,7 @@ rtems_bdbuf_set_block_size (rtems_disk_device *dd, uint32_t block_size) dd->block_to_media_block_shift = block_to_media_block_shift; dd->bds_per_group = bds_per_group; - rtems_bdbuf_read_ahead_reset (dd); + rtems_bdbuf_purge_dev (dd); } else { diff --git a/cpukit/libblock/src/blkdev-ioctl.c b/cpukit/libblock/src/blkdev-ioctl.c index b2215f17c2..54360b3bec 100644 --- a/cpukit/libblock/src/blkdev-ioctl.c +++ b/cpukit/libblock/src/blkdev-ioctl.c @@ -37,7 +37,7 @@ rtems_blkdev_ioctl(rtems_disk_device *dd, uint32_t req, void *argp) break; case RTEMS_BLKIO_SETBLKSIZE: - sc = rtems_bdbuf_set_block_size(dd, *(uint32_t *) argp); + sc = rtems_bdbuf_set_block_size(dd, *(uint32_t *) argp, true); if (sc != RTEMS_SUCCESSFUL) { errno = EIO; rc = -1; diff --git a/cpukit/libblock/src/diskdevs-init.c b/cpukit/libblock/src/diskdevs-init.c index 5ec96b250c..02ef392a28 100644 --- a/cpukit/libblock/src/diskdevs-init.c +++ b/cpukit/libblock/src/diskdevs-init.c @@ -43,7 +43,7 @@ rtems_status_code rtems_disk_init_phys( dd->capabilities = 0; } - sc = rtems_bdbuf_set_block_size(dd, block_size); + sc = rtems_bdbuf_set_block_size(dd, block_size, false); } else { sc = RTEMS_INVALID_NUMBER; } @@ -78,7 +78,7 @@ rtems_status_code rtems_disk_init_log( && block_count > 0 && block_count <= phys_block_count - block_begin ) { - sc = rtems_bdbuf_set_block_size(dd, phys_dd->media_block_size); + sc = rtems_bdbuf_set_block_size(dd, phys_dd->media_block_size, false); } else { sc = RTEMS_INVALID_NUMBER; } |