aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ceph/mds_client.c16
-rw-r--r--fs/ceph/mds_client.h3
-rw-r--r--fs/ceph/snap.c51
-rw-r--r--fs/ceph/super.h2
4 files changed, 48 insertions, 24 deletions
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c
index 81840d6b68a4..02834cecc3a0 100644
--- a/fs/ceph/mds_client.c
+++ b/fs/ceph/mds_client.c
@@ -2097,9 +2097,8 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds)
2097{ 2097{
2098 struct ceph_mds_session *session = NULL; 2098 struct ceph_mds_session *session = NULL;
2099 struct ceph_msg *reply; 2099 struct ceph_msg *reply;
2100 struct rb_node *p;
2100 int err; 2101 int err;
2101 int got;
2102 u64 next_snap_ino = 0;
2103 struct ceph_pagelist *pagelist; 2102 struct ceph_pagelist *pagelist;
2104 2103
2105 pr_info("reconnect to recovering mds%d\n", mds); 2104 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)
2155 * parent for all of our realms. If the mds has any newer info, 2154 * parent for all of our realms. If the mds has any newer info,
2156 * it will tell us. 2155 * it will tell us.
2157 */ 2156 */
2158 next_snap_ino = 0; 2157 for (p = rb_first(&mdsc->snap_realms); p; p = rb_next(p)) {
2159 while (1) { 2158 struct ceph_snap_realm *realm =
2160 struct ceph_snap_realm *realm; 2159 rb_entry(p, struct ceph_snap_realm, node);
2161 struct ceph_mds_snaprealm_reconnect sr_rec; 2160 struct ceph_mds_snaprealm_reconnect sr_rec;
2162 got = radix_tree_gang_lookup(&mdsc->snap_realms,
2163 (void **)&realm, next_snap_ino, 1);
2164 if (!got)
2165 break;
2166 2161
2167 dout(" adding snap realm %llx seq %lld parent %llx\n", 2162 dout(" adding snap realm %llx seq %lld parent %llx\n",
2168 realm->ino, realm->seq, realm->parent_ino); 2163 realm->ino, realm->seq, realm->parent_ino);
@@ -2172,7 +2167,6 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, int mds)
2172 err = ceph_pagelist_append(pagelist, &sr_rec, sizeof(sr_rec)); 2167 err = ceph_pagelist_append(pagelist, &sr_rec, sizeof(sr_rec));
2173 if (err) 2168 if (err)
2174 goto fail; 2169 goto fail;
2175 next_snap_ino = realm->ino + 1;
2176 } 2170 }
2177 2171
2178send: 2172send:
@@ -2603,7 +2597,7 @@ int ceph_mdsc_init(struct ceph_mds_client *mdsc, struct ceph_client *client)
2603 mdsc->max_sessions = 0; 2597 mdsc->max_sessions = 0;
2604 mdsc->stopping = 0; 2598 mdsc->stopping = 0;
2605 init_rwsem(&mdsc->snap_rwsem); 2599 init_rwsem(&mdsc->snap_rwsem);
2606 INIT_RADIX_TREE(&mdsc->snap_realms, GFP_NOFS); 2600 mdsc->snap_realms = RB_ROOT;
2607 INIT_LIST_HEAD(&mdsc->snap_empty); 2601 INIT_LIST_HEAD(&mdsc->snap_empty);
2608 spin_lock_init(&mdsc->snap_empty_lock); 2602 spin_lock_init(&mdsc->snap_empty_lock);
2609 mdsc->last_tid = 0; 2603 mdsc->last_tid = 0;
diff --git a/fs/ceph/mds_client.h b/fs/ceph/mds_client.h
index 98f09cd06006..9d6b90173879 100644
--- a/fs/ceph/mds_client.h
+++ b/fs/ceph/mds_client.h
@@ -5,7 +5,6 @@
5#include <linux/kref.h> 5#include <linux/kref.h>
6#include <linux/list.h> 6#include <linux/list.h>
7#include <linux/mutex.h> 7#include <linux/mutex.h>
8#include <linux/radix-tree.h>
9#include <linux/rbtree.h> 8#include <linux/rbtree.h>
10#include <linux/spinlock.h> 9#include <linux/spinlock.h>
11 10
@@ -246,7 +245,7 @@ struct ceph_mds_client {
246 * should be destroyed. 245 * should be destroyed.
247 */ 246 */
248 struct rw_semaphore snap_rwsem; 247 struct rw_semaphore snap_rwsem;
249 struct radix_tree_root snap_realms; 248 struct rb_root snap_realms;
250 struct list_head snap_empty; 249 struct list_head snap_empty;
251 spinlock_t snap_empty_lock; /* protect snap_empty */ 250 spinlock_t snap_empty_lock; /* protect snap_empty */
252 251
diff --git a/fs/ceph/snap.c b/fs/ceph/snap.c
index dcf18d92130a..49d0c4c59d81 100644
--- a/fs/ceph/snap.c
+++ b/fs/ceph/snap.c
@@ -1,6 +1,5 @@
1#include "ceph_debug.h" 1#include "ceph_debug.h"
2 2
3#include <linux/radix-tree.h>
4#include <linux/sort.h> 3#include <linux/sort.h>
5 4
6#include "super.h" 5#include "super.h"
@@ -77,6 +76,28 @@ void ceph_get_snap_realm(struct ceph_mds_client *mdsc,
77 atomic_inc(&realm->nref); 76 atomic_inc(&realm->nref);
78} 77}
79 78
79static void __insert_snap_realm(struct rb_root *root,
80 struct ceph_snap_realm *new)
81{
82 struct rb_node **p = &root->rb_node;
83 struct rb_node *parent = NULL;
84 struct ceph_snap_realm *r = NULL;
85
86 while (*p) {
87 parent = *p;
88 r = rb_entry(parent, struct ceph_snap_realm, node);
89 if (new->ino < r->ino)
90 p = &(*p)->rb_left;
91 else if (new->ino > r->ino)
92 p = &(*p)->rb_right;
93 else
94 BUG();
95 }
96
97 rb_link_node(&new->node, parent, p);
98 rb_insert_color(&new->node, root);
99}
100
80/* 101/*
81 * create and get the realm rooted at @ino and bump its ref count. 102 * create and get the realm rooted at @ino and bump its ref count.
82 * 103 *
@@ -92,8 +113,6 @@ static struct ceph_snap_realm *ceph_create_snap_realm(
92 if (!realm) 113 if (!realm)
93 return ERR_PTR(-ENOMEM); 114 return ERR_PTR(-ENOMEM);
94 115
95 radix_tree_insert(&mdsc->snap_realms, ino, realm);
96
97 atomic_set(&realm->nref, 0); /* tree does not take a ref */ 116 atomic_set(&realm->nref, 0); /* tree does not take a ref */
98 realm->ino = ino; 117 realm->ino = ino;
99 INIT_LIST_HEAD(&realm->children); 118 INIT_LIST_HEAD(&realm->children);
@@ -101,24 +120,34 @@ static struct ceph_snap_realm *ceph_create_snap_realm(
101 INIT_LIST_HEAD(&realm->empty_item); 120 INIT_LIST_HEAD(&realm->empty_item);
102 INIT_LIST_HEAD(&realm->inodes_with_caps); 121 INIT_LIST_HEAD(&realm->inodes_with_caps);
103 spin_lock_init(&realm->inodes_with_caps_lock); 122 spin_lock_init(&realm->inodes_with_caps_lock);
123 __insert_snap_realm(&mdsc->snap_realms, realm);
104 dout("create_snap_realm %llx %p\n", realm->ino, realm); 124 dout("create_snap_realm %llx %p\n", realm->ino, realm);
105 return realm; 125 return realm;
106} 126}
107 127
108/* 128/*
109 * find and get (if found) the realm rooted at @ino and bump its ref count. 129 * lookup the realm rooted at @ino.
110 * 130 *
111 * caller must hold snap_rwsem for write. 131 * caller must hold snap_rwsem for write.
112 */ 132 */
113struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc, 133struct ceph_snap_realm *ceph_lookup_snap_realm(struct ceph_mds_client *mdsc,
114 u64 ino) 134 u64 ino)
115{ 135{
116 struct ceph_snap_realm *realm; 136 struct rb_node *n = mdsc->snap_realms.rb_node;
117 137 struct ceph_snap_realm *r;
118 realm = radix_tree_lookup(&mdsc->snap_realms, ino); 138
119 if (realm) 139 while (n) {
120 dout("lookup_snap_realm %llx %p\n", realm->ino, realm); 140 r = rb_entry(n, struct ceph_snap_realm, node);
121 return realm; 141 if (ino < r->ino)
142 n = n->rb_left;
143 else if (ino > r->ino)
144 n = n->rb_right;
145 else {
146 dout("lookup_snap_realm %llx %p\n", r->ino, r);
147 return r;
148 }
149 }
150 return NULL;
122} 151}
123 152
124static void __put_snap_realm(struct ceph_mds_client *mdsc, 153static void __put_snap_realm(struct ceph_mds_client *mdsc,
@@ -132,7 +161,7 @@ static void __destroy_snap_realm(struct ceph_mds_client *mdsc,
132{ 161{
133 dout("__destroy_snap_realm %p %llx\n", realm, realm->ino); 162 dout("__destroy_snap_realm %p %llx\n", realm, realm->ino);
134 163
135 radix_tree_delete(&mdsc->snap_realms, realm->ino); 164 rb_erase(&realm->node, &mdsc->snap_realms);
136 165
137 if (realm->parent) { 166 if (realm->parent) {
138 list_del_init(&realm->child_item); 167 list_del_init(&realm->child_item);
diff --git a/fs/ceph/super.h b/fs/ceph/super.h
index b2adfccbab98..1f3928785e12 100644
--- a/fs/ceph/super.h
+++ b/fs/ceph/super.h
@@ -656,6 +656,8 @@ static inline void ceph_put_snap_context(struct ceph_snap_context *sc)
656struct ceph_snap_realm { 656struct ceph_snap_realm {
657 u64 ino; 657 u64 ino;
658 atomic_t nref; 658 atomic_t nref;
659 struct rb_node node;
660
659 u64 created, seq; 661 u64 created, seq;
660 u64 parent_ino; 662 u64 parent_ino;
661 u64 parent_since; /* snapid when our current parent became so */ 663 u64 parent_since; /* snapid when our current parent became so */