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
Container Registry
Model registry
Operate
Environments
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
redox-os
redoxfs
Commits
944b175a
Commit
944b175a
authored
1 year ago
by
Ron Williams
Committed by
Jeremy Soller
1 year ago
Browse files
Options
Downloads
Patches
Plain Diff
fix symbolic links plus general cleanup
parent
86c12ebd
No related branches found
No related tags found
1 merge request
!65
fix symbolic links plus general cleanup
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
Cargo.toml
+1
-1
1 addition, 1 deletion
Cargo.toml
src/mount/redox/resource.rs
+126
-38
126 additions, 38 deletions
src/mount/redox/resource.rs
src/mount/redox/scheme.rs
+86
-52
86 additions, 52 deletions
src/mount/redox/scheme.rs
with
213 additions
and
91 deletions
Cargo.toml
+
1
−
1
View file @
944b175a
...
...
@@ -6,7 +6,7 @@ version = "0.5.13"
license-file
=
"LICENSE"
readme
=
"README.md"
authors
=
[
"Jeremy Soller <jackpot51@gmail.com>"
]
edition
=
"201
8
"
edition
=
"20
2
1"
[lib]
name
=
"redoxfs"
...
...
This diff is collapsed.
Click to expand it.
src/mount/redox/resource.rs
+
126
−
38
View file @
944b175a
...
...
@@ -5,13 +5,13 @@ use std::time::{SystemTime, UNIX_EPOCH};
use
alloc
::
collections
::
BTreeMap
;
use
range_tree
::
RangeTree
;
use
syscall
::{
MAP_PRIVATE
,
PAGE_SIZE
,
EBADFD
};
use
syscall
::
data
::{
Map
,
Stat
,
TimeSpec
};
use
syscall
::
error
::{
Error
,
Result
,
EBADF
,
EINVAL
,
EISDIR
,
ENOMEM
,
EPERM
};
use
syscall
::
error
::{
Error
,
Result
,
EBADF
,
EINVAL
,
EISDIR
,
EPERM
};
use
syscall
::
flag
::{
MapFlags
,
F_GETFL
,
F_SETFL
,
MODE_PERM
,
O_ACCMODE
,
O_APPEND
,
O_RDONLY
,
O_RDWR
,
O_WRONLY
,
PROT_READ
,
PROT_WRITE
,
SEEK_CUR
,
SEEK_END
,
SEEK_SET
,
};
use
syscall
::{
EBADFD
,
PAGE_SIZE
};
use
crate
::{
Disk
,
Node
,
Transaction
,
TreePtr
};
...
...
@@ -34,9 +34,22 @@ pub trait Resource<D: Disk> {
fn
seek
(
&
mut
self
,
offset
:
isize
,
whence
:
usize
,
tx
:
&
mut
Transaction
<
D
>
)
->
Result
<
isize
>
;
fn
fmap
(
&
mut
self
,
fmaps
:
&
mut
Fmaps
,
flags
:
MapFlags
,
size
:
usize
,
offset
:
u64
,
tx
:
&
mut
Transaction
<
D
>
)
->
Result
<
usize
>
;
fn
fmap
(
&
mut
self
,
fmaps
:
&
mut
Fmaps
,
flags
:
MapFlags
,
size
:
usize
,
offset
:
u64
,
tx
:
&
mut
Transaction
<
D
>
,
)
->
Result
<
usize
>
;
fn
funmap
(
&
mut
self
,
fmaps
:
&
mut
Fmaps
,
offset
:
u64
,
size
:
usize
,
tx
:
&
mut
Transaction
<
D
>
)
->
Result
<
usize
>
;
fn
funmap
(
&
mut
self
,
fmaps
:
&
mut
Fmaps
,
offset
:
u64
,
size
:
usize
,
tx
:
&
mut
Transaction
<
D
>
,
)
->
Result
<
usize
>
;
fn
fchmod
(
&
mut
self
,
mode
:
u16
,
tx
:
&
mut
Transaction
<
D
>
)
->
Result
<
usize
>
{
let
mut
node
=
tx
.read_tree
(
self
.node_ptr
())
?
;
...
...
@@ -208,10 +221,23 @@ impl<D: Disk> Resource<D> for DirResource {
Ok
(
self
.seek
)
}
fn
fmap
(
&
mut
self
,
_fmaps
:
&
mut
Fmaps
,
_flags
:
MapFlags
,
_size
:
usize
,
_offset
:
u64
,
_tx
:
&
mut
Transaction
<
D
>
)
->
Result
<
usize
>
{
fn
fmap
(
&
mut
self
,
_fmaps
:
&
mut
Fmaps
,
_flags
:
MapFlags
,
_size
:
usize
,
_offset
:
u64
,
_tx
:
&
mut
Transaction
<
D
>
,
)
->
Result
<
usize
>
{
Err
(
Error
::
new
(
EBADF
))
}
fn
funmap
(
&
mut
self
,
_fmaps
:
&
mut
Fmaps
,
_offset
:
u64
,
_size
:
usize
,
_tx
:
&
mut
Transaction
<
D
>
)
->
Result
<
usize
>
{
fn
funmap
(
&
mut
self
,
_fmaps
:
&
mut
Fmaps
,
_offset
:
u64
,
_size
:
usize
,
_tx
:
&
mut
Transaction
<
D
>
,
)
->
Result
<
usize
>
{
Err
(
Error
::
new
(
EBADF
))
}
...
...
@@ -263,13 +289,8 @@ impl Fmap {
let
buf
=
slice
::
from_raw_parts_mut
(
address
,
unaligned_size
);
let
count
=
match
tx
.read_node
(
node_ptr
,
offset
,
buf
,
atime
.as_secs
(),
atime
.subsec_nanos
(),
)
{
let
count
=
match
tx
.read_node
(
node_ptr
,
offset
,
buf
,
atime
.as_secs
(),
atime
.subsec_nanos
())
{
Ok
(
ok
)
=>
ok
,
Err
(
err
)
=>
{
let
_
=
syscall
::
funmap
(
address
as
usize
,
aligned_size
);
...
...
@@ -287,7 +308,14 @@ impl Fmap {
})
}
pub
unsafe
fn
sync
<
D
:
Disk
>
(
&
mut
self
,
node_ptr
:
TreePtr
<
Node
>
,
base
:
*
mut
u8
,
offset
:
u64
,
size
:
usize
,
tx
:
&
mut
Transaction
<
D
>
)
->
Result
<
()
>
{
pub
unsafe
fn
sync
<
D
:
Disk
>
(
&
mut
self
,
node_ptr
:
TreePtr
<
Node
>
,
base
:
*
mut
u8
,
offset
:
u64
,
size
:
usize
,
tx
:
&
mut
Transaction
<
D
>
,
)
->
Result
<
()
>
{
if
self
.flags
&
PROT_WRITE
==
PROT_WRITE
{
let
mtime
=
SystemTime
::
now
()
.duration_since
(
UNIX_EPOCH
)
.unwrap
();
tx
.write_node
(
...
...
@@ -426,7 +454,14 @@ impl<D: Disk> Resource<D> for FileResource {
Ok
(
self
.seek
)
}
fn
fmap
(
&
mut
self
,
fmaps
:
&
mut
Fmaps
,
flags
:
MapFlags
,
unaligned_size
:
usize
,
offset
:
u64
,
tx
:
&
mut
Transaction
<
D
>
)
->
Result
<
usize
>
{
fn
fmap
(
&
mut
self
,
fmaps
:
&
mut
Fmaps
,
flags
:
MapFlags
,
unaligned_size
:
usize
,
offset
:
u64
,
tx
:
&
mut
Transaction
<
D
>
,
)
->
Result
<
usize
>
{
//dbg!(&self.fmaps);
let
accmode
=
self
.flags
&
O_ACCMODE
;
if
flags
.contains
(
PROT_READ
)
&&
!
(
accmode
==
O_RDWR
||
accmode
==
O_RDONLY
)
{
...
...
@@ -444,21 +479,28 @@ impl<D: Disk> Resource<D> for FileResource {
// TODO: Pass entry directory to Resource trait functions, since the node_ptr can be
// obtained by the caller.
let
fmap_info
=
fmaps
.get_mut
(
&
self
.node_ptr
.id
())
.ok_or
(
Error
::
new
(
EBADFD
))
?
;
let
fmap_info
=
fmaps
.get_mut
(
&
self
.node_ptr
.id
())
.ok_or
(
Error
::
new
(
EBADFD
))
?
;
let
new_size
=
(
offset
as
usize
+
aligned_size
)
.next_multiple_of
(
PAGE_SIZE
);
if
new_size
>
fmap_info
.size
{
fmap_info
.base
=
if
fmap_info
.base
.is_null
()
{
unsafe
{
syscall
::
fmap
(
!
0
,
&
Map
{
size
:
new_size
,
// PRIVATE/SHARED doesn't matter once the pages are passed in the fmap
// handler.
flags
:
MapFlags
::
PROT_READ
|
MapFlags
::
PROT_WRITE
|
MapFlags
::
MAP_PRIVATE
,
offset
:
0
,
address
:
0
,
})
?
as
*
mut
u8
syscall
::
fmap
(
!
0
,
&
Map
{
size
:
new_size
,
// PRIVATE/SHARED doesn't matter once the pages are passed in the fmap
// handler.
flags
:
MapFlags
::
PROT_READ
|
MapFlags
::
PROT_WRITE
|
MapFlags
::
MAP_PRIVATE
,
offset
:
0
,
address
:
0
,
},
)
?
as
*
mut
u8
}
}
else
{
unsafe
{
...
...
@@ -468,14 +510,16 @@ impl<D: Disk> Resource<D> for FileResource {
fmap_info
.size
,
0
,
new_size
,
syscall
::
MremapFlags
::
empty
()
.bits
()
|
(
PROT_READ
|
PROT_WRITE
)
.bits
()
syscall
::
MremapFlags
::
empty
()
.bits
()
|
(
PROT_READ
|
PROT_WRITE
)
.bits
()
,
)
?
as
*
mut
u8
}
};
fmap_info
.size
=
new_size
;
}
let
affected_fmaps
=
fmap_info
.ranges
.remove_and_unused
(
offset
..
offset
+
aligned_size
as
u64
);
let
affected_fmaps
=
fmap_info
.ranges
.remove_and_unused
(
offset
..
offset
+
aligned_size
as
u64
);
for
(
range
,
v_opt
)
in
affected_fmaps
{
//dbg!(&range);
...
...
@@ -483,9 +527,20 @@ impl<D: Disk> Resource<D> for FileResource {
fmap
.rc
+=
1
;
fmap
.flags
|
=
flags
;
fmap_info
.ranges
.insert
(
range
.start
,
range
.end
-
range
.start
,
fmap
);
fmap_info
.ranges
.insert
(
range
.start
,
range
.end
-
range
.start
,
fmap
);
}
else
{
let
map
=
unsafe
{
Fmap
::
new
(
self
.node_ptr
,
flags
,
unaligned_size
,
offset
,
fmap_info
.base
,
tx
)
?
};
let
map
=
unsafe
{
Fmap
::
new
(
self
.node_ptr
,
flags
,
unaligned_size
,
offset
,
fmap_info
.base
,
tx
,
)
?
};
fmap_info
.ranges
.insert
(
offset
,
aligned_size
as
u64
,
map
);
}
}
...
...
@@ -494,11 +549,20 @@ impl<D: Disk> Resource<D> for FileResource {
Ok
(
fmap_info
.base
as
usize
+
offset
as
usize
)
}
fn
funmap
(
&
mut
self
,
fmaps
:
&
mut
Fmaps
,
offset
:
u64
,
size
:
usize
,
tx
:
&
mut
Transaction
<
D
>
)
->
Result
<
usize
>
{
let
fmap_info
=
fmaps
.get_mut
(
&
self
.node_ptr
.id
())
.ok_or
(
Error
::
new
(
EBADFD
))
?
;
fn
funmap
(
&
mut
self
,
fmaps
:
&
mut
Fmaps
,
offset
:
u64
,
size
:
usize
,
tx
:
&
mut
Transaction
<
D
>
,
)
->
Result
<
usize
>
{
let
fmap_info
=
fmaps
.get_mut
(
&
self
.node_ptr
.id
())
.ok_or
(
Error
::
new
(
EBADFD
))
?
;
//dbg!(&self.fmaps);
//dbg!(self.fmaps.conflicts(offset..offset + size as u64).collect::<Vec<_>>());
#[allow(unused_mut)]
let
mut
affected_fmaps
=
fmap_info
.ranges
.remove
(
offset
..
offset
+
size
as
u64
);
for
(
range
,
mut
fmap
)
in
affected_fmaps
{
...
...
@@ -506,11 +570,19 @@ impl<D: Disk> Resource<D> for FileResource {
//log::info!("SYNCING {}..{}", range.start, range.end);
unsafe
{
fmap
.sync
(
self
.node_ptr
,
fmap_info
.base
,
range
.start
,
(
range
.end
-
range
.start
)
as
usize
,
tx
)
?
;
fmap
.sync
(
self
.node_ptr
,
fmap_info
.base
,
range
.start
,
(
range
.end
-
range
.start
)
as
usize
,
tx
,
)
?
;
}
if
fmap
.rc
>
0
{
fmap_info
.ranges
.insert
(
range
.start
,
range
.end
-
range
.start
,
fmap
);
fmap_info
.ranges
.insert
(
range
.start
,
range
.end
-
range
.start
,
fmap
);
}
}
//dbg!(&self.fmaps);
...
...
@@ -537,7 +609,13 @@ impl<D: Disk> Resource<D> for FileResource {
if
let
Some
(
fmap_info
)
=
fmaps
.get_mut
(
&
self
.node_ptr
.id
())
{
for
(
range
,
fmap
)
in
fmap_info
.ranges
.iter_mut
()
{
unsafe
{
fmap
.sync
(
self
.node_ptr
,
fmap_info
.base
,
range
.start
,
(
range
.end
-
range
.start
)
as
usize
,
tx
)
?
;
fmap
.sync
(
self
.node_ptr
,
fmap_info
.base
,
range
.start
,
(
range
.end
-
range
.start
)
as
usize
,
tx
,
)
?
;
}
}
}
...
...
@@ -623,9 +701,15 @@ impl range_tree::Value for Fmap {
Err
(
self
)
}
}
fn
split
(
self
,
prev_range
:
Option
<
core
::
ops
::
Range
<
Self
::
K
>>
,
range
:
core
::
ops
::
Range
<
Self
::
K
>
,
next_range
:
Option
<
core
::
ops
::
Range
<
Self
::
K
>>
)
->
(
Option
<
Self
>
,
Self
,
Option
<
Self
>
)
{
#[allow(unused_variables)]
fn
split
(
self
,
prev_range
:
Option
<
core
::
ops
::
Range
<
Self
::
K
>>
,
range
:
core
::
ops
::
Range
<
Self
::
K
>
,
next_range
:
Option
<
core
::
ops
::
Range
<
Self
::
K
>>
,
)
->
(
Option
<
Self
>
,
Self
,
Option
<
Self
>
)
{
(
prev_range
.map
(|
range
|
Fmap
{
prev_range
.map
(|
_
range
|
Fmap
{
rc
:
self
.rc
,
flags
:
self
.flags
,
last_page_tail
:
0
,
...
...
@@ -633,9 +717,13 @@ impl range_tree::Value for Fmap {
Fmap
{
rc
:
self
.rc
,
flags
:
self
.flags
,
last_page_tail
:
if
next_range
.is_none
()
{
self
.last_page_tail
}
else
{
0
},
last_page_tail
:
if
next_range
.is_none
()
{
self
.last_page_tail
}
else
{
0
},
},
next_range
.map
(|
range
|
Fmap
{
next_range
.map
(|
_
range
|
Fmap
{
rc
:
self
.rc
,
flags
:
self
.flags
,
last_page_tail
:
self
.last_page_tail
,
...
...
This diff is collapsed.
Click to expand it.
src/mount/redox/scheme.rs
+
86
−
52
View file @
944b175a
...
...
@@ -3,8 +3,7 @@ use std::str;
use
std
::
sync
::
atomic
::{
AtomicUsize
,
Ordering
};
use
std
::
time
::{
SystemTime
,
UNIX_EPOCH
};
use
syscall
::{
EBADFD
,
MunmapFlags
};
use
syscall
::
data
::{
Map
,
Stat
,
StatVfs
,
TimeSpec
};
use
syscall
::
data
::{
Stat
,
StatVfs
,
TimeSpec
};
use
syscall
::
error
::{
Error
,
Result
,
EACCES
,
EBADF
,
EBUSY
,
EEXIST
,
EINVAL
,
EISDIR
,
ELOOP
,
ENOENT
,
ENOTDIR
,
ENOTEMPTY
,
EPERM
,
EXDEV
,
...
...
@@ -14,6 +13,7 @@ use syscall::flag::{
O_RDWR
,
O_STAT
,
O_SYMLINK
,
O_TRUNC
,
O_WRONLY
,
};
use
syscall
::
scheme
::
SchemeMut
;
use
syscall
::{
MunmapFlags
,
EBADFD
};
use
crate
::{
Disk
,
FileSystem
,
Node
,
Transaction
,
TreeData
,
TreePtr
,
BLOCK_SIZE
};
...
...
@@ -46,12 +46,18 @@ impl<D: Disk> FileScheme<D> {
url
:
&
str
,
node
:
TreeData
<
Node
>
,
nodes
:
&
mut
Vec
<
(
TreeData
<
Node
>
,
String
)
>
,
)
->
Result
<
Vec
<
u8
>
>
{
)
->
Result
<
String
>
{
let
atime
=
SystemTime
::
now
()
.duration_since
(
UNIX_EPOCH
)
.unwrap
();
let
scheme
=
format!
(
"{}:"
,
scheme_name
);
// symbolic link is relative to this part of the url
let
mut
working_dir
=
dirname
(
url
)
.unwrap_or
(
&
scheme
)
.to_string
();
// node of the link
let
mut
node
=
node
;
for
_
in
0
..
32
{
// XXX What should the limit be?
assert!
(
node
.data
()
.is_symlink
());
let
mut
buf
=
[
0
;
4096
];
let
count
=
tx
.read_node
(
node
.ptr
(),
...
...
@@ -60,24 +66,25 @@ impl<D: Disk> FileScheme<D> {
atime
.as_secs
(),
atime
.subsec_nanos
(),
)
?
;
let
scheme
=
format!
(
"{}:"
,
scheme_name
);
let
canon
=
canonicalize
(
url
.as_bytes
(),
&
buf
[
0
..
count
]);
let
path
=
str
::
from_utf8
(
&
canon
[
scheme
.len
()
..
])
.unwrap_or
(
""
)
.trim_matches
(
'/'
);
let
target
=
canonicalize
(
&
working_dir
,
str
::
from_utf8
(
&
buf
[
..
count
])
.map_err
(|
_
|
Error
::
new
(
EINVAL
))
?
,
)
.ok_or
(
Error
::
new
(
EINVAL
))
?
;
if
!
target
.starts_with
(
&
scheme
)
{
return
Err
(
Error
::
new
(
EXDEV
));
}
let
target_path
=
&
target
[
scheme
.len
()
..
];
nodes
.clear
();
if
let
Some
((
next_node
,
next_node_name
))
=
Self
::
path_nodes
(
scheme_name
,
tx
,
path
,
uid
,
gid
,
nodes
)
?
Self
::
path_nodes
(
scheme_name
,
tx
,
target_
path
,
uid
,
gid
,
nodes
)
?
{
if
!
next_node
.data
()
.is_symlink
()
{
if
canon
.starts_with
(
scheme
.as_bytes
())
{
nodes
.push
((
next_node
,
next_node_name
));
return
Ok
(
canon
[
scheme
.len
()
..
]
.to_vec
());
}
else
{
return
Err
(
Error
::
new
(
EXDEV
));
}
nodes
.push
((
next_node
,
next_node_name
));
return
Ok
(
target_path
.to_string
());
}
node
=
next_node
;
working_dir
=
dirname
(
&
target
)
.ok_or
(
Error
::
new
(
EINVAL
))
?
.to_string
();
}
else
{
return
Err
(
Error
::
new
(
ENOENT
));
}
...
...
@@ -141,42 +148,62 @@ impl<D: Disk> FileScheme<D> {
}
}
/// given a path with a prefix, return the containing directory (or scheme)
fn
dirname
(
path
:
&
str
)
->
Option
<&
str
>
{
if
let
Some
(
separator_index
)
=
path
.trim_end_matches
(
'/'
)
.rfind
(
'/'
)
{
return
Some
(
&
path
[
..=
separator_index
]);
}
// there was no path separator, just use the scheme
if
let
Some
(
scheme
)
=
scheme_with_separator
(
path
)
{
return
Some
(
scheme
);
}
None
}
/// given a path with a scheme prefix, return the prefix including the separator
fn
scheme_with_separator
(
path
:
&
str
)
->
Option
<&
str
>
{
if
let
Some
(
sep_idx
)
=
path
.find
(
':'
)
{
let
scheme
=
&
path
[
..=
sep_idx
];
if
scheme
.find
(
'/'
)
.is_none
()
{
return
Some
(
&
scheme
);
}
}
None
}
/// Make a relative path absolute
/// Given a cwd of "scheme:/path"
/// This function will turn "foo" into "scheme:/path/foo"
/// "/foo" will turn into "scheme:/foo"
/// "bar:/foo" will be used directly, as it is already absolute
pub
fn
canonicalize
(
current
:
&
[
u8
]
,
path
:
&
[
u8
]
)
->
Vec
<
u8
>
{
pub
fn
canonicalize
(
current
:
&
str
,
path
:
&
str
)
->
Option
<
String
>
{
// This function is modified from a version in the kernel
let
mut
canon
=
if
path
.iter
()
.position
(|
&
b
|
b
==
b':'
)
.is_none
()
{
let
cwd
=
&
current
[
0
..
current
.iter
()
.rposition
(|
x
|
*
x
==
'/'
as
u8
)
.unwrap_or
(
0
)];
let
mut
canon
=
if
!
path
.starts_with
(
b"/"
)
{
let
mut
c
=
cwd
.to_vec
();
if
!
c
.ends_with
(
b"/"
)
{
c
.push
(
b'/'
);
}
c
let
mut
canon
=
if
scheme_with_separator
(
path
)
.is_none
()
{
let
mut
canon
=
if
!
path
.starts_with
(
'/'
)
{
let
mut
cwd
=
current
.trim_end_matches
(
'/'
)
.to_string
();
cwd
.push
(
'/'
);
cwd
}
else
{
cwd
[
..
cwd
.iter
()
.position
(|
&
b
|
b
==
b':'
)
.map_or
(
1
,
|
i
|
i
+
1
)]
.to_vec
()
scheme_with_separator
(
current
)
?
.to_string
()
};
canon
.
extend_from_slice
(
&
path
);
canon
.
push_str
(
path
);
canon
}
else
{
path
.to_
vec
()
path
.to_
string
()
};
// NOTE: assumes the scheme does not include anything like "../" or "./"
let
mut
result
=
{
let
parts
=
canon
.split
(|
&
c
|
c
==
b'/'
)
.filter
(|
&
part
|
part
!=
b"."
)
.split
(
'/'
)
.rev
()
.scan
(
0
,
|
nskip
,
part
|
{
if
part
==
b"."
{
if
part
==
""
{
Some
(
None
)
}
else
if
part
==
"."
{
Some
(
None
)
}
else
if
part
==
b
".."
{
}
else
if
part
==
".."
{
*
nskip
+=
1
;
Some
(
None
)
}
else
{
...
...
@@ -189,25 +216,22 @@ pub fn canonicalize(current: &[u8], path: &[u8]) -> Vec<u8> {
}
})
.filter_map
(|
x
|
x
)
.filter
(|
x
|
!
x
.is_empty
())
.collect
::
<
Vec
<
_
>>
();
parts
.iter
()
.rev
()
.fold
(
Vec
::
new
(),
|
mut
vec
,
&
part
|
{
vec
.extend_from_slice
(
part
);
vec
.push
(
b
'/'
);
vec
parts
.iter
()
.rev
()
.fold
(
String
::
new
(),
|
mut
string
,
&
part
|
{
string
.push_str
(
part
);
string
.push
(
'/'
);
string
})
};
result
.pop
();
// remove extra '/'
// replace with the root of the scheme if it's empty
if
result
.len
()
==
0
{
let
pos
=
canon
.iter
()
.position
(|
&
b
|
b
==
b':'
)
.map_or
(
canon
.len
(),
|
p
|
p
+
1
);
canon
.truncate
(
pos
);
canon
canon
.truncate
(
scheme_with_separator
(
&
canon
)
?
.len
());
Some
(
canon
)
}
else
{
result
Some
(
result
)
}
}
...
...
@@ -283,9 +307,7 @@ impl<D: Disk> SchemeMut for FileScheme<D> {
&
mut
resolve_nodes
,
)
})
?
;
let
resolved_utf8
=
str
::
from_utf8
(
&
resolved
)
.map_err
(|
_
|
Error
::
new
(
EINVAL
))
?
;
return
self
.open
(
resolved_utf8
,
flags
,
uid
,
gid
);
return
self
.open
(
&
resolved
,
flags
,
uid
,
gid
);
}
else
if
!
node
.data
()
.is_symlink
()
&&
flags
&
O_SYMLINK
==
O_SYMLINK
{
return
Err
(
Error
::
new
(
EINVAL
));
}
else
{
...
...
@@ -401,8 +423,10 @@ impl<D: Disk> SchemeMut for FileScheme<D> {
}
}
};
self
.fmap
.entry
(
resource
.node_ptr
()
.id
())
.or_insert_with
(
Default
::
default
)
.open_fds
+=
1
;
self
.fmap
.entry
(
resource
.node_ptr
()
.id
())
.or_insert_with
(
Default
::
default
)
.open_fds
+=
1
;
let
id
=
self
.next_id
.fetch_add
(
1
,
Ordering
::
SeqCst
);
self
.files
.insert
(
id
,
resource
);
...
...
@@ -536,7 +560,10 @@ impl<D: Disk> SchemeMut for FileScheme<D> {
return
Err
(
Error
::
new
(
EBADF
));
};
self
.fmap
.get_mut
(
&
resource
.node_ptr
()
.id
())
.ok_or
(
Error
::
new
(
EBADFD
))
?
.open_fds
+=
1
;
self
.fmap
.get_mut
(
&
resource
.node_ptr
()
.id
())
.ok_or
(
Error
::
new
(
EBADFD
))
?
.open_fds
+=
1
;
let
id
=
self
.next_id
.fetch_add
(
1
,
Ordering
::
SeqCst
);
self
.files
.insert
(
id
,
resource
);
...
...
@@ -790,6 +817,7 @@ impl<D: Disk> SchemeMut for FileScheme<D> {
self
.fs
.tx
(|
tx
|
file
.fmap
(
fmaps
,
flags
,
size
,
offset
,
tx
))
}
#[allow(unused_variables)]
fn
munmap
(
&
mut
self
,
id
:
usize
,
offset
:
u64
,
size
:
usize
,
flags
:
MunmapFlags
)
->
Result
<
usize
>
{
println!
(
"Munmap {}, {} {}"
,
id
,
size
,
offset
);
let
file
=
self
.files
.get_mut
(
&
id
)
.ok_or
(
Error
::
new
(
EBADF
))
?
;
...
...
@@ -801,9 +829,15 @@ impl<D: Disk> SchemeMut for FileScheme<D> {
fn
close
(
&
mut
self
,
id
:
usize
)
->
Result
<
usize
>
{
// println!("Close {}", id);
let
file
=
self
.files
.remove
(
&
id
)
.ok_or
(
Error
::
new
(
EBADF
))
?
;
let
file_info
=
self
.fmap
.get_mut
(
&
file
.node_ptr
()
.id
())
.ok_or
(
Error
::
new
(
EBADFD
))
?
;
file_info
.open_fds
=
file_info
.open_fds
.checked_sub
(
1
)
.expect
(
"open_fds not tracked correctly"
);
let
file_info
=
self
.fmap
.get_mut
(
&
file
.node_ptr
()
.id
())
.ok_or
(
Error
::
new
(
EBADFD
))
?
;
file_info
.open_fds
=
file_info
.open_fds
.checked_sub
(
1
)
.expect
(
"open_fds not tracked correctly"
);
// TODO: If open_fds reaches zero and there are no hardlinks (directory entries) to any
// particular inode, remove that inode here.
...
...
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