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
James Matlik
redoxfs
Commits
e0fceebf
Commit
e0fceebf
authored
9 years ago
by
Jeremy Soller
Browse files
Options
Downloads
Patches
Plain Diff
Allow a parent node to be given to the primitive functions
parent
4a444a34
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
src/filesystem.rs
+91
-90
91 additions, 90 deletions
src/filesystem.rs
utility/main.rs
+30
-17
30 additions, 17 deletions
utility/main.rs
with
121 additions
and
107 deletions
src/filesystem.rs
+
91
−
90
View file @
e0fceebf
use
alloc
::
boxed
::
Box
;
use
super
::{
Disk
,
Extent
,
Header
,
Node
};
use
collections
::
vec
::
Vec
;
use
super
::{
Disk
,
ExNode
,
Extent
,
Header
,
Node
};
/// A file system
pub
struct
FileSystem
<
E
>
{
pub
disk
:
Box
<
Disk
<
E
>>
,
pub
header
:
(
u64
,
Header
),
pub
root
:
(
u64
,
Node
),
pub
free
:
(
u64
,
Node
)
}
...
...
@@ -26,7 +27,6 @@ impl<E> FileSystem<E> {
Ok
(
Some
(
FileSystem
{
disk
:
disk
,
header
:
header
,
root
:
root
,
free
:
free
}))
}
else
{
...
...
@@ -52,7 +52,6 @@ impl<E> FileSystem<E> {
Ok
(
Some
(
FileSystem
{
disk
:
disk
,
header
:
header
,
root
:
root
,
free
:
free
}))
}
else
{
...
...
@@ -80,118 +79,120 @@ impl<E> FileSystem<E> {
Ok
(
false
)
}
pub
fn
node
(
&
mut
self
,
block
:
u64
)
->
Result
<
Node
,
E
>
{
pub
fn
node
(
&
mut
self
,
block
:
u64
)
->
Result
<
(
u64
,
Node
)
,
E
>
{
let
mut
node
=
Node
::
default
();
try
!
(
self
.disk
.read_at
(
block
,
&
mut
node
));
Ok
(
node
)
Ok
(
(
block
,
node
)
)
}
pub
fn
find_node
(
&
mut
self
,
name
:
&
str
)
->
Result
<
Option
<
(
u64
,
Node
)
>
,
E
>
{
let
mut
parent_node
=
(
self
.header
.1
.root
,
Node
::
default
());
loop
{
if
parent_node
.0
>
0
{
try
!
(
self
.disk
.read_at
(
parent_node
.0
,
&
mut
parent_node
.1
));
}
else
{
return
Ok
(
None
);
}
pub
fn
ex_node
(
&
mut
self
,
block
:
u64
)
->
Result
<
(
u64
,
ExNode
),
E
>
{
let
mut
node
=
ExNode
::
default
();
try
!
(
self
.disk
.read_at
(
block
,
&
mut
node
));
Ok
((
block
,
node
))
}
for
extent
in
parent_node
.1
.extents
.iter
()
{
for
i
in
0
..
extent
.length
/
512
{
let
mut
child_node
=
(
extent
.block
+
i
,
Node
::
default
());
try
!
(
self
.disk
.read_at
(
child_node
.0
,
&
mut
child_node
.1
));
pub
fn
child_nodes
(
&
mut
self
,
children
:
&
mut
Vec
<
(
u64
,
Node
)
>
,
parent_block
:
u64
)
->
Result
<
(),
E
>
{
if
parent_block
==
0
{
return
Ok
(
());
}
let
mut
matches
=
false
;
if
let
Ok
(
child_name
)
=
child_node
.1
.name
()
{
if
child_name
==
name
{
matches
=
true
;
}
}
if
matches
{
return
Ok
(
Some
(
child_node
));
}
}
let
parent
=
try
!
(
self
.node
(
parent_block
));
for
extent
in
parent
.1
.extents
.iter
()
{
for
i
in
0
..
extent
.length
/
512
{
children
.push
(
try
!
(
self
.node
(
extent
.block
+
i
)));
}
parent_node
.0
=
parent_node
.1
.next
;
parent_node
.1
=
Node
::
default
();
}
self
.child_nodes
(
children
,
parent
.1
.next
)
}
fn
create
_node
(
&
mut
self
,
name
:
&
str
,
mode
:
u64
)
->
Result
<
Option
<
(
u64
,
Node
)
>
,
E
>
{
if
let
Some
(
block
)
=
try
!
(
self
.allocate
())
{
l
et
node
=
(
block
,
Node
::
new
(
name
,
mode
)
);
try
!
(
self
.disk
.write_at
(
node
.0
,
&
node
.1
));
pub
fn
find
_node
(
&
mut
self
,
name
:
&
str
,
parent_block
:
u64
)
->
Result
<
Option
<
(
u64
,
Node
)
>
,
E
>
{
if
parent_block
==
0
{
r
et
urn
Ok
(
None
);
}
let
mut
inserted
=
false
;
let
mut
last_node
=
(
0
,
Node
::
default
());
let
mut
next_node
=
(
self
.header
.1
.root
,
Node
::
default
());
while
!
inserted
{
if
next_node
.0
>
0
{
try
!
(
self
.disk
.read_at
(
next_node
.0
,
&
mut
next_node
.1
));
}
else
{
if
let
Some
(
block
)
=
try
!
(
self
.allocate
())
{
next_node
.0
=
block
;
if
last_node
.0
>
0
{
last_node
.1
.next
=
block
;
if
last_node
.0
==
self
.root
.0
{
self
.root
.1
.next
=
last_node
.1
.next
;
}
try
!
(
self
.disk
.write_at
(
last_node
.0
,
&
last_node
.1
));
}
else
{
panic!
(
"last_node was 0"
);
}
}
else
{
return
Ok
(
None
);
let
parent
=
try
!
(
self
.node
(
parent_block
));
for
extent
in
parent
.1
.extents
.iter
()
{
for
i
in
0
..
extent
.length
/
512
{
let
child
=
try
!
(
self
.node
(
extent
.block
+
i
));
let
mut
matches
=
false
;
if
let
Ok
(
child_name
)
=
child
.1
.name
()
{
if
child_name
==
name
{
matches
=
true
;
}
}
for
mut
extent
in
next_node
.1
.extents
.iter_mut
()
{
if
extent
.block
+
extent
.length
/
512
==
block
{
inserted
=
true
;
extent
.length
+=
512
;
break
;
}
else
if
extent
.length
==
0
{
inserted
=
true
;
extent
.block
=
block
;
extent
.length
=
512
;
break
;
}
if
matches
{
return
Ok
(
Some
(
child
));
}
}
}
if
inserted
{
if
next_node
.0
==
self
.root
.0
{
self
.root
.1
.extents
=
next_node
.1
.extents
;
}
try
!
(
self
.disk
.write_at
(
next_node
.0
,
&
next_node
.1
));
self
.find_node
(
name
,
parent
.1
.next
)
}
fn
insert_block
(
&
mut
self
,
block
:
u64
,
parent_block
:
u64
)
->
Result
<
bool
,
E
>
{
if
parent_block
==
0
{
return
Ok
(
false
);
}
let
mut
inserted
=
false
;
let
mut
parent
=
try
!
(
self
.node
(
parent_block
));
for
mut
extent
in
parent
.1
.extents
.iter_mut
()
{
if
extent
.length
==
0
{
//New extent
inserted
=
true
;
extent
.block
=
block
;
extent
.length
=
512
;
break
;
}
else
if
extent
.block
==
block
+
1
{
//At beginning
inserted
=
true
;
extent
.block
=
block
;
extent
.length
+=
512
;
}
else
if
extent
.block
+
extent
.length
/
512
==
block
{
//At end
inserted
=
true
;
extent
.length
+=
512
;
break
;
}
}
if
inserted
{
try
!
(
self
.disk
.write_at
(
parent
.0
,
&
parent
.1
));
Ok
(
true
)
}
else
{
if
parent
.1
.next
==
0
{
if
let
Some
(
block
)
=
try
!
(
self
.allocate
())
{
parent
.1
.next
=
block
;
try
!
(
self
.disk
.write_at
(
parent
.0
,
&
parent
.1
));
try
!
(
self
.disk
.write_at
(
parent
.1
.next
,
&
Node
::
default
()));
}
else
{
last_node
=
next_node
;
next_node
=
(
last_node
.1
.next
,
Node
::
default
());
return
Ok
(
false
);
}
}
Ok
(
Some
(
node
))
}
else
{
Ok
(
None
)
self
.insert_block
(
block
,
parent
.1
.next
)
}
}
pub
fn
create_dir
(
&
mut
self
,
name
:
&
str
)
->
Result
<
Option
<
(
u64
,
Node
)
>
,
E
>
{
self
.create_node
(
name
,
Node
::
MODE_DIR
)
}
pub
fn
create_node
(
&
mut
self
,
name
:
&
str
,
mode
:
u64
,
parent_block
:
u64
)
->
Result
<
Option
<
(
u64
,
Node
)
>
,
E
>
{
if
let
Some
(
block
)
=
try
!
(
self
.allocate
())
{
let
node
=
(
block
,
Node
::
new
(
name
,
mode
));
try
!
(
self
.disk
.write_at
(
node
.0
,
&
node
.1
));
pub
fn
create_file
(
&
mut
self
,
name
:
&
str
)
->
Result
<
Option
<
(
u64
,
Node
)
>
,
E
>
{
self
.create_node
(
name
,
Node
::
MODE_FILE
)
if
try
!
(
self
.insert_block
(
block
,
parent_block
))
{
Ok
(
Some
(
node
))
}
else
{
Ok
(
None
)
}
}
else
{
Ok
(
None
)
}
}
fn
remove_node
(
&
mut
self
,
_name
:
&
str
,
_mode
:
u64
)
->
Result
<
bool
,
E
>
{
pub
fn
remove_node
(
&
mut
self
,
_name
:
&
str
,
_mode
:
u64
)
->
Result
<
bool
,
E
>
{
Ok
(
false
)
}
pub
fn
remove_dir
(
&
mut
self
,
name
:
&
str
)
->
Result
<
bool
,
E
>
{
self
.remove_node
(
name
,
Node
::
MODE_DIR
)
}
pub
fn
remove_file
(
&
mut
self
,
name
:
&
str
)
->
Result
<
bool
,
E
>
{
self
.remove_node
(
name
,
Node
::
MODE_FILE
)
}
}
This diff is collapsed.
Click to expand it.
utility/main.rs
+
30
−
17
View file @
e0fceebf
...
...
@@ -7,7 +7,7 @@ use std::fmt::Display;
use
std
::
io
::{
self
,
Write
};
use
std
::
path
::
Path
;
use
redoxfs
::
FileSystem
;
use
redoxfs
::
{
FileSystem
,
Node
}
;
use
image
::
Image
;
...
...
@@ -35,7 +35,7 @@ fn shell<E: Display>(mut fs: FileSystem<E>){
match
arg
.parse
::
<
u64
>
()
{
Ok
(
block
)
=>
{
match
fs
.node
(
block
)
{
Ok
(
node
)
=>
println!
(
"{}: {:#?}"
,
block
,
node
),
Ok
(
node
)
=>
println!
(
"{}: {:#?}"
,
node
.0
,
node
.1
),
Err
(
err
)
=>
println!
(
"node: failed to read {}: {}"
,
block
,
err
)
}
},
...
...
@@ -45,9 +45,24 @@ fn shell<E: Display>(mut fs: FileSystem<E>){
println!
(
"node <block>"
);
}
},
"root"
=>
{
let
block
=
fs
.header
.1
.root
;
match
fs
.node
(
block
)
{
Ok
(
node
)
=>
println!
(
"{}: {:#?}"
,
node
.0
,
node
.1
),
Err
(
err
)
=>
println!
(
"node: failed to read {}: {}"
,
block
,
err
)
}
},
"free"
=>
{
let
block
=
fs
.header
.1
.free
;
match
fs
.node
(
block
)
{
Ok
(
node
)
=>
println!
(
"{}: {:#?}"
,
node
.0
,
node
.1
),
Err
(
err
)
=>
println!
(
"node: failed to read {}: {}"
,
block
,
err
)
}
},
"find"
=>
{
if
let
Some
(
arg
)
=
args
.next
()
{
match
fs
.find_node
(
arg
)
{
let
root_block
=
fs
.header
.1
.root
;
match
fs
.find_node
(
arg
,
root_block
)
{
Ok
(
node_option
)
=>
match
node_option
{
Some
(
node
)
=>
println!
(
"{}: {:#?}"
,
node
.0
,
node
.1
),
None
=>
println!
(
"find: did not find {}"
,
arg
)
...
...
@@ -59,22 +74,19 @@ fn shell<E: Display>(mut fs: FileSystem<E>){
}
},
"ls"
=>
{
let
mut
blocks
=
Vec
::
new
();
for
extent
in
fs
.root
.1
.extents
.iter
()
{
for
i
in
0
..
extent
.length
/
512
{
blocks
.push
(
extent
.block
+
i
);
}
}
for
&
block
in
blocks
.iter
()
{
match
fs
.node
(
block
)
{
Ok
(
node
)
=>
println!
(
"{}: {:#?}"
,
block
,
node
),
Err
(
err
)
=>
println!
(
"ls: failed to read {}: {}"
,
block
,
err
)
}
let
root_block
=
fs
.header
.1
.root
;
let
mut
children
=
Vec
::
new
();
match
fs
.child_nodes
(
&
mut
children
,
root_block
)
{
Ok
(())
=>
for
node
in
children
.iter
()
{
println!
(
"{}: {:#?}"
,
node
.0
,
node
.1
);
},
Err
(
err
)
=>
println!
(
"ls: failed to read {}: {}"
,
root_block
,
err
)
}
},
"mkdir"
=>
{
if
let
Some
(
arg
)
=
args
.next
()
{
match
fs
.create_dir
(
arg
)
{
let
root_block
=
fs
.header
.1
.root
;
match
fs
.create_node
(
arg
,
Node
::
MODE_DIR
,
root_block
)
{
Ok
(
node_option
)
=>
match
node_option
{
Some
(
node
)
=>
println!
(
"{}: {:#?}"
,
node
.0
,
node
.1
),
None
=>
println!
(
"mkdir: not enough space for {}"
,
arg
)
...
...
@@ -87,7 +99,8 @@ fn shell<E: Display>(mut fs: FileSystem<E>){
},
"touch"
=>
{
if
let
Some
(
arg
)
=
args
.next
()
{
match
fs
.create_file
(
arg
)
{
let
root_block
=
fs
.header
.1
.root
;
match
fs
.create_node
(
arg
,
Node
::
MODE_FILE
,
root_block
)
{
Ok
(
node_option
)
=>
match
node_option
{
Some
(
node
)
=>
println!
(
"{}: {:#?}"
,
node
.0
,
node
.1
),
None
=>
println!
(
"touch: not enough space for {}"
,
arg
)
...
...
@@ -98,7 +111,7 @@ fn shell<E: Display>(mut fs: FileSystem<E>){
println!
(
"touch <file>"
);
}
},
_
=>
println!
(
"commands: exit header node find ls mkdir touch"
)
_
=>
println!
(
"commands: exit header node
root free
find ls mkdir touch"
)
}
}
}
...
...
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