ceph: don't assume frag tree splits in mds reply are sorted
The algorithm that updates i_fragtree relies on that the frag tree splits in mds reply are of the same order of i_fragtree. This is not true because current MDS encodes frag tree splits in ascending order of (unsigned)frag_t. But nodes in i_fragtree are sorted according to ceph_frag_compare(). The fix is sort the frag tree splits first, then updates i_fragtree. Signed-off-by: Yan, Zheng <zyan@redhat.com>
This commit is contained in:
parent
209ae762a6
commit
a407846ef7
|
@ -10,6 +10,7 @@
|
|||
#include <linux/vmalloc.h>
|
||||
#include <linux/posix_acl.h>
|
||||
#include <linux/random.h>
|
||||
#include <linux/sort.h>
|
||||
|
||||
#include "super.h"
|
||||
#include "mds_client.h"
|
||||
|
@ -299,6 +300,13 @@ out:
|
|||
return err;
|
||||
}
|
||||
|
||||
static int frag_tree_split_cmp(const void *l, const void *r)
|
||||
{
|
||||
struct ceph_frag_tree_split *ls = (struct ceph_frag_tree_split*)l;
|
||||
struct ceph_frag_tree_split *rs = (struct ceph_frag_tree_split*)r;
|
||||
return ceph_frag_compare(ls->frag, rs->frag);
|
||||
}
|
||||
|
||||
static int ceph_fill_fragtree(struct inode *inode,
|
||||
struct ceph_frag_tree_head *fragtree,
|
||||
struct ceph_mds_reply_dirfrag *dirinfo)
|
||||
|
@ -331,6 +339,11 @@ static int ceph_fill_fragtree(struct inode *inode,
|
|||
if (!update)
|
||||
goto out_unlock;
|
||||
|
||||
if (nsplits > 1) {
|
||||
sort(fragtree->splits, nsplits, sizeof(fragtree->splits[0]),
|
||||
frag_tree_split_cmp, NULL);
|
||||
}
|
||||
|
||||
dout("fill_fragtree %llx.%llx\n", ceph_vinop(inode));
|
||||
rb_node = rb_first(&ci->i_fragtree);
|
||||
for (i = 0; i < nsplits; i++) {
|
||||
|
|
Loading…
Reference in a new issue