int op = ceph_snap(inode) == CEPH_SNAPDIR ?
CEPH_MDS_OP_LSSNAP:CEPH_MDS_OP_READDIR;
- frag = ceph_choose_frag(ceph_inode(inode), frag, 0);
+ frag = ceph_choose_frag(ceph_inode(inode), frag, 0, 0);
/* query mds */
dout(10, "dir_readdir querying mds for ino %llx.%llx frag %x\n",
}
__u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
- struct ceph_inode_frag **pfrag)
+ struct ceph_inode_frag *pfrag,
+ int *found)
{
u32 t = frag_make(0, 0);
struct ceph_inode_frag *frag;
unsigned nway, i;
u32 n;
+ if (found)
+ *found = 0;
+
mutex_lock(&ci->i_fragtree_mutex);
while (1) {
WARN_ON(!frag_contains_value(t, v));
break; /* t is a leaf */
if (frag->split_by == 0) {
if (pfrag)
- *pfrag = frag;
+ memcpy(pfrag, frag, sizeof(struct ceph_inode_frag));
+
+ if (found)
+ *found = 1;
break;
}
if (is_hash &&
dentry->d_inode &&
S_ISDIR(dentry->d_inode->i_mode)) {
+ int found;
ci = ceph_inode(dentry->d_inode);
- ceph_choose_frag(ci, hash, &frag);
- if (frag) {
+ frag = kmalloc(sizeof(struct ceph_inode_frag), GFP_KERNEL);
+
+ if (!frag)
+ return -ENOMEM;
+
+ ceph_choose_frag(ci, hash, frag, &found);
+ if (found) {
/* avoid hitting dir replicas on dir
* auth delegation point.. mds will
* likely forward anyway to avoid
return mds;
}
}
+ kfree(frag);
}
if (IS_ROOT(dentry))
break;
}
extern __u32 ceph_choose_frag(struct ceph_inode_info *ci, u32 v,
- struct ceph_inode_frag **pfrag);
+ struct ceph_inode_frag *pfrag,
+ int *found);
struct ceph_dentry_info {
struct dentry *dentry;