Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ceph: add get_name() NFS export callback

Use the newly introduced LOOKUPNAME MDS request to connect child
inode to its parent directory.

Signed-off-by: Yan, Zheng <zheng.z.yan@intel.com>
Reviewed-by: Sage Weil <sage@inktank.com>

+92 -1
+40
fs/ceph/export.c
··· 202 202 return dentry; 203 203 } 204 204 205 + static int ceph_get_name(struct dentry *parent, char *name, 206 + struct dentry *child) 207 + { 208 + struct ceph_mds_client *mdsc; 209 + struct ceph_mds_request *req; 210 + int err; 211 + 212 + mdsc = ceph_inode_to_client(child->d_inode)->mdsc; 213 + req = ceph_mdsc_create_request(mdsc, CEPH_MDS_OP_LOOKUPNAME, 214 + USE_ANY_MDS); 215 + if (IS_ERR(req)) 216 + return PTR_ERR(req); 217 + 218 + mutex_lock(&parent->d_inode->i_mutex); 219 + 220 + req->r_inode = child->d_inode; 221 + ihold(child->d_inode); 222 + req->r_ino2 = ceph_vino(parent->d_inode); 223 + req->r_locked_dir = parent->d_inode; 224 + req->r_num_caps = 2; 225 + err = ceph_mdsc_do_request(mdsc, NULL, req); 226 + 227 + mutex_unlock(&parent->d_inode->i_mutex); 228 + 229 + if (!err) { 230 + struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info; 231 + memcpy(name, rinfo->dname, rinfo->dname_len); 232 + name[rinfo->dname_len] = 0; 233 + dout("get_name %p ino %llx.%llx name %s\n", 234 + child, ceph_vinop(child->d_inode), name); 235 + } else { 236 + dout("get_name %p ino %llx.%llx err %d\n", 237 + child, ceph_vinop(child->d_inode), err); 238 + } 239 + 240 + ceph_mdsc_put_request(req); 241 + return err; 242 + } 243 + 205 244 const struct export_operations ceph_export_ops = { 206 245 .encode_fh = ceph_encode_fh, 207 246 .fh_to_dentry = ceph_fh_to_dentry, 208 247 .fh_to_parent = ceph_fh_to_parent, 209 248 .get_parent = ceph_get_parent, 249 + .get_name = ceph_get_name, 210 250 };
+50 -1
fs/ceph/inode.c
··· 1044 1044 session, req->r_request_started, -1, 1045 1045 &req->r_caps_reservation); 1046 1046 if (err < 0) 1047 - return err; 1047 + goto done; 1048 1048 } else { 1049 1049 WARN_ON_ONCE(1); 1050 + } 1051 + 1052 + if (dir && req->r_op == CEPH_MDS_OP_LOOKUPNAME) { 1053 + struct qstr dname; 1054 + struct dentry *dn, *parent; 1055 + 1056 + BUG_ON(!rinfo->head->is_target); 1057 + BUG_ON(req->r_dentry); 1058 + 1059 + parent = d_find_any_alias(dir); 1060 + BUG_ON(!parent); 1061 + 1062 + dname.name = rinfo->dname; 1063 + dname.len = rinfo->dname_len; 1064 + dname.hash = full_name_hash(dname.name, dname.len); 1065 + vino.ino = le64_to_cpu(rinfo->targeti.in->ino); 1066 + vino.snap = le64_to_cpu(rinfo->targeti.in->snapid); 1067 + retry_lookup: 1068 + dn = d_lookup(parent, &dname); 1069 + dout("d_lookup on parent=%p name=%.*s got %p\n", 1070 + parent, dname.len, dname.name, dn); 1071 + 1072 + if (!dn) { 1073 + dn = d_alloc(parent, &dname); 1074 + dout("d_alloc %p '%.*s' = %p\n", parent, 1075 + dname.len, dname.name, dn); 1076 + if (dn == NULL) { 1077 + dput(parent); 1078 + err = -ENOMEM; 1079 + goto done; 1080 + } 1081 + err = ceph_init_dentry(dn); 1082 + if (err < 0) { 1083 + dput(dn); 1084 + dput(parent); 1085 + goto done; 1086 + } 1087 + } else if (dn->d_inode && 1088 + (ceph_ino(dn->d_inode) != vino.ino || 1089 + ceph_snap(dn->d_inode) != vino.snap)) { 1090 + dout(" dn %p points to wrong inode %p\n", 1091 + dn, dn->d_inode); 1092 + d_delete(dn); 1093 + dput(dn); 1094 + goto retry_lookup; 1095 + } 1096 + 1097 + req->r_dentry = dn; 1098 + dput(parent); 1050 1099 } 1051 1100 } 1052 1101
+1
fs/ceph/strings.c
··· 54 54 case CEPH_MDS_OP_LOOKUPHASH: return "lookuphash"; 55 55 case CEPH_MDS_OP_LOOKUPPARENT: return "lookupparent"; 56 56 case CEPH_MDS_OP_LOOKUPINO: return "lookupino"; 57 + case CEPH_MDS_OP_LOOKUPNAME: return "lookupname"; 57 58 case CEPH_MDS_OP_GETATTR: return "getattr"; 58 59 case CEPH_MDS_OP_SETXATTR: return "setxattr"; 59 60 case CEPH_MDS_OP_SETATTR: return "setattr";
+1
include/linux/ceph/ceph_fs.h
··· 332 332 CEPH_MDS_OP_LOOKUPHASH = 0x00102, 333 333 CEPH_MDS_OP_LOOKUPPARENT = 0x00103, 334 334 CEPH_MDS_OP_LOOKUPINO = 0x00104, 335 + CEPH_MDS_OP_LOOKUPNAME = 0x00105, 335 336 336 337 CEPH_MDS_OP_SETXATTR = 0x01105, 337 338 CEPH_MDS_OP_RMXATTR = 0x01106,