* insert results from readdir or lssnap into the metadata cache. */
| 1555 | * insert results from readdir or lssnap into the metadata cache. |
| 1556 | */ |
| 1557 | void Client::insert_readdir_results(MetaRequest *request, MetaSession *session, |
| 1558 | Inode *diri, Inode *diri_other) { |
| 1559 | |
| 1560 | auto& reply = request->reply; |
| 1561 | ConnectionRef con = request->reply->get_connection(); |
| 1562 | uint64_t features; |
| 1563 | if(session->mds_features.test(CEPHFS_FEATURE_REPLY_ENCODING)) { |
| 1564 | features = (uint64_t)-1; |
| 1565 | } |
| 1566 | else { |
| 1567 | features = con->get_features(); |
| 1568 | } |
| 1569 | |
| 1570 | dir_result_t *dirp = request->dirp; |
| 1571 | ceph_assert(dirp); |
| 1572 | |
| 1573 | // the extra buffer list is only set for readdir, lssnap and |
| 1574 | // readdir_snapdiff replies |
| 1575 | auto p = reply->get_extra_bl().cbegin(); |
| 1576 | if (!p.end()) { |
| 1577 | // snapdir? |
| 1578 | if (request->head.op == CEPH_MDS_OP_LSSNAP) { |
| 1579 | ceph_assert(diri); |
| 1580 | auto snapdir = open_snapdir(diri); |
| 1581 | diri = snapdir.get(); |
| 1582 | } |
| 1583 | bool snapdiff_req = request->head.op == CEPH_MDS_OP_READDIR_SNAPDIFF; |
| 1584 | frag_t fg; |
| 1585 | unsigned offset_hash; |
| 1586 | if (snapdiff_req) { |
| 1587 | fg = (unsigned)request->head.args.snapdiff.frag; |
| 1588 | offset_hash = (unsigned)request->head.args.snapdiff.offset_hash; |
| 1589 | } else { |
| 1590 | fg = (unsigned)request->head.args.readdir.frag; |
| 1591 | offset_hash = (unsigned)request->head.args.readdir.offset_hash; |
| 1592 | } |
| 1593 | |
| 1594 | // only open dir if we're actually adding stuff to it! |
| 1595 | Dir *dir = diri->open_dir(); |
| 1596 | ceph_assert(dir); |
| 1597 | //open opponent dir for snapdiff if any |
| 1598 | Dir *dir_other = nullptr; |
| 1599 | if (snapdiff_req) { |
| 1600 | ceph_assert(diri_other); |
| 1601 | dir_other = diri_other->open_dir(); |
| 1602 | ceph_assert(dir_other); |
| 1603 | } |
| 1604 | |
| 1605 | // dirstat |
| 1606 | DirStat dst(p, features); |
| 1607 | __u32 numdn; |
| 1608 | __u16 flags; |
| 1609 | decode(numdn, p); |
| 1610 | decode(flags, p); |
| 1611 | |
| 1612 | bool end = ((unsigned)flags & CEPH_READDIR_FRAG_END); |
| 1613 | bool hash_order = ((unsigned)flags & CEPH_READDIR_HASH_ORDER); |
| 1614 |
nothing calls this directly
no test coverage detected