void
ngx_http_file_cache_free(ngx_http_request_t *r, ngx_temp_file_t *tf)
{
    ngx_http_cache_t            *c;
    ngx_http_file_cache_t       *cache;
    ngx_http_file_cache_node_t  *fcn;

    c = r->cache;

    if (c->updated) {
        return;
    }

    c->updated = 1;

    cache = c->file_cache;

    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                   "http file cache free");

    ngx_shmtx_lock(&cache->shpool->mutex);

    fcn = c->node;
    fcn->count--;
    fcn->updating = 0;

    if (c->error) {
        fcn->valid_sec = c->valid_sec;
        fcn->valid_msec = c->valid_msec;
        fcn->error = c->error;

    } else if (!fcn->exists && fcn->count == 0) {
        ngx_queue_remove(&fcn->queue);
        ngx_rbtree_delete(&cache->sh->rbtree, &fcn->node);
        ngx_slab_free_locked(cache->shpool, fcn);
        c->node = NULL;
    }

    ngx_shmtx_unlock(&cache->shpool->mutex);

    if (c->temp_file) {
        if (tf && tf->file.fd != NGX_INVALID_FILE) {
            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                           "http file cache incomplete: \"%s\"",
                           tf->file.name.data);

            if (ngx_delete_file(tf->file.name.data) == NGX_FILE_ERROR) {
                ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
                              ngx_delete_file_n " \"%s\" failed",
                              tf->file.name.data);
            }
        }
    }
}