mirror of
https://github.com/seaweedfs/seaweedfs.git
synced 2026-10-30 00:40:44 +01:00
feat(filer): add atime to FuseAttributes + TouchAccessTime RPC (#9556)
* feat(filer): add atime field and TouchAccessTime RPC to filer proto
Introduce POSIX-style access-time tracking on the filer:
- FuseAttributes gains atime (field 22) and atime_ns (field 23).
- New TouchAccessTime RPC (and Touch{Access,Time}{Request,Response})
lets read paths bump atime without going through UpdateEntry's
chunk-rewrite/EqualEntry short-circuit.
Additive proto changes only; zero atime is treated as unset and
existing clients are unaffected. Java client proto is kept in lock
step.
Co-authored-by: Cursor <cursoragent@cursor.com>
* feat(filer): wire Atime through Attr codec with mtime fallback
Add Attr.Atime and round-trip it through EntryAttributeToPb /
EntryAttributeToExistingPb / PbToEntryAttribute. A zero proto atime
decodes as Mtime, so legacy entries report a sensible value and
freshly-created/updated entries default Atime to Mtime when callers
do not set it explicitly.
CreateEntry and UpdateEntry stamp Atime = Mtime (or Crtime) when it
is zero. TouchAccessTime later bypasses this path to write atime
alone via Store.UpdateEntry.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix(filer): preserve atime in first epoch second on decode
The Atime decode branch previously treated any attr.Atime == 0 as
unset and overwrote it with Mtime, which drops valid timestamps in
the first second of the unix epoch where attr.Atime is 0 but
attr.AtimeNs > 0. Check both fields so we only fall back to Mtime
when both are zero.
Co-authored-by: Cursor <cursoragent@cursor.com>
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
b63610cf8f
commit
4476cb282b
8 files changed
+683
-370
No files matched your search
@@ -85,6 +85,8 @@ func EntryAttributeToPb(entry *Entry) *filer_pb.FuseAttributes {
|
||||
MtimeNs: int32(entry.Attr.Mtime.Nanosecond()),
|
||||
Ctime: entry.Attr.Ctime.Unix(),
|
||||
CtimeNs: int32(entry.Attr.Ctime.Nanosecond()),
|
||||
Atime: atimeSecondsForPb(entry.Attr),
|
||||
AtimeNs: atimeNanosForPb(entry.Attr),
|
||||
FileMode: uint32(entry.Attr.Mode),
|
||||
Uid: entry.Uid,
|
||||
Gid: entry.Gid,
|
||||
@@ -100,6 +102,20 @@ func EntryAttributeToPb(entry *Entry) *filer_pb.FuseAttributes {
|
||||
}
|
||||
}
|
||||
|
||||
func atimeSecondsForPb(attr Attr) int64 {
|
||||
if attr.Atime.IsZero() {
|
||||
return 0
|
||||
}
|
||||
return attr.Atime.Unix()
|
||||
}
|
||||
|
||||
func atimeNanosForPb(attr Attr) int32 {
|
||||
if attr.Atime.IsZero() {
|
||||
return 0
|
||||
}
|
||||
return int32(attr.Atime.Nanosecond())
|
||||
}
|
||||
|
||||
// EntryAttributeToExistingPb fills an existing FuseAttributes to avoid allocation.
|
||||
// Safe to call with nil attr (will return early without populating).
|
||||
func EntryAttributeToExistingPb(entry *Entry, attr *filer_pb.FuseAttributes) {
|
||||
@@ -111,6 +127,8 @@ func EntryAttributeToExistingPb(entry *Entry, attr *filer_pb.FuseAttributes) {
|
||||
attr.MtimeNs = int32(entry.Attr.Mtime.Nanosecond())
|
||||
attr.Ctime = entry.Attr.Ctime.Unix()
|
||||
attr.CtimeNs = int32(entry.Attr.Ctime.Nanosecond())
|
||||
attr.Atime = atimeSecondsForPb(entry.Attr)
|
||||
attr.AtimeNs = atimeNanosForPb(entry.Attr)
|
||||
attr.FileMode = uint32(entry.Attr.Mode)
|
||||
attr.Uid = entry.Uid
|
||||
attr.Gid = entry.Gid
|
||||
@@ -140,6 +158,11 @@ func PbToEntryAttribute(attr *filer_pb.FuseAttributes) Attr {
|
||||
} else {
|
||||
t.Ctime = t.Mtime
|
||||
}
|
||||
if attr.Atime != 0 || attr.AtimeNs != 0 {
|
||||
t.Atime = time.Unix(attr.Atime, int64(attr.AtimeNs))
|
||||
} else {
|
||||
t.Atime = t.Mtime
|
||||
}
|
||||
t.Mode = os.FileMode(attr.FileMode)
|
||||
t.Uid = attr.Uid
|
||||
t.Gid = attr.Gid
|
||||
|
||||
Reference in new issue
Block a user