mirror of
https://github.com/ceph/ceph
synced 2025-04-01 00:26:47 +00:00
Merge PR #18942 into master
* refs/pull/18942/head: mds: lookup snapped inodes by vinodeno_t Reviewed-by: Patrick Donnelly <pdonnell@redhat.com>
This commit is contained in:
commit
658b53bcc1
@ -549,6 +549,12 @@ union ceph_mds_request_args {
|
||||
__le64 length; /* num bytes to lock from start */
|
||||
__u8 wait; /* will caller wait for lock to become available? */
|
||||
} __attribute__ ((packed)) filelock_change;
|
||||
struct {
|
||||
__le32 mask; /* CEPH_CAP_* */
|
||||
__le64 snapid;
|
||||
__le64 parent;
|
||||
__le32 hash;
|
||||
} __attribute__ ((packed)) lookupino;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define CEPH_MDS_REQUEST_HEAD_VERSION 1
|
||||
|
@ -2593,6 +2593,24 @@ void CInode::pre_cow_old_inode()
|
||||
cow_old_inode(follows, true);
|
||||
}
|
||||
|
||||
bool CInode::has_snap_data(snapid_t snapid)
|
||||
{
|
||||
bool found = snapid >= first && snapid <= last;
|
||||
if (!found && is_multiversion()) {
|
||||
auto p = old_inodes.lower_bound(snapid);
|
||||
if (p != old_inodes.end()) {
|
||||
if (p->second.first > snapid) {
|
||||
if (p != old_inodes.begin())
|
||||
--p;
|
||||
}
|
||||
if (p->second.first <= snapid && snapid <= p->first) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
void CInode::purge_stale_snap_data(const set<snapid_t>& snaps)
|
||||
{
|
||||
dout(10) << "purge_stale_snap_data " << snaps << dendl;
|
||||
|
@ -515,6 +515,7 @@ public:
|
||||
void split_old_inode(snapid_t snap);
|
||||
old_inode_t *pick_old_inode(snapid_t last);
|
||||
void pre_cow_old_inode();
|
||||
bool has_snap_data(snapid_t s);
|
||||
void purge_stale_snap_data(const std::set<snapid_t>& snaps);
|
||||
|
||||
// -- cache infrastructure --
|
||||
|
@ -788,6 +788,13 @@ public:
|
||||
CInode* get_inode(inodeno_t ino, snapid_t s=CEPH_NOSNAP) {
|
||||
return get_inode(vinodeno_t(ino, s));
|
||||
}
|
||||
CInode* lookup_snap_inode(vinodeno_t vino) {
|
||||
auto p = snap_inode_map.lower_bound(vino);
|
||||
if (p != snap_inode_map.end() &&
|
||||
p->second->ino() == vino.ino && p->second->first <= vino.snapid)
|
||||
return p->second;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CDir* get_dirfrag(dirfrag_t df) {
|
||||
CInode *in = get_inode(df.ino);
|
||||
|
@ -3057,6 +3057,9 @@ void Server::handle_client_lookup_ino(MDRequestRef& mdr,
|
||||
{
|
||||
MClientRequest *req = mdr->client_request;
|
||||
|
||||
if ((uint64_t)req->head.args.lookupino.snapid > 0)
|
||||
return _lookup_snap_ino(mdr);
|
||||
|
||||
inodeno_t ino = req->get_filepath().get_ino();
|
||||
CInode *in = mdcache->get_inode(ino);
|
||||
if (in && in->state_test(CInode::STATE_PURGING)) {
|
||||
@ -3087,7 +3090,7 @@ void Server::handle_client_lookup_ino(MDRequestRef& mdr,
|
||||
rdlocks.insert(&dn->lock);
|
||||
}
|
||||
|
||||
unsigned mask = req->head.args.getattr.mask;
|
||||
unsigned mask = req->head.args.lookupino.mask;
|
||||
if (mask) {
|
||||
Capability *cap = in->get_client_cap(mdr->get_client());
|
||||
int issued = 0;
|
||||
@ -3144,6 +3147,81 @@ void Server::handle_client_lookup_ino(MDRequestRef& mdr,
|
||||
}
|
||||
}
|
||||
|
||||
void Server::_lookup_snap_ino(MDRequestRef& mdr)
|
||||
{
|
||||
MClientRequest *req = mdr->client_request;
|
||||
|
||||
vinodeno_t vino;
|
||||
vino.ino = req->get_filepath().get_ino();
|
||||
vino.snapid = (__u64)req->head.args.lookupino.snapid;
|
||||
inodeno_t parent_ino = (__u64)req->head.args.lookupino.parent;
|
||||
__u32 hash = req->head.args.lookupino.hash;
|
||||
|
||||
dout(7) << "lookup_snap_ino " << vino << " parent " << parent_ino << " hash " << hash << dendl;
|
||||
|
||||
CInode *in = mdcache->lookup_snap_inode(vino);
|
||||
if (!in) {
|
||||
in = mdcache->get_inode(vino.ino);
|
||||
if (in) {
|
||||
if (in->state_test(CInode::STATE_PURGING) ||
|
||||
!in->has_snap_data(vino.snapid)) {
|
||||
if (in->is_dir() || !parent_ino) {
|
||||
respond_to_request(mdr, -ESTALE);
|
||||
return;
|
||||
}
|
||||
in = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (in) {
|
||||
dout(10) << "reply to lookup_snap_ino " << *in << dendl;
|
||||
mdr->snapid = vino.snapid;
|
||||
mdr->tracei = in;
|
||||
respond_to_request(mdr, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
CInode *diri = NULL;
|
||||
if (parent_ino) {
|
||||
diri = mdcache->get_inode(parent_ino);
|
||||
if (!diri) {
|
||||
mdcache->open_ino(parent_ino, mds->mdsmap->get_metadata_pool(), new C_MDS_LookupIno2(this, mdr));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!diri->is_dir()) {
|
||||
respond_to_request(mdr, -EINVAL);
|
||||
return;
|
||||
}
|
||||
|
||||
set<SimpleLock*> rdlocks, wrlocks, xlocks;
|
||||
rdlocks.insert(&diri->dirfragtreelock);
|
||||
if (!mds->locker->acquire_locks(mdr, rdlocks, wrlocks, xlocks))
|
||||
return;
|
||||
|
||||
frag_t frag = diri->dirfragtree[hash];
|
||||
CDir *dir = try_open_auth_dirfrag(diri, frag, mdr);
|
||||
if (!dir)
|
||||
return;
|
||||
|
||||
if (!dir->is_complete()) {
|
||||
if (dir->is_frozen()) {
|
||||
mds->locker->drop_locks(mdr.get());
|
||||
mdr->drop_local_auth_pins();
|
||||
dir->add_waiter(CDir::WAIT_UNFREEZE, new C_MDS_RetryRequest(mdcache, mdr));
|
||||
return;
|
||||
}
|
||||
dir->fetch(new C_MDS_RetryRequest(mdcache, mdr), true);
|
||||
return;
|
||||
}
|
||||
|
||||
respond_to_request(mdr, -ESTALE);
|
||||
} else {
|
||||
mdcache->open_ino(vino.ino, mds->mdsmap->get_metadata_pool(), new C_MDS_LookupIno2(this, mdr), false);
|
||||
}
|
||||
}
|
||||
|
||||
void Server::_lookup_ino_2(MDRequestRef& mdr, int r)
|
||||
{
|
||||
inodeno_t ino = mdr->client_request->get_filepath().get_ino();
|
||||
|
@ -192,6 +192,7 @@ public:
|
||||
void handle_client_getattr(MDRequestRef& mdr, bool is_lookup);
|
||||
void handle_client_lookup_ino(MDRequestRef& mdr,
|
||||
bool want_parent, bool want_dentry);
|
||||
void _lookup_snap_ino(MDRequestRef& mdr);
|
||||
void _lookup_ino_2(MDRequestRef& mdr, int r);
|
||||
void handle_client_readdir(MDRequestRef& mdr);
|
||||
void handle_client_file_setlock(MDRequestRef& mdr);
|
||||
|
Loading…
Reference in New Issue
Block a user