Skip to content

Commit

Permalink
client: wire up alternate_name
Browse files Browse the repository at this point in the history
Here we're exposing a public Client::walk (aka path_walk) so that the
user can inspect dentries (not something normally possible in POSIX).
We're going to skip exposing such an interface in libcephfs since
there's no reason to do that (who would use it?) except for testing.
Instead, a follow-up PR will add Client tests (for the first time, yay!)
that will exercise this code.

Also, ideally we'd also expose alternate_name via readdir results but
that is a bit more complicated since dirents do not normally refer to
external memory. So, just rely on Client::walk for testing for now.

Signed-off-by: Patrick Donnelly <[email protected]>
  • Loading branch information
batrick committed Jan 16, 2021
1 parent b91490d commit e65b8dc
Show file tree
Hide file tree
Showing 4 changed files with 113 additions and 56 deletions.
114 changes: 78 additions & 36 deletions src/client/Client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1061,14 +1061,15 @@ Dentry *Client::insert_dentry_inode(Dir *dir, const string& dname, LeaseStat *dl
}

update_dentry_lease(dn, dlease, from, session);
dn->alternate_name = std::move(dlease->alternate_name);
return dn;
}

void Client::update_dentry_lease(Dentry *dn, LeaseStat *dlease, utime_t from, MetaSession *session)
{
utime_t dttl = from;
dttl += (float)dlease->duration_ms / 1000.0;

ldout(cct, 15) << __func__ << " " << *dn << " " << *dlease << " from " << from << dendl;

ceph_assert(dn);

Expand All @@ -1085,6 +1086,7 @@ void Client::update_dentry_lease(Dentry *dn, LeaseStat *dlease, utime_t from, Me
dn->cap_shared_gen = dn->dir->parent_inode->shared_gen;
if (dlease->mask & CEPH_LEASE_PRIMARY_LINK)
dn->mark_primary();
dn->alternate_name = std::move(dlease->alternate_name);
}


Expand Down Expand Up @@ -1281,7 +1283,7 @@ void Client::insert_readdir_results(MetaRequest *request, MetaSession *session,
dirp->cache_index++;
}
// add to cached result list
dirp->buffer.push_back(dir_result_t::dentry(dn->offset, dname, in));
dirp->buffer.push_back(dir_result_t::dentry(dn->offset, dname, dn->alternate_name, in));
ldout(cct, 15) << __func__ << " " << hex << dn->offset << dec << ": '" << dname << "' -> " << in->ino << dendl;
}

Expand Down Expand Up @@ -2371,6 +2373,7 @@ ref_t<MClientRequest> Client::build_client_request(MetaRequest *request)
}
req->set_filepath(request->get_filepath());
req->set_filepath2(request->get_filepath2());
req->set_alternate_name(request->alternate_name);
req->set_data(request->data);
req->set_retry_attempt(request->retry_attempt++);
req->head.num_fwd = request->num_fwd;
Expand Down Expand Up @@ -6697,10 +6700,11 @@ bool Client::_dentry_valid(const Dentry *dn)
}

int Client::_lookup(Inode *dir, const string& dname, int mask, InodeRef *target,
const UserPerm& perms)
const UserPerm& perms, std::string* alternate_name)
{
int r = 0;
Dentry *dn = NULL;
bool did_lookup_request = false;
// can only request shared caps
mask &= CEPH_CAP_ANY_SHARED | CEPH_STAT_RSTAT;

Expand Down Expand Up @@ -6746,13 +6750,13 @@ int Client::_lookup(Inode *dir, const string& dname, int mask, InodeRef *target,
goto done;
}

relookup:
if (dir->dir &&
dir->dir->dentries.count(dname)) {
dn = dir->dir->dentries[dname];

ldout(cct, 20) << __func__ << " have dn " << dname << " mds." << dn->lease_mds << " ttl " << dn->lease_ttl
<< " seq " << dn->lease_seq
<< dendl;
ldout(cct, 20) << __func__ << " have " << *dn << " from mds." << dn->lease_mds
<< " ttl " << dn->lease_ttl << " seq " << dn->lease_seq << dendl;

if (!dn->inode || dn->inode->caps_issued_mask(mask, true)) {
if (_dentry_valid(dn)) {
Expand Down Expand Up @@ -6784,16 +6788,29 @@ int Client::_lookup(Inode *dir, const string& dname, int mask, InodeRef *target,
}
}

if (did_lookup_request) {
r = 0;
goto done;
}
r = _do_lookup(dir, dname, mask, target, perms);
goto done;
did_lookup_request = true;
if (r == 0) {
/* complete lookup to get dentry for alternate_name */
goto relookup;
} else {
goto done;
}

hit_dn:
if (dn->inode) {
*target = dn->inode;
if (alternate_name)
*alternate_name = dn->alternate_name;
} else {
r = -ENOENT;
}
touch_dn(dn);
goto done;

done:
if (r < 0)
Expand Down Expand Up @@ -6825,11 +6842,33 @@ int Client::get_or_create(Inode *dir, const char* name,
return 0;
}

int Client::walk(std::string_view path, walk_dentry_result* wdr, const UserPerm& perms, bool followsym)
{
RWRef_t mref_reader(mount_state, CLIENT_MOUNTING);
if (!mref_reader.is_state_satisfied())
return -ENOTCONN;

ldout(cct, 10) << __func__ << ": " << path << dendl;

std::scoped_lock lock(client_lock);

return path_walk(path, wdr, perms, followsym);
}

int Client::path_walk(const filepath& origpath, InodeRef *end,
const UserPerm& perms, bool followsym, int mask)
{
walk_dentry_result wdr;
int rc = path_walk(origpath, &wdr, perms, followsym, mask);
*end = std::move(wdr.in);
return rc;
}

int Client::path_walk(const filepath& origpath, walk_dentry_result* result, const UserPerm& perms, bool followsym, int mask)
{
filepath path = origpath;
InodeRef cur;
std::string alternate_name;
if (origpath.absolute())
cur = root;
else
Expand Down Expand Up @@ -6857,7 +6896,7 @@ int Client::path_walk(const filepath& origpath, InodeRef *end,
/* Get extra requested caps on the last component */
if (i == (path.depth() - 1))
caps |= mask;
int r = _lookup(cur.get(), dname, caps, &next, perms);
int r = _lookup(cur.get(), dname, caps, &next, perms, &alternate_name);
if (r < 0)
return r;
// only follow trailing symlink if followsym. always follow
Expand Down Expand Up @@ -6902,15 +6941,17 @@ int Client::path_walk(const filepath& origpath, InodeRef *end,
}
if (!cur)
return -ENOENT;
if (end)
end->swap(cur);
if (result) {
result->in = std::move(cur);
result->alternate_name = std::move(alternate_name);
}
return 0;
}


// namespace ops

int Client::link(const char *relexisting, const char *relpath, const UserPerm& perm)
int Client::link(const char *relexisting, const char *relpath, const UserPerm& perm, std::string alternate_name)
{
RWRef_t mref_reader(mount_state, CLIENT_MOUNTING);
if (!mref_reader.is_state_satisfied())
Expand Down Expand Up @@ -6951,7 +6992,7 @@ int Client::link(const char *relexisting, const char *relpath, const UserPerm& p
if (r < 0)
return r;
}
r = _link(in.get(), dir.get(), name.c_str(), perm);
r = _link(in.get(), dir.get(), name.c_str(), perm, std::move(alternate_name));
return r;
}

Expand Down Expand Up @@ -6984,7 +7025,7 @@ int Client::unlink(const char *relpath, const UserPerm& perm)
return _unlink(dir.get(), name.c_str(), perm);
}

int Client::rename(const char *relfrom, const char *relto, const UserPerm& perm)
int Client::rename(const char *relfrom, const char *relto, const UserPerm& perm, std::string alternate_name)
{
RWRef_t mref_reader(mount_state, CLIENT_MOUNTING);
if (!mref_reader.is_state_satisfied())
Expand Down Expand Up @@ -7022,14 +7063,14 @@ int Client::rename(const char *relfrom, const char *relto, const UserPerm& perm)
if (r < 0 && r != -ENOENT)
return r;
}
r = _rename(fromdir.get(), fromname.c_str(), todir.get(), toname.c_str(), perm);
r = _rename(fromdir.get(), fromname.c_str(), todir.get(), toname.c_str(), perm, std::move(alternate_name));
out:
return r;
}

// dirs

int Client::mkdir(const char *relpath, mode_t mode, const UserPerm& perm)
int Client::mkdir(const char *relpath, mode_t mode, const UserPerm& perm, std::string alternate_name)
{
RWRef_t mref_reader(mount_state, CLIENT_MOUNTING);
if (!mref_reader.is_state_satisfied())
Expand Down Expand Up @@ -7057,7 +7098,7 @@ int Client::mkdir(const char *relpath, mode_t mode, const UserPerm& perm)
if (r < 0)
return r;
}
return _mkdir(dir.get(), name.c_str(), mode, perm);
return _mkdir(dir.get(), name.c_str(), mode, perm, 0, {}, std::move(alternate_name));
}

int Client::mkdirs(const char *relpath, mode_t mode, const UserPerm& perms)
Expand Down Expand Up @@ -7179,7 +7220,7 @@ int Client::mknod(const char *relpath, mode_t mode, const UserPerm& perms, dev_t

// symlinks

int Client::symlink(const char *target, const char *relpath, const UserPerm& perms)
int Client::symlink(const char *target, const char *relpath, const UserPerm& perms, std::string alternate_name)
{
RWRef_t mref_reader(mount_state, CLIENT_MOUNTING);
if (!mref_reader.is_state_satisfied())
Expand All @@ -7206,7 +7247,7 @@ int Client::symlink(const char *target, const char *relpath, const UserPerm& per
if (r < 0)
return r;
}
return _symlink(dir.get(), name.c_str(), target, perms);
return _symlink(dir.get(), name.c_str(), target, perms, std::move(alternate_name));
}

int Client::readlink(const char *relpath, char *buf, loff_t size, const UserPerm& perms)
Expand Down Expand Up @@ -8916,7 +8957,7 @@ int Client::getdir(const char *relpath, list<string>& contents,
/****** file i/o **********/
int Client::open(const char *relpath, int flags, const UserPerm& perms,
mode_t mode, int stripe_unit, int stripe_count,
int object_size, const char *data_pool)
int object_size, const char *data_pool, std::string alternate_name)
{
RWRef_t mref_reader(mount_state, CLIENT_MOUNTING);
if (!mref_reader.is_state_satisfied())
Expand Down Expand Up @@ -8974,7 +9015,8 @@ int Client::open(const char *relpath, int flags, const UserPerm& perms,
goto out;
}
r = _create(dir.get(), dname.c_str(), flags, mode, &in, &fh, stripe_unit,
stripe_count, object_size, data_pool, &created, perms);
stripe_count, object_size, data_pool, &created, perms,
std::move(alternate_name));
}
if (r < 0)
goto out;
Expand Down Expand Up @@ -9004,12 +9046,6 @@ int Client::open(const char *relpath, int flags, const UserPerm& perms,
return r;
}

int Client::open(const char *relpath, int flags, const UserPerm& perms, mode_t mode)
{
/* Use default file striping parameters */
return open(relpath, flags, perms, mode, 0, 0, 0, NULL);
}

int Client::lookup_hash(inodeno_t ino, inodeno_t dirino, const char *name,
const UserPerm& perms)
{
Expand Down Expand Up @@ -12781,7 +12817,7 @@ int Client::ll_mknodx(Inode *parent, const char *name, mode_t mode,
int Client::_create(Inode *dir, const char *name, int flags, mode_t mode,
InodeRef *inp, Fh **fhp, int stripe_unit, int stripe_count,
int object_size, const char *data_pool, bool *created,
const UserPerm& perms)
const UserPerm& perms, std::string alternate_name)
{
ldout(cct, 8) << "_create(" << dir->ino << " " << name << ", 0" << oct <<
mode << dec << ")" << dendl;
Expand Down Expand Up @@ -12818,6 +12854,7 @@ int Client::_create(Inode *dir, const char *name, int flags, mode_t mode,
dir->make_nosnap_relative_path(path);
path.push_dentry(name);
req->set_filepath(path);
req->set_alternate_name(std::move(alternate_name));
req->set_inode(dir);
req->head.args.open.flags = cflags | CEPH_O_CREAT;

Expand Down Expand Up @@ -12874,7 +12911,8 @@ int Client::_create(Inode *dir, const char *name, int flags, mode_t mode,
}

int Client::_mkdir(Inode *dir, const char *name, mode_t mode, const UserPerm& perm,
InodeRef *inp, const std::map<std::string, std::string> &metadata)
InodeRef *inp, const std::map<std::string, std::string> &metadata,
std::string alternate_name)
{
ldout(cct, 8) << "_mkdir(" << dir->ino << " " << name << ", 0" << oct
<< mode << dec << ", uid " << perm.uid()
Expand All @@ -12901,6 +12939,7 @@ int Client::_mkdir(Inode *dir, const char *name, mode_t mode, const UserPerm& pe
req->set_inode(dir);
req->dentry_drop = CEPH_CAP_FILE_SHARED;
req->dentry_unless = CEPH_CAP_FILE_EXCL;
req->set_alternate_name(std::move(alternate_name));

mode |= S_IFDIR;
bufferlist bl;
Expand Down Expand Up @@ -13018,7 +13057,7 @@ int Client::ll_mkdirx(Inode *parent, const char *name, mode_t mode, Inode **out,
}

int Client::_symlink(Inode *dir, const char *name, const char *target,
const UserPerm& perms, InodeRef *inp)
const UserPerm& perms, std::string alternate_name, InodeRef *inp)
{
ldout(cct, 8) << "_symlink(" << dir->ino << " " << name << ", " << target
<< ", uid " << perms.uid() << ", gid " << perms.gid() << ")"
Expand All @@ -13040,6 +13079,7 @@ int Client::_symlink(Inode *dir, const char *name, const char *target,
dir->make_nosnap_relative_path(path);
path.push_dentry(name);
req->set_filepath(path);
req->set_alternate_name(std::move(alternate_name));
req->set_inode(dir);
req->set_string2(target);
req->dentry_drop = CEPH_CAP_FILE_SHARED;
Expand Down Expand Up @@ -13088,7 +13128,7 @@ int Client::ll_symlink(Inode *parent, const char *name, const char *value,
}

InodeRef in;
int r = _symlink(parent, name, value, perms, &in);
int r = _symlink(parent, name, value, perms, "", &in);
if (r == 0) {
fill_stat(in, attr);
_ll_get(in.get());
Expand Down Expand Up @@ -13126,7 +13166,7 @@ int Client::ll_symlinkx(Inode *parent, const char *name, const char *value,
}

InodeRef in;
int r = _symlink(parent, name, value, perms, &in);
int r = _symlink(parent, name, value, perms, "", &in);
if (r == 0) {
fill_statx(in, statx_to_mask(flags, want), stx);
_ll_get(in.get());
Expand Down Expand Up @@ -13288,7 +13328,7 @@ int Client::ll_rmdir(Inode *in, const char *name, const UserPerm& perms)
return _rmdir(in, name, perms);
}

int Client::_rename(Inode *fromdir, const char *fromname, Inode *todir, const char *toname, const UserPerm& perm)
int Client::_rename(Inode *fromdir, const char *fromname, Inode *todir, const char *toname, const UserPerm& perm, std::string alternate_name)
{
ldout(cct, 8) << "_rename(" << fromdir->ino << " " << fromname << " to "
<< todir->ino << " " << toname
Expand Down Expand Up @@ -13326,6 +13366,7 @@ int Client::_rename(Inode *fromdir, const char *fromname, Inode *todir, const ch
to.push_dentry(toname);
req->set_filepath(to);
req->set_filepath2(from);
req->set_alternate_name(std::move(alternate_name));

Dentry *oldde;
int res = get_or_create(fromdir, fromname, &oldde);
Expand Down Expand Up @@ -13424,10 +13465,10 @@ int Client::ll_rename(Inode *parent, const char *name, Inode *newparent,
return r;
}

return _rename(parent, name, newparent, newname, perm);
return _rename(parent, name, newparent, newname, perm, "");
}

int Client::_link(Inode *in, Inode *dir, const char *newname, const UserPerm& perm, InodeRef *inp)
int Client::_link(Inode *in, Inode *dir, const char *newname, const UserPerm& perm, std::string alternate_name, InodeRef *inp)
{
ldout(cct, 8) << "_link(" << in->ino << " to " << dir->ino << " " << newname
<< " uid " << perm.uid() << " gid " << perm.gid() << ")" << dendl;
Expand All @@ -13447,6 +13488,7 @@ int Client::_link(Inode *in, Inode *dir, const char *newname, const UserPerm& pe

filepath path(newname, dir->ino);
req->set_filepath(path);
req->set_alternate_name(std::move(alternate_name));
filepath existing(in->ino);
req->set_filepath2(existing);

Expand Down Expand Up @@ -13506,7 +13548,7 @@ int Client::ll_link(Inode *in, Inode *newparent, const char *newname,
return r;
}

return _link(in, newparent, newname, perm, &target);
return _link(in, newparent, newname, perm, "", &target);
}

int Client::ll_num_osds(void)
Expand Down Expand Up @@ -13734,7 +13776,7 @@ int Client::_ll_create(Inode *parent, const char *name, mode_t mode,
goto out;
}
r = _create(parent, name, flags, mode, in, fhp, 0, 0, 0, NULL, &created,
perms);
perms, "");
if (r < 0)
goto out;
}
Expand Down
Loading

0 comments on commit e65b8dc

Please sign in to comment.