FreeBSD Bugzilla – Attachment 204675 Details for
Bug 238197
[FUSEFS] fusefs supports neither chflags(2) not stat.st_birthtim
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Add st_birthtime support to FUSEFS backwards-incompatibly
birthtime.diff (text/plain), 10.88 KB, created by
Alan Somers
on 2019-05-28 20:21:39 UTC
(
hide
)
Description:
Add st_birthtime support to FUSEFS backwards-incompatibly
Filename:
MIME Type:
Creator:
Alan Somers
Created:
2019-05-28 20:21:39 UTC
Size:
10.88 KB
patch
obsolete
>Index: sys/fs/fuse/fuse_internal.c >=================================================================== >--- sys/fs/fuse/fuse_internal.c (revision 348319) >+++ sys/fs/fuse/fuse_internal.c (working copy) >@@ -242,6 +242,14 @@ > vp_cache_at->va_mtime.tv_nsec = attr->mtimensec; > vp_cache_at->va_ctime.tv_sec = attr->ctime; > vp_cache_at->va_ctime.tv_nsec = attr->ctimensec; >+ if (fuse_libabi_geq(data, 7, 9)) { >+ vp_cache_at->va_birthtime.tv_sec = attr->crtime; >+ vp_cache_at->va_birthtime.tv_nsec = attr->crtimensec; >+ } else { >+ /* {-1, 0} means "no value" */ >+ vp_cache_at->va_birthtime.tv_sec = -1; >+ vp_cache_at->va_birthtime.tv_nsec = 0; >+ } > if (fuse_libabi_geq(data, 7, 9) && attr->blksize > 0) > vp_cache_at->va_blocksize = attr->blksize; > else >@@ -855,7 +863,10 @@ > data = fuse_get_mpdata(mp); > dataflags = data->dataflags; > >- fdisp_init(&fdi, sizeof(*fsai)); >+ if (fuse_libabi_geq(data, 7, 9)) >+ fdisp_init(&fdi, sizeof(*fsai)); >+ else >+ fdisp_init(&fdi, FUSE_COMPAT_SETATTR_IN_SIZE); > fdisp_make_vp(&fdi, FUSE_SETATTR, vp, td, cred); > if (!cred) { > fdi.finh->uid = 0; >@@ -902,6 +913,12 @@ > if (vap->va_vaflags & VA_UTIMES_NULL) > fsai->valid |= FATTR_MTIME_NOW; > } >+ if (fuse_libabi_geq(data, 7, 9) && vap->va_birthtime.tv_sec != VNOVAL) { >+ fsai->crtime = vap->va_birthtime.tv_sec; >+ fsai->crtimensec = vap->va_birthtime.tv_nsec; >+ fsai->valid |= FATTR_CRTIME; >+ /* birthtime can never be set to UTIME_NOW */ >+ } > if (vap->va_mode != (mode_t)VNOVAL) { > fsai->mode = vap->va_mode & ALLPERMS; > fsai->valid |= FATTR_MODE; >Index: sys/fs/fuse/fuse_kernel.h >=================================================================== >--- sys/fs/fuse/fuse_kernel.h (revision 348305) >+++ sys/fs/fuse/fuse_kernel.h (working copy) >@@ -45,6 +45,9 @@ > * - add lock_owner field to fuse_setattr_in, fuse_read_in and fuse_write_in > * - add blksize field to fuse_attr > * - add file flags field to fuse_read_in and fuse_write_in >+#if defined(__FreeBSD__) >+ * - add birthtime field fo fuse_attr (FreeBSD only) >+#endif > */ > > #ifndef _FUSE_FUSE_KERNEL_H >@@ -85,14 +88,27 @@ > __u64 atime; > __u64 mtime; > __u64 ctime; >+#ifdef __APPLE__ >+ __u64 crtime; >+#endif > __u32 atimensec; > __u32 mtimensec; > __u32 ctimensec; >+#ifdef __APPLE__ >+ __u32 crtimensec; >+#endif > __u32 mode; > __u32 nlink; > __u32 uid; > __u32 gid; > __u32 rdev; >+#if defined(__APPLE__) || defined(__FreeBSD__) >+ __u32 flags; /* file flags; see chflags(2) */ >+#endif >+#ifdef __FreeBSD__ >+ __u64 crtime; >+ __u32 crtimensec; >+#endif > __u32 blksize; > __u32 padding; > }; >@@ -130,6 +146,16 @@ > #define FATTR_ATIME_NOW (1 << 7) > #define FATTR_MTIME_NOW (1 << 8) > #define FATTR_LOCKOWNER (1 << 9) >+#if defined(__APPLE__) || defined(__FreeBSD__) >+#define FATTR_CRTIME (1 << 28) >+#endif /* defined(__APPLE__) || defined(__FreeBSD__) */ >+#ifdef __APPLE__ >+#define FATTR_CHGTIME (1 << 29) >+#define FATTR_BKUPTIME (1 << 30) >+#endif /* __APPLE__ */ >+#if defined(__APPLE__) || defined(__FreeBSD__) >+#define FATTR_FLAGS (1 << 31) >+#endif /* defined(__APPLE__) || defined(__FreeBSD__) */ > > /** > * Flags returned by the OPEN request >@@ -223,7 +249,11 @@ > /* The read buffer is required to be at least 8k, but may be much larger */ > #define FUSE_MIN_READ_BUFFER 8192 > >-#define FUSE_COMPAT_ENTRY_OUT_SIZE 120 >+#ifdef __APPLE__ >+# define FUSE_COMPAT_ENTRY_OUT_SIZE 136 >+#else >+# define FUSE_COMPAT_ENTRY_OUT_SIZE 120 >+#endif > > struct fuse_entry_out { > __u64 nodeid; /* Inode ID */ >@@ -246,7 +276,11 @@ > __u64 fh; > }; > >-#define FUSE_COMPAT_ATTR_OUT_SIZE 96 >+#ifdef __APPLE__ >+# define FUSE_COMPAT_ATTR_OUT_SIZE 112 >+#else >+# define FUSE_COMPAT_ATTR_OUT_SIZE 96 >+#endif > > struct fuse_attr_out { > __u64 attr_valid; /* Cache timeout for the attributes */ >@@ -273,6 +307,9 @@ > __u64 oldnodeid; > }; > >+/* size of fuse_setattr_in before the addition of crtime and flags in 7.9 */ >+#define FUSE_COMPAT_SETATTR_IN_SIZE 88 >+ > struct fuse_setattr_in { > __u32 valid; > __u32 padding; >@@ -290,6 +327,21 @@ > __u32 uid; > __u32 gid; > __u32 unused5; >+#ifdef __APPLE__ >+ __u64 bkuptime; >+ __u64 chgtime; >+#endif /* __APPLE__ */ >+#if defined(__APPLE__) || defined(__FreeBSD__) >+ __u64 crtime; >+#endif /* defined(__APPLE__) || defined(__FreeBSD__) */ >+#ifdef __APPLE__ >+ __u32 bkuptimensec; >+ __u32 chgtimensec; >+#endif /* __APPLE__ */ >+#if defined(__APPLE__) || defined(__FreeBSD__) >+ __u32 crtimensec; >+ __u32 flags; /* file flags; see chflags(2) */ >+#endif /* defined(__APPLE__) || defined(__FreeBSD__) */ > }; > > struct fuse_open_in { >Index: sys/fs/fuse/fuse_vnops.c >=================================================================== >--- sys/fs/fuse/fuse_vnops.c (revision 348317) >+++ sys/fs/fuse/fuse_vnops.c (working copy) >@@ -1700,7 +1700,9 @@ > } > /* Don't set accmode. Permission to trunc is checked upstack */ > } >- if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) { >+ if (vap->va_atime.tv_sec != VNOVAL || >+ vap->va_mtime.tv_sec != VNOVAL || >+ vap->va_birthtime.tv_sec != VNOVAL) { > if (vap->va_vaflags & VA_UTIMES_NULL) > accmode |= VWRITE; > else >Index: tests/sys/fs/fusefs/getattr.cc >=================================================================== >--- tests/sys/fs/fusefs/getattr.cc (revision 348307) >+++ tests/sys/fs/fusefs/getattr.cc (working copy) >@@ -212,6 +212,8 @@ > out.body.attr.attr.uid = 10; > out.body.attr.attr.gid = 11; > out.body.attr.attr.rdev = 12; >+ out.body.attr.attr.crtime = 13; >+ out.body.attr.attr.crtimensec = 14; > out.body.attr.attr.blksize = 12345; > }))); > >@@ -228,16 +230,11 @@ > EXPECT_EQ(10ul, sb.st_uid); > EXPECT_EQ(11ul, sb.st_gid); > EXPECT_EQ(12ul, sb.st_rdev); >+ EXPECT_EQ(13, sb.st_birthtim.tv_sec); >+ EXPECT_EQ(14, sb.st_birthtim.tv_nsec); > EXPECT_EQ((blksize_t)12345, sb.st_blksize); > 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 > } > > TEST_F(Getattr_7_8, ok) >@@ -292,9 +289,9 @@ > EXPECT_EQ(10ul, sb.st_uid); > EXPECT_EQ(11ul, sb.st_gid); > EXPECT_EQ(12ul, sb.st_rdev); >+ /* fusefs should leave birthtime uninitialized */ >+ EXPECT_EQ(-1, sb.st_birthtim.tv_sec); >+ EXPECT_EQ(0, sb.st_birthtim.tv_nsec); > 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. > } >Index: tests/sys/fs/fusefs/mockfs.cc >=================================================================== >--- tests/sys/fs/fusefs/mockfs.cc (revision 348319) >+++ tests/sys/fs/fusefs/mockfs.cc (working copy) >@@ -253,6 +253,10 @@ > printf(" mtime=%" PRIu64 ".%u", > in.body.setattr.mtime, > in.body.setattr.mtimensec); >+ if (in.body.setattr.valid & FATTR_CRTIME) >+ printf(" crtime=%" PRIu64 ".%u", >+ in.body.setattr.crtime, >+ in.body.setattr.crtimensec); > if (in.body.setattr.valid & FATTR_FH) > printf(" fh=%" PRIu64 "", in.body.setattr.fh); > break; >Index: tests/sys/fs/fusefs/setattr.cc >=================================================================== >--- tests/sys/fs/fusefs/setattr.cc (revision 348307) >+++ tests/sys/fs/fusefs/setattr.cc (working copy) >@@ -565,13 +565,14 @@ > const char FULLPATH[] = "mountpoint/some_file.txt"; > const char RELPATH[] = "some_file.txt"; > const uint64_t ino = 42; >- const timespec oldtimes[2] = { >+ const timespec newtimes[2] = { > {.tv_sec = 1, .tv_nsec = 2}, > {.tv_sec = 3, .tv_nsec = 4}, > }; >- const timespec newtimes[2] = { >+ const timespec oldtimes[3] = { > {.tv_sec = 5, .tv_nsec = 6}, > {.tv_sec = 7, .tv_nsec = 8}, >+ {.tv_sec = 9, .tv_nsec = 10}, > }; > > EXPECT_LOOKUP(1, RELPATH) >@@ -584,12 +585,15 @@ > out.body.entry.attr.atimensec = oldtimes[0].tv_nsec; > out.body.entry.attr.mtime = oldtimes[1].tv_sec; > out.body.entry.attr.mtimensec = oldtimes[1].tv_nsec; >+ out.body.entry.attr.crtime = oldtimes[2].tv_sec; >+ out.body.entry.attr.crtimensec = oldtimes[2].tv_nsec; > }))); > > EXPECT_CALL(*m_mock, process( > ResultOf([=](auto in) { > /* In protocol 7.23, ctime will be changed too */ >- uint32_t valid = FATTR_ATIME | FATTR_MTIME; >+ uint32_t valid = FATTR_ATIME | FATTR_MTIME | >+ FATTR_CRTIME; > return (in.header.opcode == FUSE_SETATTR && > in.header.nodeid == ino && > in.body.setattr.valid == valid && >@@ -598,6 +602,14 @@ > newtimes[0].tv_nsec && > in.body.setattr.mtime == newtimes[1].tv_sec && > in.body.setattr.mtimensec == >+ newtimes[1].tv_nsec && >+ /* >+ * birthtime can't be set directly. Instead, >+ * it's set to the older of the old birthtime >+ * and the new mtime >+ */ >+ in.body.setattr.crtime == newtimes[1].tv_sec && >+ in.body.setattr.crtimensec == > newtimes[1].tv_nsec); > }, Eq(true)), > _) >@@ -609,19 +621,28 @@ > out.body.attr.attr.atimensec = newtimes[0].tv_nsec; > out.body.attr.attr.mtime = newtimes[1].tv_sec; > out.body.attr.attr.mtimensec = newtimes[1].tv_nsec; >+ out.body.attr.attr.crtime = newtimes[1].tv_sec; >+ out.body.attr.attr.crtimensec = newtimes[1].tv_nsec; > }))); >+ >+ //struct stat sb; >+ //EXPECT_EQ(0, stat(FULLPATH, &sb)); >+ //printf("atime=%ld.%ld\t", sb.st_atim.tv_sec, sb.st_atim.tv_nsec); >+ //printf("mtime=%ld.%ld\t", sb.st_mtim.tv_sec, sb.st_mtim.tv_nsec); >+ //printf("birthtime=%ld.%ld\n", sb.st_birthtim.tv_sec, sb.st_birthtim.tv_nsec); > EXPECT_EQ(0, utimensat(AT_FDCWD, FULLPATH, &newtimes[0], 0)) > << strerror(errno); > } > >-/* Change a file mtime but not its atime */ >+/* Change a file's mtime but not its atime */ > TEST_F(Setattr, utimensat_mtime_only) { > const char FULLPATH[] = "mountpoint/some_file.txt"; > const char RELPATH[] = "some_file.txt"; > const uint64_t ino = 42; >- const timespec oldtimes[2] = { >+ const timespec oldtimes[3] = { > {.tv_sec = 1, .tv_nsec = 2}, > {.tv_sec = 3, .tv_nsec = 4}, >+ {.tv_sec = 1, .tv_nsec = 1}, > }; > const timespec newtimes[2] = { > {.tv_sec = 5, .tv_nsec = UTIME_OMIT}, >@@ -638,6 +659,8 @@ > out.body.entry.attr.atimensec = oldtimes[0].tv_nsec; > out.body.entry.attr.mtime = oldtimes[1].tv_sec; > out.body.entry.attr.mtimensec = oldtimes[1].tv_nsec; >+ out.body.entry.attr.crtime = oldtimes[2].tv_sec; >+ out.body.entry.attr.crtimensec = oldtimes[2].tv_nsec; > }))); > > EXPECT_CALL(*m_mock, process( >@@ -675,9 +698,10 @@ > const char FULLPATH[] = "mountpoint/some_file.txt"; > const char RELPATH[] = "some_file.txt"; > const uint64_t ino = 42; >- const timespec oldtimes[2] = { >+ const timespec oldtimes[3] = { > {.tv_sec = 1, .tv_nsec = 2}, > {.tv_sec = 3, .tv_nsec = 4}, >+ {.tv_sec = 5, .tv_nsec = 6}, > }; > const timespec newtimes[2] = { > {.tv_sec = 0, .tv_nsec = UTIME_NOW}, >@@ -701,6 +725,8 @@ > out.body.entry.attr.atimensec = oldtimes[0].tv_nsec; > out.body.entry.attr.mtime = oldtimes[1].tv_sec; > out.body.entry.attr.mtimensec = oldtimes[1].tv_nsec; >+ out.body.entry.attr.crtime = oldtimes[2].tv_sec; >+ out.body.entry.attr.crtimensec = oldtimes[2].tv_nsec; > }))); > > EXPECT_CALL(*m_mock, process(
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 238197
: 204675