svn commit: r346138 - in projects/fuse2: sys/fs/fuse tests/sys/fs/fusefs

Alan Somers asomers at FreeBSD.org
Thu Apr 11 22:34:30 UTC 2019


Author: asomers
Date: Thu Apr 11 22:34:28 2019
New Revision: 346138
URL: https://svnweb.freebsd.org/changeset/base/346138

Log:
  fusefs: test that we reparent a vnode during rename
  
  fusefs tracks each vnode's parent.  The rename code was already correctly
  updating it.  Delete a comment that said otherwise, and add a regression
  test for it.
  
  Sponsored by:	The FreeBSD Foundation

Modified:
  projects/fuse2/sys/fs/fuse/fuse_node.h
  projects/fuse2/tests/sys/fs/fusefs/rename.cc

Modified: projects/fuse2/sys/fs/fuse/fuse_node.h
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_node.h	Thu Apr 11 22:32:34 2019	(r346137)
+++ projects/fuse2/sys/fs/fuse/fuse_node.h	Thu Apr 11 22:34:28 2019	(r346138)
@@ -76,7 +76,6 @@ struct fuse_vnode_data {
 	uint64_t	nid;
 
 	/** parent **/
-	/* XXXIP very likely to be stale, it's not updated in rename() */
 	uint64_t	parent_nid;
 
 	/** I/O **/

Modified: projects/fuse2/tests/sys/fs/fusefs/rename.cc
==============================================================================
--- projects/fuse2/tests/sys/fs/fusefs/rename.cc	Thu Apr 11 22:32:34 2019	(r346137)
+++ projects/fuse2/tests/sys/fs/fusefs/rename.cc	Thu Apr 11 22:34:28 2019	(r346138)
@@ -233,6 +233,61 @@ TEST_F(Rename, ok)
 	ASSERT_EQ(0, rename(FULLSRC, FULLDST)) << strerror(errno);
 }
 
+/* When moving a file to a new directory, update its parent */
+TEST_F(Rename, parent)
+{
+	const char FULLDST[] = "mountpoint/dstdir/dst";
+	const char RELDSTDIR[] = "dstdir";
+	const char RELDST[] = "dst";
+	const char FULLSRC[] = "mountpoint/src";
+	const char RELSRC[] = "src";
+	const char FULLDSTPARENT[] = "mountpoint/dstdir/dst/..";
+	Sequence seq;
+	uint64_t dst_dir_ino = 43;
+	uint64_t ino = 42;
+	struct stat sb;
+
+	expect_lookup(RELSRC, ino, S_IFDIR | 0755, 0, 1);
+	expect_getattr(1, S_IFDIR | 0755);
+	EXPECT_LOOKUP(1, RELDSTDIR)
+	.WillRepeatedly(Invoke(ReturnImmediate([=](auto in __unused, auto out) {
+		SET_OUT_HEADER_LEN(out, entry);
+		out->body.entry.nodeid = dst_dir_ino;
+		out->body.entry.entry_valid = UINT64_MAX;
+		out->body.entry.attr_valid = UINT64_MAX;
+		out->body.entry.attr.mode = S_IFDIR | 0755;
+		out->body.entry.attr.ino = dst_dir_ino;
+	})));
+	EXPECT_LOOKUP(dst_dir_ino, RELDST)
+	.InSequence(seq)
+	.WillOnce(Invoke(ReturnErrno(ENOENT)));
+	EXPECT_CALL(*m_mock, process(
+		ResultOf([=](auto in) {
+			const char *src = (const char*)in->body.bytes +
+				sizeof(fuse_rename_in);
+			const char *dst = src + strlen(src) + 1;
+			return (in->header.opcode == FUSE_RENAME &&
+				in->body.rename.newdir == dst_dir_ino &&
+				(0 == strcmp(RELDST, dst)) &&
+				(0 == strcmp(RELSRC, src)));
+		}, Eq(true)),
+		_)
+	).WillOnce(Invoke(ReturnErrno(0)));
+	EXPECT_LOOKUP(dst_dir_ino, RELDST)
+	.InSequence(seq)
+	.WillOnce(Invoke(ReturnImmediate([=](auto in __unused, auto out) {
+		SET_OUT_HEADER_LEN(out, entry);
+		out->body.entry.attr.mode = S_IFDIR | 0755;
+		out->body.entry.nodeid = ino;
+		out->body.entry.entry_valid = UINT64_MAX;
+		out->body.entry.attr_valid = UINT64_MAX;
+	})));
+
+	ASSERT_EQ(0, rename(FULLSRC, FULLDST)) << strerror(errno);
+	ASSERT_EQ(0, stat(FULLDSTPARENT, &sb)) << strerror(errno);
+	ASSERT_EQ(dst_dir_ino, sb.st_ino);
+}
+
 // Rename overwrites an existing destination file
 TEST_F(Rename, overwrite)
 {


More information about the svn-src-projects mailing list