summaryrefslogtreecommitdiffstats
path: root/ext2ed/doc/ext2fs-overview.sgml
blob: 0d54f07c1268444eab1be6648af2c4aaf798cf28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
<!DOCTYPE Article PUBLIC "-//Davenport//DTD DocBook V3.0//EN">

<Article>

<ArtHeader>

<Title>The extended-2 filesystem overview</Title>
<AUTHOR
>
<FirstName>Gadi Oxman, tgud@tochnapc2.technion.ac.il</FirstName>
</AUTHOR
>
<PubDate>v0.1, August 3 1995</PubDate>

</ArtHeader>

<Sect1>
<Title>Preface</Title>

<Para>
This document attempts to present an overview of the internal structure of
the ext2 filesystem. It was written in summer 95, while I was working on the 
<Literal remap="tt">ext2 filesystem editor project (EXT2ED)</Literal>. 
</Para>

<Para>
In the process of constructing EXT2ED, I acquired knowledge of the various 
design aspects of the the ext2 filesystem. This document is a result of an
effort to document this knowledge.
</Para>

<Para>
This is only the initial version of this document. It is obviously neither
error-prone nor complete, but at least it provides a starting point.
</Para>

<Para>
In the process of learning the subject, I have used the following sources /
tools:

<ItemizedList>
<ListItem>

<Para>
	Experimenting with EXT2ED, as it was developed.
</Para>
</ListItem>
<ListItem>

<Para>
	The ext2 kernel sources:

<ItemizedList>
<ListItem>

<Para>
	The main ext2 include file,
<FILENAME>/usr/include/linux/ext2&lowbar;fs.h</FILENAME>
</Para>
</ListItem>
<ListItem>

<Para>
	The contents of the directory <FILENAME>/usr/src/linux/fs/ext2</FILENAME>.
</Para>
</ListItem>
<ListItem>

<Para>
	The VFS layer sources (only a bit).
</Para>
</ListItem>

</ItemizedList>

</Para>
</ListItem>
<ListItem>

<Para>
	The slides: The Second Extended File System, Current State, Future
Development, by <personname><firstname>Remy</firstname> <surname>Card</surname></personname>.
</Para>
</ListItem>
<ListItem>

<Para>
	The slides: Optimisation in File Systems, by <personname><firstname>Stephen</firstname> <surname>Tweedie</surname></personname>.
</Para>
</ListItem>
<ListItem>

<Para>
	The various ext2 utilities.
</Para>
</ListItem>

</ItemizedList>

</Para>

</Sect1>

<Sect1>
<Title>Introduction</Title>

<Para>
The <Literal remap="tt">Second Extended File System (Ext2fs)</Literal> is very popular among Linux
users. If you use Linux, chances are that you are using the ext2 filesystem.
</Para>

<Para>
Ext2fs was designed by <personname><firstname>Remy</firstname> <surname>Card</surname></personname> and <personname><firstname>Wayne</firstname> <surname>Davison</surname></personname>. It was
implemented by <personname><firstname>Remy</firstname> <surname>Card</surname></personname> and was further enhanced by <personname><firstname>Stephen</firstname>
<surname>Tweedie</surname></personname> and <personname><firstname>Theodore</firstname> <surname>Ts'o</surname></personname>.
</Para>

<Para>
The ext2 filesystem is still under development. I will document here
version 0.5a, which is distributed along with Linux 1.2.x. At this time of
writing, the most recent version of Linux is 1.3.13, and the version of the
ext2 kernel source is 0.5b. A lot of fancy enhancements are planned for the
ext2 filesystem in Linux 1.3, so stay tuned.
</Para>

</Sect1>

<Sect1>
<Title>A filesystem - Why do we need it?</Title>

<Para>
I thought that before we dive into the various small details, I'll reserve a
few minutes for the discussion of filesystems from a general point of view.
</Para>

<Para>
A <Literal remap="tt">filesystem</Literal> consists of two word - <Literal remap="tt">file</Literal> and <Literal remap="tt">system</Literal>.
</Para>

<Para>
Everyone knows the meaning of the word <Literal remap="tt">file</Literal> - A bunch of data put
somewhere. where? This is an important question. I, for example, usually
throw almost everything into a single drawer, and have difficulties finding
something later.
</Para>

<Para>
This is where the <Literal remap="tt">system</Literal> comes in - Instead of just throwing the data
to the device, we generalize and construct a <Literal remap="tt">system</Literal> which will
virtualize for us a nice and ordered structure in which we could arrange our
data in much the same way as books are arranged in a library. The purpose of
the filesystem, as I understand it, is to make it easy for us to update and
maintain our data.
</Para>

<Para>
Normally, by <Literal remap="tt">mounting</Literal> filesystems, we just use the nice and logical
virtual structure. However, the disk knows nothing about that - The device
driver views the disk as a large continuous paper in which we can write notes
wherever we wish. It is the task of the filesystem management code to store
bookkeeping information which will serve the kernel for showing us the nice
and ordered virtual structure.
</Para>

<Para>
In this document, we consider one particular administrative structure - The
Second Extended Filesystem.
</Para>

</Sect1>

<Sect1>
<Title>The Linux VFS layer</Title>

<Para>
When Linux was first developed, it supported only one filesystem - The
<Literal remap="tt">Minix</Literal> filesystem. Today, Linux has the ability to support several
filesystems concurrently. This was done by the introduction of another layer
between the kernel and the filesystem code - The Virtual File System (VFS).
</Para>

<Para>
The kernel "speaks" with the VFS layer. The VFS layer passes the kernel's
request to the proper filesystem management code. I haven't learned much of
the VFS layer as I didn't need it for the construction of EXT2ED so that I
can't elaborate on it. Just be aware that it exists.
</Para>

</Sect1>

<Sect1>
<Title>About blocks and block groups</Title>

<Para>
In order to ease management, the ext2 filesystem logically divides the disk
into small units called <Literal remap="tt">blocks</Literal>. A block is the smallest unit which
can be allocated. Each block in the filesystem can be <Literal remap="tt">allocated</Literal> or
<Literal remap="tt">free</Literal>.
<FOOTNOTE>

<Para>
The Ext2fs source code refers to the concept of <Literal remap="tt">fragments</Literal>, which I
believe are supposed to be sub-block allocations. As far as I know,
fragments are currently unsupported in Ext2fs.
</Para>

</FOOTNOTE>

The block size can be selected to be 1024, 2048 or 4096 bytes when creating
the filesystem.
</Para>

<Para>
Ext2fs groups together a fixed number of sequential blocks into a <Literal remap="tt">group
block</Literal>. The resulting situation is that the filesystem is managed as a
series of group blocks. This is done in order to keep related information
physically close on the disk and to ease the management task. As a result,
much of the filesystem management reduces to management of a single blocks
group.
</Para>

</Sect1>

<Sect1>
<Title>The view of inodes from the point of view of a blocks group</Title>

<Para>
Each file in the filesystem is reserved a special <Literal remap="tt">inode</Literal>. I don't want
to explain inodes now. Rather, I would like to treat it as another resource,
much like a <Literal remap="tt">block</Literal> - Each blocks group contains a limited number of
inode, while any specific inode can be <Literal remap="tt">allocated</Literal> or
<Literal remap="tt">unallocated</Literal>.
</Para>

</Sect1>

<Sect1>
<Title>The group descriptors</Title>

<Para>
Each blocks group is accompanied by a <Literal remap="tt">group descriptor</Literal>. The group
descriptor summarizes some necessary information about the specific group
block. Follows the definition of the group descriptor, as defined in
<FILENAME>/usr/include/linux/ext2&lowbar;fs.h</FILENAME>:
</Para>

<Para>

<ProgramListing>
struct ext2_group_desc
{
	__u32	bg_block_bitmap;	/* Blocks bitmap block */
	__u32	bg_inode_bitmap;	/* Inodes bitmap block */
	__u32	bg_inode_table;		/* Inodes table block */
	__u16	bg_free_blocks_count;	/* Free blocks count */
	__u16	bg_free_inodes_count;	/* Free inodes count */
	__u16	bg_used_dirs_count;	/* Directories count */
	__u16	bg_pad;
	__u32	bg_reserved[3];
};
</ProgramListing>

</Para>

<Para>
The last three variables: <Literal remap="tt">bg&lowbar;free&lowbar;blocks&lowbar;count, bg&lowbar;free&lowbar;inodes&lowbar;count and bg&lowbar;used&lowbar;dirs&lowbar;count</Literal> provide statistics about the use of the three
resources in a blocks group - The <Literal remap="tt">blocks</Literal>, the <Literal remap="tt">inodes</Literal> and the
<Literal remap="tt">directories</Literal>. I believe that they are used by the kernel for balancing
the load between the various blocks groups.
</Para>

<Para>
<Literal remap="tt">bg&lowbar;block&lowbar;bitmap</Literal> contains the block number of the <Literal remap="tt">block allocation
bitmap block</Literal>. This is used to allocate / deallocate each block in the
specific blocks group.
</Para>

<Para>
<Literal remap="tt">bg&lowbar;inode&lowbar;bitmap</Literal> is fully analogous to the previous variable - It
contains the block number of the <Literal remap="tt">inode allocation bitmap block</Literal>, which
is used to allocate / deallocate each specific inode in the filesystem.
</Para>

<Para>
<Literal remap="tt">bg&lowbar;inode&lowbar;table</Literal> contains the block number of the start of the
<Literal remap="tt">inode table of the current blocks group</Literal>. The <Literal remap="tt">inode table</Literal> is
just the actual inodes which are reserved for the current block.
</Para>

<Para>
The block bitmap block, inode bitmap block and the inode table are created
when the filesystem is created.
</Para>

<Para>
The group descriptors are placed one after the other. Together they make the
<Literal remap="tt">group descriptors table</Literal>.
</Para>

<Para>
Each blocks group contains the entire table of group descriptors in its
second block, right after the superblock. However, only the first copy (in
group 0) is actually used by the kernel. The other copies are there for
backup purposes and can be of use if the main copy gets corrupted.
</Para>

</Sect1>

<Sect1>
<Title>The block bitmap allocation block</Title>

<Para>
Each blocks group contains one special block which is actually a map of the
entire blocks in the group, with respect to their allocation status. Each
<Literal remap="tt">bit</Literal> in the block bitmap indicated whether a specific block in the
group is used or free.
</Para>

<Para>
The format is actually quite simple - Just view the entire block as a series
of bits. For example,
</Para>

<Para>
Suppose the block size is 1024 bytes. As such, there is a place for
1024*8=8192 blocks in a group block. This number is one of the fields in the
filesystem's <Literal remap="tt">superblock</Literal>, which will be explained later.
</Para>

<Para>

<ItemizedList>
<ListItem>

<Para>
	Block 0 in the blocks group is managed by bit 0 of byte 0 in the bitmap
block.
</Para>
</ListItem>
<ListItem>

<Para>
	Block 7 in the blocks group is managed by bit 7 of byte 0 in the bitmap
block.
</Para>
</ListItem>
<ListItem>

<Para>
	Block 8 in the blocks group is managed by bit 0 of byte 1 in the bitmap
block.
</Para>
</ListItem>
<ListItem>

<Para>
	Block 8191 in the blocks group is managed by bit 7 of byte 1023 in the
bitmap 	block.
</Para>
</ListItem>

</ItemizedList>

</Para>

<Para>
A value of "<Literal remap="tt">1</Literal>" in the appropriate bit signals that the block is
allocated, while a value of "<Literal remap="tt">0</Literal>" signals that the block is
unallocated.
</Para>

<Para>
You will probably notice that typically, all the bits in a byte contain the
same value, making the byte's value <Literal remap="tt">0</Literal> or <Literal remap="tt">0ffh</Literal>. This is done by
the kernel on purpose in order to group related data in physically close
blocks, since the physical device is usually optimized to handle such a close
relationship.
</Para>

</Sect1>

<Sect1>
<Title>The inode allocation bitmap</Title>

<Para>
The format of the inode allocation bitmap block is exactly like the format of
the block allocation bitmap block. The explanation above is valid here, with
the work <Literal remap="tt">block</Literal> replaced by <Literal remap="tt">inode</Literal>. Typically, there are much less
inodes then blocks in a blocks group and thus only part of the inode bitmap
block is used. The number of inodes in a blocks group is another variable
which is listed in the <Literal remap="tt">superblock</Literal>.
</Para>

</Sect1>

<Sect1>
<Title>On the inode and the inode tables</Title>

<Para>
An inode is a main resource in the ext2 filesystem. It is used for various
purposes, but the main two are:

<ItemizedList>
<ListItem>

<Para>
	Support of files
</Para>
</ListItem>
<ListItem>

<Para>
	Support of directories
</Para>
</ListItem>

</ItemizedList>

</Para>

<Para>
Each file, for example, will allocate one inode from the filesystem
resources.
</Para>

<Para>
An ext2 filesystem has a total number of available inodes which is determined
while creating the filesystem. When all the inodes are used, for example, you
will not be able to create an additional file even though there will still
be free blocks on the filesystem. 
</Para>

<Para>
Each inode takes up 128 bytes in the filesystem. By default, <Literal remap="tt">mke2fs</Literal>
reserves an inode for each 4096 bytes of the filesystem space.
</Para>

<Para>
The inodes are placed in several tables, each of which contains the same
number of inodes and is placed at a different blocks group. The goal is to
place inodes and their related files in the same blocks group because of
locality arguments.
</Para>

<Para>
The number of inodes in a blocks group is available in the superblock variable
<Literal remap="tt">s&lowbar;inodes&lowbar;per&lowbar;group</Literal>. For example, if there are 2000 inodes per group,
group 0 will contain the inodes 1-2000, group 2 will contain the inodes
2001-4000, and so on.
</Para>

<Para>
Each inode table is accessed from the group descriptor of the specific
blocks group which contains the table.
</Para>

<Para>
Follows the structure of an inode in Ext2fs:
</Para>

<Para>

<ProgramListing>
struct ext2_inode {
	__u16	i_mode;		/* File mode */
	__u16	i_uid;		/* Owner Uid */
	__u32	i_size;		/* Size in bytes */
	__u32	i_atime;	/* Access time */
	__u32	i_ctime;	/* Creation time */
	__u32	i_mtime;	/* Modification time */
	__u32	i_dtime;	/* Deletion Time */
	__u16	i_gid;		/* Group Id */
	__u16	i_links_count;	/* Links count */
	__u32	i_blocks;	/* Blocks count */
	__u32	i_flags;	/* File flags */
	union {
		struct {
			__u32  l_i_reserved1;
		} linux1;
		struct {
			__u32  h_i_translator;
		} hurd1;
		struct {
			__u32  m_i_reserved1;
		} masix1;
	} osd1;				/* OS dependent 1 */
	__u32	i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
	__u32	i_version;	/* File version (for NFS) */
	__u32	i_file_acl;	/* File ACL */
	__u32	i_size_high;	/* High 32bits of size */
	__u32	i_faddr;	/* Fragment address */
	union {
		struct {
			__u8	l_i_frag;	/* Fragment number */
			__u8	l_i_fsize;	/* Fragment size */
			__u16	i_pad1;
			__u32	l_i_reserved2[2];
		} linux2;
		struct {
			__u8	h_i_frag;	/* Fragment number */
			__u8	h_i_fsize;	/* Fragment size */
			__u16	h_i_mode_high;
			__u16	h_i_uid_high;
			__u16	h_i_gid_high;
			__u32	h_i_author;
		} hurd2;
		struct {
			__u8	m_i_frag;	/* Fragment number */
			__u8	m_i_fsize;	/* Fragment size */
			__u16	m_pad1;
			__u32	m_i_reserved2[2];
		} masix2;
	} osd2;				/* OS dependent 2 */
};
</ProgramListing>

</Para>

<Sect2>
<Title>The allocated blocks</Title>

<Para>
The basic functionality of an inode is to group together a series of
allocated blocks. There is no limitation on the allocated blocks - Each
block can be allocated to each inode. Nevertheless, block allocation will
usually be done in series to take advantage of the locality principle.
</Para>

<Para>
The inode is not always used in that way. I will now explain the allocation
of blocks, assuming that the current inode type indeed refers to a list of
allocated blocks.
</Para>

<Para>
It was found experimentally that many of the files in the filesystem are
actually quite small. To take advantage of this effect, the kernel provides
storage of up to 12 block numbers in the inode itself. Those blocks are
called <Literal remap="tt">direct blocks</Literal>. The advantage is that once the kernel has the
inode, it can directly access the file's blocks, without an additional disk
access. Those 12 blocks are directly specified in the variables
<Literal remap="tt">i&lowbar;block[0] to i&lowbar;block[11]</Literal>.
</Para>

<Para>
<Literal remap="tt">i&lowbar;block[12]</Literal> is the <Literal remap="tt">indirect block</Literal> - The block pointed by
i&lowbar;block&lsqb;12] will <Literal remap="tt">not</Literal> be a data block. Rather, it will just contain a
list of direct blocks. For example, if the block size is 1024 bytes, since
each block number is 4 bytes long, there will be place for 256 indirect
blocks. That is, block 13 till block 268 in the file will be accessed by the
<Literal remap="tt">indirect block</Literal> method. The penalty in this case, compared to the
direct blocks case, is that an additional access to the device is needed -
We need <Literal remap="tt">two</Literal> accesses to reach the required data block.
</Para>

<Para>
In much the same way, <Literal remap="tt">i&lowbar;block[13]</Literal> is the <Literal remap="tt">double indirect block</Literal>
and <Literal remap="tt">i&lowbar;block[14]</Literal> is the <Literal remap="tt">triple indirect block</Literal>.
</Para>

<Para>
<Literal remap="tt">i&lowbar;block[13]</Literal> points to a block which contains pointers to indirect
blocks. Each one of them is handled in the way described above.
</Para>

<Para>
In much the same way, the triple indirect block is just an additional level
of indirection - It will point to a list of double indirect blocks.
</Para>

</Sect2>

<Sect2>
<Title>The i&lowbar;mode variable</Title>

<Para>
The i&lowbar;mode variable is used to determine the <Literal remap="tt">inode type</Literal> and the
associated <Literal remap="tt">permissions</Literal>. It is best described by representing it as an
octal number. Since it is a 16 bit variable, there will be 6 octal digits.
Those are divided into two parts - The rightmost 4 digits and the leftmost 2
digits.
</Para>

<Sect3>
<Title>The rightmost 4 octal digits</Title>

<Para>
The rightmost 4 digits are <Literal remap="tt">bit options</Literal> - Each bit has its own
purpose.
</Para>

<Para>
The last 3 digits (Octal digits 0,1 and 2) are just the usual permissions,
in the known form <Literal remap="tt">rwxrwxrwx</Literal>. Digit 2 refers to the user, digit 1 to
the group and digit 2 to everyone else. They are used by the kernel to grant
or deny access to the object presented by this inode.
<FOOTNOTE>

<Para>
A <Literal remap="tt">smarter</Literal> permissions control is one of the enhancements planned for
Linux 1.3 - The ACL (Access Control Lists). Actually, from browsing of the
kernel source, some of the ACL handling is already done.
</Para>

</FOOTNOTE>

</Para>

<Para>
Bit number 9 signals that the file (I'll refer to the object presented by
the inode as file even though it can be a special device, for example) is
<Literal remap="tt">set VTX</Literal>. I still don't know what is the meaning of "VTX".
</Para>

<Para>
Bit number 10 signals that the file is <Literal remap="tt">set group id</Literal> - I don't know
exactly the meaning of the above either.
</Para>

<Para>
Bit number 11 signals that the file is <Literal remap="tt">set user id</Literal>, which means that
the file will run with an effective user id root.
</Para>

</Sect3>

<Sect3>
<Title>The leftmost two octal digits</Title>

<Para>
Note the the leftmost octal digit can only be 0 or 1, since the total number
of bits is 16.
</Para>

<Para>
Those digits, as opposed to the rightmost 4 digits, are not bit mapped
options. They determine the type of the "file" to which the inode belongs:

<ItemizedList>
<ListItem>

<Para>
	<Literal remap="tt">01</Literal> - The file is a <Literal remap="tt">FIFO</Literal>.
</Para>
</ListItem>
<ListItem>

<Para>
	<Literal remap="tt">02</Literal> - The file is a <Literal remap="tt">character device</Literal>.
</Para>
</ListItem>
<ListItem>

<Para>
	<Literal remap="tt">04</Literal> - The file is a <Literal remap="tt">directory</Literal>.
</Para>
</ListItem>
<ListItem>

<Para>
	<Literal remap="tt">06</Literal> - The file is a <Literal remap="tt">block device</Literal>.
</Para>
</ListItem>
<ListItem>

<Para>
	<Literal remap="tt">10</Literal> - The file is a <Literal remap="tt">regular file</Literal>.
</Para>
</ListItem>
<ListItem>

<Para>
	<Literal remap="tt">12</Literal> - The file is a <Literal remap="tt">symbolic link</Literal>.
</Para>
</ListItem>
<ListItem>

<Para>
	<Literal remap="tt">14</Literal> - The file is a <Literal remap="tt">socket</Literal>.
</Para>
</ListItem>

</ItemizedList>

</Para>

</Sect3>

</Sect2>

<Sect2>
<Title>Time and date</Title>

<Para>
Linux records the last time in which various operations occurred with the
file. The time and date are saved in the standard C library format - The
number of seconds which passed since 00:00:00 GMT, January 1, 1970. The
following times are recorded:

<ItemizedList>
<ListItem>

<Para>
	<Literal remap="tt">i&lowbar;ctime</Literal> - The time in which the inode was last allocated. In
other words, the time in which the file was created.
</Para>
</ListItem>
<ListItem>

<Para>
	<Literal remap="tt">i&lowbar;mtime</Literal> - The time in which the file was last modified.
</Para>
</ListItem>
<ListItem>

<Para>
	<Literal remap="tt">i&lowbar;atime</Literal> - The time in which the file was last accessed.
</Para>
</ListItem>
<ListItem>

<Para>
	<Literal remap="tt">i&lowbar;dtime</Literal> - The time in which the inode was deallocated. In
other words, the time in which the file was deleted.
</Para>
</ListItem>

</ItemizedList>

</Para>

</Sect2>

<Sect2>
<Title>i&lowbar;size</Title>

<Para>
<Literal remap="tt">i&lowbar;size</Literal> contains information about the size of the object presented by
the inode. If the inode corresponds to a regular file, this is just the size
of the file in bytes. In other cases, the interpretation of the variable is
different.
</Para>

</Sect2>

<Sect2>
<Title>User and group id</Title>

<Para>
The user and group id of the file are just saved in the variables
<Literal remap="tt">i&lowbar;uid</Literal> and <Literal remap="tt">i&lowbar;gid</Literal>.
</Para>

</Sect2>

<Sect2>
<Title>Hard links</Title>

<Para>
Later, when we'll discuss the implementation of directories, it will be
explained that each <Literal remap="tt">directory entry</Literal> points to an inode. It is quite
possible that a <Literal remap="tt">single inode</Literal> will be pointed to from <Literal remap="tt">several</Literal>
directories. In that case, we say that there exist <Literal remap="tt">hard links</Literal> to the
file - The file can be accessed from each of the directories.
</Para>

<Para>
The kernel keeps track of the number of hard links in the variable
<Literal remap="tt">i&lowbar;links&lowbar;count</Literal>. The variable is set to "1" when first allocating the
inode, and is incremented with each additional link. Deletion of a file will
delete the current directory entry and will decrement the number of links.
Only when this number reaches zero, the inode will be actually deallocated.
</Para>

<Para>
The name <Literal remap="tt">hard link</Literal> is used to distinguish between the alias method
described above, to another alias method called <Literal remap="tt">symbolic linking</Literal>,
which will be described later.
</Para>

</Sect2>

<Sect2>
<Title>The Ext2fs extended flags</Title>

<Para>
The ext2 filesystem associates additional flags with an inode. The extended
attributes are stored in the variable <Literal remap="tt">i&lowbar;flags</Literal>. <Literal remap="tt">i&lowbar;flags</Literal> is a 32
bit variable. Only the 7 rightmost bits are defined. Of them, only 5 bits
are used in version 0.5a of the filesystem. Specifically, the
<Literal remap="tt">undelete</Literal> and the <Literal remap="tt">compress</Literal> features are not implemented, and
are to be introduced in Linux 1.3 development.
</Para>

<Para>
The currently available flags are:

<ItemizedList>
<ListItem>

<Para>
	bit 0 - Secure deletion.

When this bit is on, the file's blocks are zeroed when the file is
deleted. With this bit off, they will just be left with their
original data when the inode is deallocated.
</Para>
</ListItem>
<ListItem>

<Para>
	bit 1 - Undelete.
	
This bit is not supported yet. It will be used to provide an
<Literal remap="tt">undelete</Literal> feature in future Ext2fs developments.
</Para>
</ListItem>
<ListItem>

<Para>
	bit 2 - Compress file.

This bit is also not supported. The plan is to offer "compression on
the fly" in future releases.
</Para>
</ListItem>
<ListItem>

<Para>
	bit 3 - Synchronous updates.

With this bit on, the meta-data will be written synchronously to the
disk, as if the filesystem was mounted with the "sync" mount option.
</Para>
</ListItem>
<ListItem>

<Para>
	bit 4 - Immutable file.

When this bit is on, the file will stay as it is - Can not be
changed, deleted, renamed, no hard links, etc, before the bit is
cleared.
</Para>
</ListItem>
<ListItem>

<Para>
	bit 5 - Append only file.
	
With this option active, data will only be appended to the file.
</Para>
</ListItem>
<ListItem>

<Para>
	bit 6 - Do not dump this file.

I think that this bit is used by the port of dump to linux (ported by
<Literal remap="tt">Remy Card</Literal>) to check if the file should not be dumped.
</Para>
</ListItem>

</ItemizedList>

</Para>

</Sect2>

<Sect2>
<Title>Symbolic links</Title>

<Para>
The <Literal remap="tt">hard links</Literal> presented above are just another pointers to the same
inode. The important aspect is that the inode number is <Literal remap="tt">fixed</Literal> when
the link is created. This means that the implementation details of the
filesystem are visible to the user - In a pure abstract usage of the
filesystem, the user should not care about inodes.
</Para>

<Para>
The above causes several limitations:

<ItemizedList>
<ListItem>

<Para>
	Hard links can be done only in the same filesystem. This is obvious,
since a hard link is just an inode number in some directory entry,
and the above elements are filesystem specific.
</Para>
</ListItem>
<ListItem>

<Para>
	You can not "replace" the file which is pointed to by the hard link
after the link creation. "Replacing" the file in one directory will
still leave the original file in the other directory - The
"replacement" will not deallocate the original inode, but rather
allocate another inode for the new version, and the directory entry
at the other place will just point to the old inode number.
</Para>
</ListItem>

</ItemizedList>

</Para>

<Para>
<Literal remap="tt">Symbolic link</Literal>, on the other hand, is analyzed at <Literal remap="tt">run time</Literal>. A
symbolic link is just a <Literal remap="tt">pathname</Literal> which is accessible from an inode.
As such, it "speaks" in the language of the abstract filesystem. When the
kernel reaches a symbolic link, it will <Literal remap="tt">follow it in run time</Literal> using
its normal way of reaching directories.
</Para>

<Para>
As such, symbolic link can be made <Literal remap="tt">across different filesystems</Literal> and a
replacement of a file with a new version will automatically be active on all
its symbolic links.
</Para>

<Para>
The disadvantage is that hard link doesn't consume space except to a small
directory entry. Symbolic link, on the other hand, consumes at least an
inode, and can also consume one block.
</Para>

<Para>
When the inode is identified as a symbolic link, the kernel needs to find
the path to which it points.
</Para>

<Sect3>
<Title>Fast symbolic links</Title>

<Para>
When the pathname contains up to 64 bytes, it can be saved directly in the
inode, on the <Literal remap="tt">i&lowbar;block[0] - i&lowbar;block[15]</Literal> variables, since those are not
needed in that case. This is called <Literal remap="tt">fast</Literal> symbolic link. It is fast
because the pathname resolution can be done using the inode itself, without
accessing additional blocks. It is also economical, since it allocates only
an inode. The length of the pathname is stored in the <Literal remap="tt">i&lowbar;size</Literal>
variable.
</Para>

</Sect3>

<Sect3>
<Title>Slow symbolic links</Title>

<Para>
Starting from 65 bytes, additional block is allocated (by the use of
<Literal remap="tt">i&lowbar;block[0]</Literal>) and the pathname is stored in it. It is called slow
because the kernel needs to read additional block to resolve the pathname.
The length is again saved in <Literal remap="tt">i&lowbar;size</Literal>.
</Para>

</Sect3>

</Sect2>

<Sect2>
<Title>i&lowbar;version</Title>

<Para>
<Literal remap="tt">i&lowbar;version</Literal> is used with regard to Network File System. I don't know
its exact use.
</Para>

</Sect2>

<Sect2>
<Title>Reserved variables</Title>

<Para>
As far as I know, the variables which are connected to ACL and fragments
are not currently used. They will be supported in future versions.
</Para>

<Para>
Ext2fs is being ported to other operating systems. As far as I know,
at least in linux, the os dependent variables are also not used.
</Para>

</Sect2>

<Sect2>
<Title>Special reserved inodes</Title>

<Para>
The first ten inodes on the filesystem are special inodes:

<ItemizedList>
<ListItem>

<Para>
	Inode 1 is the <Literal remap="tt">bad blocks inode</Literal> - I believe that its data
blocks contain a list of the bad blocks in the filesystem, which
should not be allocated.
</Para>
</ListItem>
<ListItem>

<Para>
	Inode 2 is the <Literal remap="tt">root inode</Literal> - The inode of the root directory.
It is the starting point for reaching a known path in the filesystem.
</Para>
</ListItem>
<ListItem>

<Para>
	Inode 3 is the <Literal remap="tt">acl index inode</Literal>. Access control lists are
currently not supported by the ext2 filesystem, so I believe this
inode is not used.
</Para>
</ListItem>
<ListItem>

<Para>
	Inode 4 is the <Literal remap="tt">acl data inode</Literal>. Of course, the above applies
here too.
</Para>
</ListItem>
<ListItem>

<Para>
	Inode 5 is the <Literal remap="tt">boot loader inode</Literal>. I don't know its
usage.
</Para>
</ListItem>
<ListItem>

<Para>
	Inode 6 is the <Literal remap="tt">undelete directory inode</Literal>. It is also a
foundation for future enhancements, and is currently not used.
</Para>
</ListItem>
<ListItem>

<Para>
	Inodes 7-10 are <Literal remap="tt">reserved</Literal> and currently not used.
</Para>
</ListItem>

</ItemizedList>

</Para>

</Sect2>

</Sect1>

<Sect1>
<Title>Directories</Title>

<Para>
A directory is implemented in the same way as files are implemented (with
the direct blocks, indirect blocks, etc) - It is just a file which is
formatted with a special format - A list of directory entries.
</Para>

<Para>
Follows the definition of a directory entry:
</Para>

<Para>

<ProgramListing>
struct ext2_dir_entry {
	__u32	inode;			/* Inode number */
	__u16	rec_len;		/* Directory entry length */
	__u16	name_len;		/* Name length */
	char	name[EXT2_NAME_LEN];	/* File name */
};
</ProgramListing>

</Para>

<Para>
Ext2fs supports file names of varying lengths, up to 255 bytes. The
<Literal remap="tt">name</Literal> field above just contains the file name. Note that it is
<Literal remap="tt">not zero terminated</Literal>; Instead, the variable <Literal remap="tt">name&lowbar;len</Literal> contains
the length of the file name.
</Para>

<Para>
The variable <Literal remap="tt">rec&lowbar;len</Literal> is provided because the directory entries are
padded with zeroes so that the next entry will be in an offset which is
a multiplication of 4. The resulting directory entry size is stored in
<Literal remap="tt">rec&lowbar;len</Literal>. If the directory entry is the last in the block, it is
padded with zeroes till the end of the block, and rec&lowbar;len is updated
accordingly.
</Para>

<Para>
The <Literal remap="tt">inode</Literal> variable points to the inode of the above file.
</Para>

<Para>
Deletion of directory entries is done by appending of the deleted entry
space to the previous (or next, I am not sure) entry.
</Para>

</Sect1>

<Sect1>
<Title>The superblock</Title>

<Para>
The <Literal remap="tt">superblock</Literal> is a block which contains information which describes
the state of the internal filesystem.
</Para>

<Para>
The superblock is located at the <Literal remap="tt">fixed offset 1024</Literal> in the device. Its
length is 1024 bytes also.
</Para>

<Para>
The superblock, like the group descriptors, is copied on each blocks group
boundary for backup purposes. However, only the main copy is used by the
kernel.
</Para>

<Para>
The superblock contain three types of information:

<ItemizedList>
<ListItem>

<Para>
	Filesystem parameters which are fixed and which were determined when
this specific filesystem was created. Some of those parameters can
be different in different installations of the ext2 filesystem, but
can not be changed once the filesystem was created.
</Para>
</ListItem>
<ListItem>

<Para>
	Filesystem parameters which are tunable - Can always be changed.
</Para>
</ListItem>
<ListItem>

<Para>
	Information about the current filesystem state.
</Para>
</ListItem>

</ItemizedList>

</Para>

<Para>
Follows the superblock definition:
</Para>

<Para>

<ProgramListing>
struct ext2_super_block {
	__u32	s_inodes_count;		/* Inodes count */
	__u32	s_blocks_count;		/* Blocks count */
	__u32	s_r_blocks_count;	/* Reserved blocks count */
	__u32	s_free_blocks_count;	/* Free blocks count */
	__u32	s_free_inodes_count;	/* Free inodes count */
	__u32	s_first_data_block;	/* First Data Block */
	__u32	s_log_block_size;	/* Block size */
	__s32	s_log_frag_size;	/* Fragment size */
	__u32	s_blocks_per_group;	/* # Blocks per group */
	__u32	s_frags_per_group;	/* # Fragments per group */
	__u32	s_inodes_per_group;	/* # Inodes per group */
	__u32	s_mtime;		/* Mount time */
	__u32	s_wtime;		/* Write time */
	__u16	s_mnt_count;		/* Mount count */
	__s16	s_max_mnt_count;	/* Maximal mount count */
	__u16	s_magic;		/* Magic signature */
	__u16	s_state;		/* File system state */
	__u16	s_errors;		/* Behaviour when detecting errors */
	__u16	s_pad;
	__u32	s_lastcheck;		/* time of last check */
	__u32	s_checkinterval;	/* max. time between checks */
	__u32	s_creator_os;		/* OS */
	__u32	s_rev_level;		/* Revision level */
	__u16	s_def_resuid;		/* Default uid for reserved blocks */
	__u16	s_def_resgid;		/* Default gid for reserved blocks */
	__u32	s_reserved[235];	/* Padding to the end of the block */
};
</ProgramListing>

</Para>

<Sect2>
<Title>superblock identification</Title>

<Para>
The ext2 filesystem's superblock is identified by the <Literal remap="tt">s&lowbar;magic</Literal> field.
The current ext2 magic number is 0xEF53. I presume that "EF" means "Extended
Filesystem". In versions of the ext2 filesystem prior to 0.2B, the magic
number was 0xEF51. Those filesystems are not compatible with the current
versions; Specifically, the group descriptors definition is different. I
doubt if there still exists such a installation.
</Para>

</Sect2>

<Sect2>
<Title>Filesystem fixed parameters</Title>

<Para>
By using the word <Literal remap="tt">fixed</Literal>, I mean fixed with respect to a particular
installation. Those variables are usually not fixed with respect to
different installations.
</Para>

<Para>
The <Literal remap="tt">block size</Literal> is determined by using the <Literal remap="tt">s&lowbar;log&lowbar;block&lowbar;size</Literal>
variable. The block size is 1024*pow (2,s&lowbar;log&lowbar;block&lowbar;size) and should be
between 1024 and 4096. The available options are 1024, 2048 and 4096.
</Para>

<Para>
<Literal remap="tt">s&lowbar;inodes&lowbar;count</Literal> contains the total number of available inodes.
</Para>

<Para>
<Literal remap="tt">s&lowbar;blocks&lowbar;count</Literal> contains the total number of available blocks.
</Para>

<Para>
<Literal remap="tt">s&lowbar;first&lowbar;data&lowbar;block</Literal> specifies in which of the <Literal remap="tt">device block</Literal> the
<Literal remap="tt">superblock</Literal> is present. The superblock is always present at the fixed
offset 1024, but the device block numbering can differ. For example, if the
block size is 1024, the superblock will be at <Literal remap="tt">block 1</Literal> with respect to
the device. However, if the block size is 4096, offset 1024 is included in
<Literal remap="tt">block 0</Literal> of the device, and in that case <Literal remap="tt">s&lowbar;first&lowbar;data&lowbar;block</Literal>
will contain 0. At least this is how I understood this variable.
</Para>

<Para>
<Literal remap="tt">s&lowbar;blocks&lowbar;per&lowbar;group</Literal> contains the number of blocks which are grouped
together as a blocks group.
</Para>

<Para>
<Literal remap="tt">s&lowbar;inodes&lowbar;per&lowbar;group</Literal> contains the number of inodes available in a group
block. I think that this is always the total number of inodes divided by the
number of blocks groups.
</Para>

<Para>
<Literal remap="tt">s&lowbar;creator&lowbar;os</Literal> contains a code number which specifies the operating
system which created this specific filesystem:

<ItemizedList>
<ListItem>

<Para>
	<Literal remap="tt">Linux</Literal> :-) is specified by the value <Literal remap="tt">0</Literal>.
</Para>
</ListItem>
<ListItem>

<Para>
	<Literal remap="tt">Hurd</Literal> is specified by the value <Literal remap="tt">1</Literal>.
</Para>
</ListItem>
<ListItem>

<Para>
	<Literal remap="tt">Masix</Literal> is specified by the value <Literal remap="tt">2</Literal>.
</Para>
</ListItem>

</ItemizedList>

</Para>

<Para>
<Literal remap="tt">s&lowbar;rev&lowbar;level</Literal> contains the major version of the ext2 filesystem.
Currently this is always <Literal remap="tt">0</Literal>, as the most recent version is 0.5B. It
will probably take some time until we reach version 1.0.
</Para>

<Para>
As far as I know, fragments (sub-block allocations) are currently not
supported and hence a block is equal to a fragment. As a result,
<Literal remap="tt">s&lowbar;log&lowbar;frag&lowbar;size</Literal> and <Literal remap="tt">s&lowbar;frags&lowbar;per&lowbar;group</Literal> are always equal to
<Literal remap="tt">s&lowbar;log&lowbar;block&lowbar;size</Literal> and <Literal remap="tt">s&lowbar;blocks&lowbar;per&lowbar;group</Literal>, respectively.
</Para>

</Sect2>

<Sect2>
<Title>Ext2fs error handling</Title>

<Para>
The ext2 filesystem error handling is based on the following philosophy:

<OrderedList>
<ListItem>

<Para>
	Identification of problems is done by the kernel code.
</Para>
</ListItem>
<ListItem>

<Para>
	The correction task is left to an external utility, such as
<Literal remap="tt">e2fsck by Theodore Ts'o</Literal> for <Literal remap="tt">automatic</Literal> analysis and
correction, or perhaps <Literal remap="tt">debugfs by Theodore Ts'o</Literal> and
<Literal remap="tt">EXT2ED by myself</Literal>, for <Literal remap="tt">hand</Literal> analysis and correction.
</Para>
</ListItem>

</OrderedList>

</Para>

<Para>
The <Literal remap="tt">s&lowbar;state</Literal> variable is used by the kernel to pass the identification
result to third party utilities:

<ItemizedList>
<ListItem>

<Para>
	<Literal remap="tt">bit 0</Literal> of s&lowbar;state is reset when the partition is mounted and
set when the partition is unmounted. Thus, a value of 0 on an
unmounted filesystem means that the filesystem was not unmounted
properly - The filesystem is not "clean" and probably contains
errors.
</Para>
</ListItem>
<ListItem>

<Para>
	<Literal remap="tt">bit 1</Literal> of s&lowbar;state is set by the kernel when it detects an
error in the filesystem. A value of 0 doesn't mean that there isn't
an error in the filesystem, just that the kernel didn't find any.
</Para>
</ListItem>

</ItemizedList>

</Para>

<Para>
The kernel behavior when an error is found is determined by the user tunable
parameter <Literal remap="tt">s&lowbar;errors</Literal>:

<ItemizedList>
<ListItem>

<Para>
	The kernel will ignore the error and continue if <Literal remap="tt">s&lowbar;errors=1</Literal>.
</Para>
</ListItem>
<ListItem>

<Para>
	The kernel will remount the filesystem in read-only mode if
<Literal remap="tt">s&lowbar;errors=2</Literal>.
</Para>
</ListItem>
<ListItem>

<Para>
	A kernel panic will be issued if <Literal remap="tt">s&lowbar;errors=3</Literal>.
</Para>
</ListItem>

</ItemizedList>

</Para>

<Para>
The default behavior is to ignore the error.
</Para>

</Sect2>

<Sect2>
<Title>Additional parameters used by e2fsck</Title>

<Para>
Of-course, <Literal remap="tt">e2fsck</Literal> will check the filesystem if errors were detected
or if the filesystem is not clean.
</Para>

<Para>
In addition, each time the filesystem is mounted, <Literal remap="tt">s&lowbar;mnt&lowbar;count</Literal> is
incremented. When s&lowbar;mnt&lowbar;count reaches <Literal remap="tt">s&lowbar;max&lowbar;mnt&lowbar;count</Literal>, <Literal remap="tt">e2fsck</Literal>
will force a check on the filesystem even though it may be clean. It will
then zero s&lowbar;mnt&lowbar;count. <Literal remap="tt">s&lowbar;max&lowbar;mnt&lowbar;count</Literal> is a tunable parameter.
</Para>

<Para>
E2fsck also records the last time in which the file system was checked in
the <Literal remap="tt">s&lowbar;lastcheck</Literal> variable. The user tunable parameter
<Literal remap="tt">s&lowbar;checkinterval</Literal> will contain the number of seconds which are allowed
to pass since <Literal remap="tt">s&lowbar;lastcheck</Literal> until a check is forced. A value of
<Literal remap="tt">0</Literal> disables time-based check.
</Para>

</Sect2>

<Sect2>
<Title>Additional user tunable parameters</Title>

<Para>
<Literal remap="tt">s&lowbar;r&lowbar;blocks&lowbar;count</Literal> contains the number of disk blocks which are
reserved for root, the user whose id number is <Literal remap="tt">s&lowbar;def&lowbar;resuid</Literal> and the
group whose id number is <Literal remap="tt">s&lowbar;deg&lowbar;resgid</Literal>. The kernel will refuse to
allocate those last <Literal remap="tt">s&lowbar;r&lowbar;blocks&lowbar;count</Literal> if the user is not one of the
above. This is done so that the filesystem will usually not be 100&percnt; full,
since 100&percnt; full filesystems can affect various aspects of operation.
</Para>

<Para>
<Literal remap="tt">s&lowbar;def&lowbar;resuid</Literal> and <Literal remap="tt">s&lowbar;def&lowbar;resgid</Literal> contain the id of the user and
of the group who can use the reserved blocks in addition to root.
</Para>

</Sect2>

<Sect2>
<Title>Filesystem current state</Title>

<Para>
<Literal remap="tt">s&lowbar;free&lowbar;blocks&lowbar;count</Literal> contains the current number of free blocks
in the filesystem.
</Para>

<Para>
<Literal remap="tt">s&lowbar;free&lowbar;inodes&lowbar;count</Literal> contains the current number of free inodes in the
filesystem.
</Para>

<Para>
<Literal remap="tt">s&lowbar;mtime</Literal> contains the time at which the system was last mounted.
</Para>

<Para>
<Literal remap="tt">s&lowbar;wtime</Literal> contains the last time at which something was changed in the
filesystem.
</Para>

</Sect2>

</Sect1>

<Sect1>
<Title>Copyright</Title>

<Para>
This document contains source code which was taken from the Linux ext2
kernel source code, mainly from <FILENAME>/usr/include/linux/ext2&lowbar;fs.h</FILENAME>. Follows
the original copyright:
</Para>

<Para>

<ProgramListing>
/*
 *  linux/include/linux/ext2_fs.h
 *
 * Copyright (C) 1992, 1993, 1994, 1995
 * Remy Card (card@masi.ibp.fr)
 * Laboratoire MASI - Institut Blaise Pascal
 * Universite Pierre et Marie Curie (Paris VI)
 *
 *  from
 *
 *  linux/include/linux/minix_fs.h
 *
 *  Copyright (C) 1991, 1992  Linus Torvalds
 */

</ProgramListing>

</Para>

</Sect1>

<Sect1>
<Title>Acknowledgments</Title>

<Para>
I would like to thank the following people, who were involved in the
design and implementation of the ext2 filesystem kernel code and support
utilities:

<ItemizedList>
<ListItem>

<Para>
	<Literal remap="tt">Remy Card</Literal>

Who designed, implemented and maintains the ext2 filesystem kernel
code, and some of the ext2 utilities. <Literal remap="tt">Remy Card</Literal> is also the
author 	of several helpful slides concerning the ext2 filesystem.
Specifically, he is the author of <Literal remap="tt">File Management in the Linux
Kernel</Literal> and of <Literal remap="tt">The Second Extended File System - Current
State, Future Development</Literal>.

</Para>
</ListItem>
<ListItem>

<Para>
	<Literal remap="tt">Wayne Davison</Literal>

Who designed the ext2 filesystem.
</Para>
</ListItem>
<ListItem>

<Para>
	<Literal remap="tt">Stephen Tweedie</Literal>

Who helped designing the ext2 filesystem kernel code and wrote the
slides <Literal remap="tt">Optimizations in File Systems</Literal>.
</Para>
</ListItem>
<ListItem>

<Para>
	<Literal remap="tt">Theodore Ts'o</Literal>

Who is the author of several ext2 utilities and of the ext2 library
<Literal remap="tt">libext2fs</Literal> (which I didn't use, simply because I didn't know
it exists when I started to work on my project).
</Para>
</ListItem>

</ItemizedList>

</Para>

<Para>
Lastly, I would like to thank, of-course, <Literal remap="tt">Linus Torvalds</Literal> and the
<Literal remap="tt">Linux community</Literal> for providing all of us with such a great operating
system.
</Para>

<Para>
Please contact me in a case of an error report, suggestions, or just about
anything concerning this document.
</Para>

<Para>
Enjoy,
</Para>

<Para>
Gadi Oxman &lt;tgud@tochnapc2.technion.ac.il&gt;
</Para>

<Para>
Haifa, August 95
</Para>

</Sect1>

</Article>