From 15f50c8da63486ac0f24cbb6c2891b66a8081c05 Mon Sep 17 00:00:00 2001
From: Jinmou Li <jinmli@google.com>
Date: Wed, 16 Sep 2020 22:46:33 +0000
Subject: Fix kernfs unlinkat and rmdirat incorrect resolved path name

---
 test/fuse/linux/rmdir_test.cc  | 27 +++++++++++++++++++++++++++
 test/fuse/linux/unlink_test.cc | 24 ++++++++++++++++++++++++
 2 files changed, 51 insertions(+)

(limited to 'test')

diff --git a/test/fuse/linux/rmdir_test.cc b/test/fuse/linux/rmdir_test.cc
index 913d3f910..e3200e446 100644
--- a/test/fuse/linux/rmdir_test.cc
+++ b/test/fuse/linux/rmdir_test.cc
@@ -38,6 +38,7 @@ namespace {
 class RmDirTest : public FuseTest {
  protected:
   const std::string test_dir_name_ = "test_dir";
+  const std::string test_subdir_ = "test_subdir";
   const mode_t test_dir_mode_ = S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO;
 };
 
@@ -67,6 +68,32 @@ TEST_F(RmDirTest, NormalRmDir) {
   EXPECT_EQ(std::string(actual_dirname.data()), test_dir_name_);
 }
 
+TEST_F(RmDirTest, NormalRmDirSubdir) {
+  SetServerInodeLookup(test_subdir_, S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO);
+  const std::string test_dir_path_ =
+      JoinPath(mount_point_.path().c_str(), test_subdir_, test_dir_name_);
+  SetServerInodeLookup(test_dir_name_, test_dir_mode_);
+
+  // RmDir code.
+  struct fuse_out_header rmdir_header = {
+      .len = sizeof(struct fuse_out_header),
+  };
+
+  auto iov_out = FuseGenerateIovecs(rmdir_header);
+  SetServerResponse(FUSE_RMDIR, iov_out);
+
+  ASSERT_THAT(rmdir(test_dir_path_.c_str()), SyscallSucceeds());
+
+  struct fuse_in_header in_header;
+  std::vector<char> actual_dirname(test_dir_name_.length() + 1);
+  auto iov_in = FuseGenerateIovecs(in_header, actual_dirname);
+  GetServerActualRequest(iov_in);
+
+  EXPECT_EQ(in_header.len, sizeof(in_header) + test_dir_name_.length() + 1);
+  EXPECT_EQ(in_header.opcode, FUSE_RMDIR);
+  EXPECT_EQ(std::string(actual_dirname.data()), test_dir_name_);
+}
+
 }  // namespace
 
 }  // namespace testing
diff --git a/test/fuse/linux/unlink_test.cc b/test/fuse/linux/unlink_test.cc
index 5702e9b32..13efbf7c7 100644
--- a/test/fuse/linux/unlink_test.cc
+++ b/test/fuse/linux/unlink_test.cc
@@ -37,6 +37,7 @@ namespace {
 class UnlinkTest : public FuseTest {
  protected:
   const std::string test_file_ = "test_file";
+  const std::string test_subdir_ = "test_subdir";
 };
 
 TEST_F(UnlinkTest, RegularFile) {
@@ -61,6 +62,29 @@ TEST_F(UnlinkTest, RegularFile) {
   EXPECT_EQ(std::string(unlinked_file.data()), test_file_);
 }
 
+TEST_F(UnlinkTest, RegularFileSubDir) {
+  SetServerInodeLookup(test_subdir_, S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO);
+  const std::string test_file_path =
+      JoinPath(mount_point_.path().c_str(), test_subdir_, test_file_);
+  SetServerInodeLookup(test_file_, S_IFREG | S_IRWXU | S_IRWXG | S_IRWXO);
+
+  struct fuse_out_header out_header = {
+      .len = sizeof(struct fuse_out_header),
+  };
+  auto iov_out = FuseGenerateIovecs(out_header);
+  SetServerResponse(FUSE_UNLINK, iov_out);
+
+  ASSERT_THAT(unlink(test_file_path.c_str()), SyscallSucceeds());
+  struct fuse_in_header in_header;
+  std::vector<char> unlinked_file(test_file_.length() + 1);
+  auto iov_in = FuseGenerateIovecs(in_header, unlinked_file);
+  GetServerActualRequest(iov_in);
+
+  EXPECT_EQ(in_header.len, sizeof(in_header) + test_file_.length() + 1);
+  EXPECT_EQ(in_header.opcode, FUSE_UNLINK);
+  EXPECT_EQ(std::string(unlinked_file.data()), test_file_);
+}
+
 TEST_F(UnlinkTest, NoFile) {
   const std::string test_file_path =
       JoinPath(mount_point_.path().c_str(), test_file_);
-- 
cgit v1.2.3