// SPDX-License-Identifier: GPL-2.0
/*
* Main bcache entry point - handle a read or a write request and decide what to
* do with it; the make_request functions are called by the block layer.
*
* Copyright 2010, 2011 Kent Overstreet <kent.overstreet@gmail.com>
* Copyright 2012 Google, Inc.
*/
#include "bcache.h"
#include "btree.h"
#include "debug.h"
#include "request.h"
#include "writeback.h"
#include <linux/module.h>
#include <linux/hash.h>
#include <linux/random.h>
#include <linux/backing-dev.h>
#include <trace/events/bcache.h>
#define CUTOFF_CACHE_ADD 95
#define CUTOFF_CACHE_READA 90
struct kmem_cache *bch_search_cache;
static void bch_data_insert_start(struct closure *);
static unsigned cache_mode(struct cached_dev *dc)
{
return BDEV_CACHE_MODE(&dc->sb);
}
static bool verify(struct cached_dev *dc)
{
return dc->verify;
}
static void bio_csum(struct bio *bio, struct bkey *k)
{
struct bio_vec bv;
struct bvec_iter iter;
uint64_t csum = 0;
bio_for_each_segment(bv, bio, iter) {
void *d = kmap(bv.bv_page) + bv.bv_offset;
csum = bch_crc64_update(csum, d, bv.bv_len);
kunmap(bv.bv_page);
}
k->ptr[KEY_PTRS(k)] = csum & (~0ULL >> 1);
}
/* Insert data into cache */
static void bch_data_insert_keys(struct closure *cl)
{
struct data_insert_op *op = container_of(cl, struct data_insert_op, cl);
atomic_t *journal_ref = NULL;
struct bkey *replace_key = op->replace ? &op->replace_key : NULL;
int ret;
/*
* If we're looping, might already be waiting on
* another journal write - can't wait on more than one journal write at
* a time
*
* XXX: this looks wrong
*/
#if 0
while (atomic_read(&s->cl.remaining) & CLOSURE_WAITING)
closure_sync(&s->cl);
#endif
if (!op->replace)
journal_ref = bch_journal(op->c, &op->insert_keys,
op->flush_journal ? cl : NULL);
ret = bch_btree_insert(op->c, &op->insert_keys,
journal_ref, replace_key);