Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a105f00c authored by Sage Weil's avatar Sage Weil
Browse files

ceph: use rbtree for snap_realms



Switch from radix tree to rbtree for snap realms.  This is much more
appropriate given that realm keys are few and far between.

Signed-off-by: default avatarSage Weil <sage@newdream.net>
parent 44ca18f2
Loading
Loading
Loading
Loading
+5 −11
Original line number Original line Diff line number Diff line
@@ -2097,9 +2097,8 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds)
{
{
	struct ceph_mds_session *session = NULL;
	struct ceph_mds_session *session = NULL;
	struct ceph_msg *reply;
	struct ceph_msg *reply;
	struct rb_node *p;
	int err;
	int err;
	int got;
	u64 next_snap_ino = 0;
	struct ceph_pagelist *pagelist;
	struct ceph_pagelist *pagelist;


	pr_info("reconnect to recovering mds%d\n", mds);
	pr_info("reconnect to recovering mds%d\n", mds);
@@ -2155,14 +2154,10 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds)
	 * parent for all of our realms.  If the mds has any newer info,
	 * parent for all of our realms.  If the mds has any newer info,
	 * it will tell us.
	 * it will tell us.
	 */
	 */
	next_snap_ino = 0;
	for (p = rb_first(&mdsc->snap_realms); p; p = rb_next(p)) {
	while (1) {
		struct ceph_snap_realm *realm =
		struct ceph_snap_realm *realm;
			rb_entry(p, struct ceph_snap_realm, node);
		struct ceph_mds_snaprealm_reconnect sr_rec;
		struct ceph_mds_snaprealm_reconnect sr_rec;
		got = radix_tree_gang_lookup(&mdsc->snap_realms,
					     (void **)&realm, next_snap_ino, 1);
		if (!got)
			break;


		dout(" adding snap realm %llx seq %lld parent %llx\n",
		dout(" adding snap realm %llx seq %lld parent %llx\n",
		     realm->ino, realm->seq, realm->parent_ino);
		     realm->ino, realm->seq, realm->parent_ino);
@@ -2172,7 +2167,6 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds)
		err = ceph_pagelist_append(pagelist, &sr_rec, sizeof(sr_rec));
		err = ceph_pagelist_append(pagelist, &sr_rec, sizeof(sr_rec));
		if (err)
		if (err)
			goto fail;
			goto fail;
		next_snap_ino = realm->ino + 1;
	}
	}


send:
send:
@@ -2603,7 +2597,7 @@ int ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client)
	mdsc->max_sessions = 0;
	mdsc->max_sessions = 0;
	mdsc->stopping = 0;
	mdsc->stopping = 0;
	init_rwsem(&mdsc->snap_rwsem);
	init_rwsem(&mdsc->snap_rwsem);
	INIT_RADIX_TREE(&mdsc->snap_realms, GFP_NOFS);
	mdsc->snap_realms = RB_ROOT;
	INIT_LIST_HEAD(&mdsc->snap_empty);
	INIT_LIST_HEAD(&mdsc->snap_empty);
	spin_lock_init(&mdsc->snap_empty_lock);
	spin_lock_init(&mdsc->snap_empty_lock);
	mdsc->last_tid = 0;
	mdsc->last_tid = 0;
+1 −2
Original line number Original line Diff line number Diff line
@@ -5,7 +5,6 @@
#include <linux/kref.h>
#include <linux/kref.h>
#include <linux/list.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/mutex.h>
#include <linux/radix-tree.h>
#include <linux/rbtree.h>
#include <linux/rbtree.h>
#include <linux/spinlock.h>
#include <linux/spinlock.h>


@@ -246,7 +245,7 @@ struct ceph_mds_client {
	 * should be destroyed.
	 * should be destroyed.
	 */
	 */
	struct rw_semaphore     snap_rwsem;
	struct rw_semaphore     snap_rwsem;
	struct radix_tree_root  snap_realms;
	struct rb_root          snap_realms;
	struct list_head        snap_empty;
	struct list_head        snap_empty;
	spinlock_t              snap_empty_lock;  /* protect snap_empty */
	spinlock_t              snap_empty_lock;  /* protect snap_empty */


+40 −11
Original line number Original line Diff line number Diff line
#include "ceph_debug.h"
#include "ceph_debug.h"


#include <linux/radix-tree.h>
#include <linux/sort.h>
#include <linux/sort.h>


#include "super.h"
#include "super.h"
@@ -77,6 +76,28 @@ void ceph_get_snap_realm(struct ceph_mds_client *mdsc,
	atomic_inc(&realm->nref);
	atomic_inc(&realm->nref);
}
}


static void __insert_snap_realm(struct rb_root *root,
				struct ceph_snap_realm *new)
{
	struct rb_node **p = &root->rb_node;
	struct rb_node *parent = NULL;
	struct ceph_snap_realm *r = NULL;

	while (*p) {
		parent = *p;
		r = rb_entry(parent, struct ceph_snap_realm, node);
		if (new->ino < r->ino)
			p = &(*p)->rb_left;
		else if (new->ino > r->ino)
			p = &(*p)->rb_right;
		else
			BUG();
	}

	rb_link_node(&new->node, parent, p);
	rb_insert_color(&new->node, root);
}

/*
/*
 * create and get the realm rooted at @ino and bump its ref count.
 * create and get the realm rooted at @ino and bump its ref count.
 *
 *
@@ -92,8 +113,6 @@ static struct ceph_snap_realm *ceph_create_snap_realm(
	if (!realm)
	if (!realm)
		return ERR_PTR(-ENOMEM);
		return ERR_PTR(-ENOMEM);


	radix_tree_insert(&mdsc->snap_realms, ino, realm);

	atomic_set(&realm->nref, 0);    /* tree does not take a ref */
	atomic_set(&realm->nref, 0);    /* tree does not take a ref */
	realm->ino = ino;
	realm->ino = ino;
	INIT_LIST_HEAD(&realm->children);
	INIT_LIST_HEAD(&realm->children);
@@ -101,24 +120,34 @@ static struct ceph_snap_realm *ceph_create_snap_realm(
	INIT_LIST_HEAD(&realm->empty_item);
	INIT_LIST_HEAD(&realm->empty_item);
	INIT_LIST_HEAD(&realm->inodes_with_caps);
	INIT_LIST_HEAD(&realm->inodes_with_caps);
	spin_lock_init(&realm->inodes_with_caps_lock);
	spin_lock_init(&realm->inodes_with_caps_lock);
	__insert_snap_realm(&mdsc->snap_realms, realm);
	dout("create_snap_realm %llx %p\n", realm->ino, realm);
	dout("create_snap_realm %llx %p\n", realm->ino, realm);
	return realm;
	return realm;
}
}


/*
/*
 * find and get (if found) the realm rooted at @ino and bump its ref count.
 * lookup the realm rooted at @ino.
 *
 *
 * caller must hold snap_rwsem for write.
 * caller must hold snap_rwsem for write.
 */
 */
struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc,
struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc,
					       u64 ino)
					       u64 ino)
{
{
	struct ceph_snap_realm *realm;
	struct rb_node *n = mdsc->snap_realms.rb_node;
	struct ceph_snap_realm *r;


	realm = radix_tree_lookup(&mdsc->snap_realms, ino);
	while (n) {
	if (realm)
		r = rb_entry(n, struct ceph_snap_realm, node);
		dout("lookup_snap_realm %llx %p\n", realm->ino, realm);
		if (ino < r->ino)
	return realm;
			n = n->rb_left;
		else if (ino > r->ino)
			n = n->rb_right;
		else {
			dout("lookup_snap_realm %llx %p\n", r->ino, r);
			return r;
		}
	}
	return NULL;
}
}


static void __put_snap_realm(struct ceph_mds_client *mdsc,
static void __put_snap_realm(struct ceph_mds_client *mdsc,
@@ -132,7 +161,7 @@ static void __destroy_snap_realm(struct ceph_mds_client *mdsc,
{
{
	dout("__destroy_snap_realm %p %llx\n", realm, realm->ino);
	dout("__destroy_snap_realm %p %llx\n", realm, realm->ino);


	radix_tree_delete(&mdsc->snap_realms, realm->ino);
	rb_erase(&realm->node, &mdsc->snap_realms);


	if (realm->parent) {
	if (realm->parent) {
		list_del_init(&realm->child_item);
		list_del_init(&realm->child_item);
+2 −0
Original line number Original line Diff line number Diff line
@@ -656,6 +656,8 @@ static inline void ceph_put_snap_context(struct ceph_snap_context *sc)
struct ceph_snap_realm {
struct ceph_snap_realm {
	u64 ino;
	u64 ino;
	atomic_t nref;
	atomic_t nref;
	struct rb_node node;

	u64 created, seq;
	u64 created, seq;
	u64 parent_ino;
	u64 parent_ino;
	u64 parent_since;   /* snapid when our current parent became so */
	u64 parent_since;   /* snapid when our current parent became so */