Changeset e7fb54e in rtems for cpukit/libblock


Ignore:
Timestamp:
01/26/10 15:09:03 (14 years ago)
Author:
Thomas Doerfler <Thomas.Doerfler@…>
Branches:
4.10, 4.11, 5, master
Children:
1027f153
Parents:
b7de5de
Message:

add purge capability to libblock, add proper test case

Location:
cpukit/libblock
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libblock/include/rtems/bdbuf.h

    rb7de5de re7fb54e  
    8787 *   am [label="ACCESS MODIFIED",style="filled",fillcolor="royalblue"];
    8888 *   ae [label="ACCESS EMPTY",style="filled",fillcolor="royalblue"];
     89 *   ap [label="ACCESS PURGED",style="filled",fillcolor="royalblue"];
    8990 *   t [label="TRANSFER",style="filled",fillcolor="red"];
     91 *   tp [label="TRANSFER PURGED",style="filled",fillcolor="red"];
    9092 *   s [label="SYNC",style="filled",fillcolor="red"];
    9193 *   m [label="MODIFIED",style="filled",fillcolor="gold"];
     
    98100 *   f -> e [label="Buffer Recycle"];
    99101 *   e -> ae [label="Get"];
    100  *   e -> t [label="Read\nRead Ahead"];
     102 *   e -> t [label="Read"];
     103 *   e -> f [label="Nobody Waits"];
     104 *   c -> ac [label="Get\nRead"];
     105 *   c -> e [label="Buffer Recycle\nPurge"];
    101106 *   c -> f [label="Reallocate\nBlock Size Changed"];
    102  *   c -> ac [label="Get\nRead"];
    103  *   c -> e [label="Buffer Recycle"];
    104107 *   t -> c [label="Transfer Done",color="red",fontcolor="red"];
    105  *   t -> e [label="Transfer Error With Waiter",color="red",fontcolor="red"];
    106  *   t -> f [label="Transfer Error Without Waiter",color="red",fontcolor="red"];
     108 *   t -> e [label="Transfer Error",color="red",fontcolor="red"];
     109 *   t -> tp [label="Purge"];
     110 *   tp -> e [label="Transfer Done\nTransfer Error",color="red",fontcolor="red"];
    107111 *   m -> t [label="Swapout"];
    108112 *   m -> s [label="Block Size Changed"];
    109113 *   m -> am [label="Get\nRead"];
     114 *   m -> e [label="Purge"];
    110115 *   ac -> m [label="Release Modified",color="royalblue",fontcolor="royalblue"];
    111116 *   ac -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
    112117 *   ac -> c [label="Release",color="royalblue",fontcolor="royalblue"];
     118 *   ac -> ap [label="Purge"];
    113119 *   am -> m [label="Release\nRelease Modified",color="royalblue",fontcolor="royalblue"];
    114120 *   am -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
     121 *   am -> ap [label="Purge"];
    115122 *   ae -> m [label="Release Modified",color="royalblue",fontcolor="royalblue"];
    116123 *   ae -> s [label="Sync",color="royalblue",fontcolor="royalblue"];
    117  *   ae -> e [label="Release With Waiter",color="royalblue",fontcolor="royalblue"];
    118  *   ae -> f [label="Release Without Waiter",color="royalblue",fontcolor="royalblue"];
     124 *   ae -> e [label="Release",color="royalblue",fontcolor="royalblue"];
     125 *   ae -> ap [label="Purge"];
     126 *   ap -> e [label="Release\nRelease Modified\nSync",color="royalblue",fontcolor="royalblue"];
    119127 *   s -> t [label="Swapout"];
     128 *   s -> e [label="Purge",color="red",fontcolor="red"];
    120129 * }
    121130 * @enddot
     
    185194 *   <tr>
    186195 *     <td>EMPTY</td><td></td><td>X</td>
    187  *     <td>X</td><td></td><td></td><td></td><td></td>
     196 *     <td></td><td></td><td></td><td></td><td></td>
    188197 *   </tr>
    189198 *   <tr>
     
    192201 *   </tr>
    193202 *   <tr>
    194  *     <td>ACCESS_CACHED</td><td>X</td><td>X</td>
     203 *     <td>ACCESS CACHED</td><td>X</td><td>X</td>
    195204 *     <td></td><td></td><td></td><td>X</td><td>X</td>
    196205 *   </tr>
    197206 *   <tr>
    198  *     <td>ACCESS_MODIFIED</td><td>X</td><td>X</td>
     207 *     <td>ACCESS MODIFIED</td><td>X</td><td>X</td>
    199208 *     <td></td><td></td><td></td><td>X</td><td>X</td>
    200209 *   </tr>
    201210 *   <tr>
    202  *     <td>ACCESS_EMPTY</td><td></td><td>X</td>
     211 *     <td>ACCESS EMPTY</td><td></td><td>X</td>
     212 *     <td></td><td></td><td></td><td>X</td><td>X</td>
     213 *   </tr>
     214 *   <tr>
     215 *     <td>ACCESS PURGED</td><td></td><td>X</td>
    203216 *     <td></td><td></td><td></td><td>X</td><td>X</td>
    204217 *   </tr>
     
    215228 *     <td></td><td></td><td></td><td>X</td><td>X</td>
    216229 *   </tr>
     230 *   <tr>
     231 *     <td>TRANSFER PURGED</td><td></td><td>X</td>
     232 *     <td></td><td></td><td></td><td>X</td><td>X</td>
     233 *   </tr>
    217234 * </table>
    218235 */
     
    250267
    251268  /**
     269   * @brief Accessed by upper layer with purged data.
     270   */
     271  RTEMS_BDBUF_STATE_ACCESS_PURGED,
     272
     273  /**
    252274   * @brief Modified by upper layer.
    253275   */
     
    262284   * @brief In transfer by block device driver.
    263285   */
    264   RTEMS_BDBUF_STATE_TRANSFER
     286  RTEMS_BDBUF_STATE_TRANSFER,
     287
     288  /**
     289   * @brief In transfer by block device driver and purged.
     290   */
     291  RTEMS_BDBUF_STATE_TRANSFER_PURGED
    265292} rtems_bdbuf_buf_state;
    266293
     
    543570rtems_bdbuf_syncdev (dev_t dev);
    544571
     572/**
     573 * @brief Purges all buffers that matches the device identifier @a dev.
     574 *
     575 * This may result in loss of data.
     576 */
     577void
     578rtems_bdbuf_purge_dev (dev_t dev);
     579
     580/**
     581 * @brief Purges all buffers that matches the device major number @a major.
     582 *
     583 * This may result in loss of data.
     584 */
     585void
     586rtems_bdbuf_purge_major (rtems_device_major_number major);
     587
    545588/** @} */
    546589
  • cpukit/libblock/src/bdbuf.c

    rb7de5de re7fb54e  
    145145  (((uint32_t)'B' << 24) | ((uint32_t)(n) & (uint32_t)0x00FFFFFF))
    146146
     147#define RTEMS_BLKDEV_FATAL_BDBUF_STATE_11      RTEMS_BLKDEV_FATAL_ERROR(1)
    147148#define RTEMS_BLKDEV_FATAL_BDBUF_STATE_4       RTEMS_BLKDEV_FATAL_ERROR(2)
    148149#define RTEMS_BLKDEV_FATAL_BDBUF_STATE_5       RTEMS_BLKDEV_FATAL_ERROR(3)
     
    10341035
    10351036static void
     1037rtems_bdbuf_remove_from_tree (rtems_bdbuf_buffer *bd)
     1038{
     1039  if (rtems_bdbuf_avl_remove (&bdbuf_cache.tree, bd) != 0)
     1040    rtems_bdbuf_fatal (bd->state, RTEMS_BLKDEV_FATAL_BDBUF_TREE_RM);
     1041}
     1042
     1043static void
     1044rtems_bdbuf_remove_from_tree_and_lru_list (rtems_bdbuf_buffer *bd)
     1045{
     1046  switch (bd->state)
     1047  {
     1048    case RTEMS_BDBUF_STATE_FREE:
     1049      break;
     1050    case RTEMS_BDBUF_STATE_CACHED:
     1051      rtems_bdbuf_remove_from_tree (bd);
     1052      break;
     1053    default:
     1054      rtems_bdbuf_fatal (bd->state, RTEMS_BLKDEV_FATAL_BDBUF_STATE_10);
     1055  }
     1056
     1057  rtems_chain_extract (&bd->link);
     1058}
     1059
     1060static void
     1061rtems_bdbuf_make_free_and_add_to_lru_list (rtems_bdbuf_buffer *bd)
     1062{
     1063  rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_FREE);
     1064  rtems_chain_prepend (&bdbuf_cache.lru, &bd->link);
     1065}
     1066
     1067static void
     1068rtems_bdbuf_make_empty (rtems_bdbuf_buffer *bd)
     1069{
     1070  rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_EMPTY);
     1071}
     1072
     1073static void
     1074rtems_bdbuf_make_cached_and_add_to_lru_list (rtems_bdbuf_buffer *bd)
     1075{
     1076  rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_CACHED);
     1077  rtems_chain_append (&bdbuf_cache.lru, &bd->link);
     1078}
     1079
     1080static void
     1081rtems_bdbuf_discard_buffer (rtems_bdbuf_buffer *bd)
     1082{
     1083  rtems_bdbuf_make_empty (bd);
     1084
     1085  if (bd->waiters == 0)
     1086  {
     1087    rtems_bdbuf_remove_from_tree (bd);
     1088    rtems_bdbuf_make_free_and_add_to_lru_list (bd);
     1089  }
     1090}
     1091
     1092static void
    10361093rtems_bdbuf_add_to_modified_list_after_access (rtems_bdbuf_buffer *bd)
    10371094{
     
    10761133rtems_bdbuf_add_to_lru_list_after_access (rtems_bdbuf_buffer *bd)
    10771134{
    1078   rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_CACHED);
    1079   rtems_chain_append (&bdbuf_cache.lru, &bd->link);
    10801135  rtems_bdbuf_group_release (bd);
     1136  rtems_bdbuf_make_cached_and_add_to_lru_list (bd);
    10811137
    10821138  if (bd->waiters)
     
    10861142}
    10871143
    1088 static void
    1089 rtems_bdbuf_add_to_sync_list_after_access (rtems_bdbuf_buffer *bd)
    1090 {
    1091   rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_SYNC);
    1092 
    1093   rtems_chain_append (&bdbuf_cache.sync, &bd->link);
    1094 
    1095   if (bd->waiters)
    1096     rtems_bdbuf_wake (&bdbuf_cache.access_waiters);
    1097 }
    1098 
    10991144/**
    11001145 * Compute the number of BDs per group for a given buffer size.
     
    11221167
    11231168static void
    1124 rtems_bdbuf_remove_from_tree (rtems_bdbuf_buffer *bd)
    1125 {
    1126   if (rtems_bdbuf_avl_remove (&bdbuf_cache.tree, bd) != 0)
    1127     rtems_bdbuf_fatal (bd->state, RTEMS_BLKDEV_FATAL_BDBUF_TREE_RM);
    1128 }
    1129 
    1130 static void
    1131 rtems_bdbuf_remove_from_tree_and_lru_list (rtems_bdbuf_buffer *bd)
    1132 {
    1133   switch (bd->state)
    1134   {
    1135     case RTEMS_BDBUF_STATE_FREE:
    1136       break;
    1137     case RTEMS_BDBUF_STATE_CACHED:
    1138       rtems_bdbuf_remove_from_tree (bd);
    1139       break;
    1140     default:
    1141       rtems_bdbuf_fatal (bd->state, RTEMS_BLKDEV_FATAL_BDBUF_STATE_10);
    1142   }
    1143 
    1144   rtems_chain_extract (&bd->link);
    1145 }
    1146 
    1147 static void
    1148 rtems_bdbuf_make_free_and_add_to_lru_list (rtems_bdbuf_buffer *bd)
    1149 {
    1150   rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_FREE);
    1151   rtems_chain_prepend (&bdbuf_cache.lru, &bd->link);
    1152 }
    1153 
    1154 static void
    1155 rtems_bdbuf_make_empty_and_add_to_lru_list (rtems_bdbuf_buffer *bd)
    1156 {
    1157   rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_EMPTY);
    1158   rtems_chain_append (&bdbuf_cache.lru, &bd->link);
    1159 }
    1160 
    1161 static void
    1162 rtems_bdbuf_release_empty_buffer (rtems_bdbuf_buffer *bd)
     1169rtems_bdbuf_discard_buffer_after_access (rtems_bdbuf_buffer *bd)
    11631170{
    11641171  rtems_bdbuf_group_release (bd);
     1172  rtems_bdbuf_discard_buffer (bd);
    11651173
    11661174  if (bd->waiters)
    1167   {
    1168     rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_EMPTY);
    1169     rtems_chain_append (&bdbuf_cache.lru, &bd->link);
    11701175    rtems_bdbuf_wake (&bdbuf_cache.access_waiters);
    1171   }
    11721176  else
    1173   {
    1174     rtems_bdbuf_remove_from_tree (bd);
    1175     rtems_bdbuf_make_free_and_add_to_lru_list (bd);
    11761177    rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
    1177   }
    11781178}
    11791179
     
    12211221
    12221222static void
    1223 rtems_bdbuf_recycle_buffer (rtems_bdbuf_buffer *bd,
    1224                             dev_t               dev,
    1225                             rtems_blkdev_bnum   block)
     1223rtems_bdbuf_setup_empty_buffer (rtems_bdbuf_buffer *bd,
     1224                                dev_t               dev,
     1225                                rtems_blkdev_bnum   block)
    12261226{
    12271227  bd->dev       = dev;
     
    12341234    rtems_fatal_error_occurred (RTEMS_BLKDEV_FATAL_BDBUF_RECYCLE);
    12351235
    1236   rtems_bdbuf_make_empty_and_add_to_lru_list (bd);
     1236  rtems_bdbuf_make_empty (bd);
    12371237}
    12381238
     
    12471247  {
    12481248    rtems_bdbuf_buffer *bd = (rtems_bdbuf_buffer *) node;
    1249     rtems_bdbuf_buffer *recycle_bd = NULL;
     1249    rtems_bdbuf_buffer *empty_bd = NULL;
    12501250
    12511251    if (rtems_bdbuf_tracer)
     
    12641264        rtems_bdbuf_remove_from_tree_and_lru_list (bd);
    12651265
    1266         recycle_bd = bd;
     1266        empty_bd = bd;
    12671267      }
    12681268      else if (bd->group->users == 0)
    1269         recycle_bd = rtems_bdbuf_group_realloc (bd->group, bds_per_group);
    1270     }
    1271 
    1272     if (recycle_bd != NULL)
    1273     {
    1274       rtems_bdbuf_recycle_buffer (recycle_bd, dev, block);
    1275 
    1276       return recycle_bd;
     1269        empty_bd = rtems_bdbuf_group_realloc (bd->group, bds_per_group);
     1270    }
     1271
     1272    if (empty_bd != NULL)
     1273    {
     1274      rtems_bdbuf_setup_empty_buffer (empty_bd, dev, block);
     1275
     1276      return empty_bd;
    12771277    }
    12781278
     
    15301530      case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
    15311531      case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
     1532      case RTEMS_BDBUF_STATE_ACCESS_PURGED:
    15321533        rtems_bdbuf_wait (bd, &bdbuf_cache.access_waiters);
    15331534        break;
     1535      case RTEMS_BDBUF_STATE_SYNC:
    15341536      case RTEMS_BDBUF_STATE_TRANSFER:
    1535       case RTEMS_BDBUF_STATE_SYNC:
     1537      case RTEMS_BDBUF_STATE_TRANSFER_PURGED:
    15361538        rtems_bdbuf_wait (bd, &bdbuf_cache.transfer_waiters);
    15371539        break;
     
    15871589      case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
    15881590      case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
     1591      case RTEMS_BDBUF_STATE_ACCESS_PURGED:
    15891592        rtems_bdbuf_wait (bd, &bdbuf_cache.access_waiters);
    15901593        break;
     1594      case RTEMS_BDBUF_STATE_SYNC:
    15911595      case RTEMS_BDBUF_STATE_TRANSFER:
    1592       case RTEMS_BDBUF_STATE_SYNC:
     1596      case RTEMS_BDBUF_STATE_TRANSFER_PURGED:
    15931597        rtems_bdbuf_wait (bd, &bdbuf_cache.transfer_waiters);
    15941598        break;
     
    16121616      case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
    16131617      case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
     1618      case RTEMS_BDBUF_STATE_ACCESS_PURGED:
    16141619        return;
    16151620      case RTEMS_BDBUF_STATE_SYNC:
    16161621      case RTEMS_BDBUF_STATE_TRANSFER:
     1622      case RTEMS_BDBUF_STATE_TRANSFER_PURGED:
    16171623        rtems_bdbuf_wait (bd, &bdbuf_cache.transfer_waiters);
    16181624        break;
     
    16301636
    16311637  rtems_bdbuf_anonymous_wait (&bdbuf_cache.buffer_waiters);
     1638}
     1639
     1640static void
     1641rtems_bdbuf_sync_after_access (rtems_bdbuf_buffer *bd)
     1642{
     1643  rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_SYNC);
     1644
     1645  rtems_chain_append (&bdbuf_cache.sync, &bd->link);
     1646
     1647  if (bd->waiters)
     1648    rtems_bdbuf_wake (&bdbuf_cache.access_waiters);
     1649
     1650  rtems_bdbuf_wake_swapper ();
     1651  rtems_bdbuf_wait_for_sync_done (bd);
     1652
     1653  /*
     1654   * We may have created a cached or empty buffer which may be recycled.
     1655   */
     1656  if (bd->waiters == 0
     1657        && (bd->state == RTEMS_BDBUF_STATE_CACHED
     1658          || bd->state == RTEMS_BDBUF_STATE_EMPTY))
     1659  {
     1660    if (bd->state == RTEMS_BDBUF_STATE_EMPTY)
     1661    {
     1662      rtems_bdbuf_remove_from_tree (bd);
     1663      rtems_bdbuf_make_free_and_add_to_lru_list (bd);
     1664    }
     1665    rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
     1666  }
    16321667}
    16331668
     
    19311966  int result = 0;
    19321967  uint32_t transfer_index = 0;
    1933   bool wake_transfer = false;
    1934   bool wake_buffer = false;
     1968  bool wake_transfer_waiters = false;
     1969  bool wake_buffer_waiters = false;
    19351970
    19361971  if (cache_locked)
     
    19521987  {
    19531988    rtems_bdbuf_buffer *bd = req->bufs [transfer_index].user;
    1954     bool waiters = bd->waiters > 0;
     1989    bool waiters = bd->waiters;
    19551990
    19561991    if (waiters)
    1957       wake_transfer = true;
     1992      wake_transfer_waiters = true;
    19581993    else
    1959       wake_buffer = true;
     1994      wake_buffer_waiters = true;
    19601995
    19611996    rtems_bdbuf_group_release (bd);
    19621997
    1963     if (sc == RTEMS_SUCCESSFUL)
    1964     {
    1965       rtems_bdbuf_set_state (bd, RTEMS_BDBUF_STATE_CACHED);
    1966       rtems_chain_append (&bdbuf_cache.lru, &bd->link);
    1967     }
    1968     else if (waiters)
    1969     {
    1970       rtems_bdbuf_make_empty_and_add_to_lru_list (bd);
    1971     }
     1998    if (sc == RTEMS_SUCCESSFUL && bd->state == RTEMS_BDBUF_STATE_TRANSFER)
     1999      rtems_bdbuf_make_cached_and_add_to_lru_list (bd);
    19722000    else
    1973     {
    1974       rtems_bdbuf_remove_from_tree (bd);
    1975       rtems_bdbuf_make_free_and_add_to_lru_list (bd);
    1976     }
     2001      rtems_bdbuf_discard_buffer (bd);
    19772002
    19782003    if (rtems_bdbuf_tracer)
     
    19802005  }
    19812006
    1982   if (wake_transfer)
     2007  if (wake_transfer_waiters)
    19832008    rtems_bdbuf_wake (&bdbuf_cache.transfer_waiters);
    19842009
    1985   if (wake_buffer)
     2010  if (wake_buffer_waiters)
    19862011    rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
    19872012
     
    21012126      break;
    21022127    case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
    2103       rtems_bdbuf_release_empty_buffer (bd);
     2128    case RTEMS_BDBUF_STATE_ACCESS_PURGED:
     2129      rtems_bdbuf_discard_buffer_after_access (bd);
    21042130      break;
    21052131    case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
     
    21352161      rtems_bdbuf_add_to_modified_list_after_access (bd);
    21362162      break;
     2163    case RTEMS_BDBUF_STATE_ACCESS_PURGED:
     2164      rtems_bdbuf_discard_buffer_after_access (bd);
     2165      break;
    21372166    default:
    21382167      rtems_bdbuf_fatal (bd->state, RTEMS_BLKDEV_FATAL_BDBUF_STATE_6);
     
    21622191    case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
    21632192    case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
    2164       rtems_bdbuf_add_to_sync_list_after_access (bd);
     2193      rtems_bdbuf_sync_after_access (bd);
     2194      break;
     2195    case RTEMS_BDBUF_STATE_ACCESS_PURGED:
     2196      rtems_bdbuf_discard_buffer_after_access (bd);
    21652197      break;
    21662198    default:
     
    21712203  if (rtems_bdbuf_tracer)
    21722204    rtems_bdbuf_show_usage ();
    2173 
    2174   rtems_bdbuf_wake_swapper ();
    2175   rtems_bdbuf_wait_for_sync_done (bd);
    2176 
    2177   /*
    2178    * If no one intercepts the sync, we created a cached buffer which may be
    2179    * recycled.
    2180    */
    2181   if (bd->waiters == 0
    2182         && (bd->state == RTEMS_BDBUF_STATE_CACHED
    2183           || bd->state == RTEMS_BDBUF_STATE_EMPTY))
    2184   {
    2185     if (bd->state == RTEMS_BDBUF_STATE_EMPTY)
    2186     {
    2187       rtems_bdbuf_remove_from_tree (bd);
    2188       rtems_bdbuf_make_free_and_add_to_lru_list (bd);
    2189     }
    2190     rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
    2191   }
    21922205
    21932206  rtems_bdbuf_unlock_cache ();
     
    28102823  rtems_task_delete (RTEMS_SELF);
    28112824}
     2825
     2826static void
     2827rtems_bdbuf_purge_list (rtems_chain_control *purge_list)
     2828{
     2829  bool wake_buffer_waiters = false;
     2830  rtems_chain_node *node = NULL;
     2831
     2832  while ((node = rtems_chain_get (purge_list)) != NULL)
     2833  {
     2834    rtems_bdbuf_buffer *bd = (rtems_bdbuf_buffer *) node;
     2835
     2836    if (bd->waiters == 0)
     2837      wake_buffer_waiters = true;
     2838
     2839    rtems_bdbuf_discard_buffer (bd);
     2840  }
     2841
     2842  if (wake_buffer_waiters)
     2843    rtems_bdbuf_wake (&bdbuf_cache.buffer_waiters);
     2844}
     2845
     2846typedef bool (*rtems_bdbuf_purge_compare)(dev_t a, dev_t b);
     2847
     2848static void
     2849rtems_bdbuf_gather_for_purge (rtems_chain_control *purge_list,
     2850                              rtems_bdbuf_purge_compare compare,
     2851                              dev_t dev)
     2852{
     2853  rtems_bdbuf_buffer *stack [RTEMS_BDBUF_AVL_MAX_HEIGHT];
     2854  rtems_bdbuf_buffer **prev = stack;
     2855  rtems_bdbuf_buffer *cur = bdbuf_cache.tree;
     2856
     2857  *prev = NULL;
     2858
     2859  while (cur != NULL)
     2860  {
     2861    if ((*compare) (cur->dev, dev))
     2862    {
     2863      switch (cur->state)
     2864      {
     2865        case RTEMS_BDBUF_STATE_FREE:
     2866        case RTEMS_BDBUF_STATE_EMPTY:
     2867        case RTEMS_BDBUF_STATE_ACCESS_PURGED:
     2868        case RTEMS_BDBUF_STATE_TRANSFER_PURGED:
     2869          break;
     2870        case RTEMS_BDBUF_STATE_SYNC:
     2871          rtems_bdbuf_wake (&bdbuf_cache.transfer_waiters);
     2872          /* Fall through */
     2873        case RTEMS_BDBUF_STATE_MODIFIED:
     2874          rtems_bdbuf_group_release (cur);
     2875          /* Fall through */
     2876        case RTEMS_BDBUF_STATE_CACHED:
     2877          rtems_chain_extract (&cur->link);
     2878          rtems_chain_append (purge_list, &cur->link);
     2879          break;
     2880        case RTEMS_BDBUF_STATE_TRANSFER:
     2881          rtems_bdbuf_set_state (cur, RTEMS_BDBUF_STATE_TRANSFER_PURGED);
     2882          break;
     2883        case RTEMS_BDBUF_STATE_ACCESS_CACHED:
     2884        case RTEMS_BDBUF_STATE_ACCESS_EMPTY:
     2885        case RTEMS_BDBUF_STATE_ACCESS_MODIFIED:
     2886          rtems_bdbuf_set_state (cur, RTEMS_BDBUF_STATE_ACCESS_PURGED);
     2887          break;
     2888        default:
     2889          rtems_fatal_error_occurred (RTEMS_BLKDEV_FATAL_BDBUF_STATE_11);
     2890      }
     2891    }
     2892
     2893    if (cur->avl.left != NULL)
     2894    {
     2895      /* Left */
     2896      ++prev;
     2897      *prev = cur;
     2898      cur = cur->avl.left;
     2899    }
     2900    else if (cur->avl.right != NULL)
     2901    {
     2902      /* Right */
     2903      ++prev;
     2904      *prev = cur;
     2905      cur = cur->avl.right;
     2906    }
     2907    else
     2908    {
     2909      while (*prev != NULL && cur == (*prev)->avl.right)
     2910      {
     2911        /* Up */
     2912        cur = *prev;
     2913        --prev;
     2914      }
     2915      if (*prev != NULL)
     2916        /* Right */
     2917        cur = (*prev)->avl.right;
     2918      else
     2919        /* Finished */
     2920        cur = NULL;
     2921    }
     2922  }
     2923}
     2924
     2925static void
     2926rtems_bdbuf_purge (rtems_bdbuf_purge_compare compare, dev_t dev)
     2927{
     2928  rtems_chain_control purge_list;
     2929
     2930  rtems_chain_initialize_empty (&purge_list);
     2931  rtems_bdbuf_lock_cache ();
     2932  rtems_bdbuf_gather_for_purge (&purge_list, compare, dev);
     2933  rtems_bdbuf_purge_list (&purge_list);
     2934  rtems_bdbuf_unlock_cache ();
     2935}
     2936
     2937static bool
     2938rtems_bdbuf_purge_compare_dev (dev_t a, dev_t b)
     2939{
     2940  return a == b;
     2941}
     2942
     2943void
     2944rtems_bdbuf_purge_dev (dev_t dev)
     2945{
     2946  rtems_bdbuf_purge (rtems_bdbuf_purge_compare_dev, dev);
     2947}
     2948
     2949static bool
     2950rtems_bdbuf_purge_compare_major (dev_t a, dev_t b)
     2951{
     2952  return rtems_filesystem_dev_major_t (a) == rtems_filesystem_dev_major_t (b);
     2953}
     2954
     2955void
     2956rtems_bdbuf_purge_major (rtems_device_major_number major)
     2957{
     2958  dev_t dev = rtems_filesystem_make_dev_t (major, 0);
     2959
     2960  rtems_bdbuf_purge (rtems_bdbuf_purge_compare_major, dev);
     2961}
Note: See TracChangeset for help on using the changeset viewer.