static char sccsid
[] = "@(#)mkproto.c 4.4 (Berkeley) %G%";
* Make a file system prototype.
* usage: mkproto filsys proto
fprintf(stderr
, "usage: mkproto filsys proto\n");
if (fso
< 0 || fsi
< 0) {
rdfs(SBLOCK
, SBSIZE
, (char *)fs
);
fscs
= (struct csum
*)calloc(1, fs
->fs_cssize
);
for (i
= 0; i
< fs
->fs_cssize
; i
+= fs
->fs_bsize
)
rdfs(fsbtodb(fs
, fs
->fs_csaddr
+ numfrags(fs
, i
)),
(int)(fs
->fs_cssize
- i
< fs
->fs_bsize
?
fs
->fs_cssize
- i
: fs
->fs_bsize
),
proto
= fopen(argv
[2], "r");
descend((struct inode
*)0);
wtfs(SBLOCK
, SBSIZE
, (char *)fs
);
for (i
= 0; i
< fs
->fs_cssize
; i
+= fs
->fs_bsize
)
wtfs(fsbtodb(&sblock
, fs
->fs_csaddr
+ numfrags(&sblock
, i
)),
(int)(fs
->fs_cssize
- i
< fs
->fs_bsize
?
fs
->fs_cssize
- i
: fs
->fs_bsize
),
struct dinode
*dip
, inos
[MAXBSIZE
/ sizeof (struct dinode
)];
daddr_t ib
[MAXBSIZE
/ sizeof (daddr_t
)];
in
.i_mode
= gmode(token
[0], "-bcd", IFREG
, IFBLK
, IFCHR
, IFDIR
);
in
.i_mode
|= gmode(token
[1], "-u", 0, ISUID
, 0, 0);
in
.i_mode
|= gmode(token
[2], "-g", 0, ISGID
, 0, 0);
for (i
= 3; i
< 6; i
++) {
if (c
< '0' || c
> '7') {
printf("%c/%s: bad octal mode digit\n", c
, token
);
in
.i_mode
|= (c
-'0')<<(15-3*i
);
in
.i_uid
= getnum(); in
.i_gid
= getnum();
for (i
= 0; i
< fs
->fs_bsize
; i
++)
for (i
= 0; i
< NINDIR(fs
); i
++)
for (i
= 0; i
< NDADDR
; i
++)
for (i
= 0; i
< NIADDR
; i
++)
if (par
!= (struct inode
*)0) {
rdfs(fsbtodb(fs
, i
), fs
->fs_bsize
, (char *)inos
);
dip
= &inos
[ROOTINO
% INOPB(fs
)];
in
.i_nlink
= dip
->di_nlink
;
in
.i_size
= dip
->di_size
;
in
.i_db
[0] = dip
->di_db
[0];
rdfs(fsbtodb(fs
, in
.i_db
[0]), fs
->fs_bsize
, buf
);
switch (in
.i_mode
&IFMT
) {
printf("%s: cannot open\n", token
);
while ((i
= read(f
, buf
, (int)fs
->fs_bsize
)) > 0) {
newblk(buf
, &ibc
, ib
, (int)blksize(fs
, &in
, ibc
));
* content is maj/min types
in
.i_rdev
= (i
<< 8) | f
;
if (in
.i_number
!= ROOTINO
) {
entry(&in
, in
.i_number
, ".", buf
);
entry(&in
, par
->i_number
, "..", buf
);
if (token
[0]=='$' && token
[1]=='\0')
entry(&in
, (ino_t
)(ino
+1), token
, buf
);
if (in
.i_number
!= ROOTINO
)
newblk(buf
, &ibc
, ib
, (int)blksize(fs
, &in
, 0));
wtfs(fsbtodb(fs
, in
.i_db
[0]), (int)fs
->fs_bsize
, buf
);
gmode(c
, s
, m0
, m1
, m2
, m3
)
printf("%c/%s: bad mode\n", c
, token
);
for (i
= 0; c
=token
[i
]; i
++) {
printf("%s: bad number\n", token
);
switch (c
= getc(proto
)) {
printf("Unexpected EOF\n");
while (getc(proto
) != '\n')
} while (c
!= ' ' && c
!= '\t' && c
!= '\n' && c
!= '\0');
entry(ip
, inum
, str
, buf
)
register struct direct
*dp
, *odp
;
int oldsize
, newsize
, spacefree
;
odp
= dp
= (struct direct
*)buf
;
while ((int)dp
- (int)buf
< ip
->i_size
) {
dp
= (struct direct
*)((int)dp
+ dp
->d_reclen
);
spacefree
= odp
->d_reclen
- oldsize
;
dp
= (struct direct
*)((int)odp
+ oldsize
);
dp
->d_namlen
= strlen(str
);
if (spacefree
>= newsize
) {
dp
->d_reclen
= spacefree
;
dp
= (struct direct
*)((int)odp
+ odp
->d_reclen
);
if ((int)dp
- (int)buf
>= fs
->fs_bsize
) {
printf("directory too large\n");
dp
->d_namlen
= strlen(str
);
dp
->d_reclen
= DIRBLKSIZ
;
ip
->i_size
= (int)dp
- (int)buf
+ newsize
;
newblk(buf
, aibc
, ib
, size
)
wtfs(fsbtodb(fs
, bno
), (int)fs
->fs_bsize
, buf
);
for (i
= 0; i
< fs
->fs_bsize
; i
++)
if (*aibc
>= NINDIR(fs
)) {
printf("indirect block full\n");
struct dinode buf
[MAXBSIZE
/ sizeof (struct dinode
)];
ip
->i_atime
= ip
->i_mtime
= ip
->i_ctime
= time((long *)0);
switch (ip
->i_mode
&IFMT
) {
for (i
= 0; i
< *aibc
; i
++) {
ip
->i_ib
[0] = alloc((int)fs
->fs_bsize
);
for (i
= 0; i
< NINDIR(fs
) - NDADDR
; i
++) {
ib
[i
+NDADDR
] = (daddr_t
)0;
wtfs(fsbtodb(fs
, ip
->i_ib
[0]),
(int)fs
->fs_bsize
, (char *)ib
);
printf("bad mode %o\n", ip
->i_mode
);
d
= fsbtodb(fs
, itod(fs
, ip
->i_number
));
rdfs(d
, (int)fs
->fs_bsize
, (char *)buf
);
buf
[itoo(fs
, ip
->i_number
)].di_ic
= ip
->i_ic
;
wtfs(d
, (int)fs
->fs_bsize
, (char *)buf
);
rdfs(fsbtodb(&sblock
, cgtod(&sblock
, cg
)), (int)sblock
.fs_cgsize
,
if (acg
.cg_magic
!= CG_MAGIC
) {
printf("cg %d: bad magic number\n", cg
);
if (acg
.cg_cs
.cs_nbfree
== 0) {
printf("ran out of space\n");
for (d
= 0; d
< acg
.cg_ndblk
; d
+= sblock
.fs_frag
)
if (isblock(&sblock
, (u_char
*)acg
.cg_free
, d
/ sblock
.fs_frag
))
printf("internal error: can't find block in cyl %d\n", cg
);
clrblock(&sblock
, (u_char
*)acg
.cg_free
, d
/ sblock
.fs_frag
);
sblock
.fs_cstotal
.cs_nbfree
--;
acg
.cg_btot
[cbtocylno(&sblock
, d
)]--;
acg
.cg_b
[cbtocylno(&sblock
, d
)][cbtorpos(&sblock
, d
)]--;
if (size
!= sblock
.fs_bsize
) {
frag
= howmany(size
, sblock
.fs_fsize
);
fscs
[cg
].cs_nffree
+= sblock
.fs_frag
- frag
;
sblock
.fs_cstotal
.cs_nffree
+= sblock
.fs_frag
- frag
;
acg
.cg_cs
.cs_nffree
+= sblock
.fs_frag
- frag
;
acg
.cg_frsum
[sblock
.fs_frag
- frag
]++;
for (i
= frag
; i
< sblock
.fs_frag
; i
++)
setbit(acg
.cg_free
, d
+ i
);
wtfs(fsbtodb(&sblock
, cgtod(&sblock
, cg
)), (int)sblock
.fs_cgsize
,
return (acg
.cg_cgx
* fs
->fs_fpg
+ d
);
* Allocate an inode on the disk
register struct inode
*ip
;
struct dinode buf
[MAXBSIZE
/ sizeof (struct dinode
)];
c
= itog(&sblock
, ip
->i_number
);
rdfs(fsbtodb(&sblock
, cgtod(&sblock
, c
)), (int)sblock
.fs_cgsize
,
if (acg
.cg_magic
!= CG_MAGIC
) {
printf("cg %d: bad magic number\n", c
);
if (ip
->i_mode
& IFDIR
) {
sblock
.fs_cstotal
.cs_ndir
++;
setbit(acg
.cg_iused
, ip
->i_number
);
wtfs(fsbtodb(&sblock
, cgtod(&sblock
, c
)), (int)sblock
.fs_cgsize
,
sblock
.fs_cstotal
.cs_nifree
--;
if(ip
->i_number
>= sblock
.fs_ipg
* sblock
.fs_ncg
) {
printf("fsinit: inode value out of range (%d).\n",
* read a block from the file system
if (lseek(fsi
, bno
* DEV_BSIZE
, 0) < 0) {
printf("seek error: %ld\n", bno
);
printf("read error: %ld\n", bno
);
* write a block to the file system
lseek(fso
, bno
* DEV_BSIZE
, 0);
if (lseek(fso
, bno
* DEV_BSIZE
, 0) < 0) {
printf("seek error: %ld\n", bno
);
n
= write(fso
, bf
, size
);
printf("write error: %D\n", bno
);
* check if a block is available
mask
= 0x0f << ((h
& 0x1) << 2);
return ((cp
[h
>> 1] & mask
) == mask
);
mask
= 0x03 << ((h
& 0x3) << 1);
return ((cp
[h
>> 2] & mask
) == mask
);
mask
= 0x01 << (h
& 0x7);
return ((cp
[h
>> 3] & mask
) == mask
);
fprintf(stderr
, "isblock bad fs_frag %d\n", fs
->fs_frag
);
* take a block out of the map
cp
[h
>> 1] &= ~(0x0f << ((h
& 0x1) << 2));
cp
[h
>> 2] &= ~(0x03 << ((h
& 0x3) << 1));
cp
[h
>> 3] &= ~(0x01 << (h
& 0x7));
fprintf(stderr
, "clrblock bad fs_frag %d\n", fs
->fs_frag
);