Custom post type filter by post meta – not returning correct counts

That is normal. Even if you use the core filters, for exmaple filter by month, that numbers doesn’t change. Also, you have made some mistakes in your queyr; for example, you should set the meta_key argumente in the where statement.

Anyway, I tink it is much better to use meta_query argument for the main WP_Query object. This can be done via the parse_query filter:

add_filter( 'parse_query', 'cyb_admin_posts_filter' );
function cyb_admin_posts_filter( $query ) {
    $screen = get_current_screen();
    if( is_admin() && $query->post_type == 'product' && $screen->base == 'edit.php' ) {
        if ( !empty($_GET['location']) ) {
           $query->query_vars['meta_query'] = array(
                                                  'meta_key' => 'location',
                                                  'meta_value' => esc_sql($_GET['location'])
                                              );
        }
    }
}

Although I said that the post count doesn’t change when using a filter as a normal behaviour, if you want ot update it you can use the views_edit-* filter (where * is the post type) and perform the query again (yes, again, a new query for each counter) to update the post counter. For example (No tested, jus writting here as example. Note that I’ve made it for the “All” filter, do similar task for the others filters):

add_action( 'views_edit-product', 'cyb_update_product_counter' );
function cyb_update_product_counter( $views ) {

    foreach ( $views as $index => $view ) {

         $args = array(
        'post_type'   => 'product'
                 );
         if( isset($_GET['location'] && !empty($_GET['location'] ) {
               $args['meta_query'] = array (
                                        'meta_key'    => 'location',
                                        'meta_value'  => esc_sql($_GET['location'])
                                     );
         }
         //Check for "All" filter. Do similar for other filters
         if( $index == 'all') {
             $args['all_posts'] = 1;
         }

         //Update the count and filter links
         $query = new WP_Query($args);
         if($query->found_posts > 0) {
             $views[$index] = preg_replace( '/ <span class="count">\([0-9]+\)<\/span>/', $result->found_posts, $view );
         } else {
              unset($views[$index]);
         }

}