aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorYan, Zheng <zheng.z.yan@intel.com>2014-04-18 04:00:30 -0400
committerYan, Zheng <zheng.z.yan@intel.com>2014-06-05 21:29:54 -0400
commit3e7fbe9cebfdaac380419507908e10c499ddd25b (patch)
tree6352978e76ad863fb1c33a539f589ac83c0723e3 /fs
parent2cd698be9a3d3a0f8f3c66814eac34144c31954c (diff)
ceph: introduce ceph_fill_fragtree()
Move the code that update the i_fragtree into a separate function. Also add simple probabilistic test to decide whether the i_fragtree should be updated Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ceph/inode.c129
1 files changed, 84 insertions, 45 deletions
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c
index 8ad50a30808e..850b26d2e601 100644
--- a/fs/ceph/inode.c
+++ b/fs/ceph/inode.c
@@ -10,6 +10,7 @@
10#include <linux/writeback.h> 10#include <linux/writeback.h>
11#include <linux/vmalloc.h> 11#include <linux/vmalloc.h>
12#include <linux/posix_acl.h> 12#include <linux/posix_acl.h>
13#include <linux/random.h>
13 14
14#include "super.h" 15#include "super.h"
15#include "mds_client.h" 16#include "mds_client.h"
@@ -179,9 +180,8 @@ struct ceph_inode_frag *__ceph_find_frag(struct ceph_inode_info *ci, u32 f)
179 * specified, copy the frag delegation info to the caller if 180 * specified, copy the frag delegation info to the caller if
180 * it is present. 181 * it is present.
181 */ 182 */
182u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v, 183static u32 __ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
183 struct ceph_inode_frag *pfrag, 184 struct ceph_inode_frag *pfrag, int *found)
184 int *found)
185{ 185{
186 u32 t = ceph_frag_make(0, 0); 186 u32 t = ceph_frag_make(0, 0);
187 struct ceph_inode_frag *frag; 187 struct ceph_inode_frag *frag;
@@ -191,7 +191,6 @@ u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
191 if (found) 191 if (found)
192 *found = 0; 192 *found = 0;
193 193
194 mutex_lock(&ci->i_fragtree_mutex);
195 while (1) { 194 while (1) {
196 WARN_ON(!ceph_frag_contains_value(t, v)); 195 WARN_ON(!ceph_frag_contains_value(t, v));
197 frag = __ceph_find_frag(ci, t); 196 frag = __ceph_find_frag(ci, t);
@@ -220,10 +219,19 @@ u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
220 } 219 }
221 dout("choose_frag(%x) = %x\n", v, t); 220 dout("choose_frag(%x) = %x\n", v, t);
222 221
223 mutex_unlock(&ci->i_fragtree_mutex);
224 return t; 222 return t;
225} 223}
226 224
225u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
226 struct ceph_inode_frag *pfrag, int *found)
227{
228 u32 ret;
229 mutex_lock(&ci->i_fragtree_mutex);
230 ret = __ceph_choose_frag(ci, v, pfrag, found);
231 mutex_unlock(&ci->i_fragtree_mutex);
232 return ret;
233}
234
227/* 235/*
228 * Process dirfrag (delegation) info from the mds. Include leaf 236 * Process dirfrag (delegation) info from the mds. Include leaf
229 * fragment in tree ONLY if ndist > 0. Otherwise, only 237 * fragment in tree ONLY if ndist > 0. Otherwise, only
@@ -286,6 +294,75 @@ out:
286 return err; 294 return err;
287} 295}
288 296
297static int ceph_fill_fragtree(struct inode *inode,
298 struct ceph_frag_tree_head *fragtree,
299 struct ceph_mds_reply_dirfrag *dirinfo)
300{
301 struct ceph_inode_info *ci = ceph_inode(inode);
302 struct ceph_inode_frag *frag;
303 struct rb_node *rb_node;
304 int i;
305 u32 id, nsplits;
306 bool update = false;
307
308 mutex_lock(&ci->i_fragtree_mutex);
309 nsplits = le32_to_cpu(fragtree->nsplits);
310 if (nsplits) {
311 i = prandom_u32() % nsplits;
312 id = le32_to_cpu(fragtree->splits[i].frag);
313 if (!__ceph_find_frag(ci, id))
314 update = true;
315 } else if (!RB_EMPTY_ROOT(&ci->i_fragtree)) {
316 rb_node = rb_first(&ci->i_fragtree);
317 frag = rb_entry(rb_node, struct ceph_inode_frag, node);
318 if (frag->frag != ceph_frag_make(0, 0) || rb_next(rb_node))
319 update = true;
320 }
321 if (!update && dirinfo) {
322 id = le32_to_cpu(dirinfo->frag);
323 if (id != __ceph_choose_frag(ci, id, NULL, NULL))
324 update = true;
325 }
326 if (!update)
327 goto out_unlock;
328
329 dout("fill_fragtree %llx.%llx\n", ceph_vinop(inode));
330 rb_node = rb_first(&ci->i_fragtree);
331 for (i = 0; i < nsplits; i++) {
332 id = le32_to_cpu(fragtree->splits[i].frag);
333 frag = NULL;
334 while (rb_node) {
335 frag = rb_entry(rb_node, struct ceph_inode_frag, node);
336 if (ceph_frag_compare(frag->frag, id) >= 0) {
337 if (frag->frag != id)
338 frag = NULL;
339 else
340 rb_node = rb_next(rb_node);
341 break;
342 }
343 rb_node = rb_next(rb_node);
344 rb_erase(&frag->node, &ci->i_fragtree);
345 kfree(frag);
346 frag = NULL;
347 }
348 if (!frag) {
349 frag = __get_or_create_frag(ci, id);
350 if (IS_ERR(frag))
351 continue;
352 }
353 frag->split_by = le32_to_cpu(fragtree->splits[i].by);
354 dout(" frag %x split by %d\n", frag->frag, frag->split_by);
355 }
356 while (rb_node) {
357 frag = rb_entry(rb_node, struct ceph_inode_frag, node);
358 rb_node = rb_next(rb_node);
359 rb_erase(&frag->node, &ci->i_fragtree);
360 kfree(frag);
361 }
362out_unlock:
363 mutex_unlock(&ci->i_fragtree_mutex);
364 return 0;
365}
289 366
290/* 367/*
291 * initialize a newly allocated inode. 368 * initialize a newly allocated inode.
@@ -584,12 +661,8 @@ static int fill_inode(struct inode *inode,
584 struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc; 661 struct ceph_mds_client *mdsc = ceph_inode_to_client(inode)->mdsc;
585 struct ceph_mds_reply_inode *info = iinfo->in; 662 struct ceph_mds_reply_inode *info = iinfo->in;
586 struct ceph_inode_info *ci = ceph_inode(inode); 663 struct ceph_inode_info *ci = ceph_inode(inode);
587 int i;
588 int issued = 0, implemented, new_issued; 664 int issued = 0, implemented, new_issued;
589 struct timespec mtime, atime, ctime; 665 struct timespec mtime, atime, ctime;
590 u32 nsplits;
591 struct ceph_inode_frag *frag;
592 struct rb_node *rb_node;
593 struct ceph_buffer *xattr_blob = NULL; 666 struct ceph_buffer *xattr_blob = NULL;
594 struct ceph_cap *new_cap = NULL; 667 struct ceph_cap *new_cap = NULL;
595 int err = 0; 668 int err = 0;
@@ -804,42 +877,8 @@ static int fill_inode(struct inode *inode,
804 ceph_queue_vmtruncate(inode); 877 ceph_queue_vmtruncate(inode);
805 878
806 /* populate frag tree */ 879 /* populate frag tree */
807 /* FIXME: move me up, if/when version reflects fragtree changes */ 880 if (S_ISDIR(inode->i_mode))
808 nsplits = le32_to_cpu(info->fragtree.nsplits); 881 ceph_fill_fragtree(inode, &info->fragtree, dirinfo);
809 mutex_lock(&ci->i_fragtree_mutex);
810 rb_node = rb_first(&ci->i_fragtree);
811 for (i = 0; i < nsplits; i++) {
812 u32 id = le32_to_cpu(info->fragtree.splits[i].frag);
813 frag = NULL;
814 while (rb_node) {
815 frag = rb_entry(rb_node, struct ceph_inode_frag, node);
816 if (ceph_frag_compare(frag->frag, id) >= 0) {
817 if (frag->frag != id)
818 frag = NULL;
819 else
820 rb_node = rb_next(rb_node);
821 break;
822 }
823 rb_node = rb_next(rb_node);
824 rb_erase(&frag->node, &ci->i_fragtree);
825 kfree(frag);
826 frag = NULL;
827 }
828 if (!frag) {
829 frag = __get_or_create_frag(ci, id);
830 if (IS_ERR(frag))
831 continue;
832 }
833 frag->split_by = le32_to_cpu(info->fragtree.splits[i].by);
834 dout(" frag %x split by %d\n", frag->frag, frag->split_by);
835 }
836 while (rb_node) {
837 frag = rb_entry(rb_node, struct ceph_inode_frag, node);
838 rb_node = rb_next(rb_node);
839 rb_erase(&frag->node, &ci->i_fragtree);
840 kfree(frag);
841 }
842 mutex_unlock(&ci->i_fragtree_mutex);
843 882
844 /* update delegation info? */ 883 /* update delegation info? */
845 if (dirinfo) 884 if (dirinfo)