From: Tejun Heo <tj-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
To: Kent Overstreet <koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
Cc: linux-bcache-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
dm-devel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org,
agk-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org
Subject: Re: [Bcache v13 11/16] bcache: Core btree code
Date: Tue, 22 May 2012 15:40:58 -0700 [thread overview]
Message-ID: <20120522224058.GL14339@google.com> (raw)
In-Reply-To: <7f1de39b6d7040b3fe271500776f4b985b21ea82.1336619038.git.koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
Hello, Kent.
On Wed, May 09, 2012 at 11:10:48PM -0400, Kent Overstreet wrote:
> +#define BKEY_PADDED(key) \
> + union { struct bkey key; uint64_t key ## _pad[8]; }
What does the '8' mean? And why does struct bbio use 3 instead? Does
this have to be a macro? Can't we have struct bkey_padded (or
whatever)?
> +struct io {
> + /* Used to track sequential IO so it can be skipped */
> + struct hlist_node hash;
> + struct list_head lru;
> +
> + unsigned long jiffies;
> + unsigned sequential;
> + sector_t last;
> +};
I don't think bcache can have struct io. :P
> +struct dirty_io {
> + struct closure cl;
> + struct cached_dev *d;
> + struct bio bio;
> +};
> +
> +struct dirty {
> + struct rb_node node;
> + BKEY_PADDED(key);
> + struct dirty_io *io;
> +};
...
> +struct cache {
Nor these and so on.
> +/* Bkey fields: all units are in sectors */
> +
> +#define KEY_FIELD(name, field, offset, size) \
> + BITMASK(name, struct bkey, field, offset, size)
> +
> +#define PTR_FIELD(name, offset, size) \
> + static inline uint64_t name(const struct bkey *k, unsigned i) \
> + { return (k->ptr[i] >> offset) & ~(((uint64_t) ~0) << size); } \
> + \
> + static inline void SET_##name(struct bkey *k, unsigned i, uint64_t v)\
> + { \
> + k->ptr[i] &= ~(~((uint64_t) ~0 << size) << offset); \
> + k->ptr[i] |= v << offset; \
> + }
> +
> +KEY_FIELD(KEY_PTRS, header, 60, 3)
> +KEY_FIELD(HEADER_SIZE, header, 58, 2)
> +KEY_FIELD(KEY_CSUM, header, 56, 2)
> +KEY_FIELD(KEY_PINNED, header, 55, 1)
> +KEY_FIELD(KEY_DIRTY, header, 36, 1)
> +
> +KEY_FIELD(KEY_SIZE, header, 20, 16)
> +KEY_FIELD(KEY_DEV, header, 0, 20)
> +
> +KEY_FIELD(KEY_SECTOR, key, 16, 47)
> +KEY_FIELD(KEY_SNAPSHOT, key, 0, 16)
> +
> +PTR_FIELD(PTR_DEV, 51, 12)
> +PTR_FIELD(PTR_OFFSET, 8, 43)
> +PTR_FIELD(PTR_GEN, 0, 8)
So, apart from the the macros, key is 64bit containing the backend
device and extent offset and size with the ptr fields somehow point to
cache. Am I understanding it correctly? If right, I'm *tiny* bit
apprehensive about using only 43bits for offset. While the block 9
bits means 52bit addressing, the 9 bit block size is now there mostly
to work as buffer between memory bitness growth and storage device
size growth so that we have 9 bit buffer as storage device reaches
ulong addressing limit. Probably those days are far out enough.
> +void btree_read_done(struct closure *cl)
> +{
> + struct btree *b = container_of(cl, struct btree, io.cl);
> + struct bset *i = b->sets[0].data;
> + struct btree_iter *iter = b->c->fill_iter;
> + const char *err = "bad btree header";
> + BUG_ON(b->nsets || b->written);
> +
> + bbio_free(b->bio, b->c);
> + b->bio = NULL;
> +
> + mutex_lock(&b->c->fill_lock);
> + iter->used = 0;
> +
> + if (btree_node_io_error(b) ||
> + !i->seq)
> + goto err;
> +
> + for (;
> + b->written < btree_blocks(b) && i->seq == b->sets[0].data->seq;
> + i = write_block(b)) {
> + err = "unsupported bset version";
> + if (i->version > BCACHE_BSET_VERSION)
> + goto err;
> +
> + err = "bad btree header";
> + if (b->written + set_blocks(i, b->c) > btree_blocks(b))
> + goto err;
> +
> + err = "bad magic";
> + if (i->magic != bset_magic(b->c))
> + goto err;
> +
> + err = "bad checksum";
> + switch (i->version) {
> + case 0:
> + if (i->csum != csum_set(i))
> + goto err;
> + break;
> + case BCACHE_BSET_VERSION:
> + if (i->csum != btree_csum_set(b, i))
> + goto err;
> + break;
> + }
> +
> + err = "empty set";
> + if (i != b->sets[0].data && !i->keys)
> + goto err;
> +
> + btree_iter_push(iter, i->start, end(i));
> +
> + b->written += set_blocks(i, b->c);
> + }
> +
> + err = "corrupted btree";
> + for (i = write_block(b);
> + index(i, b) < btree_blocks(b);
> + i = ((void *) i) + block_bytes(b->c))
> + if (i->seq == b->sets[0].data->seq)
> + goto err;
> +
> + btree_sort_and_fix_extents(b, iter);
> +
> + i = b->sets[0].data;
> + err = "short btree key";
> + if (b->sets[0].size &&
> + bkey_cmp(&b->key, &b->sets[0].end) < 0)
> + goto err;
> +
> + if (b->written < btree_blocks(b))
> + bset_init_next(b);
> +
> + if (0) {
> +err: set_btree_node_io_error(b);
> + cache_set_error(b->c, "%s at bucket %lu, block %zu, %u keys",
> + err, PTR_BUCKET_NR(b->c, &b->key, 0),
> + index(i, b), i->keys);
> + }
Please don't do that. Just define out: label, move error specific
path to the end of the function and jump to out at the end of that.
> +
> + mutex_unlock(&b->c->fill_lock);
> +
> + spin_lock(&b->c->btree_read_time_lock);
> + time_stats_update(&b->c->btree_read_time, b->io_start_time);
> + spin_unlock(&b->c->btree_read_time_lock);
> +
> + smp_wmb(); /* read_done is our write lock */
> + set_btree_node_read_done(b);
> +
> + closure_return(cl);
> +}
> +
> +static void btree_read_resubmit(struct closure *cl)
> +{
> + struct btree *b = container_of(cl, struct btree, io.cl);
> +
> + submit_bbio_split(b->bio, b->c, &b->key, 0);
> + continue_at(&b->io.cl, btree_read_done, system_wq);
> +}
I suppose submit_bbio_split() can't fail here somehow unlike from
btree_read() path? If so, please add a comment to explain and maybe
WARN_ON_ONCE() on failure. Subtlety to comment ratio is *way* off.
> +static struct btree *mca_bucket_alloc(struct cache_set *c,
> + struct bkey *k, gfp_t gfp)
> +{
> + struct btree *b = kzalloc(sizeof(struct btree), gfp);
> + if (!b)
> + return NULL;
> +
> + init_rwsem(&b->lock);
> + INIT_LIST_HEAD(&b->list);
> + INIT_DELAYED_WORK(&b->work, btree_write_work);
> + b->c = c;
> + closure_init_unlocked(&b->io);
> +
> + mca_data_alloc(b, k, gfp);
> + return b->sets[0].data ? b : NULL;
> +}
mca_data_alloc() failure path seems like a resource leak but it isn't
because mca_data_alloc() puts it in free list. Is the extra level of
caching necessary? How is it different from sl?b allocator cache?
And either way, comments please.
> +static int mca_reap(struct btree *b, struct closure *cl)
> +{
> + lockdep_assert_held(&b->c->bucket_lock);
> +
> + if (!down_write_trylock(&b->lock))
> + return -1;
> +
> + BUG_ON(btree_node_dirty(b) && !b->sets[0].data);
> +
> + if (cl && btree_node_dirty(b))
> + btree_write(b, true, NULL);
> +
> + if (cl)
> + closure_wait_event_async(&b->io.wait, cl,
> + atomic_read(&b->io.cl.remaining) == -1);
> +
> + if (btree_node_dirty(b) ||
> + atomic_read(&b->io.cl.remaining) != -1 ||
> + work_pending(&b->work.work)) {
> + rw_unlock(true, b);
> + return -EAGAIN;
> + }
> +
> + return 0;
> +}
Mixing -1 and -EAGAIN returns usually isn't a good idea.
> +static struct btree *alloc_bucket(struct cache_set *c, struct bkey *k,
> + int level, struct closure *cl)
> +{
> + struct btree *b, *i;
> + unsigned page_order = ilog2(KEY_SIZE(k) / PAGE_SECTORS ?: 1);
> +
> + lockdep_assert_held(&c->bucket_lock);
> +retry:
> + if (find_bucket(c, k))
> + return NULL;
> +
> + /* btree_free() doesn't free memory; it sticks the node on the end of
> + * the list. Check if there's any freed nodes there:
> + */
> + list_for_each_entry(b, &c->btree_cache_freeable, list)
> + if (page_order <= b->page_order &&
> + !b->key.ptr[0] &&
> + !mca_reap(b, NULL))
> + goto out;
> +
> + /* We never free struct btree itself, just the memory that holds the on
> + * disk node. Check the freed list before allocating a new one:
> + */
> + list_for_each_entry(b, &c->btree_cache_freed, list)
> + if (!mca_reap(b, NULL)) {
> + mca_data_alloc(b, k, __GFP_NOWARN|GFP_NOIO);
> + if (!b->sets[0].data) {
> + rw_unlock(true, b);
> + goto err;
> + } else
> + goto out;
> + }
> +
> + b = mca_bucket_alloc(c, k, __GFP_NOWARN|GFP_NOIO);
> + if (!b)
> + goto err;
> +
> + BUG_ON(!down_write_trylock(&b->lock));
> +out:
> + BUG_ON(!closure_is_unlocked(&b->io.cl));
> +
> + bkey_copy(&b->key, k);
> + list_move(&b->list, &c->btree_cache);
> + hlist_del_init_rcu(&b->hash);
> + hlist_add_head_rcu(&b->hash, hash_bucket(c, k));
> + lock_set_subclass(&b->lock.dep_map, level + 1, _THIS_IP_);
> +
> + b->flags = 0;
> + b->level = level;
> + b->written = 0;
> + b->nsets = 0;
> + for (int i = 0; i < MAX_BSETS; i++)
> + b->sets[i].size = 0;
> + for (int i = 1; i < MAX_BSETS; i++)
> + b->sets[i].data = NULL;
Why separate loops?
> +
> + return b;
> +err:
> + if (current->bio_list)
> + return ERR_PTR(-EAGAIN);
What does this test do?
Thanks.
--
tejun
WARNING: multiple messages have this Message-ID (diff)
From: Tejun Heo <tj@kernel.org>
To: Kent Overstreet <koverstreet@google.com>
Cc: linux-bcache@vger.kernel.org, linux-kernel@vger.kernel.org,
dm-devel@redhat.com, agk@redhat.com
Subject: Re: [Bcache v13 11/16] bcache: Core btree code
Date: Tue, 22 May 2012 15:40:58 -0700 [thread overview]
Message-ID: <20120522224058.GL14339@google.com> (raw)
In-Reply-To: <7f1de39b6d7040b3fe271500776f4b985b21ea82.1336619038.git.koverstreet@google.com>
Hello, Kent.
On Wed, May 09, 2012 at 11:10:48PM -0400, Kent Overstreet wrote:
> +#define BKEY_PADDED(key) \
> + union { struct bkey key; uint64_t key ## _pad[8]; }
What does the '8' mean? And why does struct bbio use 3 instead? Does
this have to be a macro? Can't we have struct bkey_padded (or
whatever)?
> +struct io {
> + /* Used to track sequential IO so it can be skipped */
> + struct hlist_node hash;
> + struct list_head lru;
> +
> + unsigned long jiffies;
> + unsigned sequential;
> + sector_t last;
> +};
I don't think bcache can have struct io. :P
> +struct dirty_io {
> + struct closure cl;
> + struct cached_dev *d;
> + struct bio bio;
> +};
> +
> +struct dirty {
> + struct rb_node node;
> + BKEY_PADDED(key);
> + struct dirty_io *io;
> +};
...
> +struct cache {
Nor these and so on.
> +/* Bkey fields: all units are in sectors */
> +
> +#define KEY_FIELD(name, field, offset, size) \
> + BITMASK(name, struct bkey, field, offset, size)
> +
> +#define PTR_FIELD(name, offset, size) \
> + static inline uint64_t name(const struct bkey *k, unsigned i) \
> + { return (k->ptr[i] >> offset) & ~(((uint64_t) ~0) << size); } \
> + \
> + static inline void SET_##name(struct bkey *k, unsigned i, uint64_t v)\
> + { \
> + k->ptr[i] &= ~(~((uint64_t) ~0 << size) << offset); \
> + k->ptr[i] |= v << offset; \
> + }
> +
> +KEY_FIELD(KEY_PTRS, header, 60, 3)
> +KEY_FIELD(HEADER_SIZE, header, 58, 2)
> +KEY_FIELD(KEY_CSUM, header, 56, 2)
> +KEY_FIELD(KEY_PINNED, header, 55, 1)
> +KEY_FIELD(KEY_DIRTY, header, 36, 1)
> +
> +KEY_FIELD(KEY_SIZE, header, 20, 16)
> +KEY_FIELD(KEY_DEV, header, 0, 20)
> +
> +KEY_FIELD(KEY_SECTOR, key, 16, 47)
> +KEY_FIELD(KEY_SNAPSHOT, key, 0, 16)
> +
> +PTR_FIELD(PTR_DEV, 51, 12)
> +PTR_FIELD(PTR_OFFSET, 8, 43)
> +PTR_FIELD(PTR_GEN, 0, 8)
So, apart from the the macros, key is 64bit containing the backend
device and extent offset and size with the ptr fields somehow point to
cache. Am I understanding it correctly? If right, I'm *tiny* bit
apprehensive about using only 43bits for offset. While the block 9
bits means 52bit addressing, the 9 bit block size is now there mostly
to work as buffer between memory bitness growth and storage device
size growth so that we have 9 bit buffer as storage device reaches
ulong addressing limit. Probably those days are far out enough.
> +void btree_read_done(struct closure *cl)
> +{
> + struct btree *b = container_of(cl, struct btree, io.cl);
> + struct bset *i = b->sets[0].data;
> + struct btree_iter *iter = b->c->fill_iter;
> + const char *err = "bad btree header";
> + BUG_ON(b->nsets || b->written);
> +
> + bbio_free(b->bio, b->c);
> + b->bio = NULL;
> +
> + mutex_lock(&b->c->fill_lock);
> + iter->used = 0;
> +
> + if (btree_node_io_error(b) ||
> + !i->seq)
> + goto err;
> +
> + for (;
> + b->written < btree_blocks(b) && i->seq == b->sets[0].data->seq;
> + i = write_block(b)) {
> + err = "unsupported bset version";
> + if (i->version > BCACHE_BSET_VERSION)
> + goto err;
> +
> + err = "bad btree header";
> + if (b->written + set_blocks(i, b->c) > btree_blocks(b))
> + goto err;
> +
> + err = "bad magic";
> + if (i->magic != bset_magic(b->c))
> + goto err;
> +
> + err = "bad checksum";
> + switch (i->version) {
> + case 0:
> + if (i->csum != csum_set(i))
> + goto err;
> + break;
> + case BCACHE_BSET_VERSION:
> + if (i->csum != btree_csum_set(b, i))
> + goto err;
> + break;
> + }
> +
> + err = "empty set";
> + if (i != b->sets[0].data && !i->keys)
> + goto err;
> +
> + btree_iter_push(iter, i->start, end(i));
> +
> + b->written += set_blocks(i, b->c);
> + }
> +
> + err = "corrupted btree";
> + for (i = write_block(b);
> + index(i, b) < btree_blocks(b);
> + i = ((void *) i) + block_bytes(b->c))
> + if (i->seq == b->sets[0].data->seq)
> + goto err;
> +
> + btree_sort_and_fix_extents(b, iter);
> +
> + i = b->sets[0].data;
> + err = "short btree key";
> + if (b->sets[0].size &&
> + bkey_cmp(&b->key, &b->sets[0].end) < 0)
> + goto err;
> +
> + if (b->written < btree_blocks(b))
> + bset_init_next(b);
> +
> + if (0) {
> +err: set_btree_node_io_error(b);
> + cache_set_error(b->c, "%s at bucket %lu, block %zu, %u keys",
> + err, PTR_BUCKET_NR(b->c, &b->key, 0),
> + index(i, b), i->keys);
> + }
Please don't do that. Just define out: label, move error specific
path to the end of the function and jump to out at the end of that.
> +
> + mutex_unlock(&b->c->fill_lock);
> +
> + spin_lock(&b->c->btree_read_time_lock);
> + time_stats_update(&b->c->btree_read_time, b->io_start_time);
> + spin_unlock(&b->c->btree_read_time_lock);
> +
> + smp_wmb(); /* read_done is our write lock */
> + set_btree_node_read_done(b);
> +
> + closure_return(cl);
> +}
> +
> +static void btree_read_resubmit(struct closure *cl)
> +{
> + struct btree *b = container_of(cl, struct btree, io.cl);
> +
> + submit_bbio_split(b->bio, b->c, &b->key, 0);
> + continue_at(&b->io.cl, btree_read_done, system_wq);
> +}
I suppose submit_bbio_split() can't fail here somehow unlike from
btree_read() path? If so, please add a comment to explain and maybe
WARN_ON_ONCE() on failure. Subtlety to comment ratio is *way* off.
> +static struct btree *mca_bucket_alloc(struct cache_set *c,
> + struct bkey *k, gfp_t gfp)
> +{
> + struct btree *b = kzalloc(sizeof(struct btree), gfp);
> + if (!b)
> + return NULL;
> +
> + init_rwsem(&b->lock);
> + INIT_LIST_HEAD(&b->list);
> + INIT_DELAYED_WORK(&b->work, btree_write_work);
> + b->c = c;
> + closure_init_unlocked(&b->io);
> +
> + mca_data_alloc(b, k, gfp);
> + return b->sets[0].data ? b : NULL;
> +}
mca_data_alloc() failure path seems like a resource leak but it isn't
because mca_data_alloc() puts it in free list. Is the extra level of
caching necessary? How is it different from sl?b allocator cache?
And either way, comments please.
> +static int mca_reap(struct btree *b, struct closure *cl)
> +{
> + lockdep_assert_held(&b->c->bucket_lock);
> +
> + if (!down_write_trylock(&b->lock))
> + return -1;
> +
> + BUG_ON(btree_node_dirty(b) && !b->sets[0].data);
> +
> + if (cl && btree_node_dirty(b))
> + btree_write(b, true, NULL);
> +
> + if (cl)
> + closure_wait_event_async(&b->io.wait, cl,
> + atomic_read(&b->io.cl.remaining) == -1);
> +
> + if (btree_node_dirty(b) ||
> + atomic_read(&b->io.cl.remaining) != -1 ||
> + work_pending(&b->work.work)) {
> + rw_unlock(true, b);
> + return -EAGAIN;
> + }
> +
> + return 0;
> +}
Mixing -1 and -EAGAIN returns usually isn't a good idea.
> +static struct btree *alloc_bucket(struct cache_set *c, struct bkey *k,
> + int level, struct closure *cl)
> +{
> + struct btree *b, *i;
> + unsigned page_order = ilog2(KEY_SIZE(k) / PAGE_SECTORS ?: 1);
> +
> + lockdep_assert_held(&c->bucket_lock);
> +retry:
> + if (find_bucket(c, k))
> + return NULL;
> +
> + /* btree_free() doesn't free memory; it sticks the node on the end of
> + * the list. Check if there's any freed nodes there:
> + */
> + list_for_each_entry(b, &c->btree_cache_freeable, list)
> + if (page_order <= b->page_order &&
> + !b->key.ptr[0] &&
> + !mca_reap(b, NULL))
> + goto out;
> +
> + /* We never free struct btree itself, just the memory that holds the on
> + * disk node. Check the freed list before allocating a new one:
> + */
> + list_for_each_entry(b, &c->btree_cache_freed, list)
> + if (!mca_reap(b, NULL)) {
> + mca_data_alloc(b, k, __GFP_NOWARN|GFP_NOIO);
> + if (!b->sets[0].data) {
> + rw_unlock(true, b);
> + goto err;
> + } else
> + goto out;
> + }
> +
> + b = mca_bucket_alloc(c, k, __GFP_NOWARN|GFP_NOIO);
> + if (!b)
> + goto err;
> +
> + BUG_ON(!down_write_trylock(&b->lock));
> +out:
> + BUG_ON(!closure_is_unlocked(&b->io.cl));
> +
> + bkey_copy(&b->key, k);
> + list_move(&b->list, &c->btree_cache);
> + hlist_del_init_rcu(&b->hash);
> + hlist_add_head_rcu(&b->hash, hash_bucket(c, k));
> + lock_set_subclass(&b->lock.dep_map, level + 1, _THIS_IP_);
> +
> + b->flags = 0;
> + b->level = level;
> + b->written = 0;
> + b->nsets = 0;
> + for (int i = 0; i < MAX_BSETS; i++)
> + b->sets[i].size = 0;
> + for (int i = 1; i < MAX_BSETS; i++)
> + b->sets[i].data = NULL;
Why separate loops?
> +
> + return b;
> +err:
> + if (current->bio_list)
> + return ERR_PTR(-EAGAIN);
What does this test do?
Thanks.
--
tejun
next prev parent reply other threads:[~2012-05-22 22:40 UTC|newest]
Thread overview: 152+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-10 3:07 [Bcache v13 00/16] Kent Overstreet
[not found] ` <cover.1336619038.git.koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-10 3:08 ` [Bcache v13 01/16] Only clone bio vecs that are in use Kent Overstreet
2012-05-10 3:08 ` Kent Overstreet
[not found] ` <cb817596299fecd01ea36e4a80203f23165bda75.1336619038.git.koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-10 21:35 ` [dm-devel] " Vivek Goyal
2012-05-10 21:35 ` Vivek Goyal
[not found] ` <20120510213556.GO23768-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2012-05-10 21:42 ` Kent Overstreet
2012-05-10 21:42 ` Kent Overstreet
[not found] ` <CAH+dOxJ2Vi=8Oq1zDZLmqD9-a_wgM=co3+xemw4XBoiDkh_4zg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-05-11 13:29 ` Jeff Moyer
2012-05-11 13:29 ` Jeff Moyer
2012-05-11 20:29 ` Kent Overstreet
2012-05-15 16:19 ` Tejun Heo
2012-05-15 16:19 ` Tejun Heo
2012-05-10 3:08 ` [Bcache v13 02/16] Bio pool freeing Kent Overstreet
2012-05-10 3:08 ` Kent Overstreet
[not found] ` <ba8ce9fcca87f192ff5f5d3a436eb8f4d0bcb006.1336619038.git.koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-10 21:32 ` [dm-devel] " Vivek Goyal
2012-05-10 21:32 ` Vivek Goyal
2012-05-10 21:39 ` Kent Overstreet
[not found] ` <CAH+dOxL7QwcyUm46cK-pF1qK+kHYC=67iAaQDDwUF2ssJwergA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2012-05-10 21:52 ` Vivek Goyal
2012-05-10 21:52 ` Vivek Goyal
[not found] ` <20120510215208.GC2613-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2012-05-10 21:53 ` Kent Overstreet
2012-05-10 21:53 ` Kent Overstreet
2012-05-15 16:24 ` Tejun Heo
2012-05-15 16:24 ` Tejun Heo
2012-05-15 16:25 ` Tejun Heo
2012-05-15 16:25 ` Tejun Heo
2012-05-10 3:08 ` [Bcache v13 03/16] Revert "rw_semaphore: remove up/down_read_non_owner" Kent Overstreet
2012-05-10 3:08 ` Kent Overstreet
[not found] ` <3f51ec3e69b8f471e2d1cc539f01504e2b903fed.1336619038.git.koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-15 16:37 ` Tejun Heo
2012-05-15 16:37 ` Tejun Heo
2012-05-15 16:38 ` Tejun Heo
2012-05-10 3:09 ` [Bcache v13 04/16] Fix ratelimit macro to compile in c99 mode Kent Overstreet
2012-05-10 3:09 ` Kent Overstreet
[not found] ` <d7cfd6b70316efc3fe2ce575203d906a610e3670.1336619038.git.koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-15 16:43 ` Tejun Heo
2012-05-15 16:43 ` Tejun Heo
2012-05-10 3:09 ` [Bcache v13 06/16] Export blk_fill_rwbs() Kent Overstreet
2012-05-10 3:09 ` Kent Overstreet
2012-05-10 3:11 ` [Bcache v13 16/16] bcache: Debug and tracing code Kent Overstreet
2012-05-10 3:11 ` Kent Overstreet
2012-05-10 18:34 ` [Bcache v13 00/16] Dan Williams
2012-05-10 18:34 ` Dan Williams
2012-05-18 10:06 ` Arnd Bergmann
2012-05-18 10:06 ` Arnd Bergmann
2012-05-30 8:29 ` Tejun Heo
2012-05-30 8:29 ` Tejun Heo
2012-05-30 8:54 ` Zhi Yong Wu
2012-05-30 8:54 ` Zhi Yong Wu
2012-05-10 3:09 ` [Bcache v13 05/16] Export get_random_int() Kent Overstreet
[not found] ` <5278ad493eb3ad441b2091b4c119d741e47f5c97.1336619038.git.koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-15 16:44 ` Tejun Heo
2012-05-15 16:44 ` Tejun Heo
2012-05-10 3:09 ` [Bcache v13 07/16] Closures Kent Overstreet
[not found] ` <82f00ebb4ee0404788c5bd7fbfa1fe4969f28ba1.1336619038.git.koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-15 22:41 ` Tejun Heo
2012-05-15 22:41 ` Tejun Heo
[not found] ` <20120515224137.GA15386-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-18 6:29 ` Kent Overstreet
2012-05-18 6:29 ` Kent Overstreet
[not found] ` <20120518062948.GA21163-RcKxWJ4Cfj3IzGYXcIpNmNLIRw13R84JkQQo+JxHRPFibQn6LdNjmg@public.gmane.org>
2012-05-18 10:02 ` Alan Cox
2012-05-18 10:02 ` Alan Cox
2012-05-21 19:40 ` Kent Overstreet
2012-05-10 3:10 ` [Bcache v13 08/16] bcache: Documentation, and changes to generic code Kent Overstreet
2012-05-10 3:10 ` [Bcache v13 09/16] Bcache: generic utility code Kent Overstreet
[not found] ` <c3f0ca2a499f532253d4c16a30837d43e237266a.1336619038.git.koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-10 19:35 ` Dan Williams
2012-05-10 19:35 ` Dan Williams
2012-05-10 21:42 ` Kent Overstreet
2012-05-22 21:17 ` Tejun Heo
2012-05-22 21:17 ` Tejun Heo
2012-05-23 3:12 ` Kent Overstreet
2012-05-23 3:12 ` Kent Overstreet
[not found] ` <20120523031214.GA607-RcKxWJ4Cfj3IzGYXcIpNmNLIRw13R84JkQQo+JxHRPFibQn6LdNjmg@public.gmane.org>
2012-05-23 3:36 ` Joe Perches
2012-05-23 3:36 ` Joe Perches
2012-05-23 4:50 ` [PATCH] Add human-readable units modifier to vsnprintf() Kent Overstreet
[not found] ` <20120523045023.GE607-RcKxWJ4Cfj3IzGYXcIpNmNLIRw13R84JkQQo+JxHRPFibQn6LdNjmg@public.gmane.org>
2012-05-23 5:10 ` Joe Perches
2012-05-23 5:10 ` Joe Perches
2012-05-23 5:22 ` Kent Overstreet
2012-05-23 5:22 ` Kent Overstreet
[not found] ` <20120523052236.GA14312-RcKxWJ4Cfj3IzGYXcIpNmNLIRw13R84JkQQo+JxHRPFibQn6LdNjmg@public.gmane.org>
2012-05-23 5:42 ` Joe Perches
2012-05-23 5:42 ` Joe Perches
2012-05-23 6:04 ` Kent Overstreet
2012-05-23 6:04 ` Kent Overstreet
[not found] ` <20120523060435.GD14312-RcKxWJ4Cfj3IzGYXcIpNmNLIRw13R84JkQQo+JxHRPFibQn6LdNjmg@public.gmane.org>
2012-05-23 6:12 ` Joe Perches
2012-05-23 6:12 ` Joe Perches
2012-05-23 5:08 ` [Bcache v13 09/16] Bcache: generic utility code Tejun Heo
2012-05-23 5:08 ` Tejun Heo
[not found] ` <20120523050808.GA29976-RcKxWJ4Cfj1J2suj2OqeGauc2jM2gXBXkQQo+JxHRPFibQn6LdNjmg@public.gmane.org>
2012-05-23 5:54 ` Kent Overstreet
2012-05-23 5:54 ` Kent Overstreet
[not found] ` <20120523055402.GC14312-RcKxWJ4Cfj3IzGYXcIpNmNLIRw13R84JkQQo+JxHRPFibQn6LdNjmg@public.gmane.org>
2012-05-23 16:51 ` Tejun Heo
2012-05-23 16:51 ` Tejun Heo
[not found] ` <20120522211706.GH14339-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-23 15:15 ` [dm-devel] " Vivek Goyal
2012-05-23 15:15 ` Vivek Goyal
[not found] ` <20120523151538.GJ14943-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2012-05-23 15:33 ` Kent Overstreet
2012-05-23 15:33 ` Kent Overstreet
2012-05-22 21:19 ` Tejun Heo
2012-05-22 21:19 ` Tejun Heo
2012-05-10 3:10 ` [Bcache v13 10/16] bcache: Superblock/initialization/sysfs code Kent Overstreet
2012-05-10 3:10 ` [Bcache v13 11/16] bcache: Core btree code Kent Overstreet
[not found] ` <7f1de39b6d7040b3fe271500776f4b985b21ea82.1336619038.git.koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-22 22:12 ` Tejun Heo
2012-05-22 22:12 ` Tejun Heo
[not found] ` <20120522221259.GJ14339-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-23 3:45 ` Kent Overstreet
2012-05-23 3:45 ` Kent Overstreet
[not found] ` <20120523034546.GB607-RcKxWJ4Cfj3IzGYXcIpNmNLIRw13R84JkQQo+JxHRPFibQn6LdNjmg@public.gmane.org>
2012-05-23 5:20 ` Tejun Heo
2012-05-23 5:20 ` Tejun Heo
2012-05-23 5:34 ` Kent Overstreet
[not found] ` <20120523053403.GB14312-RcKxWJ4Cfj3IzGYXcIpNmNLIRw13R84JkQQo+JxHRPFibQn6LdNjmg@public.gmane.org>
2012-05-23 17:24 ` Tejun Heo
2012-05-23 17:24 ` Tejun Heo
2012-05-22 22:40 ` Tejun Heo [this message]
2012-05-22 22:40 ` Tejun Heo
2012-05-30 7:47 ` Tejun Heo
2012-05-30 7:47 ` Tejun Heo
[not found] ` <20120530074708.GA32121-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-31 1:09 ` Kent Overstreet
2012-05-31 1:09 ` Kent Overstreet
2012-05-10 3:11 ` [Bcache v13 12/16] bcache: Bset code (lookups within a btree node) Kent Overstreet
[not found] ` <5b5998d7d09ec36377acdb5d15665d1e4e818521.1336619038.git.koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-22 22:39 ` Tejun Heo
2012-05-22 22:39 ` Tejun Heo
[not found] ` <20120522223932.GK14339-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-23 4:21 ` Kent Overstreet
2012-05-23 4:21 ` Kent Overstreet
[not found] ` <20120523042114.GC607-RcKxWJ4Cfj3IzGYXcIpNmNLIRw13R84JkQQo+JxHRPFibQn6LdNjmg@public.gmane.org>
2012-05-23 17:55 ` Tejun Heo
2012-05-23 17:55 ` Tejun Heo
[not found] ` <20120523175544.GC18143-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-23 20:49 ` Tejun Heo
2012-05-23 20:49 ` Tejun Heo
[not found] ` <20120523204914.GC3933-Gd/HAXX7CRxy/B6EtB590w@public.gmane.org>
2012-05-24 18:11 ` Tejun Heo
2012-05-24 18:11 ` Tejun Heo
2012-05-10 3:11 ` [Bcache v13 13/16] bcache: Journalling Kent Overstreet
2012-05-10 3:11 ` [Bcache v13 14/16] bcache: Request, io and allocation code Kent Overstreet
[not found] ` <9ea33658f2a71b3b9bd2ec10bee959bef146f23c.1336619038.git.koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-22 22:42 ` Tejun Heo
2012-05-22 22:42 ` Tejun Heo
[not found] ` <20120522224255.GM14339-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-23 1:44 ` Kent Overstreet
2012-05-23 1:44 ` Kent Overstreet
2012-05-23 4:24 ` Kent Overstreet
2012-05-23 4:24 ` Kent Overstreet
2012-05-22 22:44 ` Tejun Heo
2012-05-22 22:44 ` Tejun Heo
2012-05-30 7:23 ` Tejun Heo
2012-05-30 7:23 ` Tejun Heo
[not found] ` <20120530072358.GB4854-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-31 0:52 ` Kent Overstreet
2012-05-31 0:52 ` Kent Overstreet
[not found] ` <20120531005224.GA5645-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org>
2012-05-31 2:43 ` Tejun Heo
2012-05-31 2:43 ` Tejun Heo
2012-05-31 5:13 ` Kent Overstreet
[not found] ` <20120531051321.GA12602-RcKxWJ4Cfj3IzGYXcIpNmNLIRw13R84JkQQo+JxHRPFibQn6LdNjmg@public.gmane.org>
2012-05-31 6:45 ` Tejun Heo
2012-05-31 6:45 ` Tejun Heo
[not found] ` <20120531064515.GA18984-9pTldWuhBndy/B6EtB590w@public.gmane.org>
2012-06-01 2:37 ` Tejun Heo
2012-06-01 2:37 ` Tejun Heo
2012-05-31 2:45 ` Tejun Heo
2012-05-30 7:32 ` Tejun Heo
2012-05-30 7:32 ` Tejun Heo
2012-05-10 3:11 ` [Bcache v13 15/16] bcache: Writeback Kent Overstreet
2012-05-10 13:54 ` [Bcache v13 00/16] Vivek Goyal
2012-05-10 13:54 ` [dm-devel] " Vivek Goyal
2012-05-10 15:03 ` Vivek Goyal
[not found] ` <20120510150353.GI23768-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2012-05-10 15:34 ` Kent Overstreet
2012-05-10 15:34 ` Kent Overstreet
[not found] ` <1188908028.170.1336674698865.JavaMail.mail@webmail09>
2012-05-10 18:49 ` [Bcache v13 11/16] bcache: Core btree code Joe Perches
2012-05-10 21:48 ` Kent Overstreet
2012-05-10 21:48 ` Kent Overstreet
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120522224058.GL14339@google.com \
--to=tj-dgejt+ai2ygdnm+yrofe0a@public.gmane.org \
--cc=agk-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
--cc=dm-devel-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org \
--cc=koverstreet-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org \
--cc=linux-bcache-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.