Skip to content

Commit

Permalink
fusefs: fix invalid value for st_birthtime.tv_nsec
Browse files Browse the repository at this point in the history
If a file system's on-disk format does not support st_birthtime, it
isn't clear what value it should return in stat(2).  Neither our man
page nor the OpenGroup specifies.  But our convention for UFS and
msdosfs is to return { .tv_sec = -1, .tv_nsec = 0 }.  fusefs is
different.  It returns { .tv_sec = -1, .tv_nsec = -1 }.  It's done that
ever since the initial import in SVN r241519.

Most software apparently handles this just fine.  It must, because we've
had no complaints.  But the Rust standard library will panic when
reading such a timestamp during std::fs::metadata, even if the caller
doesn't care about that particular value.  That's a separate bug, and
should be fixed.

Change our invalid value to match msdosfs and ufs, pacifying the Rust
standard library.

PR:		276602
MFC after:	1 week
Sponsored by:	Axcient
Reviewed by:	emaste
Differential Revision: https://reviews.freebsd.org/D43590
  • Loading branch information
asomers committed Feb 4, 2024
1 parent cd724c2 commit 55b80e2
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 13 deletions.
1 change: 0 additions & 1 deletion sys/fs/fuse/fuse_internal.c
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,6 @@ fuse_internal_cache_attrs(struct vnode *vp, struct fuse_attr *attr,
else
return;

vattr_null(vp_cache_at);
vp_cache_at->va_fsid = mp->mnt_stat.f_fsid.val[0];
vp_cache_at->va_fileid = attr->ino;
vp_cache_at->va_mode = attr->mode & ~S_IFMT;
Expand Down
7 changes: 7 additions & 0 deletions sys/fs/fuse/fuse_node.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,14 @@ fuse_vnode_init(struct vnode *vp, struct fuse_vnode_data *fvdat,
{
fvdat->nid = nodeid;
LIST_INIT(&fvdat->handles);

vattr_null(&fvdat->cached_attrs);
fvdat->cached_attrs.va_birthtime.tv_sec = -1;
fvdat->cached_attrs.va_birthtime.tv_nsec = 0;
fvdat->cached_attrs.va_fsid = VNOVAL;
fvdat->cached_attrs.va_gen = 0;
fvdat->cached_attrs.va_rdev = NODEV;

if (nodeid == FUSE_ROOT_ID) {
vp->v_vflag |= VV_ROOT;
}
Expand Down
15 changes: 9 additions & 6 deletions tests/sys/fs/fusefs/getattr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -246,12 +246,15 @@ TEST_F(Getattr, ok)
EXPECT_EQ(ino, sb.st_ino);
EXPECT_EQ(S_IFREG | 0644, sb.st_mode);

//st_birthtim and st_flags are not supported by protocol 7.8. They're
//only supported as OS-specific extensions to OSX.
//EXPECT_EQ(, sb.st_birthtim);
//EXPECT_EQ(, sb.st_flags);

//FUSE can't set st_blksize until protocol 7.9
/*
* st_birthtim and st_flags are not supported by the fuse protocol.
* They're only supported as OS-specific extensions to OSX. For
* birthtime, the convention for "not supported" is "negative one
* second".
*/
EXPECT_EQ(-1, sb.st_birthtim.tv_sec);
EXPECT_EQ(0, sb.st_birthtim.tv_nsec);
EXPECT_EQ(0u, sb.st_flags);
}

/*
Expand Down
15 changes: 9 additions & 6 deletions tests/sys/fs/fusefs/lookup.cc
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,15 @@ TEST_F(Lookup, attr_cache)
// fuse(4) does not _yet_ support inode generations
//EXPECT_EQ(generation, sb.st_gen);

//st_birthtim and st_flags are not supported by protocol 7.8. They're
//only supported as OS-specific extensions to OSX.
//EXPECT_EQ(, sb.st_birthtim);
//EXPECT_EQ(, sb.st_flags);

//FUSE can't set st_blksize until protocol 7.9
/*
* st_birthtim and st_flags are not supported by the fuse protocol.
* They're only supported as OS-specific extensions to OSX. For
* birthtime, the convention for "not supported" is "negative one
* second".
*/
EXPECT_EQ(-1, sb.st_birthtim.tv_sec);
EXPECT_EQ(0, sb.st_birthtim.tv_nsec);
EXPECT_EQ(0u, sb.st_flags);
}

/*
Expand Down

0 comments on commit 55b80e2

Please sign in to comment.