Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions cli/src/fuse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,33 @@ impl Filesystem for AgentFSFuse {
}
}

/// Synchronizes file data to persistent storage.
///
/// Ensures all pending writes are durably committed by temporarily
/// enabling FULL synchronous mode in SQLite.
fn fsync(&mut self, _req: &Request, _ino: u64, fh: u64, _datasync: bool, reply: ReplyEmpty) {
let path = {
let open_files = self.open_files.lock();
match open_files.get(&fh) {
Some(file) => file.path.clone(),
None => {
reply.error(libc::EBADF);
return;
}
}
};

let agentfs = self.agentfs.clone();
let result = self
.runtime
.block_on(async move { agentfs.fs.fsync(&path).await });

match result {
Ok(()) => reply.ok(),
Err(_) => reply.error(libc::EIO),
}
}

/// Releases (closes) an open file handle.
///
/// Removes the file handle from the open files table.
Expand Down
18 changes: 18 additions & 0 deletions sdk/rust/src/filesystem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ impl Filesystem {
// Initialize schema first
Self::initialize_schema(&conn).await?;

// Disable synchronous mode for filesystem fsync() semantics.
conn.execute("PRAGMA synchronous = OFF", ()).await?;

// Get chunk_size from config (or use default)
let chunk_size = Self::read_chunk_size(&conn).await?;

Expand Down Expand Up @@ -1550,6 +1553,21 @@ impl Filesystem {
Ok(FilesystemStats { inodes, bytes_used })
}

/// Synchronize file data to persistent storage
///
/// Temporarily enables FULL synchronous mode, runs a transaction to force
/// a checkpoint, then restores OFF mode. This ensures durability while
/// maintaining high performance for normal operations.
///
/// Note: The path parameter is ignored since all data is in a single database.
pub async fn fsync(&self, _path: &str) -> Result<()> {
self.conn.execute("PRAGMA synchronous = FULL", ()).await?;
self.conn.execute("BEGIN", ()).await?;
self.conn.execute("COMMIT", ()).await?;
self.conn.execute("PRAGMA synchronous = OFF", ()).await?;
Ok(())
}

/// Get the number of chunks for a given inode (for testing)
#[cfg(test)]
async fn get_chunk_count(&self, ino: i64) -> Result<i64> {
Expand Down