mirror of
https://github.com/usatiuk/dhfs.git
synced 2025-10-28 20:47:49 +01:00
mtimes
This commit is contained in:
@@ -14,11 +14,15 @@ public abstract class FsNode extends JObject {
|
||||
|
||||
protected FsNode(UUID uuid) {
|
||||
this._uuid = uuid;
|
||||
this._fsNodeData._ctime = System.currentTimeMillis();
|
||||
this._fsNodeData._mtime = _fsNodeData._ctime;
|
||||
}
|
||||
|
||||
protected FsNode(UUID uuid, long mode) {
|
||||
this._uuid = uuid;
|
||||
this._fsNodeData._mode = mode;
|
||||
this._fsNodeData._ctime = System.currentTimeMillis();
|
||||
this._fsNodeData._mtime = _fsNodeData._ctime;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -26,10 +30,12 @@ public abstract class FsNode extends JObject {
|
||||
return _uuid.toString();
|
||||
}
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public static class FsNodeData implements Serializable {
|
||||
@Getter
|
||||
@Setter
|
||||
private long _mode;
|
||||
private long _ctime;
|
||||
private long _mtime;
|
||||
}
|
||||
|
||||
final FsNodeData _fsNodeData = new FsNodeData();
|
||||
@@ -67,4 +73,27 @@ public abstract class FsNode extends JObject {
|
||||
public long getMode() {
|
||||
return runReadLocked(FsNodeData::getMode);
|
||||
}
|
||||
|
||||
public void setCtime(long ctime) {
|
||||
runWriteLocked((fsNodeData) -> {
|
||||
fsNodeData.setCtime(ctime);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public long getCtime() {
|
||||
return runReadLocked(FsNodeData::getCtime);
|
||||
}
|
||||
|
||||
public void setMtime(long mtime) {
|
||||
runWriteLocked((fsNodeData) -> {
|
||||
fsNodeData.setMtime(mtime);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
public long getMtime() {
|
||||
return runReadLocked(FsNodeData::getMtime);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.usatiuk.dhfs.storage.files.service;
|
||||
|
||||
import com.usatiuk.dhfs.storage.files.objects.FsNode;
|
||||
import com.usatiuk.dhfs.storage.files.objects.Directory;
|
||||
import com.usatiuk.dhfs.storage.files.objects.File;
|
||||
import com.usatiuk.dhfs.storage.files.objects.FsNode;
|
||||
import io.smallrye.mutiny.Uni;
|
||||
|
||||
import java.util.Optional;
|
||||
@@ -16,6 +16,7 @@ public interface DhfsFileService {
|
||||
Uni<Boolean> rmdir(String name);
|
||||
Uni<Boolean> unlink(String name);
|
||||
Uni<Boolean> rename(String from, String to);
|
||||
Uni<Boolean> setTimes(String fileUuid, long atimeMs, long mtimeMs);
|
||||
Uni<Iterable<String>> readDir(String name);
|
||||
|
||||
Uni<Long> size(File f);
|
||||
|
||||
@@ -335,11 +335,12 @@ public class DhfsFileServiceImpl implements DhfsFileService {
|
||||
var lchunkBytes = lchunkRead.get().getBytes();
|
||||
|
||||
if (last.getKey() + lchunkBytes.length > offset + data.length) {
|
||||
int start = (int) ((offset + data.length) - last.getKey());
|
||||
Chunk newChunk = new Chunk(Arrays.copyOfRange(lchunkBytes, start, lchunkBytes.length - start));
|
||||
var startInFile = offset + data.length;
|
||||
var startInChunk = startInFile - last.getKey();
|
||||
Chunk newChunk = new Chunk(Arrays.copyOfRange(lchunkBytes, (int) startInChunk, lchunkBytes.length));
|
||||
jObjectManager.tryPut(namespace, newChunk).await().indefinitely();
|
||||
|
||||
newChunks.put(first.getKey(), newChunk.getHash());
|
||||
newChunks.put(startInFile, newChunk.getHash());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,6 +348,7 @@ public class DhfsFileServiceImpl implements DhfsFileService {
|
||||
file.runWriteLocked((fsNodeData, fileData) -> {
|
||||
fileData.getChunks().clear();
|
||||
fileData.getChunks().putAll(newChunks);
|
||||
fsNodeData.setMtime(System.currentTimeMillis());
|
||||
return null;
|
||||
});
|
||||
} catch (Exception e) {
|
||||
@@ -372,6 +374,7 @@ public class DhfsFileServiceImpl implements DhfsFileService {
|
||||
try {
|
||||
file.runWriteLocked((fsNodeData, fileData) -> {
|
||||
fileData.getChunks().clear();
|
||||
fsNodeData.setMtime(System.currentTimeMillis());
|
||||
return null;
|
||||
});
|
||||
} catch (Exception e) {
|
||||
@@ -424,6 +427,31 @@ public class DhfsFileServiceImpl implements DhfsFileService {
|
||||
file.runWriteLocked((fsNodeData, fileData) -> {
|
||||
fileData.getChunks().clear();
|
||||
fileData.getChunks().putAll(newChunks);
|
||||
fsNodeData.setMtime(System.currentTimeMillis());
|
||||
return null;
|
||||
});
|
||||
} catch (Exception e) {
|
||||
Log.error("Error writing file chunks: " + fileUuid, e);
|
||||
return Uni.createFrom().item(false);
|
||||
}
|
||||
|
||||
jObjectManager.put(namespace, file).await().indefinitely();
|
||||
|
||||
return Uni.createFrom().item(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Uni<Boolean> setTimes(String fileUuid, long atimeMs, long mtimeMs) {
|
||||
var fileOpt = jObjectManager.get(namespace, fileUuid, File.class).await().indefinitely();
|
||||
if (fileOpt.isEmpty()) {
|
||||
Log.error("File not found when trying to read: " + fileUuid);
|
||||
return Uni.createFrom().item(false);
|
||||
}
|
||||
var file = fileOpt.get();
|
||||
|
||||
try {
|
||||
file.runWriteLocked((fsNodeData, fileData) -> {
|
||||
fsNodeData.setMtime(mtimeMs);
|
||||
return null;
|
||||
});
|
||||
} catch (Exception e) {
|
||||
|
||||
@@ -20,6 +20,7 @@ import ru.serce.jnrfuse.FuseStubFS;
|
||||
import ru.serce.jnrfuse.struct.FileStat;
|
||||
import ru.serce.jnrfuse.struct.FuseFileInfo;
|
||||
import ru.serce.jnrfuse.struct.Statvfs;
|
||||
import ru.serce.jnrfuse.struct.Timespec;
|
||||
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Optional;
|
||||
@@ -78,9 +79,38 @@ public class DhfsFuse extends FuseStubFS {
|
||||
stat.st_mode.set(S_IFDIR | d.getMode());
|
||||
stat.st_nlink.set(2);
|
||||
}
|
||||
var foundDent = (FsNode) found.get();
|
||||
|
||||
var ctime = System.currentTimeMillis();
|
||||
stat.st_atim.tv_sec.set(ctime / 1000);
|
||||
stat.st_atim.tv_nsec.set((ctime % 1000) * 1000);
|
||||
|
||||
// FIXME: Race?
|
||||
stat.st_ctim.tv_sec.set(foundDent.getCtime() / 1000);
|
||||
stat.st_ctim.tv_nsec.set((foundDent.getCtime() % 1000) * 1000);
|
||||
stat.st_mtim.tv_sec.set(foundDent.getMtime() / 1000);
|
||||
stat.st_mtim.tv_nsec.set((foundDent.getMtime() % 1000) * 1000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int utimens(String path, Timespec[] timespec) {
|
||||
try {
|
||||
var fileOpt = fileService.open(path).await().indefinitely();
|
||||
if (fileOpt.isEmpty()) return -ErrorCodes.ENOENT();
|
||||
var file = fileOpt.get();
|
||||
var res = fileService.setTimes(file.getUuid().toString(),
|
||||
timespec[0].tv_sec.get() * 1000,
|
||||
timespec[1].tv_sec.get() * 1000).await().indefinitely();
|
||||
if (!res) return -ErrorCodes.EINVAL();
|
||||
else return 0;
|
||||
} catch (Exception e) {
|
||||
Log.error("When setting time " + path, e);
|
||||
return -ErrorCodes.ENOENT();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int open(String path, FuseFileInfo fi) {
|
||||
if (fileService.open(path).await().indefinitely().isEmpty()) return -ErrorCodes.ENOENT();
|
||||
|
||||
Reference in New Issue
Block a user