8 #define stat xv6_stat // avoid clash with host struct stat
26 void wsect(uint
, void*);
27 void winode(uint
, struct dinode
*);
28 void rinode(uint inum
, struct dinode
*ip
);
29 void rsect(uint sec
, void *buf
);
30 uint
ialloc(ushort type
);
31 void iappend(uint inum
, void *p
, int n
);
33 // convert to intel byte order
38 uchar
*a
= (uchar
*)&y
;
48 uchar
*a
= (uchar
*)&y
;
57 main(int argc
, char *argv
[])
60 uint rootino
, inum
, off
;
66 fprintf(stderr
, "Usage: mkfs fs.img files...\n");
70 assert((512 % sizeof(struct dinode
)) == 0);
71 assert((512 % sizeof(struct dirent
)) == 0);
73 fsfd
= open(argv
[1], O_RDWR
|O_CREAT
|O_TRUNC
, 0666);
80 sb
.nblocks
= xint(nblocks
); // so whole disk is size sectors
81 sb
.ninodes
= xint(ninodes
);
83 bitblocks
= size
/(512*8) + 1;
84 usedblocks
= ninodes
/ IPB
+ 3 + bitblocks
;
85 freeblock
= usedblocks
;
87 printf("used %d (bit %d ninode %zu) free %u total %d\n", usedblocks
,
88 bitblocks
, ninodes
/IPB
+ 1, freeblock
, nblocks
+usedblocks
);
90 assert(nblocks
+ usedblocks
== size
);
92 for(i
= 0; i
< nblocks
+ usedblocks
; i
++)
95 memset(buf
, 0, sizeof(buf
));
96 memmove(buf
, &sb
, sizeof(sb
));
99 rootino
= ialloc(T_DIR
);
100 assert(rootino
== ROOTINO
);
102 bzero(&de
, sizeof(de
));
103 de
.inum
= xshort(rootino
);
104 strcpy(de
.name
, ".");
105 iappend(rootino
, &de
, sizeof(de
));
107 bzero(&de
, sizeof(de
));
108 de
.inum
= xshort(rootino
);
109 strcpy(de
.name
, "..");
110 iappend(rootino
, &de
, sizeof(de
));
112 for(i
= 2; i
< argc
; i
++){
113 assert(index(argv
[i
], '/') == 0);
115 if((fd
= open(argv
[i
], 0)) < 0){
120 // Skip leading _ in name when writing to file system.
121 // The binaries are named _rm, _cat, etc. to keep the
122 // build operating system from trying to execute them
123 // in place of system binaries like rm and cat.
124 if(argv
[i
][0] == '_')
127 inum
= ialloc(T_FILE
);
129 bzero(&de
, sizeof(de
));
130 de
.inum
= xshort(inum
);
131 strncpy(de
.name
, argv
[i
], DIRSIZ
);
132 iappend(rootino
, &de
, sizeof(de
));
134 while((cc
= read(fd
, buf
, sizeof(buf
))) > 0)
135 iappend(inum
, buf
, cc
);
140 // fix size of root inode dir
141 rinode(rootino
, &din
);
142 off
= xint(din
.size
);
143 off
= ((off
/BSIZE
) + 1) * BSIZE
;
144 din
.size
= xint(off
);
145 winode(rootino
, &din
);
153 wsect(uint sec
, void *buf
)
155 if(lseek(fsfd
, sec
* 512L, 0) != sec
* 512L){
159 if(write(fsfd
, buf
, 512) != 512){
168 return (inum
/ IPB
) + 2;
172 winode(uint inum
, struct dinode
*ip
)
180 dip
= ((struct dinode
*)buf
) + (inum
% IPB
);
186 rinode(uint inum
, struct dinode
*ip
)
194 dip
= ((struct dinode
*)buf
) + (inum
% IPB
);
199 rsect(uint sec
, void *buf
)
201 if(lseek(fsfd
, sec
* 512L, 0) != sec
* 512L){
205 if(read(fsfd
, buf
, 512) != 512){
214 uint inum
= freeinode
++;
217 bzero(&din
, sizeof(din
));
218 din
.type
= xshort(type
);
219 din
.nlink
= xshort(1);
231 printf("balloc: first %d blocks have been allocated\n", used
);
232 assert(used
< 512*8);
234 for(i
= 0; i
< used
; i
++){
235 buf
[i
/8] = buf
[i
/8] | (0x1 << (i
%8));
237 printf("balloc: write bitmap block at sector %zu\n", ninodes
/IPB
+ 3);
238 wsect(ninodes
/ IPB
+ 3, buf
);
241 #define min(a, b) ((a) < (b) ? (a) : (b))
244 iappend(uint inum
, void *xp
, int n
)
250 uint indirect
[NINDIRECT
];
255 off
= xint(din
.size
);
258 assert(fbn
< MAXFILE
);
260 if(xint(din
.addrs
[fbn
]) == 0){
261 din
.addrs
[fbn
] = xint(freeblock
++);
264 x
= xint(din
.addrs
[fbn
]);
266 if(xint(din
.addrs
[NDIRECT
]) == 0){
267 // printf("allocate indirect block\n");
268 din
.addrs
[NDIRECT
] = xint(freeblock
++);
271 // printf("read indirect block\n");
272 rsect(xint(din
.addrs
[NDIRECT
]), (char*)indirect
);
273 if(indirect
[fbn
- NDIRECT
] == 0){
274 indirect
[fbn
- NDIRECT
] = xint(freeblock
++);
276 wsect(xint(din
.addrs
[NDIRECT
]), (char*)indirect
);
278 x
= xint(indirect
[fbn
-NDIRECT
]);
280 n1
= min(n
, (fbn
+ 1) * 512 - off
);
282 bcopy(p
, buf
+ off
- (fbn
* 512), n1
);
288 din
.size
= xint(off
);