tout(cct) << relpath << std::endl;
filepath existing(relexisting);
- filepath path(relpath);
- string name = path.last_dentry();
- path.pop_dentry();
InodeRef in, dir;
int r = path_walk(existing, &in);
if (r < 0)
- goto out;
+ return r;
+ if (std::string(relpath) == "/") {
+ r = -EEXIST;
+ return r;
+ }
+ filepath path(relpath);
+ string name = path.last_dentry();
+ path.pop_dentry();
+
r = path_walk(path, &dir);
if (r < 0)
- goto out;
+ return r;
if (cct->_conf->client_permissions) {
if (S_ISDIR(in->mode)) {
r = -EPERM;
- goto out;
+ return r;
}
r = may_hardlink(in.get());
if (r < 0)
- goto out;
+ return r;
r = may_create(dir.get());
if (r < 0)
- goto out;
+ return r;
}
r = _link(in.get(), dir.get(), name.c_str());
- out:
return r;
}
tout(cct) << "unlink" << std::endl;
tout(cct) << relpath << std::endl;
+ if (std::string(relpath) == "/")
+ return -EISDIR;
+
filepath path(relpath);
string name = path.last_dentry();
path.pop_dentry();
tout(cct) << relfrom << std::endl;
tout(cct) << relto << std::endl;
+ if (std::string(relfrom) == "/" || std::string(relto) == "/")
+ return -EBUSY;
+
filepath from(relfrom);
filepath to(relto);
string fromname = from.last_dentry();
tout(cct) << mode << std::endl;
ldout(cct, 10) << "mkdir: " << relpath << dendl;
+ if (std::string(relpath) == "/")
+ return -EEXIST;
+
filepath path(relpath);
string name = path.last_dentry();
path.pop_dentry();
Mutex::Locker lock(client_lock);
tout(cct) << "rmdir" << std::endl;
tout(cct) << relpath << std::endl;
+
+ if (std::string(relpath) == "/")
+ return -EBUSY;
+
filepath path(relpath);
string name = path.last_dentry();
path.pop_dentry();
tout(cct) << relpath << std::endl;
tout(cct) << mode << std::endl;
tout(cct) << rdev << std::endl;
+
+ if (std::string(relpath) == "/")
+ return -EEXIST;
+
filepath path(relpath);
string name = path.last_dentry();
path.pop_dentry();
tout(cct) << target << std::endl;
tout(cct) << relpath << std::endl;
+ if (std::string(relpath) == "/")
+ return -EEXIST;
+
filepath path(relpath);
string name = path.last_dentry();
path.pop_dentry();
// shutdown should force close opened file/dir
ceph_shutdown(cmount);
}
+
+TEST(LibCephFS, OperationsOnRoot)
+{
+ struct ceph_mount_info *cmount;
+ ASSERT_EQ(ceph_create(&cmount, NULL), 0);
+ ASSERT_EQ(ceph_conf_read_file(cmount, NULL), 0);
+ ASSERT_EQ(0, ceph_conf_parse_env(cmount, NULL));
+ ASSERT_EQ(ceph_mount(cmount, "/"), 0);
+
+ char dirname[32];
+ sprintf(dirname, "/somedir%x", getpid());
+
+ ASSERT_EQ(ceph_mkdir(cmount, dirname, 0755), 0);
+
+ ASSERT_EQ(ceph_rmdir(cmount, "/"), -EBUSY);
+
+ ASSERT_EQ(ceph_link(cmount, "/", "/"), -EEXIST);
+ ASSERT_EQ(ceph_link(cmount, dirname, "/"), -EEXIST);
+ ASSERT_EQ(ceph_link(cmount, "nonExisitingDir", "/"), -ENOENT);
+
+ ASSERT_EQ(ceph_unlink(cmount, "/"), -EISDIR);
+
+ ASSERT_EQ(ceph_rename(cmount, "/", "/"), -EBUSY);
+ ASSERT_EQ(ceph_rename(cmount, dirname, "/"), -EBUSY);
+ ASSERT_EQ(ceph_rename(cmount, "nonExistingDir", "/"), -EBUSY);
+ ASSERT_EQ(ceph_rename(cmount, "/", dirname), -EBUSY);
+ ASSERT_EQ(ceph_rename(cmount, "/", "nonExistingDir"), -EBUSY);
+
+ ASSERT_EQ(ceph_mkdir(cmount, "/", 0777), -EEXIST);
+
+ ASSERT_EQ(ceph_mknod(cmount, "/", 0, 0), -EEXIST);
+
+ ASSERT_EQ(ceph_symlink(cmount, "/", "/"), -EEXIST);
+ ASSERT_EQ(ceph_symlink(cmount, dirname, "/"), -EEXIST);
+ ASSERT_EQ(ceph_symlink(cmount, "nonExistingDir", "/"), -EEXIST);
+
+ ceph_shutdown(cmount);
+}