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
19 changes: 19 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ members = [
"packages/cli",
"packages/client",
"packages/error",
"packages/fuse",
"packages/nfs",
"packages/server",
"packages/util",
"packages/util",
]
resolver = "2"

Expand Down Expand Up @@ -112,6 +114,8 @@ tangram_client = { path = "packages/client" }
tangram_error = { path = "packages/error" }
tangram_server = { path = "packages/server" }
tangram_util = { path = "packages/util" }
tangram_fuse = { path = "packages/fuse" }
tangram_nfs = { path = "packages/nfs" }
tar = { version = "0.4" }
tempfile = "3"
thiserror = "1"
Expand Down
16 changes: 16 additions & 0 deletions packages/fuse/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "tangram_fuse"
authors.workspace = true
description.workspace = true
edition.workspace = true
homepage.workspace = true
license.workspace = true
repository.workspace = true
version.workspace = true

[dependencies]
num = { workspace = true }
zerocopy = { workspace = true }

[lints]
workspace = true
1 change: 1 addition & 0 deletions packages/fuse/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod sys;
File renamed without changes.
17 changes: 17 additions & 0 deletions packages/nfs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[package]
name = "tangram_nfs"
authors.workspace = true
description.workspace = true
edition.workspace = true
homepage.workspace = true
license.workspace = true
repository.workspace = true
version.workspace = true

[dependencies]
num = { workspace = true }
tokio = { workspace = true }
tracing = { workspace = true }

[lints]
workspace = true
3 changes: 3 additions & 0 deletions packages/nfs/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod rpc;
pub mod types;
pub mod xdr;
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,7 @@ where
Ok(())
}

#[must_use]
pub fn success<T>(verf: Option<Auth>, value: T) -> ReplyBody
where
T: xdr::ToXdr,
Expand All @@ -436,11 +437,13 @@ where
ReplyBody::Accepted(ReplyAccepted { verf, stat })
}

#[must_use]
pub fn error(verf: Option<Auth>, reason: ReplyAcceptedStat) -> ReplyBody {
let verf = verf.unwrap_or_default();
ReplyBody::Accepted(ReplyAccepted { verf, stat: reason })
}

#[must_use]
pub fn reject(reason: ReplyRejected) -> ReplyBody {
ReplyBody::Rejected(reason)
}
13 changes: 13 additions & 0 deletions packages/server/src/vfs/nfs/types.rs → packages/nfs/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1248,6 +1248,7 @@ pub enum nfs_argop4 {
}

impl nfs_argop4 {
#[must_use]
pub fn name(&self) -> &'static str {
match self {
Self::OP_ACCESS(_) => "ACCESS",
Expand Down Expand Up @@ -1292,6 +1293,7 @@ impl nfs_argop4 {
}
}

#[must_use]
pub fn opnum(&self) -> nfs_opnum4 {
match self {
Self::OP_ACCESS(_) => nfs_opnum4::OP_ACCESS,
Expand Down Expand Up @@ -1526,6 +1528,7 @@ impl xdr::FromXdr for stateid4 {
}

impl stateid4 {
#[must_use]
pub fn new(seqid: seqid4, index: u64, is_lock_set: bool) -> Self {
let is_lock_set = u32::from(is_lock_set);
let mut other = [0; NFS4_OTHER_SIZE];
Expand All @@ -1535,14 +1538,17 @@ impl stateid4 {
Self { seqid, other }
}

#[must_use]
pub fn index(&self) -> u64 {
u64::from_be_bytes(self.other[0..8].try_into().unwrap())
}

#[must_use]
pub fn is_lock_set(&self) -> bool {
u32::from_be_bytes(self.other[8..12].try_into().unwrap()) == 1
}

#[must_use]
pub fn is_valid(&self) -> bool {
if [0, u64::MAX].contains(&self.index()) {
[0, u32::MAX].contains(&self.seqid.0)
Expand All @@ -1553,6 +1559,7 @@ impl stateid4 {
}

impl seqid4 {
#[must_use]
pub fn increment(self) -> Self {
if self.0 == u32::MAX {
Self(1)
Expand Down Expand Up @@ -2915,12 +2922,14 @@ impl bitmap4 {
self.0[word] |= 1 << (bit % 32);
}

#[must_use]
pub fn get(&self, bit: usize) -> bool {
let word = self.0.get(bit / 32).copied().unwrap_or(0);
let flag = 1 & (word >> (bit % 32));
flag != 0
}

#[must_use]
pub fn intersection(&self, rhs: &Self) -> Self {
let sz = self.0.len().max(rhs.0.len());
let mut new = vec![0; sz];
Expand All @@ -2934,13 +2943,16 @@ impl bitmap4 {
}

impl nfstime4 {
#[allow(clippy::new_without_default)]
#[must_use]
pub fn new() -> nfstime4 {
nfstime4 {
seconds: 0,
nseconds: 0,
}
}

#[must_use]
pub fn now() -> nfstime4 {
let now = std::time::SystemTime::now();
let dur = now.duration_since(std::time::UNIX_EPOCH).unwrap();
Expand Down Expand Up @@ -2981,6 +2993,7 @@ impl From<std::io::Error> for nfsstat4 {
}

impl nfs_resop4 {
#[must_use]
pub fn status(&self) -> nfsstat4 {
match self {
nfs_resop4::OP_ACCESS(ACCESS4res::Error(e)) => *e,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ impl From<std::io::Error> for Error {
}

impl<'d> Decoder<'d> {
#[must_use]
pub fn from_bytes(input: &'d [u8]) -> Self {
Self { input }
}
Expand Down
2 changes: 2 additions & 0 deletions packages/server/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ sourcemap = { workspace = true }
swc_core = { workspace = true }
tangram_client = { workspace = true }
tangram_error = { workspace = true }
tangram_fuse = { workspace = true }
tangram_nfs = { workspace = true }
tangram_util = { workspace = true }
tempfile = { workspace = true }
time = { workspace = true }
Expand Down
2 changes: 1 addition & 1 deletion packages/server/src/vfs/fuse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ use std::{
};
use tangram_client as tg;
use tangram_error::{Result, Wrap, WrapErr};
use tangram_fuse::sys;
use tokio::io::{AsyncReadExt, AsyncSeekExt};
use zerocopy::{AsBytes, FromBytes};
mod sys;

/// A FUSE server.
#[derive(Clone)]
Expand Down
82 changes: 42 additions & 40 deletions packages/server/src/vfs/nfs.rs
Original file line number Diff line number Diff line change
@@ -1,33 +1,3 @@
use self::types::{
bitmap4, cb_client4, change_info4, dirlist4, entry4, fattr4, fs_locations4, fsid4, length4,
locker4, nfs_argop4, nfs_client_id4, nfs_fh4, nfs_ftype4, nfs_lock_type4, nfs_opnum4,
nfs_resop4, nfsace4, nfsstat4, nfstime4, offset4, open_claim4, open_delegation4,
open_delegation_type4, pathname4, specdata4, stateid4, verifier4, ACCESS4args, ACCESS4res,
ACCESS4resok, CLOSE4args, CLOSE4res, COMPOUND4res, GETATTR4args, GETATTR4res, GETATTR4resok,
GETFH4res, GETFH4resok, LOCK4args, LOCK4res, LOCK4resok, LOCKT4args, LOCKT4res, LOCKU4args,
LOCKU4res, LOOKUP4args, LOOKUP4res, LOOKUPP4res, NVERIFY4res, OPEN4args, OPEN4res, OPEN4resok,
OPENATTR4args, OPENATTR4res, OPEN_CONFIRM4args, OPEN_CONFIRM4res, OPEN_CONFIRM4resok,
PUTFH4args, PUTFH4res, READ4args, READ4res, READ4resok, READDIR4args, READDIR4res,
READDIR4resok, READLINK4res, READLINK4resok, RELEASE_LOCKOWNER4args, RELEASE_LOCKOWNER4res,
RENEW4args, RENEW4res, RESTOREFH4res, SAVEFH4res, SECINFO4args, SECINFO4res, SETCLIENTID4args,
SETCLIENTID4res, SETCLIENTID4resok, SETCLIENTID_CONFIRM4args, SETCLIENTID_CONFIRM4res,
ACCESS4_EXECUTE, ACCESS4_LOOKUP, ACCESS4_READ, ANONYMOUS_STATE_ID, FATTR4_ACL,
FATTR4_ACLSUPPORT, FATTR4_ARCHIVE, FATTR4_CANSETTIME, FATTR4_CASE_INSENSITIVE,
FATTR4_CASE_PRESERVING, FATTR4_CHANGE, FATTR4_CHOWN_RESTRICTED, FATTR4_FH_EXPIRE_TYPE,
FATTR4_FILEHANDLE, FATTR4_FILEID, FATTR4_FILES_AVAIL, FATTR4_FILES_FREE, FATTR4_FILES_TOTAL,
FATTR4_FSID, FATTR4_FS_LOCATIONS, FATTR4_HIDDEN, FATTR4_HOMOGENEOUS, FATTR4_LEASE_TIME,
FATTR4_LINK_SUPPORT, FATTR4_MAXFILESIZE, FATTR4_MAXLINK, FATTR4_MAXNAME, FATTR4_MAXREAD,
FATTR4_MAXWRITE, FATTR4_MIMETYPE, FATTR4_MODE, FATTR4_MOUNTED_ON_FILEID, FATTR4_NAMED_ATTR,
FATTR4_NO_TRUNC, FATTR4_NUMLINKS, FATTR4_OWNER, FATTR4_OWNER_GROUP, FATTR4_QUOTA_AVAIL_HARD,
FATTR4_QUOTA_AVAIL_SOFT, FATTR4_QUOTA_USED, FATTR4_RAWDEV, FATTR4_RDATTR_ERROR, FATTR4_SIZE,
FATTR4_SPACE_AVAIL, FATTR4_SPACE_FREE, FATTR4_SPACE_TOTAL, FATTR4_SPACE_USED,
FATTR4_SUPPORTED_ATTRS, FATTR4_SYMLINK_SUPPORT, FATTR4_SYSTEM, FATTR4_TIME_ACCESS,
FATTR4_TIME_BACKUP, FATTR4_TIME_CREATE, FATTR4_TIME_DELTA, FATTR4_TIME_METADATA,
FATTR4_TIME_MODIFY, FATTR4_TYPE, FATTR4_UNIQUE_HANDLES, MODE4_RGRP, MODE4_ROTH, MODE4_RUSR,
MODE4_XGRP, MODE4_XOTH, MODE4_XUSR, NFS4_VERIFIER_SIZE, NFS_PROG, NFS_VERS,
OPEN4_RESULT_CONFIRM, OPEN4_RESULT_LOCKTYPE_POSIX, OPEN4_SHARE_ACCESS_BOTH,
OPEN4_SHARE_ACCESS_WRITE, READ_BYPASS_STATE_ID, RPC_VERS,
};
use either::Either;
use fnv::FnvBuildHasher;
use num::ToPrimitive;
Expand All @@ -40,15 +10,47 @@ use std::{
};
use tangram_client as tg;
use tangram_error::{Result, WrapErr};
use tangram_nfs::{
rpc,
types::{
bitmap4, cb_client4, change_info4, dirlist4, entry4, fattr4, fs_locations4, fsid4, length4,
locker4, nfs_argop4, nfs_client_id4, nfs_fh4, nfs_ftype4, nfs_lock_type4, nfs_opnum4,
nfs_resop4, nfsace4, nfsstat4, nfstime4, offset4, open_claim4, open_delegation4,
open_delegation_type4, pathname4, specdata4, stateid4, verifier4, ACCESS4args, ACCESS4res,
ACCESS4resok, CLOSE4args, CLOSE4res, COMPOUND4args, COMPOUND4res, GETATTR4args,
GETATTR4res, GETATTR4resok, GETFH4res, GETFH4resok, ILLEGAL4res, LOCK4args, LOCK4res,
LOCK4resok, LOCKT4args, LOCKT4res, LOCKU4args, LOCKU4res, LOOKUP4args, LOOKUP4res,
LOOKUPP4res, NVERIFY4res, OPEN4args, OPEN4res, OPEN4resok, OPENATTR4args, OPENATTR4res,
OPEN_CONFIRM4args, OPEN_CONFIRM4res, OPEN_CONFIRM4resok, PUTFH4args, PUTFH4res,
PUTPUBFH4res, PUTROOTFH4res, READ4args, READ4res, READ4resok, READDIR4args, READDIR4res,
READDIR4resok, READLINK4res, READLINK4resok, RELEASE_LOCKOWNER4args, RELEASE_LOCKOWNER4res,
RENEW4args, RENEW4res, RESTOREFH4res, SAVEFH4res, SECINFO4args, SECINFO4res,
SETCLIENTID4args, SETCLIENTID4res, SETCLIENTID4resok, SETCLIENTID_CONFIRM4args,
SETCLIENTID_CONFIRM4res, ACCESS4_EXECUTE, ACCESS4_LOOKUP, ACCESS4_READ, ANONYMOUS_STATE_ID,
FATTR4_ACL, FATTR4_ACLSUPPORT, FATTR4_ARCHIVE, FATTR4_CANSETTIME, FATTR4_CASE_INSENSITIVE,
FATTR4_CASE_PRESERVING, FATTR4_CHANGE, FATTR4_CHOWN_RESTRICTED, FATTR4_FH_EXPIRE_TYPE,
FATTR4_FILEHANDLE, FATTR4_FILEID, FATTR4_FILES_AVAIL, FATTR4_FILES_FREE,
FATTR4_FILES_TOTAL, FATTR4_FSID, FATTR4_FS_LOCATIONS, FATTR4_HIDDEN, FATTR4_HOMOGENEOUS,
FATTR4_LEASE_TIME, FATTR4_LINK_SUPPORT, FATTR4_MAXFILESIZE, FATTR4_MAXLINK, FATTR4_MAXNAME,
FATTR4_MAXREAD, FATTR4_MAXWRITE, FATTR4_MIMETYPE, FATTR4_MODE, FATTR4_MOUNTED_ON_FILEID,
FATTR4_NAMED_ATTR, FATTR4_NO_TRUNC, FATTR4_NUMLINKS, FATTR4_OWNER, FATTR4_OWNER_GROUP,
FATTR4_QUOTA_AVAIL_HARD, FATTR4_QUOTA_AVAIL_SOFT, FATTR4_QUOTA_USED, FATTR4_RAWDEV,
FATTR4_RDATTR_ERROR, FATTR4_SIZE, FATTR4_SPACE_AVAIL, FATTR4_SPACE_FREE,
FATTR4_SPACE_TOTAL, FATTR4_SPACE_USED, FATTR4_SUPPORTED_ATTRS, FATTR4_SYMLINK_SUPPORT,
FATTR4_SYSTEM, FATTR4_TIME_ACCESS, FATTR4_TIME_BACKUP, FATTR4_TIME_CREATE,
FATTR4_TIME_DELTA, FATTR4_TIME_METADATA, FATTR4_TIME_MODIFY, FATTR4_TYPE,
FATTR4_UNIQUE_HANDLES, MODE4_RGRP, MODE4_ROTH, MODE4_RUSR, MODE4_XGRP, MODE4_XOTH,
MODE4_XUSR, NFS4_VERIFIER_SIZE, NFS_PROG, NFS_VERS, OPEN4_RESULT_CONFIRM,
OPEN4_RESULT_LOCKTYPE_POSIX, OPEN4_SHARE_ACCESS_BOTH, OPEN4_SHARE_ACCESS_WRITE,
READ_BYPASS_STATE_ID, RPC_VERS,
},
xdr,
};
use tokio::{
io::{AsyncReadExt, AsyncSeekExt},
net::{TcpListener, TcpStream},
};

mod rpc;
mod types;
mod xdr;

const ROOT: nfs_fh4 = nfs_fh4(0);
type Map<K, V> = HashMap<K, V, FnvBuildHasher>;

Expand Down Expand Up @@ -409,7 +411,7 @@ impl Server {
decoder: &mut xdr::Decoder<'_>,
) -> rpc::ReplyBody {
// Deserialize the arguments up front.
let args = match decoder.decode::<types::COMPOUND4args>() {
let args = match decoder.decode::<COMPOUND4args>() {
Ok(args) => args,
Err(e) => {
tracing::error!(?e, "Failed to decode COMPOUND args.");
Expand All @@ -424,7 +426,7 @@ impl Server {
};

// Handle the operations.
let types::COMPOUND4args {
let COMPOUND4args {
tag,
minorversion,
argarray,
Expand Down Expand Up @@ -496,7 +498,7 @@ impl Server {

async fn handle_arg(&self, ctx: &mut Context, arg: nfs_argop4) -> nfs_resop4 {
match arg {
nfs_argop4::OP_ILLEGAL => nfs_resop4::OP_ILLEGAL(types::ILLEGAL4res {
nfs_argop4::OP_ILLEGAL => nfs_resop4::OP_ILLEGAL(ILLEGAL4res {
status: nfsstat4::NFS4ERR_OP_ILLEGAL,
}),
nfs_argop4::OP_ACCESS(arg) => nfs_resop4::OP_ACCESS(self.handle_access(ctx, arg).await),
Expand Down Expand Up @@ -531,13 +533,13 @@ impl Server {
},
nfs_argop4::OP_PUTPUBFH => {
Self::handle_put_file_handle(ctx, &PUTFH4args { object: ROOT });
nfs_resop4::OP_PUTPUBFH(types::PUTPUBFH4res {
nfs_resop4::OP_PUTPUBFH(PUTPUBFH4res {
status: nfsstat4::NFS4_OK,
})
},
nfs_argop4::OP_PUTROOTFH => {
Self::handle_put_file_handle(ctx, &PUTFH4args { object: ROOT });
nfs_resop4::OP_PUTROOTFH(types::PUTROOTFH4res {
nfs_resop4::OP_PUTROOTFH(PUTROOTFH4res {
status: nfsstat4::NFS4_OK,
})
},
Expand Down Expand Up @@ -568,7 +570,7 @@ impl Server {
nfs_argop4::OP_RELEASE_LOCKOWNER(arg) => {
nfs_resop4::OP_RELEASE_LOCKOWNER(self.handle_release_lockowner(ctx, arg).await)
},
nfs_argop4::Unimplemented(arg) => types::nfs_resop4::Unknown(arg),
nfs_argop4::Unimplemented(arg) => nfs_resop4::Unknown(arg),
}
}

Expand Down