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

Configure Feed

Select the types of activity you want to include in your feed.

ceph: make ceph_fill_trace and ceph_get_name decrypt names

When we get a dentry in a trace, decrypt the name so we can properly
instantiate the dentry or fill out ceph_get_name() buffer.

Signed-off-by: Jeff Layton <jlayton@kernel.org>
Reviewed-by: Xiubo Li <xiubli@redhat.com>
Reviewed-and-tested-by: Luís Henriques <lhenriques@suse.de>
Reviewed-by: Milind Changire <mchangir@redhat.com>
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>

authored by

Jeff Layton and committed by
Ilya Dryomov
85529096 457117f0

+60 -14
+32 -12
fs/ceph/export.c
··· 7 7 8 8 #include "super.h" 9 9 #include "mds_client.h" 10 + #include "crypto.h" 10 11 11 12 /* 12 13 * Basic fh ··· 536 535 { 537 536 struct ceph_mds_client *mdsc; 538 537 struct ceph_mds_request *req; 538 + struct inode *dir = d_inode(parent); 539 539 struct inode *inode = d_inode(child); 540 + struct ceph_mds_reply_info_parsed *rinfo; 540 541 int err; 541 542 542 543 if (ceph_snap(inode) != CEPH_NOSNAP) ··· 550 547 if (IS_ERR(req)) 551 548 return PTR_ERR(req); 552 549 553 - inode_lock(d_inode(parent)); 554 - 550 + inode_lock(dir); 555 551 req->r_inode = inode; 556 552 ihold(inode); 557 553 req->r_ino2 = ceph_vino(d_inode(parent)); 558 - req->r_parent = d_inode(parent); 559 - ihold(req->r_parent); 554 + req->r_parent = dir; 555 + ihold(dir); 560 556 set_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags); 561 557 req->r_num_caps = 2; 562 558 err = ceph_mdsc_do_request(mdsc, NULL, req); 559 + inode_unlock(dir); 563 560 564 - inode_unlock(d_inode(parent)); 561 + if (err) 562 + goto out; 565 563 566 - if (!err) { 567 - struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info; 564 + rinfo = &req->r_reply_info; 565 + if (!IS_ENCRYPTED(dir)) { 568 566 memcpy(name, rinfo->dname, rinfo->dname_len); 569 567 name[rinfo->dname_len] = 0; 570 - dout("get_name %p ino %llx.%llx name %s\n", 571 - child, ceph_vinop(inode), name); 572 568 } else { 573 - dout("get_name %p ino %llx.%llx err %d\n", 574 - child, ceph_vinop(inode), err); 575 - } 569 + struct fscrypt_str oname = FSTR_INIT(NULL, 0); 570 + struct ceph_fname fname = { .dir = dir, 571 + .name = rinfo->dname, 572 + .ctext = rinfo->altname, 573 + .name_len = rinfo->dname_len, 574 + .ctext_len = rinfo->altname_len }; 576 575 576 + err = ceph_fname_alloc_buffer(dir, &oname); 577 + if (err < 0) 578 + goto out; 579 + 580 + err = ceph_fname_to_usr(&fname, NULL, &oname, NULL); 581 + if (!err) { 582 + memcpy(name, oname.name, oname.len); 583 + name[oname.len] = 0; 584 + } 585 + ceph_fname_free_buffer(dir, &oname); 586 + } 587 + out: 588 + dout("get_name %p ino %llx.%llx err %d %s%s\n", 589 + child, ceph_vinop(inode), err, 590 + err ? "" : "name ", err ? "" : name); 577 591 ceph_mdsc_put_request(req); 578 592 return err; 579 593 }
+28 -2
fs/ceph/inode.c
··· 1406 1406 if (dir && req->r_op == CEPH_MDS_OP_LOOKUPNAME && 1407 1407 test_bit(CEPH_MDS_R_PARENT_LOCKED, &req->r_req_flags) && 1408 1408 !test_bit(CEPH_MDS_R_ABORTED, &req->r_req_flags)) { 1409 + bool is_nokey = false; 1409 1410 struct qstr dname; 1410 1411 struct dentry *dn, *parent; 1412 + struct fscrypt_str oname = FSTR_INIT(NULL, 0); 1413 + struct ceph_fname fname = { .dir = dir, 1414 + .name = rinfo->dname, 1415 + .ctext = rinfo->altname, 1416 + .name_len = rinfo->dname_len, 1417 + .ctext_len = rinfo->altname_len }; 1411 1418 1412 1419 BUG_ON(!rinfo->head->is_target); 1413 1420 BUG_ON(req->r_dentry); ··· 1422 1415 parent = d_find_any_alias(dir); 1423 1416 BUG_ON(!parent); 1424 1417 1425 - dname.name = rinfo->dname; 1426 - dname.len = rinfo->dname_len; 1418 + err = ceph_fname_alloc_buffer(dir, &oname); 1419 + if (err < 0) { 1420 + dput(parent); 1421 + goto done; 1422 + } 1423 + 1424 + err = ceph_fname_to_usr(&fname, NULL, &oname, &is_nokey); 1425 + if (err < 0) { 1426 + dput(parent); 1427 + ceph_fname_free_buffer(dir, &oname); 1428 + goto done; 1429 + } 1430 + dname.name = oname.name; 1431 + dname.len = oname.len; 1427 1432 dname.hash = full_name_hash(parent, dname.name, dname.len); 1428 1433 tvino.ino = le64_to_cpu(rinfo->targeti.in->ino); 1429 1434 tvino.snap = le64_to_cpu(rinfo->targeti.in->snapid); ··· 1450 1431 dname.len, dname.name, dn); 1451 1432 if (!dn) { 1452 1433 dput(parent); 1434 + ceph_fname_free_buffer(dir, &oname); 1453 1435 err = -ENOMEM; 1454 1436 goto done; 1437 + } 1438 + if (is_nokey) { 1439 + spin_lock(&dn->d_lock); 1440 + dn->d_flags |= DCACHE_NOKEY_NAME; 1441 + spin_unlock(&dn->d_lock); 1455 1442 } 1456 1443 err = 0; 1457 1444 } else if (d_really_is_positive(dn) && ··· 1470 1445 dput(dn); 1471 1446 goto retry_lookup; 1472 1447 } 1448 + ceph_fname_free_buffer(dir, &oname); 1473 1449 1474 1450 req->r_dentry = dn; 1475 1451 dput(parent);