diff --git a/src/Makefile.am b/src/Makefile.am index cd8e23322ec..9d338eb59e0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -854,11 +854,11 @@ test_rados_api_misc_LDADD = librados.la ${UNITTEST_STATIC_LDADD} test_rados_api_misc_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} bin_DEBUGPROGRAMS += test_rados_api_misc -test_libcephfs_readdir_SOURCES = test/libcephfs/readdir_r_cb.cc -test_libcephfs_readdir_LDFLAGS = $(PTHREAD_CFLAGS) ${AM_LDFLAGS} -test_libcephfs_readdir_LDADD = ${UNITTEST_STATIC_LDADD} libcephfs.la -test_libcephfs_readdir_CXXFLAGS = $(AM_CXXFLAGS) ${UNITTEST_CXXFLAGS} -bin_DEBUGPROGRAMS += test_libcephfs_readdir +test_libcephfs_SOURCES = test/libcephfs/test.cc test/libcephfs/readdir_r_cb.cc +test_libcephfs_LDFLAGS = $(PTHREAD_CFLAGS) ${AM_LDFLAGS} +test_libcephfs_LDADD = ${UNITTEST_STATIC_LDADD} libcephfs.la +test_libcephfs_CXXFLAGS = $(AM_CXXFLAGS) ${UNITTEST_CXXFLAGS} +bin_DEBUGPROGRAMS += test_libcephfs test_filestore_SOURCES = test/filestore/store_test.cc test_filestore_LDFLAGS = ${AM_LDFLAGS} diff --git a/src/include/filepath.h b/src/include/filepath.h index 88470759197..ec1519d5464 100644 --- a/src/include/filepath.h +++ b/src/include/filepath.h @@ -90,7 +90,7 @@ class filepath { * if we are fed a relative path as a string, either set ino=0 (strictly * relative) or 1 (absolute). throw out any leading '/'. */ - filepath(const char *s) { + filepath(const char *s) : encoded(false) { set_path(s); } void set_path(const char *s) { diff --git a/src/mds/Server.cc b/src/mds/Server.cc index c87f4a847f6..4c52ca2f36d 100644 --- a/src/mds/Server.cc +++ b/src/mds/Server.cc @@ -1876,7 +1876,6 @@ CInode* Server::rdlock_path_pin_ref(MDRequest *mdr, int n, if (mdr->done_locking) return mdr->in[n]; - // traverse int r = mdcache->path_traverse(mdr, NULL, NULL, refpath, &mdr->dn[n], &mdr->in[n], MDS_TRAVERSE_FORWARD); if (r > 0) @@ -2099,6 +2098,14 @@ void Server::handle_client_getattr(MDRequest *mdr, bool is_lookup) { MClientRequest *req = mdr->client_request; set rdlocks, wrlocks, xlocks; + + if (req->get_filepath().depth() == 0 && is_lookup) { + // refpath can't be empty for lookup but it can for + // getattr (we do getattr with empty refpath for mount of '/') + reply_request(mdr, -EINVAL); + return; + } + CInode *ref = rdlock_path_pin_ref(mdr, 0, rdlocks, false, false, NULL, !is_lookup); if (!ref) return; diff --git a/src/test/libcephfs/test.cc b/src/test/libcephfs/test.cc new file mode 100644 index 00000000000..af79b72c5ab --- /dev/null +++ b/src/test/libcephfs/test.cc @@ -0,0 +1,67 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include "gtest/gtest.h" +#include "include/cephfs/libcephfs.h" +#include +#include +#include +#include + +TEST(LibCephFS, Open_empty_component) { + + pid_t mypid = getpid(); + struct ceph_mount_info *cmount; + ASSERT_EQ(0, ceph_create(&cmount, NULL)); + ASSERT_EQ(0, ceph_conf_read_file(cmount, NULL)); + ASSERT_EQ(0, ceph_mount(cmount, "/")); + + char c_dir[1024]; + sprintf(c_dir, "/open_test_%d", mypid); + struct ceph_dir_result *dirp; + + ASSERT_EQ(0, ceph_mkdirs(cmount, c_dir, 0777)); + + ASSERT_EQ(0, ceph_opendir(cmount, c_dir, &dirp)); + + char c_path[1024]; + sprintf(c_path, "/open_test_%d//created_file_%d", mypid, mypid); + int fd = ceph_open(cmount, c_path, O_RDONLY|O_CREAT, 0666); + ASSERT_LT(0, fd); + + ASSERT_EQ(0, ceph_close(cmount, fd)); + ASSERT_EQ(0, ceph_closedir(cmount, dirp)); + ceph_shutdown(cmount); + + ASSERT_EQ(0, ceph_create(&cmount, NULL)); + ASSERT_EQ(0, ceph_conf_read_file(cmount, NULL)); + + ASSERT_EQ(0, ceph_mount(cmount, "/")); + + fd = ceph_open(cmount, c_path, O_RDONLY, 0666); + ASSERT_LT(0, fd); + + ASSERT_EQ(0, ceph_close(cmount, fd)); + ASSERT_EQ(0, ceph_closedir(cmount, dirp)); + ceph_shutdown(cmount); +} + +TEST(LibCephFS, Mount_non_exist) { + + struct ceph_mount_info *cmount; + + ASSERT_EQ(0, ceph_create(&cmount, NULL)); + ASSERT_EQ(0, ceph_conf_read_file(cmount, NULL)); + ASSERT_NE(0, ceph_mount(cmount, "/non-exist")); +}