Dhfs-fuse: fix ctime

This commit is contained in:
2025-05-14 11:39:40 +02:00
parent e7f5be689f
commit afb6f0c270
3 changed files with 16 additions and 12 deletions

View File

@@ -11,10 +11,11 @@ import java.util.Set;
/** /**
* File is a data structure that represents a file in the file system * File is a data structure that represents a file in the file system
* @param key unique key *
* @param mode file mode * @param key unique key
* @param cTime creation time * @param mode file mode
* @param mTime modification time * @param cTime inode modification time
* @param mTime modification time
* @param symlink true if the file is a symlink, false otherwise * @param symlink true if the file is a symlink, false otherwise
*/ */
public record File(JObjectKey key, long mode, long cTime, long mTime, public record File(JObjectKey key, long mode, long cTime, long mTime,
@@ -40,6 +41,10 @@ public record File(JObjectKey key, long mode, long cTime, long mTime,
return new File(key, mode, cTime, System.currentTimeMillis(), symlink); return new File(key, mode, cTime, System.currentTimeMillis(), symlink);
} }
public File withCurrentCTime() {
return new File(key, mode, System.currentTimeMillis(), mTime, symlink);
}
@Override @Override
public Collection<JObjectKey> collectRefsTo() { public Collection<JObjectKey> collectRefsTo() {
return Set.of(); return Set.of();

View File

@@ -289,7 +289,7 @@ public class DhfsFileService {
} else if (dent instanceof RemoteObjectMeta) { } else if (dent instanceof RemoteObjectMeta) {
var remote = remoteTx.getData(JDataRemote.class, uuid).orElse(null); var remote = remoteTx.getData(JDataRemote.class, uuid).orElse(null);
if (remote instanceof File f) { if (remote instanceof File f) {
remoteTx.putData(f.withMode(mode).withCurrentMTime()); remoteTx.putData(f.withMode(mode).withCurrentCTime());
return true; return true;
} else { } else {
throw new IllegalArgumentException(uuid + " is not a file"); throw new IllegalArgumentException(uuid + " is not a file");
@@ -723,11 +723,10 @@ public class DhfsFileService {
* Set the access and modification times of a file. * Set the access and modification times of a file.
* *
* @param fileUuid the ID of the file * @param fileUuid the ID of the file
* @param atimeMs the access time in milliseconds
* @param mtimeMs the modification time in milliseconds * @param mtimeMs the modification time in milliseconds
* @return true if the times were set successfully, false otherwise * @return true if the times were set successfully, false otherwise
*/ */
public Boolean setTimes(JObjectKey fileUuid, long atimeMs, long mtimeMs) { public Boolean setTimes(JObjectKey fileUuid, long mtimeMs) {
return jObjectTxManager.executeTx(() -> { return jObjectTxManager.executeTx(() -> {
var dent = curTx.get(JData.class, fileUuid).orElseThrow(() -> new StatusRuntimeExceptionNoStacktrace(Status.NOT_FOUND)); var dent = curTx.get(JData.class, fileUuid).orElseThrow(() -> new StatusRuntimeExceptionNoStacktrace(Status.NOT_FOUND));
@@ -737,7 +736,7 @@ public class DhfsFileService {
} else if (dent instanceof RemoteObjectMeta) { } else if (dent instanceof RemoteObjectMeta) {
var remote = remoteTx.getData(JDataRemote.class, fileUuid).orElse(null); var remote = remoteTx.getData(JDataRemote.class, fileUuid).orElse(null);
if (remote instanceof File f) { if (remote instanceof File f) {
remoteTx.putData(f.withCTime(atimeMs).withMTime(mtimeMs)); remoteTx.putData(f.withCTime(System.currentTimeMillis()).withMTime(mtimeMs));
return true; return true;
} else { } else {
throw new IllegalArgumentException(fileUuid + " is not a file"); throw new IllegalArgumentException(fileUuid + " is not a file");

View File

@@ -188,8 +188,9 @@ public class DhfsFuse extends FuseStubFS {
stat.st_ctim.tv_nsec.set((found.get().ctime() % 1000) * 1000); stat.st_ctim.tv_nsec.set((found.get().ctime() % 1000) * 1000);
stat.st_mtim.tv_sec.set(found.get().mtime() / 1000); stat.st_mtim.tv_sec.set(found.get().mtime() / 1000);
stat.st_mtim.tv_nsec.set((found.get().mtime() % 1000) * 1000); stat.st_mtim.tv_nsec.set((found.get().mtime() % 1000) * 1000);
stat.st_atim.tv_sec.set(found.get().mtime() / 1000); var atime = Math.max(found.get().ctime(), found.get().mtime());
stat.st_atim.tv_nsec.set((found.get().mtime() % 1000) * 1000); stat.st_atim.tv_sec.set(atime / 1000);
stat.st_atim.tv_nsec.set((atime % 1000) * 1000000L);
stat.st_blksize.set(blksize); stat.st_blksize.set(blksize);
} catch (Throwable e) { } catch (Throwable e) {
Log.error("When getattr " + path, e); Log.error("When getattr " + path, e);
@@ -205,8 +206,7 @@ public class DhfsFuse extends FuseStubFS {
if (fileOpt.isEmpty()) return -ErrorCodes.ENOENT(); if (fileOpt.isEmpty()) return -ErrorCodes.ENOENT();
var file = fileOpt.get(); var file = fileOpt.get();
var res = fileService.setTimes(file, var res = fileService.setTimes(file,
timespec[0].tv_sec.get() * 1000, timespec[1].tv_sec.get() * 1000L + timespec[1].tv_nsec.longValue() / 1000000L);
timespec[1].tv_sec.get() * 1000);
if (!res) return -ErrorCodes.EINVAL(); if (!res) return -ErrorCodes.EINVAL();
else return 0; else return 0;
} catch (Throwable e) { } catch (Throwable e) {