Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
F
FPGA Configuration Space
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
FPGA Configuration Space
Commits
08c1cc62
Commit
08c1cc62
authored
May 22, 2013
by
Alessandro Rubini
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sdbfs/userspace/gensdbfs: support subdirectories
Signed-off-by:
Alessandro Rubini
<
rubini@gnudd.com
>
parent
a92586eb
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
97 additions
and
46 deletions
+97
-46
gensdbfs.c
sdbfs/userspace/gensdbfs.c
+92
-44
gensdbfs.h
sdbfs/userspace/gensdbfs.h
+5
-2
No files found.
sdbfs/userspace/gensdbfs.c
View file @
08c1cc62
...
...
@@ -36,6 +36,8 @@ static unsigned long devsize = 0; /* unspecified */
static
unsigned
long
lastwritten
=
0
;
static
char
*
prgname
;
static
struct
sdbf
*
prepare_dir
(
char
*
name
,
struct
sdbf
*
parent
);
static
inline
unsigned
long
SDB_ALIGN
(
unsigned
long
x
)
{
return
(
x
+
(
blocksize
-
1
))
&
~
(
blocksize
-
1
);
...
...
@@ -60,7 +62,7 @@ static void __fill_product(struct sdb_product *p, char *name, time_t t,
p
->
record_type
=
record_type
;
}
/* Helpers for scan_input(), which is below */
/* Helpers for scan_input
dir
(), which is below */
static
void
__fill_dot
(
struct
sdbf
*
dot
,
char
*
dir
)
{
struct
sdb_interconnect
*
i
=
&
dot
->
s_i
;
...
...
@@ -79,6 +81,21 @@ static void __fill_dot(struct sdbf *dot, char *dir)
__fill_product
(
p
,
"."
,
0
/* date */
,
sdb_type_interconnect
);
}
/* Helper for __fill_file, below, f->stat and f->fullname already valid */
static
int
__fill_dir
(
struct
sdbf
*
f
)
{
struct
sdb_bridge
*
b
=
&
f
->
s_b
;
struct
sdb_component
*
c
=
&
b
->
sdb_component
;
struct
sdb_product
*
p
=
&
c
->
product
;
/* addr first and last filled later */
__fill_product
(
p
,
f
->
basename
,
f
->
stbuf
.
st_mtime
,
sdb_type_bridge
);
f
->
subdir
=
prepare_dir
(
f
->
fullname
,
f
->
dot
);
if
(
!
f
->
subdir
)
return
-
1
;
return
1
;
}
static
int
__fill_file
(
struct
sdbf
*
f
,
char
*
dir
,
char
*
fname
)
{
char
fn
[
PATH_MAX
];
...
...
@@ -97,12 +114,8 @@ static int __fill_file(struct sdbf *f, char *dir, char *fname)
strerror
(
errno
));
return
-
1
;
}
if
(
S_ISDIR
(
f
->
stbuf
.
st_mode
))
{
/* FIXME: support subdirs */
fprintf
(
stderr
,
"%s: ignoring subdirectory
\"
%s
\"\n
"
,
prgname
,
fn
);
return
0
;
}
if
(
S_ISDIR
(
f
->
stbuf
.
st_mode
))
return
__fill_dir
(
f
);
if
(
!
S_ISREG
(
f
->
stbuf
.
st_mode
))
{
fprintf
(
stderr
,
"%s: ignoring non-regular
\"
%s
\"\n
"
,
prgname
,
fn
);
...
...
@@ -173,8 +186,13 @@ static int parse_config_line(struct sdbf *tree, struct sdbf *current, int line,
return
0
;
}
if
(
sscanf
(
t
,
"position = %li"
,
&
int32
)
==
1
)
{
if
(
tree
->
level
!=
0
)
{
fprintf
(
stderr
,
"%s: Can't set position in subdirs"
" (file
\"
%s
\"
)
\n
"
,
prgname
,
current
->
fullname
);
return
0
;
}
current
->
userpos
=
1
;
current
->
a
start
=
int32
;
current
->
u
start
=
int32
;
return
0
;
}
...
...
@@ -184,7 +202,7 @@ static int parse_config_line(struct sdbf *tree, struct sdbf *current, int line,
}
/* step 0: read the directory and build the tree. Returns NULL on error */
static
struct
sdbf
*
scan_input
(
char
*
name
,
struct
sdbf
*
parent
,
FILE
**
cfgf
)
static
struct
sdbf
*
scan_input
dir
(
char
*
name
,
struct
sdbf
*
parent
,
FILE
**
cfgf
)
{
DIR
*
d
;
struct
dirent
*
de
;
...
...
@@ -218,8 +236,8 @@ static struct sdbf *scan_input(char *name, struct sdbf *parent, FILE **cfgf)
strerror
(
errno
));
return
NULL
;
}
for
(
n
=
1
/* 0 resvd for interconnect */
;
(
de
=
readdir
(
d
));
)
{
tree
[
n
].
de
=
*
de
;
for
(
n
=
1
;
(
de
=
readdir
(
d
));
)
{
/* dot is special: it fills slot 0 */
if
(
!
strcmp
(
de
->
d_name
,
"."
))
{
tree
[
0
].
de
=
*
de
;
__fill_dot
(
tree
,
name
);
...
...
@@ -240,6 +258,9 @@ static struct sdbf *scan_input(char *name, struct sdbf *parent, FILE **cfgf)
/* don't exit on this error: proceed without cfg */
continue
;
}
tree
[
n
].
level
=
tree
[
0
].
level
;
tree
[
n
].
de
=
*
de
;
tree
[
n
].
dot
=
tree
;
ret
=
__fill_file
(
tree
+
n
,
name
,
de
->
d_name
);
if
(
ret
<
0
)
return
NULL
;
...
...
@@ -273,8 +294,8 @@ static void dump_tree(struct sdbf *tree)
for
(
i
=
0
;
i
<
n
;
i
++
,
tree
++
)
{
printf
(
"%s:
\"
%s
\"
ino %li
\n
"
,
tree
->
fullname
,
tree
->
de
.
d_name
,
(
long
)
tree
->
de
.
d_ino
);
printf
(
"
astart %lx, rstart
%lx, size %lx (%lx)
\n
"
,
tree
->
astart
,
tree
->
rstart
,
tree
->
size
,
printf
(
"
ustart %lx, rstart %lx, base
%lx, size %lx (%lx)
\n
"
,
tree
->
ustart
,
tree
->
rstart
,
tree
->
base
,
tree
->
size
,
tree
->
stbuf
.
st_size
);
dumpstruct
(
stdout
,
"sdb record"
,
&
tree
->
s_d
,
sizeof
(
tree
->
s_d
));
...
...
@@ -325,29 +346,45 @@ static struct sdbf *alloc_storage(struct sdbf *tree)
int
i
,
n
;
unsigned
long
rpos
;
/* the next expected relative position */
unsigned
long
l
,
last
;
/* keep track of last, for directory record */
struct
sdbf
*
f
;
struct
sdbf
*
f
,
*
sub
;
tree
->
s_i
.
sdb_component
.
addr_first
=
htonll
(
tree
->
astart
);
/* The managed space starts at zero, even if the directory is later */
tree
->
s_i
.
sdb_component
.
addr_first
=
htonll
(
0
);
/* The "suggested" output place is after the directory itself */
n
=
ntohs
(
tree
->
s_i
.
sdb_records
);
rpos
=
SDB_ALIGN
(
n
*
sizeof
(
struct
sdb_device
));
last
=
tree
->
astart
+
rpos
;
rpos
=
tree
->
ustart
+
SDB_ALIGN
(
n
*
sizeof
(
struct
sdb_device
));
last
=
rpos
;
for
(
i
=
1
;
i
<
n
;
i
++
)
{
f
=
tree
+
i
;
if
(
f
->
userpos
)
{
/* user-specified position */
f
->
s_d
.
sdb_component
.
addr_first
=
htonll
(
f
->
a
start
);
l
=
f
->
a
start
+
f
->
size
-
1
;
if
(
f
->
userpos
)
{
/* user-specified position
(level 0)
*/
f
->
s_d
.
sdb_component
.
addr_first
=
htonll
(
f
->
u
start
);
l
=
f
->
u
start
+
f
->
size
-
1
;
f
->
s_d
.
sdb_component
.
addr_last
=
htonll
(
l
);
if
(
l
>
last
)
last
=
l
;
continue
;
}
/* If a directory, make it allocate itself */
if
(
f
->
subdir
)
{
f
->
subdir
->
base
=
tree
->
base
+
rpos
;
sub
=
alloc_storage
(
f
->
subdir
);
if
(
!
sub
)
{
fprintf
(
stderr
,
"%s: Error allocating %s
\n
"
,
prgname
,
f
->
fullname
);
return
NULL
;
}
f
->
size
=
ntohll
(
sub
->
s_i
.
sdb_component
.
addr_last
);
f
->
s_b
.
sdb_child
=
htonll
(
rpos
);
}
/* position not mandated: go sequential from previous one */
f
->
rstart
=
rpos
;
f
->
s_d
.
sdb_component
.
addr_first
=
htonll
(
tree
->
astart
+
rpos
);
l
=
tree
->
astart
+
rpos
+
f
->
size
-
1
;
f
->
s_d
.
sdb_component
.
addr_first
=
htonll
(
rpos
);
l
=
rpos
+
f
->
size
-
1
;
f
->
s_d
.
sdb_component
.
addr_last
=
htonll
(
l
);
if
(
l
>
last
)
last
=
l
;
if
(
getenv
(
"VERBOSE"
))
fprintf
(
stderr
,
"allocated relative %s: %lx to %lx
\n
"
,
f
->
fullname
,
rpos
,
l
);
rpos
=
SDB_ALIGN
(
rpos
+
f
->
size
);
}
/* finally, save the last used byte for the whole directory */
...
...
@@ -370,10 +407,20 @@ static struct sdbf *write_sdb(struct sdbf *tree, FILE *out)
return
NULL
;
}
n
=
ntohs
(
tree
->
s_i
.
sdb_records
);
/* First, write the directory, from its starting position */
fseek
(
out
,
tree
->
astart
,
SEEK_SET
);
for
(
i
=
0
;
i
<
n
;
i
++
)
/*
* First, write the directory, from its possibly user-set position.
* Meanwhile, update base for each of them (used in subdirs)
*/
fseek
(
out
,
tree
->
base
+
tree
->
ustart
,
SEEK_SET
);
for
(
i
=
0
;
i
<
n
;
i
++
)
{
fwrite
(
&
tree
[
i
].
s_d
,
sizeof
(
tree
[
i
].
s_d
),
1
,
out
);
if
(
i
>
1
)
/* don't change initial base */
tree
[
i
].
base
=
tree
[
0
].
base
+
tree
[
i
].
rstart
;
}
if
(
getenv
(
"VERBOSE"
))
/* show the user */
dump_tree
(
tree
);
/* then each file */
for
(
i
=
1
;
i
<
n
;
i
++
)
{
sdbf
=
tree
+
i
;
...
...
@@ -384,15 +431,16 @@ static struct sdbf *write_sdb(struct sdbf *tree, FILE *out)
continue
;
}
/*
* This astart and rstart stuff must be cleaned up, especially
* when we add subdirectories. Currently, user-placed files
* use astart, while auto-allocated use rstart from dir head
*/
if
(
sdbf
->
userpos
)
fseek
(
out
,
sdbf
->
astart
,
SEEK_SET
);
if
(
sdbf
->
userpos
)
/* only at level 0 */
fseek
(
out
,
sdbf
->
ustart
,
SEEK_SET
);
else
fseek
(
out
,
tree
->
astart
+
sdbf
->
rstart
,
SEEK_SET
);
fseek
(
out
,
tree
->
base
+
sdbf
->
rstart
,
SEEK_SET
);
if
(
sdbf
->
subdir
)
{
write_sdb
(
sdbf
->
subdir
,
out
);
fclose
(
f
);
continue
;
}
for
(
copied
=
0
;
copied
<
sdbf
->
stbuf
.
st_size
;
)
{
j
=
fread
(
buf
,
1
,
blocksize
,
f
);
...
...
@@ -406,12 +454,13 @@ static struct sdbf *write_sdb(struct sdbf *tree, FILE *out)
}
fclose
(
f
);
}
free
(
buf
);
return
tree
;
}
/*
* This is the main procedure for each directory, called recursively
* from scan_input() above
* from scan_input
dir
() above
*/
static
struct
sdbf
*
prepare_dir
(
char
*
name
,
struct
sdbf
*
parent
)
{
...
...
@@ -419,24 +468,18 @@ static struct sdbf *prepare_dir(char *name, struct sdbf *parent)
struct
sdbf
*
tree
;
/* scan the whole input tree and save the information */
tree
=
scan_input
(
name
,
parent
,
&
fcfg
);
tree
=
scan_input
dir
(
name
,
parent
,
&
fcfg
);
if
(
!
tree
)
return
NULL
;
/* read configuration file and save its info for each file */
if
(
fcfg
)
if
(
fcfg
)
{
tree
=
scan_config
(
tree
,
fcfg
);
fclose
(
fcfg
);
}
if
(
!
tree
)
return
NULL
;
/* allocate space in the storage */
tree
=
alloc_storage
(
tree
);
if
(
!
tree
)
return
NULL
;
if
(
getenv
(
"VERBOSE"
))
dump_tree
(
tree
);
return
tree
;
}
...
...
@@ -507,6 +550,11 @@ int main(int argc, char **argv)
if
(
!
tree
)
exit
(
1
);
/* allocate space in the storage */
tree
=
alloc_storage
(
tree
);
if
(
!
tree
)
exit
(
1
);
/* write out the whole tree, recusively */
tree
=
write_sdb
(
tree
,
fout
);
if
(
!
tree
)
...
...
sdbfs/userspace/gensdbfs.h
View file @
08c1cc62
...
...
@@ -16,11 +16,12 @@ struct sdbf {
};
char
*
fullname
;
char
*
basename
;
unsigned
long
astart
,
rstart
;
/* absolute
, relative */
unsigned
long
size
;
unsigned
long
ustart
,
rstart
;
/* user (mandated)
, relative */
unsigned
long
base
,
size
;
/* base is absolute, for output */
int
nfiles
,
totsize
;
/* for dirs */
struct
sdbf
*
dot
;
/* for files, pointer to owning dir */
struct
sdbf
*
parent
;
/* for dirs, current dir in ../ */
struct
sdbf
*
subdir
;
/* for files that are dirs */
int
level
;
/* subdir level */
int
userpos
;
/* only allowed at level 0 */
};
...
...
@@ -36,4 +37,6 @@ static inline uint64_t htonll(uint64_t ll)
return
res
;
}
#define ntohll htonll
#endif
/* __GENSDBFS_H__ */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment