Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
R
redoxfs
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Uygar Sapmaz
redoxfs
Commits
9471a2e4
Commit
9471a2e4
authored
7 years ago
by
Jeremy Soller
Browse files
Options
Downloads
Patches
Plain Diff
WIP: Add mtime/ctime to Redox
parent
dcce0d9e
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
mkfs/main.rs
+4
-2
4 additions, 2 deletions
mkfs/main.rs
mount/fuse.rs
+40
-11
40 additions, 11 deletions
mount/fuse.rs
src/filesystem.rs
+17
-6
17 additions, 6 deletions
src/filesystem.rs
src/header.rs
+1
-1
1 addition, 1 deletion
src/header.rs
src/node.rs
+20
-4
20 additions, 4 deletions
src/node.rs
with
82 additions
and
24 deletions
mkfs/main.rs
+
4
−
2
View file @
9471a2e4
...
...
@@ -3,7 +3,7 @@
extern
crate
redoxfs
;
extern
crate
syscall
;
use
std
::{
env
,
process
,
str
};
use
std
::{
env
,
process
,
str
,
time
};
use
redoxfs
::
FileSystem
;
...
...
@@ -14,9 +14,11 @@ pub mod image;
fn
main
()
{
let
mut
args
=
env
::
args
();
if
let
Some
(
path
)
=
args
.nth
(
1
)
{
let
ctime
=
time
::
SystemTime
::
now
()
.duration_since
(
time
::
UNIX_EPOCH
)
.unwrap
();
//Open an existing image
match
Image
::
open
(
&
path
)
{
Ok
(
disk
)
=>
match
FileSystem
::
create
(
Box
::
new
(
disk
))
{
Ok
(
disk
)
=>
match
FileSystem
::
create
(
Box
::
new
(
disk
)
,
ctime
.as_secs
(),
ctime
.subsec_nanos
()
)
{
Ok
(
filesystem
)
=>
{
println!
(
"redoxfs-mkfs: created filesystem on {}, size {} MB"
,
path
,
filesystem
.header
.1
.size
/
1024
/
1024
);
},
...
...
This diff is collapsed.
Click to expand it.
mount/fuse.rs
+
40
−
11
View file @
9471a2e4
...
...
@@ -4,6 +4,7 @@ extern crate time;
use
redoxfs
;
use
std
::
path
::
Path
;
use
std
::
os
::
unix
::
ffi
::
OsStrExt
;
use
std
::
time
::{
SystemTime
,
UNIX_EPOCH
};
use
self
::
fuse
::{
FileType
,
FileAttr
,
Filesystem
,
Request
,
ReplyData
,
ReplyEntry
,
ReplyAttr
,
ReplyCreate
,
ReplyDirectory
,
ReplyEmpty
,
ReplyStatfs
,
ReplyWrite
};
use
self
::
time
::
Timespec
;
...
...
@@ -12,7 +13,7 @@ pub use self::fuse::mount;
const
TTL
:
Timespec
=
Timespec
{
sec
:
1
,
nsec
:
0
};
// 1 second
const
CREATE
_TIME
:
Timespec
=
Timespec
{
sec
:
0
,
nsec
:
0
};
const
NULL
_TIME
:
Timespec
=
Timespec
{
sec
:
0
,
nsec
:
0
};
pub
struct
Fuse
{
pub
fs
:
redoxfs
::
FileSystem
,
...
...
@@ -23,10 +24,16 @@ fn node_attr(node: &(u64, redoxfs::Node)) -> FileAttr {
ino
:
node
.0
,
size
:
node
.1
.extents
[
0
]
.length
,
blocks
:
(
node
.1
.extents
[
0
]
.length
+
511
)
/
512
,
atime
:
CREATE_TIME
,
mtime
:
CREATE_TIME
,
ctime
:
CREATE_TIME
,
crtime
:
CREATE_TIME
,
atime
:
NULL_TIME
,
mtime
:
Timespec
{
sec
:
node
.1
.mtime
as
i64
,
nsec
:
node
.1
.mtime_nsec
as
i32
,
},
ctime
:
Timespec
{
sec
:
node
.1
.ctime
as
i64
,
nsec
:
node
.1
.ctime_nsec
as
i32
,
},
crtime
:
NULL_TIME
,
kind
:
if
node
.1
.is_dir
()
{
FileType
::
Directory
}
else
if
node
.1
.is_symlink
()
{
...
...
@@ -68,7 +75,7 @@ impl Filesystem for Fuse {
fn
setattr
(
&
mut
self
,
_req
:
&
Request
,
block
:
u64
,
mode
:
Option
<
u32
>
,
uid
:
Option
<
u32
>
,
gid
:
Option
<
u32
>
,
size
:
Option
<
u64
>
,
_atime
:
Option
<
Timespec
>
,
_
mtime
:
Option
<
Timespec
>
,
_fh
:
Option
<
u64
>
,
_atime
:
Option
<
Timespec
>
,
mtime
:
Option
<
Timespec
>
,
_fh
:
Option
<
u64
>
,
_crtime
:
Option
<
Timespec
>
,
_chgtime
:
Option
<
Timespec
>
,
_bkuptime
:
Option
<
Timespec
>
,
_flags
:
Option
<
u32
>
,
reply
:
ReplyAttr
)
{
if
let
Some
(
mode
)
=
mode
{
...
...
@@ -127,6 +134,23 @@ impl Filesystem for Fuse {
}
}
if
let
Some
(
mtime
)
=
mtime
{
match
self
.fs
.node
(
block
)
{
Ok
(
mut
node
)
=>
if
mtime
.sec
as
u64
>
node
.1
.mtime
||
(
mtime
.sec
as
u64
==
node
.1
.mtime
&&
mtime
.nsec
as
u32
>
node
.1
.mtime_nsec
)
{
node
.1
.mtime
=
mtime
.sec
as
u64
;
node
.1
.mtime_nsec
=
mtime
.nsec
as
u32
;
if
let
Err
(
err
)
=
self
.fs
.write_at
(
node
.0
,
&
node
.1
)
{
reply
.error
(
err
.errno
as
i32
);
return
;
}
},
Err
(
err
)
=>
{
reply
.error
(
err
.errno
as
i32
);
return
;
}
}
}
match
self
.fs
.node
(
block
)
{
Ok
(
node
)
=>
{
reply
.attr
(
&
TTL
,
&
node_attr
(
&
node
));
...
...
@@ -150,7 +174,8 @@ impl Filesystem for Fuse {
}
fn
write
(
&
mut
self
,
_req
:
&
Request
,
block
:
u64
,
_fh
:
u64
,
offset
:
u64
,
data
:
&
[
u8
],
_flags
:
u32
,
reply
:
ReplyWrite
)
{
match
self
.fs
.write_node
(
block
,
offset
,
&
data
)
{
let
mtime
=
SystemTime
::
now
()
.duration_since
(
UNIX_EPOCH
)
.unwrap
();
match
self
.fs
.write_node
(
block
,
offset
,
&
data
,
mtime
.as_secs
(),
mtime
.subsec_nanos
())
{
Ok
(
count
)
=>
{
reply
.written
(
count
as
u32
);
},
...
...
@@ -196,7 +221,8 @@ impl Filesystem for Fuse {
}
fn
create
(
&
mut
self
,
_req
:
&
Request
,
parent_block
:
u64
,
name
:
&
Path
,
mode
:
u32
,
flags
:
u32
,
reply
:
ReplyCreate
)
{
match
self
.fs
.create_node
(
redoxfs
::
Node
::
MODE_FILE
|
(
mode
as
u16
&
redoxfs
::
Node
::
MODE_PERM
),
name
.to_str
()
.unwrap
(),
parent_block
)
{
let
ctime
=
SystemTime
::
now
()
.duration_since
(
UNIX_EPOCH
)
.unwrap
();
match
self
.fs
.create_node
(
redoxfs
::
Node
::
MODE_FILE
|
(
mode
as
u16
&
redoxfs
::
Node
::
MODE_PERM
),
name
.to_str
()
.unwrap
(),
parent_block
,
ctime
.as_secs
(),
ctime
.subsec_nanos
())
{
Ok
(
node
)
=>
{
// println!("Create {:?}:{:o}:{:o}", node.1.name(), node.1.mode, mode);
reply
.created
(
&
TTL
,
&
node_attr
(
&
node
),
0
,
0
,
flags
);
...
...
@@ -208,7 +234,8 @@ impl Filesystem for Fuse {
}
fn
mkdir
(
&
mut
self
,
_req
:
&
Request
,
parent_block
:
u64
,
name
:
&
Path
,
mode
:
u32
,
reply
:
ReplyEntry
)
{
match
self
.fs
.create_node
(
redoxfs
::
Node
::
MODE_DIR
|
(
mode
as
u16
&
redoxfs
::
Node
::
MODE_PERM
),
name
.to_str
()
.unwrap
(),
parent_block
)
{
let
ctime
=
SystemTime
::
now
()
.duration_since
(
UNIX_EPOCH
)
.unwrap
();
match
self
.fs
.create_node
(
redoxfs
::
Node
::
MODE_DIR
|
(
mode
as
u16
&
redoxfs
::
Node
::
MODE_PERM
),
name
.to_str
()
.unwrap
(),
parent_block
,
ctime
.as_secs
(),
ctime
.subsec_nanos
())
{
Ok
(
node
)
=>
{
// println!("Mkdir {:?}:{:o}:{:o}", node.1.name(), node.1.mode, mode);
reply
.entry
(
&
TTL
,
&
node_attr
(
&
node
),
0
);
...
...
@@ -257,9 +284,11 @@ impl Filesystem for Fuse {
}
fn
symlink
(
&
mut
self
,
_req
:
&
Request
,
parent_block
:
u64
,
name
:
&
Path
,
link
:
&
Path
,
reply
:
ReplyEntry
)
{
match
self
.fs
.create_node
(
redoxfs
::
Node
::
MODE_SYMLINK
|
0o777
,
name
.to_str
()
.unwrap
(),
parent_block
)
{
let
ctime
=
SystemTime
::
now
()
.duration_since
(
UNIX_EPOCH
)
.unwrap
();
match
self
.fs
.create_node
(
redoxfs
::
Node
::
MODE_SYMLINK
|
0o777
,
name
.to_str
()
.unwrap
(),
parent_block
,
ctime
.as_secs
(),
ctime
.subsec_nanos
())
{
Ok
(
node
)
=>
{
match
self
.fs
.write_node
(
node
.0
,
0
,
link
.as_os_str
()
.as_bytes
())
{
let
mtime
=
SystemTime
::
now
()
.duration_since
(
UNIX_EPOCH
)
.unwrap
();
match
self
.fs
.write_node
(
node
.0
,
0
,
link
.as_os_str
()
.as_bytes
(),
mtime
.as_secs
(),
mtime
.subsec_nanos
())
{
Ok
(
_count
)
=>
{
reply
.entry
(
&
TTL
,
&
node_attr
(
&
node
),
0
);
},
...
...
This diff is collapsed.
Click to expand it.
src/filesystem.rs
+
17
−
6
View file @
9471a2e4
...
...
@@ -37,15 +37,15 @@ impl FileSystem {
}
/// Create a file system on a disk
pub
fn
create
(
mut
disk
:
Box
<
Disk
>
)
->
Result
<
Self
>
{
pub
fn
create
(
mut
disk
:
Box
<
Disk
>
,
ctime
:
u64
,
ctime_nsec
:
u32
)
->
Result
<
Self
>
{
let
size
=
disk
.size
()
?
;
if
size
>=
4
*
512
{
let
mut
free
=
(
2
,
Node
::
new
(
Node
::
MODE_FILE
,
"free"
,
0
));
let
mut
free
=
(
2
,
Node
::
new
(
Node
::
MODE_FILE
,
"free"
,
0
,
ctime
,
ctime_nsec
));
free
.1
.extents
[
0
]
=
Extent
::
new
(
4
,
size
-
4
*
512
);
disk
.write_at
(
free
.0
,
&
free
.1
)
?
;
let
root
=
(
1
,
Node
::
new
(
Node
::
MODE_DIR
|
0o755
,
"root"
,
0
));
let
root
=
(
1
,
Node
::
new
(
Node
::
MODE_DIR
|
0o755
,
"root"
,
0
,
ctime
,
ctime_nsec
));
disk
.write_at
(
root
.0
,
&
root
.1
)
?
;
let
header
=
(
0
,
Header
::
new
(
size
,
root
.0
,
free
.0
));
...
...
@@ -194,11 +194,11 @@ impl FileSystem {
}
}
pub
fn
create_node
(
&
mut
self
,
mode
:
u16
,
name
:
&
str
,
parent_block
:
u64
)
->
Result
<
(
u64
,
Node
)
>
{
pub
fn
create_node
(
&
mut
self
,
mode
:
u16
,
name
:
&
str
,
parent_block
:
u64
,
ctime
:
u64
,
ctime_nsec
:
u32
)
->
Result
<
(
u64
,
Node
)
>
{
if
self
.find_node
(
name
,
parent_block
)
.is_ok
()
{
Err
(
Error
::
new
(
EEXIST
))
}
else
{
let
node
=
(
self
.allocate
(
1
)
?
,
Node
::
new
(
mode
,
name
,
parent_block
));
let
node
=
(
self
.allocate
(
1
)
?
,
Node
::
new
(
mode
,
name
,
parent_block
,
ctime
,
ctime_nsec
));
self
.write_at
(
node
.0
,
&
node
.1
)
?
;
self
.insert_blocks
(
node
.0
,
512
,
parent_block
)
?
;
...
...
@@ -276,6 +276,7 @@ impl FileSystem {
}
}
// TODO: modification time
fn
node_ensure_len
(
&
mut
self
,
block
:
u64
,
mut
length
:
u64
)
->
Result
<
()
>
{
if
block
==
0
{
return
Err
(
Error
::
new
(
ENOENT
));
...
...
@@ -319,6 +320,7 @@ impl FileSystem {
}
}
//TODO: modification time
pub
fn
node_set_len
(
&
mut
self
,
block
:
u64
,
mut
length
:
u64
)
->
Result
<
()
>
{
if
block
==
0
{
return
Err
(
Error
::
new
(
ENOENT
));
...
...
@@ -450,7 +452,7 @@ impl FileSystem {
Ok
(
i
)
}
pub
fn
write_node
(
&
mut
self
,
block
:
u64
,
offset
:
u64
,
buf
:
&
[
u8
])
->
Result
<
usize
>
{
pub
fn
write_node
(
&
mut
self
,
block
:
u64
,
offset
:
u64
,
buf
:
&
[
u8
]
,
mtime
:
u64
,
mtime_nsec
:
u32
)
->
Result
<
usize
>
{
let
block_offset
=
offset
/
512
;
let
mut
byte_offset
=
(
offset
%
512
)
as
usize
;
...
...
@@ -512,6 +514,15 @@ impl FileSystem {
assert_eq!
(
block
,
extent
.block
+
(
extent
.length
+
511
)
/
512
);
}
if
i
>
0
{
let
mut
node
=
self
.node
(
block
)
?
;
if
mtime
>
node
.1
.mtime
||
(
mtime
==
node
.1
.mtime
&&
mtime_nsec
>
node
.1
.mtime_nsec
)
{
node
.1
.mtime
=
mtime
;
node
.1
.mtime_nsec
=
mtime_nsec
;
self
.write_at
(
node
.0
,
&
node
.1
)
?
;
}
}
Ok
(
i
)
}
...
...
This diff is collapsed.
Click to expand it.
src/header.rs
+
1
−
1
View file @
9471a2e4
...
...
@@ -22,7 +22,7 @@ pub struct Header {
impl
Header
{
pub
const
SIGNATURE
:
&
'static
[
u8
;
8
]
=
b"RedoxFS
\0
"
;
pub
const
VERSION
:
u64
=
1
;
pub
const
VERSION
:
u64
=
2
;
pub
fn
default
()
->
Header
{
Header
{
...
...
This diff is collapsed.
Click to expand it.
src/node.rs
+
20
−
4
View file @
9471a2e4
...
...
@@ -8,7 +8,11 @@ pub struct Node {
pub
mode
:
u16
,
pub
uid
:
u32
,
pub
gid
:
u32
,
pub
name
:
[
u8
;
246
],
pub
ctime
:
u64
,
pub
ctime_nsec
:
u32
,
pub
mtime
:
u64
,
pub
mtime_nsec
:
u32
,
pub
name
:
[
u8
;
222
],
pub
parent
:
u64
,
pub
next
:
u64
,
pub
extents
:
[
Extent
;
15
],
...
...
@@ -30,15 +34,19 @@ impl Node {
mode
:
0
,
uid
:
0
,
gid
:
0
,
name
:
[
0
;
246
],
ctime
:
0
,
ctime_nsec
:
0
,
mtime
:
0
,
mtime_nsec
:
0
,
name
:
[
0
;
222
],
parent
:
0
,
next
:
0
,
extents
:
[
Extent
::
default
();
15
],
}
}
pub
fn
new
(
mode
:
u16
,
name
:
&
str
,
parent
:
u64
)
->
Node
{
let
mut
bytes
=
[
0
;
2
46
];
pub
fn
new
(
mode
:
u16
,
name
:
&
str
,
parent
:
u64
,
ctime
:
u64
,
ctime_nsec
:
u32
)
->
Node
{
let
mut
bytes
=
[
0
;
2
22
];
for
(
mut
b
,
c
)
in
bytes
.iter_mut
()
.zip
(
name
.bytes
())
{
*
b
=
c
;
}
...
...
@@ -47,6 +55,10 @@ impl Node {
mode
:
mode
,
uid
:
0
,
gid
:
0
,
ctime
:
ctime
,
ctime_nsec
:
ctime_nsec
,
mtime
:
ctime
,
mtime_nsec
:
ctime_nsec
,
name
:
bytes
,
parent
:
parent
,
next
:
0
,
...
...
@@ -105,6 +117,10 @@ impl fmt::Debug for Node {
.field
(
"mode"
,
&
self
.mode
)
.field
(
"uid"
,
&
self
.uid
)
.field
(
"gid"
,
&
self
.gid
)
.field
(
"ctime"
,
&
self
.ctime
)
.field
(
"ctime_nsec"
,
&
self
.ctime_nsec
)
.field
(
"mtime"
,
&
self
.mtime
)
.field
(
"mtime_nsec"
,
&
self
.mtime_nsec
)
.field
(
"name"
,
&
self
.name
())
.field
(
"next"
,
&
self
.next
)
.field
(
"extents"
,
&
extents
)
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment