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:
Patrick Donnelly 2017-11-22 13:39:53 -08:00
commit 658b53bcc1
No known key found for this signature in database
GPG Key ID: 3A2A7E25BEA8AADB
6 changed files with 112 additions and 1 deletions

View File

@ -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

View File

@ -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;

View File

@ -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 --

View File

@ -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);

View File

@ -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();

View File

@ -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);