// namespace ops
-int Client::link(const char *relexisting, const char *relpath, const UserPerm& perm, std::string alternate_name)
+int Client::do_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())
return r;
}
-int Client::rename(const char *relfrom, const char *relto, const UserPerm& perm, std::string alternate_name)
+int Client::do_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())
// dirs
-int Client::mkdir(const char *relpath, mode_t mode, const UserPerm& perm, std::string alternate_name)
-{
- return mkdirat(CEPHFS_AT_FDCWD, relpath, mode, perm, alternate_name);
-}
-
-int Client::mkdirat(int dirfd, const char *relpath, mode_t mode, const UserPerm& perm,
+int Client::do_mkdirat(int dirfd, const char *relpath, mode_t mode, const UserPerm& perm,
std::string alternate_name)
{
RWRef_t mref_reader(mount_state, CLIENT_MOUNTING);
// symlinks
-int Client::symlink(const char *target, const char *relpath, const UserPerm& perms, std::string alternate_name)
-{
- return symlinkat(target, CEPHFS_AT_FDCWD, relpath, perms, alternate_name);
-}
-
-int Client::symlinkat(const char *target, int dirfd, const char *relpath, const UserPerm& perms,
+int Client::do_symlinkat(const char *target, int dirfd, const char *relpath, const UserPerm& perms,
std::string alternate_name)
{
RWRef_t mref_reader(mount_state, CLIENT_MOUNTING);
return r;
}
-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, std::string alternate_name)
-{
- return openat(CEPHFS_AT_FDCWD, relpath, flags, perms, mode, stripe_unit,
- stripe_count, object_size, data_pool, std::move(alternate_name));
-}
-
-int Client::openat(int dirfd, const char *relpath, int flags, const UserPerm& perms,
+int Client::do_openat(int dirfd, const char *relpath, int flags, const UserPerm& perms,
mode_t mode, int stripe_unit, int stripe_count, int object_size,
const char *data_pool, std::string alternate_name) {
RWRef_t mref_reader(mount_state, CLIENT_MOUNTING);
void seekdir(dir_result_t *dirp, loff_t offset);
int may_delete(const char *relpath, const UserPerm& perms);
- int link(const char *existing, const char *newname, const UserPerm& perm, std::string alternate_name="");
+ int link(const char *oldpath, const char *newpath, const UserPerm& perm) {
+ return do_link(oldpath, newpath, perm);
+ }
int unlink(const char *path, const UserPerm& perm);
int unlinkat(int dirfd, const char *relpath, int flags, const UserPerm& perm);
- int rename(const char *from, const char *to, const UserPerm& perm, std::string alternate_name="");
+ int rename(const char *from, const char *to, const UserPerm& perm) {
+ return do_rename(from, to, perm);
+ }
// dirs
- int mkdir(const char *path, mode_t mode, const UserPerm& perm, std::string alternate_name="");
- int mkdirat(int dirfd, const char *relpath, mode_t mode, const UserPerm& perm,
- std::string alternate_name="");
+ int mkdir(const char *path, mode_t mode, const UserPerm& perm) {
+ return mkdirat(CEPHFS_AT_FDCWD, path, mode, perm);
+ }
+ int mkdirat(int dirfd, const char *path, mode_t mode, const UserPerm& perm) {
+ return do_mkdirat(dirfd, path, mode, perm);
+ }
int mkdirs(const char *path, mode_t mode, const UserPerm& perms);
int rmdir(const char *path, const UserPerm& perms);
int readlink(const char *path, char *buf, loff_t size, const UserPerm& perms);
int readlinkat(int dirfd, const char *relpath, char *buf, loff_t size, const UserPerm& perms);
- int symlink(const char *existing, const char *newname, const UserPerm& perms, std::string alternate_name="");
- int symlinkat(const char *target, int dirfd, const char *relpath, const UserPerm& perms,
- std::string alternate_name="");
-
- // path traversal for high-level interface
- int walk(std::string_view path, struct walk_dentry_result* result, const UserPerm& perms, bool followsym=true);
+ int symlink(const char *target, const char *linkpath, const UserPerm& perms) {
+ return symlinkat(target, CEPHFS_AT_FDCWD, linkpath, perms);
+ }
+ int symlinkat(const char *target, int dirfd, const char *linkpath, const UserPerm& perms) {
+ return do_symlinkat(target, dirfd, linkpath, perms);
+ }
// inode stuff
unsigned statx_to_mask(unsigned int flags, unsigned int want);
// file ops
int mknod(const char *path, mode_t mode, const UserPerm& perms, dev_t rdev=0);
- int create_and_open(int dirfd, const char *relpath, int flags, const UserPerm& perms,
- mode_t mode, int stripe_unit, int stripe_count, int object_size,
- const char *data_pool, std::string alternate_name);
- int open(const char *path, int flags, const UserPerm& perms, mode_t mode=0, std::string alternate_name="") {
- return open(path, flags, perms, mode, 0, 0, 0, NULL, alternate_name);
+ int open(const char *path, int flags, const UserPerm& perms, mode_t mode=0) {
+ return open(path, flags, perms, mode, 0, 0, 0, NULL);
}
int open(const char *path, int flags, const UserPerm& perms,
mode_t mode, int stripe_unit, int stripe_count, int object_size,
- const char *data_pool, std::string alternate_name="");
- int openat(int dirfd, const char *relpath, int flags, const UserPerm& perms,
+ const char *data_pool) {
+ return openat(CEPHFS_AT_FDCWD, path, flags, perms, mode, stripe_unit, stripe_count, object_size, data_pool);
+ }
+ int openat(int dirfd, const char *path, int flags, const UserPerm& perms, mode_t mode=0) {
+ return openat(dirfd, path, flags, perms, mode, 0, 0, 0, NULL);
+ }
+ int openat(int dirfd, const char *path, int flags, const UserPerm& perms,
mode_t mode, int stripe_unit, int stripe_count,
- int object_size, const char *data_pool, std::string alternate_name);
- int openat(int dirfd, const char *path, int flags, const UserPerm& perms, mode_t mode=0,
- std::string alternate_name="") {
- return openat(dirfd, path, flags, perms, mode, 0, 0, 0, NULL, alternate_name);
+ int object_size, const char *data_pool) {
+ return do_openat(dirfd, path, flags, perms, mode, stripe_unit, stripe_count, object_size, data_pool);
}
int lookup_hash(inodeno_t ino, inodeno_t dirino, const char *name,
void dump_mds_requests(Formatter *f);
void dump_mds_sessions(Formatter *f, bool cap_dump=false);
+ // path traversal for testing, looking at walk_dentry_result
+ int walk(std::string_view path, struct walk_dentry_result* result, const UserPerm& perms, bool followsym=true);
+
int make_request(MetaRequest *req, const UserPerm& perms,
InodeRef *ptarget = 0, bool *pcreated = 0,
mds_rank_t use_mds=-1, bufferlist *pdirbl=0,
void handle_client_reply(const MConstRef<MClientReply>& reply);
bool is_dir_operation(MetaRequest *request);
+ int create_and_open(int dirfd, const char *relpath, int flags, const UserPerm& perms,
+ mode_t mode, int stripe_unit, int stripe_count, int object_size,
+ const char *data_pool, std::string alternate_name);
+
+ int do_mkdirat(int dirfd, const char *relpath, mode_t mode, const UserPerm& perm, std::string alternate_name="");
+ int do_rename(const char *from, const char *to, const UserPerm& perm, std::string alternate_name="");
+ int do_link(const char *existing, const char *newname, const UserPerm& perm, std::string alternate_name="");
+ int do_symlinkat(const char *target, int dirfd, const char *linkpath, const UserPerm& perms, std::string alternate_name="");
+ int do_openat(int dirfd, const char *path, int flags, const UserPerm& perms, mode_t mode, int stripe_unit, int stripe_count, int object_size, const char *data_pool, std::string alternate_name="");
+
int path_walk(const filepath& fp, struct walk_dentry_result* result, const UserPerm& perms, bool followsym=true, int mask=0,
InodeRef dirinode=nullptr);
int path_walk(const filepath& fp, InodeRef *end, const UserPerm& perms,
class ClientScaffold : public Client {
public:
+ using Client::walk_dentry_result;
+
ClientScaffold(Messenger *m, MonClient *mc, Objecter *objecter_) : Client(m, mc, objecter_) {}
virtual ~ClientScaffold()
{ }
wait_on_list(waiting_for_reclaim);
return session->reclaim_state == MetaSession::RECLAIM_FAIL ? true : false;
}
+
+ /* Expose alternate_name for testing. There is no need to use virtual
+ * methods as we will call these only from the Derived class.
+ */
+ int symlinkat(const char *target, int dirfd, const char *linkpath, const UserPerm& perms, std::string alternate_name) {
+ return do_symlinkat(target, dirfd, linkpath, perms, std::move(alternate_name));
+ }
+ int mkdirat(int dirfd, const char *path, mode_t mode, const UserPerm& perm, std::string alternate_name) {
+ return do_mkdirat(CEPHFS_AT_FDCWD, path, mode, perm, std::move(alternate_name));
+ }
+ int rename(const char *from, const char *to, const UserPerm& perm, std::string alternate_name) {
+ return do_rename(from, to, perm, std::move(alternate_name));
+ }
+ int link(const char *oldpath, const char *newpath, const UserPerm& perm, std::string alternate_name) {
+ return do_link(oldpath, newpath, perm, std::move(alternate_name));
+ }
+ int openat(int dirfd, const char *path, int flags, const UserPerm& perms,
+ mode_t mode, int stripe_unit, int stripe_count,
+ int object_size, const char *data_pool, std::string alternate_name) {
+ return do_openat(dirfd, path, flags, perms, mode, stripe_unit, stripe_count, object_size, data_pool, std::move(alternate_name));
+ }
+
+ int walk(std::string_view path, struct walk_dentry_result* result, const UserPerm& perms, bool followsym=true) {
+ return Client::walk(path, result, perms, followsym);
+ }
};
class TestClient : public ::testing::Test {
delete messenger;
messenger = nullptr;
}
+ // TODO expose altname versions
protected:
static inline ceph::async::io_context_pool icp;
static inline UserPerm myperm{0,0};
TEST_F(TestClient, AlternateNameRemount) {
auto altname = std::string("foo");
auto dir = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid());
- ASSERT_EQ(0, client->mkdir(dir.c_str(), 0777, myperm, altname));
+ ASSERT_EQ(0, client->mkdirat(CEPHFS_AT_FDCWD, dir.c_str(), 0777, myperm, altname));
client->unmount();
TearDown();
client->mount("/", myperm, true);
{
- Client::walk_dentry_result wdr;
+ ClientScaffold::walk_dentry_result wdr;
ASSERT_EQ(0, client->walk(dir.c_str(), &wdr, myperm));
ASSERT_EQ(wdr.alternate_name, altname);
}
TEST_F(TestClient, AlternateNameMkdir) {
auto dir = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid());
- ASSERT_EQ(0, client->mkdir(dir.c_str(), 0777, myperm, "foo"));
+ ASSERT_EQ(0, client->mkdirat(CEPHFS_AT_FDCWD, dir.c_str(), 0777, myperm, "foo"));
{
- Client::walk_dentry_result wdr;
+ ClientScaffold::walk_dentry_result wdr;
ASSERT_EQ(0, client->walk(dir.c_str(), &wdr, myperm));
ASSERT_EQ(wdr.alternate_name, "foo");
}
TEST_F(TestClient, AlternateNameLong) {
auto altname = std::string(4096+1024, '-');
auto dir = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid());
- ASSERT_EQ(0, client->mkdir(dir.c_str(), 0777, myperm, altname));
+ ASSERT_EQ(0, client->mkdirat(CEPHFS_AT_FDCWD, dir.c_str(), 0777, myperm, altname));
{
- Client::walk_dentry_result wdr;
+ ClientScaffold::walk_dentry_result wdr;
ASSERT_EQ(0, client->walk(dir.c_str(), &wdr, myperm));
ASSERT_EQ(wdr.alternate_name, altname);
}
TEST_F(TestClient, AlternateNameCreat) {
auto altname = std::string("foo");
auto file = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid());
- int fd = client->open(file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, altname);
+ int fd = client->openat(CEPHFS_AT_FDCWD, file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, 0, 0, 0, nullptr, altname);
ASSERT_LE(0, fd);
ASSERT_EQ(3, client->write(fd, "baz", 3, 0));
ASSERT_EQ(0, client->close(fd));
{
- Client::walk_dentry_result wdr;
+ ClientScaffold::walk_dentry_result wdr;
ASSERT_EQ(0, client->walk(file, &wdr, myperm));
ASSERT_EQ(wdr.alternate_name, altname);
}
TEST_F(TestClient, AlternateNameSymlink) {
auto altname = std::string("foo");
auto file = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid());
- int fd = client->open(file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, altname);
+ int fd = client->openat(CEPHFS_AT_FDCWD, file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, 0, 0, 0, nullptr, altname);
ASSERT_LE(0, fd);
ASSERT_EQ(3, client->write(fd, "baz", 3, 0));
ASSERT_EQ(0, client->close(fd));
auto file2 = file+"2";
auto altname2 = altname+"2";
- ASSERT_EQ(0, client->symlink(file.c_str(), file2.c_str(), myperm, altname2));
+ ASSERT_EQ(0, client->symlinkat(file.c_str(), CEPHFS_AT_FDCWD, file2.c_str(), myperm, altname2));
{
- Client::walk_dentry_result wdr;
+ ClientScaffold::walk_dentry_result wdr;
ASSERT_EQ(0, client->walk(file2, &wdr, myperm, false));
ASSERT_EQ(wdr.alternate_name, altname2);
ASSERT_EQ(0, client->walk(file, &wdr, myperm));
TEST_F(TestClient, AlternateNameRename) {
auto altname = std::string("foo");
auto file = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid());
- int fd = client->open(file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, altname);
+ int fd = client->openat(CEPHFS_AT_FDCWD, file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, 0, 0, 0, nullptr, altname);
ASSERT_LE(0, fd);
ASSERT_EQ(3, client->write(fd, "baz", 3, 0));
ASSERT_EQ(0, client->close(fd));
ASSERT_EQ(0, client->rename(file.c_str(), file2.c_str(), myperm, altname2));
{
- Client::walk_dentry_result wdr;
+ ClientScaffold::walk_dentry_result wdr;
ASSERT_EQ(0, client->walk(file2, &wdr, myperm));
ASSERT_EQ(wdr.alternate_name, altname2);
}
TEST_F(TestClient, AlternateNameRenameExistMatch) {
auto altname = std::string("foo");
auto file = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid());
- int fd = client->open(file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, altname);
+ int fd = client->openat(CEPHFS_AT_FDCWD, file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, 0, 0, 0, nullptr, altname);
ASSERT_LE(0, fd);
ASSERT_EQ(3, client->write(fd, "baz", 3, 0));
ASSERT_EQ(0, client->close(fd));
auto file2 = file+"2";
auto altname2 = altname+"2";
- fd = client->open(file2.c_str(), O_CREAT|O_WRONLY, myperm, 0777, altname2);
+ fd = client->openat(CEPHFS_AT_FDCWD, file2.c_str(), O_CREAT|O_WRONLY, myperm, 0777, 0, 0, 0, nullptr, altname2);
ASSERT_LE(0, fd);
ASSERT_EQ(3, client->write(fd, "baz", 3, 0));
ASSERT_EQ(0, client->close(fd));
ASSERT_EQ(0, client->rename(file.c_str(), file2.c_str(), myperm, altname2));
{
- Client::walk_dentry_result wdr;
+ ClientScaffold::walk_dentry_result wdr;
ASSERT_EQ(0, client->walk(file2, &wdr, myperm));
ASSERT_EQ(wdr.alternate_name, altname2);
}
TEST_F(TestClient, AlternateNameRenameExistMisMatch) {
auto altname = std::string("foo");
auto file = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid());
- int fd = client->open(file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, altname);
+ int fd = client->openat(CEPHFS_AT_FDCWD, file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, 0, 0, 0, nullptr, altname);
ASSERT_LE(0, fd);
ASSERT_EQ(3, client->write(fd, "baz", 3, 0));
ASSERT_EQ(0, client->close(fd));
auto file2 = file+"2";
auto altname2 = altname+"2";
- fd = client->open(file2.c_str(), O_CREAT|O_WRONLY, myperm, 0777, altname+"mismatch");
+ fd = client->openat(CEPHFS_AT_FDCWD, file2.c_str(), O_CREAT|O_WRONLY, myperm, 0777, 0, 0, 0, nullptr, altname+"mismatch");
ASSERT_LE(0, fd);
ASSERT_EQ(3, client->write(fd, "baz", 3, 0));
ASSERT_EQ(0, client->close(fd));
ASSERT_EQ(-EINVAL, client->rename(file.c_str(), file2.c_str(), myperm, altname2));
{
- Client::walk_dentry_result wdr;
+ ClientScaffold::walk_dentry_result wdr;
ASSERT_EQ(0, client->walk(file2, &wdr, myperm));
ASSERT_EQ(wdr.alternate_name, altname+"mismatch");
}
TEST_F(TestClient, AlternateNameLink) {
auto altname = std::string("foo");
auto file = fmt::format("{}_{}", ::testing::UnitTest::GetInstance()->current_test_info()->name(), getpid());
- int fd = client->open(file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, altname);
+ int fd = client->openat(CEPHFS_AT_FDCWD, file.c_str(), O_CREAT|O_WRONLY, myperm, 0777, 0, 0, 0, nullptr, altname);
ASSERT_LE(0, fd);
ASSERT_EQ(3, client->write(fd, "baz", 3, 0));
ASSERT_EQ(0, client->close(fd));
ASSERT_EQ(0, client->link(file.c_str(), file2.c_str(), myperm, altname2));
{
- Client::walk_dentry_result wdr;
+ ClientScaffold::walk_dentry_result wdr;
ASSERT_EQ(0, client->walk(file2, &wdr, myperm));
ASSERT_EQ(wdr.alternate_name, altname2);
ASSERT_EQ(0, client->walk(file, &wdr, myperm));