// not written yet, but i want to link!
-int Client::chdir(const char *relpath)
+int Client::chdir(const char *relpath, std::string &new_cwd)
{
Mutex::Locker lock(client_lock);
tout(cct) << "chdir" << std::endl;
if (cwd != in)
cwd.swap(in);
ldout(cct, 3) << "chdir(" << relpath << ") cwd now " << cwd->ino << dendl;
+
+ getcwd(new_cwd);
return 0;
}
Inode *in = cwd.get();
while (in != root) {
assert(in->dn_set.size() < 2); // dirs can't be hard-linked
+
+ // A cwd or ancester is unlinked
+ if (in->dn_set.empty()) {
+ return;
+ }
+
Dentry *dn = in->get_first_parent();
+
+
if (!dn) {
// look it up
ldout(cct, 10) << "getcwd looking up parent for " << *in << dendl;
int statfs(const char *path, struct statvfs *stbuf);
// crap
- int chdir(const char *s);
+ int chdir(const char *s, std::string &new_cwd);
void getcwd(std::string& cwd);
// namespace ops
client->fsync(fd, b);
} else if (strcmp(op, "chdir") == 0) {
const char *a = t.get_string(buf, p);
- client->chdir(a);
+ // Client users should remember their path, but since this
+ // is just a synthetic client we ignore it.
+ std::string ignore;
+ client->chdir(a, ignore);
} else if (strcmp(op, "statfs") == 0) {
struct statvfs stbuf;
client->statfs("/", &stbuf);
return cwd.c_str();
}
+ int chdir(const char *to)
+ {
+ return client->chdir(to, cwd);
+ }
+
CephContext *get_ceph_context() const {
return cct;
}
{
if (!cmount->is_mounted())
return -ENOTCONN;
- return cmount->get_client()->chdir(s);
+ return cmount->chdir(s);
}
extern "C" int ceph_opendir(struct ceph_mount_info *cmount,
cephfs.close(fd)
cephfs.unlink('file-2')
+@with_setup(setup_test)
+def test_delete_cwd():
+ assert_equal("/", cephfs.getcwd())
+
+ cephfs.mkdir("/temp-directory", 0755)
+ cephfs.chdir("/temp-directory")
+ cephfs.rmdir("/temp-directory")
+
+ # getcwd gives you something stale here: it remembers the path string
+ # even when things are unlinked. It's up to the caller to find out
+ # whether it really still exists
+ assert_equal("/temp-directory", cephfs.getcwd())