diff options
author | Chris Johns <chrisj@rtems.org> | 2010-05-18 02:14:05 +0000 |
---|---|---|
committer | Chris Johns <chrisj@rtems.org> | 2010-05-18 02:14:05 +0000 |
commit | 8aa608df3241d07de26d8700ce762476a09a7706 (patch) | |
tree | 5210870b71151291b3225aba7eb47b9381d4914a | |
parent | 010-05-18 Chris Johns <chrisj@rtems.org> (diff) | |
download | rtems-8aa608df3241d07de26d8700ce762476a09a7706.tar.bz2 |
2010-05-18 Chris Johns <chrisj@rtems.org>
* libblock/src/diskdevs.c, libblock/include/rtems/blkdev.h,
libblock/src/bdbuf.c: PR 1448/filesystem.
* libblock/include/rtems/blkdev.h, libblock/src/bdbuf.c: PR
1514/filesystem.
-rw-r--r-- | cpukit/ChangeLog | 8 | ||||
-rw-r--r-- | cpukit/libblock/include/rtems/blkdev.h | 33 | ||||
-rw-r--r-- | cpukit/libblock/src/bdbuf.c | 53 | ||||
-rw-r--r-- | cpukit/libblock/src/diskdevs.c | 2 |
4 files changed, 71 insertions, 25 deletions
diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index 6c97c84ae3..bd8cec917b 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,11 @@ +2010-05-18 Chris Johns <chrisj@rtems.org> + + * libblock/src/diskdevs.c, libblock/include/rtems/blkdev.h, + libblock/src/bdbuf.c: PR 1448/filesystem. + + * libblock/include/rtems/blkdev.h, libblock/src/bdbuf.c: PR + 1514/filesystem. + 2010-05-17 Oleg Kravtsov <Oleg.Kravtsov@oktetlabs.ru> PR 1449/cpukit diff --git a/cpukit/libblock/include/rtems/blkdev.h b/cpukit/libblock/include/rtems/blkdev.h index 63fb2db108..85907278e9 100644 --- a/cpukit/libblock/include/rtems/blkdev.h +++ b/cpukit/libblock/include/rtems/blkdev.h @@ -42,23 +42,18 @@ extern "C" { /** * Block device request type. + * + * @warning The sync request is an IO one and only used from the cache. Use the + * Block IO when operating at the device level. We need a sync request + * to avoid requests looping for ever. */ typedef enum rtems_blkdev_request_op { RTEMS_BLKDEV_REQ_READ, /**< Read the requested blocks of data. */ RTEMS_BLKDEV_REQ_WRITE, /**< Write the requested blocks of data. */ - RTEMS_BLKDEV_CAPABILITIES /**< Return the driver capabilities set. */ + RTEMS_BLKDEV_REQ_SYNC /**< Sync any data with the media. */ } rtems_blkdev_request_op; /** - * Only consecutive multi-sector buffer requests are supported. - * - * This option means the cache will only supply multiple buffers that are - * inorder so the ATA multi-sector command for example can be used. This is a - * hack to work around the current ATA driver. - */ -#define RTEMS_BLKDEV_CAP_MULTISECTOR_CONT (1 << 0) - -/** * @brief Block device request done callback function type. * * The first parameter @a arg must be the argument provided by the block device @@ -147,7 +142,7 @@ typedef struct rtems_blkdev_request { /** * The start block in a request. * - * Only valid if the driver has returned the @ref RTEMS_BLKDEV_CAPABILITIES of + * Only valid if the driver has returned the @ref RTEMS_BLKIO_CAPABILITIES of * @ref RTEMS_BLKDEV_CAP_MULTISECTOR_CONT. */ #define RTEMS_BLKDEV_START_BLOCK(req) (req->bufs[0].block) @@ -165,10 +160,26 @@ typedef struct rtems_blkdev_request { #define RTEMS_BLKIO_GETSIZE _IOR('B', 5, rtems_blkdev_bnum) #define RTEMS_BLKIO_SYNCDEV _IO('B', 6) #define RTEMS_BLKIO_DELETED _IO('B', 7) +#define RTEMS_BLKIO_CAPABILITIES _IO('B', 8) /** @} */ /** + * Only consecutive multi-sector buffer requests are supported. + * + * This option means the cache will only supply multiple buffers that are + * inorder so the ATA multi-sector command for example can be used. This is a + * hack to work around the current ATA driver. + */ +#define RTEMS_BLKDEV_CAP_MULTISECTOR_CONT (1 << 0) + +/** + * The driver will accept a sync call. A sync call is made to a driver + * after a bdbuf cache sync has finished. + */ +#define RTEMS_BLKDEV_CAP_SYNC (1 << 1) + +/** * The device driver interface conventions suppose that a driver may contain an * initialize, open, close, read, write and IO control entry points. These * primitives (except initialize) can be implemented in a generic fashion based diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c index 3d3ecbee9e..ce579d3730 100644 --- a/cpukit/libblock/src/bdbuf.c +++ b/cpukit/libblock/src/bdbuf.c @@ -60,6 +60,7 @@ typedef struct rtems_bdbuf_swapout_transfer { rtems_chain_control bds; /**< The transfer list of BDs. */ dev_t dev; /**< The device the transfer is for. */ + bool syncing; /**< The data is a sync'ing. */ rtems_blkdev_request* write_req; /**< The write request array. */ uint32_t bufs_per_bd; /**< Number of buffers per bd. */ } rtems_bdbuf_swapout_transfer; @@ -74,7 +75,7 @@ typedef struct rtems_bdbuf_swapout_worker * idle. */ rtems_id id; /**< The id of the task so we can wake * it. */ - volatile bool enabled; /**< The worked is enabled. */ + volatile bool enabled; /**< The worker is enabled. */ rtems_bdbuf_swapout_transfer transfer; /**< The transfer data for this * thread. */ } rtems_bdbuf_swapout_worker; @@ -1319,9 +1320,9 @@ rtems_bdbuf_init (void) if (bdbuf_cache.initialised) { rtems_bdbuf_restore_preemption (prev_mode); - return RTEMS_RESOURCE_IN_USE; } + memset(&bdbuf_cache, 0, sizeof(bdbuf_cache)); bdbuf_cache.initialised = true; rtems_bdbuf_restore_preemption (prev_mode); @@ -2042,7 +2043,7 @@ rtems_bdbuf_read (dev_t dev, #define bdbuf_alloc(size) __builtin_alloca (size) req = bdbuf_alloc (sizeof (rtems_blkdev_request) + - sizeof ( rtems_blkdev_sg_buffer) * + sizeof (rtems_blkdev_sg_buffer) * (bdbuf_config.max_read_ahead_blocks + 1)); if (rtems_bdbuf_tracer) @@ -2260,7 +2261,7 @@ rtems_bdbuf_null_disk_ioctl (rtems_disk_device *dd, uint32_t req, void *arg) /** * Swapout transfer to the driver. The driver will break this I/O into groups * of consecutive write requests is multiple consecutive buffers are required - * by the driver. + * by the driver. The cache is not locked. * * @param transfer The transfer transaction. */ @@ -2373,7 +2374,20 @@ rtems_bdbuf_swapout_write (rtems_bdbuf_swapout_transfer* transfer) } if (dd != &null_disk) + { + /* + * If sync'ing and the deivce is capability of handling a sync IO control + * call perform the call. + */ + if (transfer->syncing && + (dd->phys_dev->capabilities & RTEMS_BLKDEV_CAP_SYNC)) + { + /* int result = */ dd->ioctl (dd->phys_dev, RTEMS_BLKDEV_REQ_SYNC, NULL); + /* How should the error be handled ? */ + } + rtems_disk_release (dd); + } } } @@ -2401,20 +2415,31 @@ rtems_bdbuf_swapout_modified_processing (dev_t* dev, if (!rtems_chain_is_empty (chain)) { rtems_chain_node* node = rtems_chain_head (chain); + bool sync_all; + node = node->next; + /* + * A sync active with no valid dev means sync all. + */ + if (sync_active && (*dev == BDBUF_INVALID_DEV)) + sync_all = true; + else + sync_all = false; + while (!rtems_chain_is_tail (chain, node)) { rtems_bdbuf_buffer* bd = (rtems_bdbuf_buffer*) node; /* * Check if the buffer's hold timer has reached 0. If a sync is active - * or someone waits for a buffer force all the timers to 0. + * or someone waits for a buffer written force all the timers to 0. * * @note Lots of sync requests will skew this timer. It should be based * on TOD to be accurate. Does it matter ? */ - if (sync_active || rtems_bdbuf_has_buffer_waiters ()) + if (sync_all || (sync_active && (*dev == bd->dev)) + || rtems_bdbuf_has_buffer_waiters ()) bd->hold_timer = 0; if (bd->hold_timer) @@ -2515,11 +2540,11 @@ rtems_bdbuf_swapout_processing (unsigned long timer_delta, /* * If a sync is active do not use a worker because the current code does not * cleaning up after. We need to know the buffers have been written when - * syncing to the release sync lock and currently worker threads do not - * return to here. We do not know the worker is the last in a sequence of - * sync writes until after we have it running so we do not know to tell it to - * release the lock. The simplest solution is to get the main swap out task - * perform all sync operations. + * syncing to release sync lock and currently worker threads do not return to + * here. We do not know the worker is the last in a sequence of sync writes + * until after we have it running so we do not know to tell it to release the + * lock. The simplest solution is to get the main swap out task perform all + * sync operations. */ if (bdbuf_cache.sync_active) worker = NULL; @@ -2533,7 +2558,8 @@ rtems_bdbuf_swapout_processing (unsigned long timer_delta, rtems_chain_initialize_empty (&transfer->bds); transfer->dev = BDBUF_INVALID_DEV; - + transfer->syncing = bdbuf_cache.sync_active; + /* * When the sync is for a device limit the sync to that device. If the sync * is for a buffer handle process the devices in the order on the sync @@ -2541,7 +2567,7 @@ rtems_bdbuf_swapout_processing (unsigned long timer_delta, */ if (bdbuf_cache.sync_active) transfer->dev = bdbuf_cache.sync_device; - + /* * If we have any buffers in the sync queue move them to the modified * list. The first sync buffer will select the device we use. @@ -2753,6 +2779,7 @@ rtems_bdbuf_swapout_task (rtems_task_argument arg) transfer.write_req = rtems_bdbuf_swapout_writereq_alloc (); rtems_chain_initialize_empty (&transfer.bds); transfer.dev = BDBUF_INVALID_DEV; + transfer.syncing = false; /* * Localise the period. diff --git a/cpukit/libblock/src/diskdevs.c b/cpukit/libblock/src/diskdevs.c index 8336fcbb67..08a6a9bf8c 100644 --- a/cpukit/libblock/src/diskdevs.c +++ b/cpukit/libblock/src/diskdevs.c @@ -259,7 +259,7 @@ rtems_status_code rtems_disk_create_phys( dd->ioctl = handler; dd->driver_data = driver_data; - if ((*handler)(dd, RTEMS_BLKDEV_CAPABILITIES, &dd->capabilities) < 0) { + if ((*handler)(dd, RTEMS_BLKIO_CAPABILITIES, &dd->capabilities) < 0) { dd->capabilities = 0; } |